예제 #1
0
    private void render()
    {
        WriteToFile(trackSegment.ToString());
        Transform startPositionMarker = base.transform;
        LandPatch terrain             = GameController.Instance.park.getTerrain(startPositionMarker.position);

        if (terrain == null)
        {
            Object.Destroy(base.gameObject);
        }
        else
        {
            /*
             * Vector3 point = terrain.getPoint (startPositionMarker.position);
             * Vector3 position = startPositionMarker.position;
             * float num = position.y - point.y;
             * if (num < 0.25f) {
             *  Object.Destroy (base.gameObject);
             * }
             * else{
             *  GameObject gameObject = new GameObject();
             *  gameObject.transform.parent = startPositionMarker.transform;
             *  gameObject.transform.localPosition = Vector3.zero;
             *  gameObject.transform.localRotation = Quaternion.identity;
             *  gameObject.transform.parent = base.instance.transform;
             *  Vector3 localScale = base.transform.localScale;
             *  localScale.y = num;
             *  gameObject.transform.localScale = localScale;
             *  BoundingBox boundingBox = base.instance.AddComponent<BoundingBox>();
             *  boundingBox.setManuallyPositioned ();
             *  boundingBox.layers = BoundingVolume.Layers.Support;
             *  boundingBox.setBounds (base.getBounds (startPositionMarker.position, point, 0.12f));
             *  boundingBox.setPosition (startPositionMarker.position, Quaternion.identity);
             *  base.boundingVolumes.Add (boundingBox);
             *  GameObject gameObject2 = Object.Instantiate (base.supportBaseGO);
             *  gameObject2.transform.parent = startPositionMarker.transform;
             *  gameObject2.transform.localPosition = Vector3.zero;
             *  Transform transform = gameObject2.transform;
             *  Vector3 position2 = startPositionMarker.position;
             *  transform.Translate (0f, 0f - (position2.y - point.y), 0f);
             *  gameObject2.transform.localRotation = Quaternion.identity;
             *  gameObject2.transform.parent = base.instance.transform;
             * }
             */
        }
    }
    public override void afterExtrusion(TrackSegment4 trackSegment, GameObject putMeshOnGO)
    {
        base.afterExtrusion(trackSegment, putMeshOnGO);
        float tieInterval = trackSegment.getLength(0) / (float)Mathf.RoundToInt(trackSegment.getLength(0) / this.tieSpacing);
        float pos         = 0;

        // Topper Crossties
        while (pos <= trackSegment.getLength(0) + 0.1f)
        {
            float tForDistance = trackSegment.getTForDistance(pos, 0);
            pos += tieInterval;
            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);

            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();
        }

        //Rendering beams
        int       i       = 0;
        LandPatch terrain = GameController.Instance.park.getTerrain(trackSegment.getStartpoint());

        foreach (SupportPosition position in supportPosts[trackSegment.getStartpoint()])
        {
            if (i > 0)
            {
                if (terrain == null)
                {
                    //left post
                    woodenVerticalSupportPostExtruder.extrude(new Vector3(position.verticalSupportPostLeft.x, position.verticalSupportPostLeft.y + supportBeamExtension, position.verticalSupportPostLeft.z), new Vector3(0, -1, 0), position.verticalSupportPostTangent);
                    woodenVerticalSupportPostExtruder.extrude(position.verticalSupportPostLeft, new Vector3(0, -1, 0), position.verticalSupportPostTangent);
                    woodenVerticalSupportPostExtruder.end();

                    //right post
                    woodenVerticalSupportPostExtruder.extrude(new Vector3(position.verticalSupportPostRight.x, position.verticalSupportPostRight.y + supportBeamExtension, position.verticalSupportPostRight.z), new Vector3(0, -1, 0), position.verticalSupportPostTangent);
                    woodenVerticalSupportPostExtruder.extrude(position.verticalSupportPostRight, new Vector3(0, -1, 0), position.verticalSupportPostTangent);
                    woodenVerticalSupportPostExtruder.end();
                }
                if (!(trackSegment is Station))
                {
                    //bottom beam
                    if (position.bottomBarVisible)
                    {
                        metalCrossTieExtrude(position.bottomBarLeft, position.barsTangent, Vector3.up);
                        metalCrossTieExtrude(position.bottomBarRight, position.barsTangent, Vector3.up);
                        metalCrossTieEnd();
                    }

                    //top beam
                    if (position.topBarVisible)
                    {
                        metalCrossTieExtrude(position.topBarLeft, position.barsTangent, Vector3.up);
                        metalCrossTieExtrude(position.topBarRight, position.barsTangent, Vector3.up);
                        metalCrossTieEnd();
                    }
                }
                //i beam
                if (position.bottomBarVisible)
                {
                    metalIBeamExtrude(position.iBeamLeft, position.iBeamTangent, position.iBeamNormal);
                    metalIBeamExtrude(position.iBeamRight, position.iBeamTangent, position.iBeamNormal);
                    metalIBeamEnd();
                }
                else
                {
                    metalCrossTieExtrude(position.iBeamLeft, position.iBeamTangent, position.iBeamNormal);
                    metalCrossTieExtrude(position.iBeamRight, position.iBeamTangent, position.iBeamNormal);
                    metalCrossTieEnd();
                }
            }
            i++;
        }

        //rendering extruders
        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;
        }
    }
예제 #3
0
    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();
    }
    private void render()
    {
        Transform startPositionMarker = base.transform;
        LandPatch terrain             = GameController.Instance.park.getTerrain(startPositionMarker.position);

        if (terrain == null)
        {
            Object.Destroy(base.gameObject);
        }
        else
        {
            HybridCoasterMeshGenerator meshGenerator = (HybridCoasterMeshGenerator)track.TrackedRide.meshGenerator;
            foreach (SupportPosition position in meshGenerator.supportPosts[trackSegment.getStartpoint()])
            {
                leftVerticalSupportPost   = new Vector3(position.verticalSupportPostLeft.x, position.verticalSupportPostLeft.y + meshGenerator.supportBeamExtension, position.verticalSupportPostLeft.z);
                rightVerticalSupportPost  = new Vector3(position.verticalSupportPostRight.x, position.verticalSupportPostRight.y + meshGenerator.supportBeamExtension, position.verticalSupportPostRight.z);
                projectedTangentDirection = position.verticalSupportPostTangent;

                leftVerticalSupportPost_floor  = GameController.Instance.park.getTerrain(leftVerticalSupportPost).getPoint(leftVerticalSupportPost);
                rightVerticalSupportPost_floor = GameController.Instance.park.getTerrain(rightVerticalSupportPost).getPoint(rightVerticalSupportPost);

                leftVerticalSupportPost_footerHeight = leftVerticalSupportPost_floor.y + 0.1f;
                if (GameController.Instance.park.getTerrain(leftVerticalSupportPost).WaterHeight > leftVerticalSupportPost_footerHeight)
                {
                    leftVerticalSupportPost_footerHeight = GameController.Instance.park.getTerrain(leftVerticalSupportPost).WaterHeight + 0.025f;
                }
                rightVerticalSupportPost_footerHeight = rightVerticalSupportPost_floor.y + 0.1f;
                if (GameController.Instance.park.getTerrain(rightVerticalSupportPost).WaterHeight > rightVerticalSupportPost_footerHeight)
                {
                    rightVerticalSupportPost_footerHeight = GameController.Instance.park.getTerrain(rightVerticalSupportPost).WaterHeight + 0.025f;
                }
                if (leftVerticalSupportPost.y > leftVerticalSupportPost_floor.y)
                {
                    woodenVerticalSupportPostExtruder.extrude(leftVerticalSupportPost, new Vector3(0, -1, 0), projectedTangentDirection);
                    woodenVerticalSupportPostExtruder.extrude(leftVerticalSupportPost_floor, new Vector3(0, -1, 0), projectedTangentDirection);
                    woodenVerticalSupportPostExtruder.end();
                    concreteVerticalSupportFooterExtruder.extrude(new Vector3(leftVerticalSupportPost_floor.x, leftVerticalSupportPost_footerHeight, leftVerticalSupportPost_floor.z), new Vector3(0, -1, 0), projectedTangentDirection);
                    concreteVerticalSupportFooterExtruder.extrude(new Vector3(leftVerticalSupportPost_floor.x, leftVerticalSupportPost_floor.y - 0.05f, leftVerticalSupportPost_floor.z), new Vector3(0, -1, 0), projectedTangentDirection);
                    concreteVerticalSupportFooterExtruder.end();
                }
                if (rightVerticalSupportPost.y > rightVerticalSupportPost_floor.y)
                {
                    woodenVerticalSupportPostExtruder.extrude(rightVerticalSupportPost, new Vector3(0, -1, 0), projectedTangentDirection);
                    woodenVerticalSupportPostExtruder.extrude(rightVerticalSupportPost_floor, new Vector3(0, -1, 0), projectedTangentDirection);
                    woodenVerticalSupportPostExtruder.end();
                    concreteVerticalSupportFooterExtruder.extrude(new Vector3(rightVerticalSupportPost_floor.x, rightVerticalSupportPost_footerHeight, rightVerticalSupportPost_floor.z), new Vector3(0, -1, 0), projectedTangentDirection);
                    concreteVerticalSupportFooterExtruder.extrude(new Vector3(rightVerticalSupportPost_floor.x, rightVerticalSupportPost_floor.y - 0.05f, rightVerticalSupportPost_floor.z), new Vector3(0, -1, 0), projectedTangentDirection);
                    concreteVerticalSupportFooterExtruder.end();
                }
            }

            List <BoxExtruder> extruders = new List <BoxExtruder>();
            if (woodenVerticalSupportPostExtruder.vertices.Count > 0)
            {
                extruders.Add(woodenVerticalSupportPostExtruder);
            }
            if (woodenHorizontalSupportPostExtruder.vertices.Count > 0)
            {
                extruders.Add(woodenHorizontalSupportPostExtruder);
            }
            if (concreteVerticalSupportFooterExtruder.vertices.Count > 0)
            {
                extruders.Add(concreteVerticalSupportFooterExtruder);
            }
            foreach (BoxExtruder extruder in extruders)
            {
                GameObject gameObject = new GameObject("supportObject");
                gameObject.transform.parent        = base.instance.transform;
                gameObject.transform.localPosition = Vector3.zero;
                gameObject.transform.localRotation = Quaternion.identity;
                MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>();
                meshRenderer.sharedMaterial = track.TrackedRide.meshGenerator.material;
                MeshFilter meshFilter = gameObject.AddComponent <MeshFilter>();
                Mesh       mesh       = extruder.getMesh(base.instance.transform.worldToLocalMatrix);
                trackSegment.addGeneratedMesh(mesh);
                meshFilter.mesh = mesh;
            }
        }
    }
예제 #5
0
    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;
        }
    }