Track BuildR Track holds all the point and curve data It is responsible for holding other track based data It also generates all the curve data in Recalculate Data which is used in Generator class It has some functions to allow other scripts to access basic track information
Наследование: MonoBehaviour
Пример #1
0
    public static void ConformTrack(TrackBuildRTrack track, Terrain terrain)
    {
        TerrainData terrainData       = terrain.terrainData;
        int         terrainWidth      = terrainData.heightmapWidth;
        int         terrainHeight     = terrainData.heightmapHeight;
        float       terrainHeightmapY = terrain.terrainData.heightmapScale.y;
        float       terrainY          = terrain.transform.position.y / terrainHeightmapY;
        float       conformAccuracy   = track.conformAccuracy;

        float[,] originalData = terrainData.GetHeights(0, 0, terrainWidth, terrainHeight);

        Bounds trackBounds    = new Bounds();
        int    numberOfCurves = track.numberOfCurves;

        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];
            if (curve.holder == null)
            {
                continue;
            }
            Renderer[] rends = curve.holder.GetComponentsInChildren <Renderer>();
            foreach (Renderer rend in rends)
            {
                trackBounds.Encapsulate(rend.bounds);
            }
        }

        Vector3 trackOffset = track.transform.position - terrain.transform.position;
        Vector3 trackScale  = new Vector3(trackBounds.size.x / terrainData.size.x, 1.0f / terrain.terrainData.size.y, trackBounds.size.z / terrainData.size.z);

        int realNumberOfPoints = track.realNumberOfPoints;

        for (int i = 0; i < realNumberOfPoints; i++)
        {
            TrackBuildRPoint point = track[i];
            Vector3          trackPointPosition = point.position;
            int pointX = Mathf.RoundToInt(((trackPointPosition.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
            int pointY = Mathf.RoundToInt(((trackPointPosition.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

            pointX = Mathf.Clamp(pointX, 0, terrainWidth - 1);
            pointY = Mathf.Clamp(pointY, 0, terrainHeight - 1);

            trackPointPosition.y = originalData[pointY, pointX] * terrain.terrainData.size.y - terrainY + conformAccuracy;
            point.position       = trackPointPosition;

            Vector3 controlPoint = point.forwardControlPoint;
            pointX = Mathf.RoundToInt(((controlPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
            pointY = Mathf.RoundToInt(((controlPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

            pointX = Mathf.Clamp(pointX, 0, terrainWidth - 1);
            pointY = Mathf.Clamp(pointY, 0, terrainHeight - 1);

            controlPoint.y            = originalData[pointY, pointX] * terrain.terrainData.size.y - terrainY + conformAccuracy;
            point.forwardControlPoint = controlPoint;

            point.isDirty = true;
        }
        track.RecalculateCurves();
    }
Пример #2
0
    void OnEnable()
    {
        if (target != null)
        {
            _trackBuildR = (TrackBuildR)target;
            _track = _trackBuildR.track;
        }

        _stageToolbarTexturesA = new Texture2D[numberOfMenuOptionsA];
        _stageToolbarTexturesA[0] = (Texture2D)Resources.Load("GUI/track");
        _stageToolbarTexturesA[1] = (Texture2D)Resources.Load("GUI/boundary");
        _stageToolbarTexturesA[2] = (Texture2D)Resources.Load("GUI/bumpers");
        _stageToolbarTexturesA[3] = (Texture2D)Resources.Load("GUI/textures");
        _stageToolbarTexturesA[4] = (Texture2D)Resources.Load("GUI/terrain");
        _stageToolbarTexturesB = new Texture2D[numberOfMenuOptionsB];
        _stageToolbarTexturesB[0] = (Texture2D)Resources.Load("GUI/stunt");
        _stageToolbarTexturesB[1] = (Texture2D)Resources.Load("GUI/diagram");
        _stageToolbarTexturesB[2] = (Texture2D)Resources.Load("GUI/options");
        _stageToolbarTexturesB[3] = (Texture2D)Resources.Load("GUI/export");

        //Preview Camera
        if (_trackBuildR.trackEditorPreview != null)
            DestroyImmediate(_trackBuildR.trackEditorPreview);
        if (!EditorApplication.isPlaying && SystemInfo.supportsRenderTextures)
        {
            _trackBuildR.trackEditorPreview = new GameObject("Track Preview Cam");
            _trackBuildR.trackEditorPreview.hideFlags = HideFlags.HideAndDontSave;
            _trackBuildR.trackEditorPreview.AddComponent<Camera>();
            _trackBuildR.trackEditorPreview.GetComponent<Camera>().fieldOfView = 80;
            _trackBuildR.trackEditorPreview.GetComponent<Camera>().depth = -99999;
            //Retreive camera settings from the main camera
            Camera[] cams = Camera.allCameras;
            bool sceneHasCamera = cams.Length > 0;
            Camera sceneCamera = null;
            Skybox sceneCameraSkybox = null;
            if (Camera.main)
            {
                sceneCamera = Camera.main;
            }
            else if (sceneHasCamera)
            {
                sceneCamera = cams[0];
            }

            if (sceneCamera != null)
                if (sceneCameraSkybox == null)
                    sceneCameraSkybox = sceneCamera.GetComponent<Skybox>();
            if (sceneCamera != null)
            {
                _trackBuildR.trackEditorPreview.GetComponent<Camera>().backgroundColor = sceneCamera.backgroundColor;
                if (sceneCameraSkybox != null)
                    _trackBuildR.trackEditorPreview.AddComponent<Skybox>().material = sceneCameraSkybox.material;
                else
                    if (RenderSettings.skybox != null)
                        _trackBuildR.trackEditorPreview.AddComponent<Skybox>().material = RenderSettings.skybox;
            }
        }
    }
Пример #3
0
    public void Init()
    {
        track = gameObject.AddComponent <TrackBuildRTrack>();
        track.InitTextures();
        track.baseTransform = transform;

        TrackBuildRPoint p0 = gameObject.AddComponent <TrackBuildRPoint>(); // ScriptableObject.CreateInstance<TrackBuildRPoint>();
        TrackBuildRPoint p1 = gameObject.AddComponent <TrackBuildRPoint>(); //ScriptableObject.CreateInstance<TrackBuildRPoint>();
        TrackBuildRPoint p2 = gameObject.AddComponent <TrackBuildRPoint>(); //ScriptableObject.CreateInstance<TrackBuildRPoint>();
        TrackBuildRPoint p3 = gameObject.AddComponent <TrackBuildRPoint>(); //ScriptableObject.CreateInstance<TrackBuildRPoint>();

        p0.baseTransform = transform;
        p1.baseTransform = transform;
        p2.baseTransform = transform;
        p3.baseTransform = transform;

        p0.position = new Vector3(-20, 0, -20);
        p1.position = new Vector3(20, 0, -20);
        p2.position = new Vector3(20, 0, 20);
        p3.position = new Vector3(-20, 0, 20);

        p0.forwardControlPoint = new Vector3(0, 0, -20);
        p1.forwardControlPoint = new Vector3(40, 0, -20);
        p2.forwardControlPoint = new Vector3(0, 0, 20);
        p3.forwardControlPoint = new Vector3(-40, 0, 20);

        p0.leftForwardControlPoint = new Vector3(-15, 0, -20);
        p1.leftForwardControlPoint = new Vector3(25, 0, -20);
        p2.leftForwardControlPoint = new Vector3(5, 0, 20);
        p3.leftForwardControlPoint = new Vector3(-35, 0, 20);

        p0.rightForwardControlPoint = new Vector3(15, 0, -20);
        p1.rightForwardControlPoint = new Vector3(55, 0, -20);
        p2.rightForwardControlPoint = new Vector3(-5, 0, 20);
        p3.rightForwardControlPoint = new Vector3(-45, 0, 20);

        track.AddPoint(p0);
        track.AddPoint(p1);
        track.AddPoint(p2);
        track.AddPoint(p3);

        generator = gameObject.AddComponent <TrackBuildRGenerator>();

        ForceFullRecalculation();

        track.diagramMesh           = new Mesh();
        track.diagramMesh.vertices  = new [] { new Vector3(-1, 0, -1), new Vector3(1, 0, -1), new Vector3(-1, 0, 1), new Vector3(1, 0, 1) };
        track.diagramMesh.uv        = new [] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1) };
        track.diagramMesh.triangles = new [] { 1, 0, 2, 1, 2, 3 };

        track.diagramGO = new GameObject("Diagram");
        track.diagramGO.transform.parent                 = transform;
        track.diagramGO.transform.localPosition          = Vector3.zero;
        track.diagramGO.AddComponent <MeshFilter>().mesh = track.diagramMesh;
        track.diagramMaterial = new Material(Shader.Find("Unlit/Texture"));
        track.diagramGO.AddComponent <MeshRenderer>().material   = track.diagramMaterial;
        track.diagramGO.AddComponent <MeshCollider>().sharedMesh = track.diagramMesh;
    }
Пример #4
0
    /// <summary>
    /// unfinished!
    /// </summary>
    /// <param name="track"></param>
    /// <param name="selectedPoint"></param>
    public static void AddTwist(TrackBuildRTrack track, int selectedPoint)
    {
        TrackBuildRPoint atPoint   = track[selectedPoint];
        TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1);

        float      twistDistance      = Mathf.Min((lastPoint.arcLength + atPoint.arcLength) * 0.333f, track.maxJumpLength);
        Vector3    twistDirection     = atPoint.trackDirection;
        Vector3    twistMiddle        = atPoint.worldPosition;
        Vector3    twistUp            = atPoint.trackUp;
        Vector3    twistAxis          = Vector3.Cross(twistDirection, twistUp);
        float      twistRadius        = track.twistRadius;
        Vector3    twistStartPosition = -twistDirection * (twistDistance * 0.33f);
        Vector3    twistEndPosition   = twistDirection * (twistDistance * 0.33f);
        Vector3    twistCentreHeight  = twistUp * twistRadius;
        Quaternion twistAngle         = Quaternion.LookRotation(twistDirection, twistUp);
        Vector3    twistCenter        = atPoint.worldPosition + Vector3.up * twistRadius;
        float      controlPointLength = twistRadius / (Mathf.PI);

        int   numberOfPoints = track.twistPoints;
        float arcPercent     = 1.0f / numberOfPoints;

        TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[numberOfPoints + 1];
        for (int i = 0; i < numberOfPoints; i++)
        {
            float   pointArcPercent   = arcPercent * i;
            float   radA              = Mathf.PI * 2 * (pointArcPercent + 0.5f);
            Vector3 pointLoopPosition = twistAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * twistRadius);
            float   smoothI           = pointArcPercent * pointArcPercent * (3.0f - 2.0f * pointArcPercent);
            Vector3 lateral           = Vector3.Lerp(twistStartPosition, twistEndPosition, pointArcPercent + (pointArcPercent - smoothI));
            Vector3 pointPosition     = (pointLoopPosition) + lateral;
            Vector3 pointDirection    = Vector3.Cross(-pointLoopPosition, twistAxis).normalized;

            TrackBuildRPoint newTrackPoint = track.InsertPoint(selectedPoint + 1 + i);
            newTrackPoint.worldPosition       = twistCenter + pointPosition;
            newTrackPoint.trackUpQ            = Quaternion.LookRotation(-pointLoopPosition, pointDirection);
            newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength);
            loopPoints[i] = newTrackPoint;
        }
        atPoint.worldPosition      += twistStartPosition;
        atPoint.trackUpQ            = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection);
        atPoint.forwardControlPoint = atPoint.worldPosition + (twistDirection * controlPointLength) - twistAxis;
        loopPoints[6] = atPoint;
        //                    _trackBuildR.pointMode = TrackBuildR.pointModes.transform;

        for (int i = 0; i < numberOfPoints + 1; i++)
        {
            loopPoints[i].extrudeTrack       = true;
            loopPoints[i].extrudeTrackBottom = true;
            loopPoints[i].extrudeLength      = 0.5f;
            loopPoints[i].RecalculateStoredValues();
        }
    }
Пример #5
0
    public static void AddLoop(TrackBuildRTrack track, int selectedPointIndex)
    {
        TrackBuildRPoint atPoint = track[selectedPointIndex];
        int     atPointIndex     = selectedPointIndex;
        float   loopRadius       = track.loopRadius;
        float   trackWidth       = atPoint.width;
        Vector3 trackDirection   = atPoint.trackDirection.normalized;
        Vector3 trackUp          = atPoint.trackUpQ * Vector3.forward;
        Vector3 trackCross       = atPoint.trackCross;

        Vector3    entryPosition       = atPoint.worldPosition + (trackCross * trackWidth * 0.6f);
        Vector3    loopAxis            = Vector3.Cross(trackDirection, trackUp);
        Vector3    loopCenter          = atPoint.worldPosition + Vector3.up * loopRadius;
        Quaternion loopAngle           = Quaternion.FromToRotation(Vector3.right, trackDirection);
        float      controlPointLength  = loopRadius / (Mathf.PI);
        Vector3    controlPointLateral = -loopAxis;

        int   numberOfPoints = 6;
        float arcPercent     = 1.0f / numberOfPoints;

        TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[7];
        for (int i = 0; i < numberOfPoints; i++)
        {
            float            pointArcPercent   = arcPercent * i;
            TrackBuildRPoint newTrackPoint     = track.InsertPoint(atPointIndex + 1);
            float            rad               = Mathf.PI * 2 * (pointArcPercent + 0.5f);
            Vector3          pointLoopPosition = loopAngle * ((new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0)) * loopRadius);
            Vector3          lateral           = Vector3.Lerp((trackCross * trackWidth * -0.6f), (trackCross * trackWidth * 0.6f), pointArcPercent);
            Vector3          pointPosition     = (pointLoopPosition) + lateral;
            Vector3          pointDirection    = Vector3.Cross(-pointLoopPosition, loopAxis).normalized;
            newTrackPoint.worldPosition       = loopCenter + pointPosition;
            newTrackPoint.trackUpQ            = Quaternion.LookRotation(-pointLoopPosition, pointDirection);
            newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength) - controlPointLateral;
            loopPoints[i] = newTrackPoint;
        }
        atPoint.worldPosition       = entryPosition;
        atPoint.trackUpQ            = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection);
        atPoint.forwardControlPoint = atPoint.worldPosition + (trackDirection * controlPointLength) + controlPointLateral;
        loopPoints[6] = atPoint;
        //                    _trackBuildR.pointMode = TrackBuildR.pointModes.transform;

        for (int i = 0; i < numberOfPoints + 1; i++)
        {
            loopPoints[i].extrudeTrack       = true;
            loopPoints[i].extrudeTrackBottom = true;
            loopPoints[i].extrudeLength      = 0.5f;
            loopPoints[i].RecalculateStoredValues();
        }
    }
Пример #6
0
    public static void AddLoop(TrackBuildRTrack track, int selectedPointIndex)
    {
        TrackBuildRPoint atPoint = track[selectedPointIndex];
        int atPointIndex = selectedPointIndex;
        float loopRadius = track.loopRadius;
        float trackWidth = atPoint.width;
        Vector3 trackDirection = atPoint.trackDirection.normalized;
        Vector3 trackUp = atPoint.trackUpQ * Vector3.forward;
        Vector3 trackCross = atPoint.trackCross;

        Vector3 entryPosition = atPoint.worldPosition + (trackCross * trackWidth * 0.6f);
        Vector3 loopAxis = Vector3.Cross(trackDirection, trackUp);
        Vector3 loopCenter = atPoint.worldPosition + Vector3.up * loopRadius;
        Quaternion loopAngle = Quaternion.FromToRotation(Vector3.right, trackDirection);
        float controlPointLength = loopRadius / (Mathf.PI);
        Vector3 controlPointLateral = -loopAxis;

        int numberOfPoints = 6;
        float arcPercent = 1.0f / numberOfPoints;
        TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[7];
        for (int i = 0; i < numberOfPoints; i++)
        {
            float pointArcPercent = arcPercent * i;
            TrackBuildRPoint newTrackPoint = track.InsertPoint(atPointIndex + 1);
            float rad = Mathf.PI * 2 * (pointArcPercent + 0.5f);
            Vector3 pointLoopPosition = loopAngle * ((new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0)) * loopRadius);
            Vector3 lateral = Vector3.Lerp((trackCross * trackWidth * -0.6f), (trackCross * trackWidth * 0.6f), pointArcPercent);
            Vector3 pointPosition = (pointLoopPosition) + lateral;
            Vector3 pointDirection = Vector3.Cross(-pointLoopPosition, loopAxis).normalized;
            newTrackPoint.worldPosition = loopCenter + pointPosition;
            newTrackPoint.trackUpQ = Quaternion.LookRotation(-pointLoopPosition, pointDirection);
            newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength) - controlPointLateral;
            loopPoints[i] = newTrackPoint;
        }
        atPoint.worldPosition = entryPosition;
        atPoint.trackUpQ = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection);
        atPoint.forwardControlPoint = atPoint.worldPosition + (trackDirection * controlPointLength) + controlPointLateral;
        loopPoints[6] = atPoint;
        //                    _trackBuildR.pointMode = TrackBuildR.pointModes.transform;

        for (int i = 0; i < numberOfPoints + 1; i++)
        {
            loopPoints[i].extrudeTrack = true;
            loopPoints[i].extrudeTrackBottom = true;
            loopPoints[i].extrudeLength = 0.5f;
            loopPoints[i].RecalculateStoredValues();
        }
    }
Пример #7
0
    public static void AddJumpTwist(TrackBuildRTrack track, int selectedPoint)
    {
        TrackBuildRPoint atPoint   = track[selectedPoint];
        TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1);
        TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1);

        float trackPartDistance = lastPoint.arcLength + atPoint.arcLength;
        float jumpDistance      = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength);

        float      trackWidth      = atPoint.width * 0.5f;
        Vector3    startCross      = atPoint.trackCross;
        Vector3    jumpDirection   = atPoint.trackDirection;
        Vector3    jumpMiddle      = atPoint.worldPosition;
        Quaternion atPointUpQ      = atPoint.trackUpQ;
        Quaternion trackUpJump     = Quaternion.AngleAxis(track.twistAngle, -jumpDirection);
        Quaternion trackCrossExit  = trackUpJump * (atPointUpQ);
        Quaternion trackCrossEntry = Quaternion.Inverse(trackUpJump) * (atPointUpQ);
        Vector3    jumpLateral     = startCross * track.twistAngle / 33.3f;

        Vector3 jumpHeight        = atPointUpQ * (Vector3.forward * track.jumpHeight);
        Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f) + jumpHeight - jumpLateral;
        Vector3 jumpEndPosition   = jumpMiddle + jumpDirection * (jumpDistance * 0.33f) + jumpHeight + jumpLateral;

        lastPoint.extrudeTrack       = true;
        lastPoint.extrudeLength      = track.jumpHeight;
        lastPoint.extrudeCurveEnd    = true;
        lastPoint.extrudeTrackBottom = true;

        atPoint.Reset();
        atPoint.worldPosition       = jumpStartPosition;
        atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight;
        atPoint.trackUpQ            = trackCrossExit;
        atPoint.render = false;

        TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1);

        jumpEnd.worldPosition       = jumpEndPosition;
        jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition - jumpHeight;
        jumpEnd.trackUpQ            = trackCrossEntry;
        jumpEnd.extrudeTrack        = true;
        jumpEnd.extrudeLength       = track.jumpHeight;
        jumpEnd.extrudeCurveEnd     = true;
        jumpEnd.extrudeTrackBottom  = true;

        atPoint.RecalculateStoredValues();
        jumpEnd.RecalculateStoredValues();
    }
Пример #8
0
    public static void ResetTerrain(TrackBuildRTrack track, Terrain terrain)
    {
        TerrainData terrainData   = terrain.terrainData;
        int         terrainWidth  = terrainData.heightmapWidth;
        int         terrainHeight = terrainData.heightmapHeight;

        float[,] tData = terrainData.GetHeights(0, 0, terrainWidth, terrainHeight);
        for (int x = 0; x < terrainWidth; x++)
        {
            for (int y = 0; y < terrainHeight; y++)
            {
                tData[x, y] = 1;
            }
        }

        terrainData.SetHeights(0, 0, tData);
        terrain.terrainData = terrainData;
    }
Пример #9
0
    public void Start()
    {
        //find nearest curve
        trackData = track.track;
        float nearestCurveDistance = Mathf.Infinity;
        int   numberOfCurves       = trackData.numberOfCurves;

        for (int i = 0; i < numberOfCurves; i++)
        {
            Vector3 curveCenter  = trackData[i].center;
            float   thisDistance = (curveCenter - transform.position).sqrMagnitude;
            if (thisDistance < nearestCurveDistance)
            {
//                curveIndex = i;
                nearestCurveDistance = thisDistance;
            }
        }

        //        TrackBuildRCurve curve = trackData.Curve(curveIndex);
    }
Пример #10
0
    public static void AddJump(TrackBuildRTrack track, int selectedPoint)
    {
        TrackBuildRPoint atPoint   = track[selectedPoint];
        TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1);
        TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1);

        float trackPartDistance = lastPoint.arcLength + atPoint.arcLength;
        float jumpDistance      = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength);

        Vector3    jumpDirection = atPoint.trackDirection;
        Vector3    jumpMiddle    = atPoint.worldPosition;
        Vector3    startCross    = atPoint.trackCross;
        float      trackWidth    = atPoint.width * 0.5f;
        Quaternion trackUp       = atPoint.trackUpQ;

        Vector3 jumpHeight        = trackUp * (Vector3.forward * track.jumpHeight);
        Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f);
        Vector3 jumpEndPosition   = jumpMiddle + jumpDirection * (jumpDistance * 0.33f);

        lastPoint.extrudeTrack    = true;
        lastPoint.extrudeLength   = track.jumpHeight;
        lastPoint.extrudeCurveEnd = true;

        atPoint.Reset();
        atPoint.worldPosition       = jumpStartPosition + jumpHeight;
        atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight * 2;
        atPoint.trackUpQ            = trackUp;
        atPoint.render = false;

        TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1);

        jumpEnd.worldPosition       = jumpEndPosition + jumpHeight;
        jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition;
        jumpEnd.trackUpQ            = trackUp;
        jumpEnd.extrudeTrack        = true;
        jumpEnd.extrudeLength       = track.jumpHeight;
        jumpEnd.extrudeCurveEnd     = true;

        atPoint.RecalculateStoredValues();
        jumpEnd.RecalculateStoredValues();
    }
Пример #11
0
    public static void AddJump(TrackBuildRTrack track, int selectedPoint)
    {
        TrackBuildRPoint atPoint = track[selectedPoint];
        TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1);
//        TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1);

        float trackPartDistance = lastPoint.arcLength + atPoint.arcLength;
        float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength);

        Vector3 jumpDirection = atPoint.trackDirection;
        Vector3 jumpMiddle = atPoint.worldPosition;
//        Vector3 startCross = atPoint.trackCross;
//        float trackWidth = atPoint.width * 0.5f;
        Quaternion trackUp = atPoint.trackUpQ;

        Vector3 jumpHeight = trackUp * (Vector3.forward * track.jumpHeight);
        Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f);
        Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f);

        lastPoint.extrudeTrack = true;
        lastPoint.extrudeLength = track.jumpHeight;
        lastPoint.extrudeCurveEnd = true;

        atPoint.Reset();
        atPoint.worldPosition = jumpStartPosition + jumpHeight;
        atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight * 2;
        atPoint.trackUpQ = trackUp;
        atPoint.render = false;

        TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1);
        jumpEnd.worldPosition = jumpEndPosition + jumpHeight;
        jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition;
        jumpEnd.trackUpQ = trackUp;
        jumpEnd.extrudeTrack = true;
        jumpEnd.extrudeLength = track.jumpHeight;
        jumpEnd.extrudeCurveEnd = true;

        atPoint.RecalculateStoredValues();
        jumpEnd.RecalculateStoredValues();
    }
Пример #12
0
    public static void MergeTerrain(TrackBuildRTrack track, Terrain terrain)
    {
        TerrainData terrainData = terrain.terrainData;
        int terrainWidth = terrainData.heightmapWidth;
        int terrainHeight = terrainData.heightmapHeight;
        float terrainHeightmapY = terrain.terrainData.heightmapScale.y;
        float terrainY = terrain.transform.position.y / terrainHeightmapY;
        Vector3 meshScale = terrainData.heightmapScale;
        float terrainAccuracy = track.terrainAccuracy;
        float terrainMergeMargin = track.terrainMergeMargin;
        float trackY = track.transform.position.y;

        float[,] originalData = terrainData.GetHeights(0, 0, terrainWidth, terrainHeight);
        float[,] mergeData = new float[terrainWidth, terrainHeight];
        float[,] modifiedData = new float[terrainWidth, terrainHeight];
        int[,] modifiedPointLock = new int[terrainWidth, terrainHeight];

        Bounds trackBounds = new Bounds();
        int numberOfCurves = track.numberOfCurves;
        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];
            if(curve.holder == null)
                continue;
            Renderer[] rends = curve.holder.GetComponentsInChildren<Renderer>();
            foreach (Renderer rend in rends)
            {
                trackBounds.Encapsulate(rend.bounds);
            }
        }

        Vector3 trackOffset = track.transform.position - terrain.transform.position;
        Vector3 trackScale = new Vector3(trackBounds.size.x / terrainData.size.x, 1.0f / terrain.terrainData.size.y, trackBounds.size.z / terrainData.size.z);

        float mergeWidth = track.terrainMergeWidth;
        AnimationCurve mergeCurve = track.mergeCurve;
        float minScaleUnit = Mathf.Min(meshScale.x, meshScale.z);
        Vector3 trackHeightMod = new Vector3(0,trackY,0);
        for(int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];
            int storedPointSize = curve.storedPointSize;
            for(int p = 0; p < storedPointSize-1; p++)
            {
                Vector3 pointA = curve.sampledPoints[p] + trackHeightMod;
                Vector3 pointB = curve.sampledPoints[p + 1] + trackHeightMod;
                Vector3 crossA = curve.sampledTrackCrosses[p];
                Vector3 crossB = curve.sampledTrackCrosses[p+1];
                float widthA = curve.sampledWidths[p] * terrainMergeMargin;
                float widthB = curve.sampledWidths[p + 1] * terrainMergeMargin;
//                float heightA = (pointA.y - terrainAccuracy) * trackScale.y - terrainY;
//                float heightB = (pointB.y - terrainAccuracy) * trackScale.y - terrainY;

                Vector3 lpointA = (pointA - crossA * (widthA + mergeWidth));
                Vector3 rpointA = (pointA + crossA * (widthA + mergeWidth));
                Vector3 lpointB = (pointB - crossB * (widthB + mergeWidth));
                Vector3 rpointB = (pointB + crossB * (widthB + mergeWidth));

                float crownA = curve.sampledCrowns[p] - terrainAccuracy;
                float crownB = curve.sampledCrowns[p + 1] - terrainAccuracy;

                float pointDistanceLeft = Vector3.Distance(lpointA, lpointB) * 1.8f;
                float pointDistanceRight = Vector3.Distance(rpointA, rpointB) * 1.8f;
                float pointDistance = Mathf.Max(pointDistanceLeft, pointDistanceRight);
                float pointFillResolution = minScaleUnit/ pointDistance * 0.125f;

                float heightLA = (lpointA.y - terrainAccuracy) * trackScale.y - terrainY;
                float heightRA = (rpointA.y - terrainAccuracy) * trackScale.y - terrainY;
                float heightLB = (lpointB.y - terrainAccuracy) * trackScale.y - terrainY;
                float heightRB = (rpointB.y - terrainAccuracy) * trackScale.y - terrainY;

                for (float pf = 0; pf < 1; pf += pointFillResolution)//point a to point b
                {
                    //Track Filler
                    Vector3 fillPoint = Vector3.Lerp(pointA, pointB, pf);
                    Vector3 fillCross = Vector3.Lerp(crossA, crossB, pf);
                    float fillWidth = Mathf.Lerp(widthA, widthB, pf);// *1.2f;
                    float fillCrown = Mathf.Lerp(crownA, crownB, pf);// *1.2f;
                    float fillTrackHeightL = Mathf.Lerp(heightLA, heightLB, pf);
                    float fillTrackHeightR = Mathf.Lerp(heightRA, heightRB, pf);

                    Vector3 leftTrackPoint = fillPoint - fillCross * fillWidth;
                    Vector3 rightTrackPoint = fillPoint + fillCross * fillWidth;

                    int leftX = Mathf.RoundToInt(((leftTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int leftY = Mathf.RoundToInt(((leftTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    int rightX = Mathf.RoundToInt(((rightTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int rightY = Mathf.RoundToInt(((rightTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

                    int diffX = leftX - rightX;
                    int diffY = leftY - rightY;
                    int trackCrossFillAmount = Mathf.Max(Mathf.Abs(diffX),1) * Mathf.Max(Mathf.Abs(diffY),1);
                    for (int f = 0; f < trackCrossFillAmount; f++)//left to right
                    {
                        float move = f / (float)trackCrossFillAmount;
                        int fillX = Mathf.RoundToInt(Mathf.Lerp(leftX, rightX, move));
                        int fillY = Mathf.RoundToInt(Mathf.Lerp(leftY, rightY, move));
                        if(fillX < 0 || fillY < 0 || fillX >= terrainWidth || fillY >= terrainHeight)
                            continue;
                        float crownHeight = Mathf.Sin(move * Mathf.PI) * fillCrown / terrainHeightmapY;
                        float fillTrackHeight = Mathf.Lerp(fillTrackHeightL, fillTrackHeightR, move) + crownHeight;
                        int currentPointLock = modifiedPointLock[fillY, fillX];
                        if (currentPointLock == 0 || mergeData[fillY, fillX] > fillTrackHeight)
                            mergeData[fillY, fillX] = fillTrackHeight;
                        modifiedPointLock[fillY, fillX] = 1;//point lock
                    }

                    //Merge
                    Vector3 leftMergePoint = leftTrackPoint - fillCross * mergeWidth;

                    int leftMergeLeftX = Mathf.RoundToInt(((leftMergePoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int leftMergeLeftY = Mathf.RoundToInt(((leftMergePoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    int leftMergeRightX = Mathf.RoundToInt(((leftTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int leftMergeRightY = Mathf.RoundToInt(((leftTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
//                  
                    int leftMergeDiffX = leftMergeLeftX - leftMergeRightX;
                    int leftMergeDiffY = leftMergeLeftY - leftMergeRightY;
                    int leftMergeFillAmount = Mathf.Max(Mathf.Abs(leftMergeDiffX), 1) * Mathf.Max(Mathf.Abs(leftMergeDiffY), 1);// Mathf.Max(Mathf.Abs(leftMergeDiffX), Mathf.Abs(leftMergeDiffY));
                    for (int f = 0; f < leftMergeFillAmount; f++)
                    {
                        float move = f / (float)leftMergeFillAmount;
                        int fillX = Mathf.RoundToInt(Mathf.Lerp(leftMergeLeftX, leftMergeRightX, move));
                        int fillY = Mathf.RoundToInt(Mathf.Lerp(leftMergeLeftY, leftMergeRightY, move));
                        if (fillX < 0 || fillY < 0 || fillX >= terrainWidth || fillY >= terrainHeight)
                            continue;
                        float curveStrength = mergeCurve.Evaluate(move);
                        float fillTrackHeight = fillTrackHeightL;
                        float mergeHeight = Mathf.Lerp(originalData[fillY, fillX], fillTrackHeight, curveStrength);
                        int pointLock = modifiedPointLock[fillY, fillX];
                        float currentMergeHeight = mergeData[fillY, fillX];
                        float currentDifference = Mathf.Abs(currentMergeHeight - fillTrackHeight);
                        float newDifference = Mathf.Abs(mergeHeight - fillTrackHeight);
                        if (newDifference < currentDifference && pointLock == 0)
                        {
                            mergeData[fillY, fillX] = mergeHeight;
                        }
                    }

                    Vector3 rightMergePoint = rightTrackPoint + fillCross * mergeWidth;
                    int rightMergeLeftX = Mathf.RoundToInt(((rightMergePoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int rightMergeLeftY = Mathf.RoundToInt(((rightMergePoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    int rightMergeRightX = Mathf.RoundToInt(((rightTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int rightMergeRightY = Mathf.RoundToInt(((rightTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    
                    //                  
                    int rightMergeDiffX = rightMergeLeftX - rightMergeRightX;
                    int rightMergeDiffY = rightMergeLeftY - rightMergeRightY;
                    int rightMergeFillAmount = Mathf.Max(Mathf.Abs(rightMergeDiffX),1) * Mathf.Max(Mathf.Abs(rightMergeDiffY),1);// Mathf.Max(Mathf.Abs(leftMergeDiffX), Mathf.Abs(leftMergeDiffY));
                    for (int f = 0; f < rightMergeFillAmount; f++)
                    {
                        float move = f / (float)rightMergeFillAmount;
                        int fillX = Mathf.RoundToInt(Mathf.Lerp(rightMergeLeftX, rightMergeRightX, move));
                        int fillY = Mathf.RoundToInt(Mathf.Lerp(rightMergeLeftY, rightMergeRightY, move));
                        if (fillX < 0 || fillY < 0 || fillX >= terrainWidth || fillY >= terrainHeight)
                            continue;
                        float curveStrength = mergeCurve.Evaluate(move);
                        float fillTrackHeight = fillTrackHeightR;
                        float mergeHeight = Mathf.Lerp(originalData[fillY, fillX], fillTrackHeight, curveStrength);
                        int pointLock = modifiedPointLock[fillY, fillX];
                        float currentMergeHeight = mergeData[fillY, fillX];
                        float currentDifference = Mathf.Abs(currentMergeHeight - fillTrackHeight);
                        float newDifference = Mathf.Abs(mergeHeight - fillTrackHeight);
                        if (newDifference < currentDifference && pointLock == 0)
                        {
                            mergeData[fillY, fillX] = mergeHeight;
                        }
                    }
                }
            }
        }

        for(int x = 0; x < terrainWidth; x++)
        {
            for(int y = 0; y < terrainHeight; y++)
            {
                bool isNotEdge = x > 0 && x < terrainWidth-1 && y > 0 && y < terrainHeight-1;
                if (mergeData[x, y] == 0)
                {
                    int mergeNeighbours = 0;
                    if(isNotEdge)
                    {
                        mergeNeighbours += (mergeData[x+1, y] != 0) ? 1 : 0;
                        mergeNeighbours += (mergeData[x-1, y] != 0) ? 1 : 0;
                        mergeNeighbours += (mergeData[x, y+1] != 0) ? 1 : 0;
                        mergeNeighbours += (mergeData[x, y-1] != 0) ? 1 : 0;
                    }
                    if(mergeNeighbours > 1)//if a hole is surounded by rasied terrain in two or more neighbouring places
                    {
                        float mergeHeight = 0;
                        mergeHeight += (mergeData[x + 1, y] != 0) ? mergeData[x + 1, y] : 0;
                        mergeHeight += (mergeData[x - 1, y] != 0) ? mergeData[x - 1, y] : 0;
                        mergeHeight += (mergeData[x, y + 1] != 0) ? mergeData[x, y + 1] : 0;
                        mergeHeight += (mergeData[x, y - 1] != 0) ? mergeData[x, y - 1] : 0;
                        modifiedData[x, y] = mergeHeight / mergeNeighbours;//clean up holes
                    }
                    else
                    {
                        modifiedData[x, y] = originalData[x, y];//use original
                    }
                }
                else
                {
                    modifiedData[x, y] = mergeData[x, y];
                }
            }
        }

        terrainData.SetHeights(0, 0, modifiedData);
        terrain.terrainData = terrainData;
    }
Пример #13
0
    public static void MergeTerrain(TrackBuildRTrack track, Terrain terrain)
    {
        TerrainData terrainData        = terrain.terrainData;
        int         terrainWidth       = terrainData.heightmapWidth;
        int         terrainHeight      = terrainData.heightmapHeight;
        float       terrainHeightmapY  = terrain.terrainData.heightmapScale.y;
        float       terrainY           = terrain.transform.position.y / terrainHeightmapY;
        Vector3     meshScale          = terrainData.heightmapScale;
        float       terrainAccuracy    = track.terrainAccuracy;
        float       terrainMergeMargin = track.terrainMergeMargin;

        float[,] originalData    = terrainData.GetHeights(0, 0, terrainWidth, terrainHeight);
        float[,] mergeData       = new float[terrainWidth, terrainHeight];
        float[,] modifiedData    = new float[terrainWidth, terrainHeight];
        int[,] modifiedPointLock = new int[terrainWidth, terrainHeight];

        Bounds trackBounds    = new Bounds();
        int    numberOfCurves = track.numberOfCurves;

        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];
            if (curve.holder == null)
            {
                continue;
            }
            Renderer[] rends = curve.holder.GetComponentsInChildren <Renderer>();
            foreach (Renderer rend in rends)
            {
                trackBounds.Encapsulate(rend.bounds);
            }
        }

        Vector3 trackOffset = track.transform.position - terrain.transform.position;
        Vector3 trackScale  = new Vector3(trackBounds.size.x / terrainData.size.x, 1.0f / terrain.terrainData.size.y, trackBounds.size.z / terrainData.size.z);

        float          mergeWidth   = track.terrainMergeWidth;
        AnimationCurve mergeCurve   = track.mergeCurve;
        float          minScaleUnit = Mathf.Min(meshScale.x, meshScale.z);

        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];
            int storedPointSize    = curve.storedPointSize;
            for (int p = 0; p < storedPointSize - 1; p++)
            {
                Vector3 pointA = curve.sampledPoints[p];
                Vector3 pointB = curve.sampledPoints[p + 1];
                Vector3 crossA = curve.sampledTrackCrosses[p];
                Vector3 crossB = curve.sampledTrackCrosses[p + 1];
                float   widthA = curve.sampledWidths[p] * terrainMergeMargin;
                float   widthB = curve.sampledWidths[p + 1] * terrainMergeMargin;
//                float heightA = (pointA.y - terrainAccuracy) * trackScale.y - terrainY;
//                float heightB = (pointB.y - terrainAccuracy) * trackScale.y - terrainY;

                Vector3 lpointA = (pointA - crossA * (widthA + mergeWidth));
                Vector3 rpointA = (pointA + crossA * (widthA + mergeWidth));
                Vector3 lpointB = (pointB - crossB * (widthB + mergeWidth));
                Vector3 rpointB = (pointB + crossB * (widthB + mergeWidth));

                float crownA = curve.sampledCrowns[p] - terrainAccuracy;
                float crownB = curve.sampledCrowns[p + 1] - terrainAccuracy;

                float pointDistanceLeft   = Vector3.Distance(lpointA, lpointB) * 1.8f;
                float pointDistanceRight  = Vector3.Distance(rpointA, rpointB) * 1.8f;
                float pointDistance       = Mathf.Max(pointDistanceLeft, pointDistanceRight);
                float pointFillResolution = minScaleUnit / pointDistance * 0.125f;

                float heightLA = (lpointA.y - terrainAccuracy) * trackScale.y - terrainY;
                float heightRA = (rpointA.y - terrainAccuracy) * trackScale.y - terrainY;
                float heightLB = (lpointB.y - terrainAccuracy) * trackScale.y - terrainY;
                float heightRB = (rpointB.y - terrainAccuracy) * trackScale.y - terrainY;

                for (float pf = 0; pf < 1; pf += pointFillResolution)//point a to point b
                {
                    //Track Filler
                    Vector3 fillPoint        = Vector3.Lerp(pointA, pointB, pf);
                    Vector3 fillCross        = Vector3.Lerp(crossA, crossB, pf);
                    float   fillWidth        = Mathf.Lerp(widthA, widthB, pf); // *1.2f;
                    float   fillCrown        = Mathf.Lerp(crownA, crownB, pf); // *1.2f;
                    float   fillTrackHeightL = Mathf.Lerp(heightLA, heightLB, pf);
                    float   fillTrackHeightR = Mathf.Lerp(heightRA, heightRB, pf);

                    Vector3 leftTrackPoint  = fillPoint - fillCross * fillWidth;
                    Vector3 rightTrackPoint = fillPoint + fillCross * fillWidth;

                    int leftX  = Mathf.RoundToInt(((leftTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int leftY  = Mathf.RoundToInt(((leftTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    int rightX = Mathf.RoundToInt(((rightTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int rightY = Mathf.RoundToInt(((rightTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

                    int diffX = leftX - rightX;
                    int diffY = leftY - rightY;
                    int trackCrossFillAmount = Mathf.Max(Mathf.Abs(diffX), 1) * Mathf.Max(Mathf.Abs(diffY), 1);
                    for (int f = 0; f < trackCrossFillAmount; f++)//left to right
                    {
                        float move  = f / (float)trackCrossFillAmount;
                        int   fillX = Mathf.RoundToInt(Mathf.Lerp(leftX, rightX, move));
                        int   fillY = Mathf.RoundToInt(Mathf.Lerp(leftY, rightY, move));
                        if (fillX < 0 || fillY < 0 || fillX >= terrainWidth || fillY >= terrainHeight)
                        {
                            continue;
                        }
                        float crownHeight      = Mathf.Sin(move * Mathf.PI) * fillCrown / terrainHeightmapY;
                        float fillTrackHeight  = Mathf.Lerp(fillTrackHeightL, fillTrackHeightR, move) + crownHeight;
                        int   currentPointLock = modifiedPointLock[fillY, fillX];
                        if (currentPointLock == 0 || mergeData[fillY, fillX] > fillTrackHeight)
                        {
                            mergeData[fillY, fillX] = fillTrackHeight;
                        }
                        modifiedPointLock[fillY, fillX] = 1;//point lock
                    }

                    //Merge
                    Vector3 leftMergePoint = leftTrackPoint - fillCross * mergeWidth;

                    int leftMergeLeftX  = Mathf.RoundToInt(((leftMergePoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int leftMergeLeftY  = Mathf.RoundToInt(((leftMergePoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    int leftMergeRightX = Mathf.RoundToInt(((leftTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int leftMergeRightY = Mathf.RoundToInt(((leftTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
//
                    int leftMergeDiffX      = leftMergeLeftX - leftMergeRightX;
                    int leftMergeDiffY      = leftMergeLeftY - leftMergeRightY;
                    int leftMergeFillAmount = Mathf.Max(Mathf.Abs(leftMergeDiffX), 1) * Mathf.Max(Mathf.Abs(leftMergeDiffY), 1);// Mathf.Max(Mathf.Abs(leftMergeDiffX), Mathf.Abs(leftMergeDiffY));
                    for (int f = 0; f < leftMergeFillAmount; f++)
                    {
                        float move  = f / (float)leftMergeFillAmount;
                        int   fillX = Mathf.RoundToInt(Mathf.Lerp(leftMergeLeftX, leftMergeRightX, move));
                        int   fillY = Mathf.RoundToInt(Mathf.Lerp(leftMergeLeftY, leftMergeRightY, move));
                        if (fillX < 0 || fillY < 0 || fillX >= terrainWidth || fillY >= terrainHeight)
                        {
                            continue;
                        }
                        float curveStrength      = mergeCurve.Evaluate(move);
                        float fillTrackHeight    = fillTrackHeightL;
                        float mergeHeight        = Mathf.Lerp(originalData[fillY, fillX], fillTrackHeight, curveStrength);
                        int   pointLock          = modifiedPointLock[fillY, fillX];
                        float currentMergeHeight = mergeData[fillY, fillX];
                        float currentDifference  = Mathf.Abs(currentMergeHeight - fillTrackHeight);
                        float newDifference      = Mathf.Abs(mergeHeight - fillTrackHeight);
                        if (newDifference < currentDifference && pointLock == 0)
                        {
                            mergeData[fillY, fillX] = mergeHeight;
                        }
                    }

                    Vector3 rightMergePoint  = rightTrackPoint + fillCross * mergeWidth;
                    int     rightMergeLeftX  = Mathf.RoundToInt(((rightMergePoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int     rightMergeLeftY  = Mathf.RoundToInt(((rightMergePoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);
                    int     rightMergeRightX = Mathf.RoundToInt(((rightTrackPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
                    int     rightMergeRightY = Mathf.RoundToInt(((rightTrackPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

                    //
                    int rightMergeDiffX      = rightMergeLeftX - rightMergeRightX;
                    int rightMergeDiffY      = rightMergeLeftY - rightMergeRightY;
                    int rightMergeFillAmount = Mathf.Max(Mathf.Abs(rightMergeDiffX), 1) * Mathf.Max(Mathf.Abs(rightMergeDiffY), 1);// Mathf.Max(Mathf.Abs(leftMergeDiffX), Mathf.Abs(leftMergeDiffY));
                    for (int f = 0; f < rightMergeFillAmount; f++)
                    {
                        float move  = f / (float)rightMergeFillAmount;
                        int   fillX = Mathf.RoundToInt(Mathf.Lerp(rightMergeLeftX, rightMergeRightX, move));
                        int   fillY = Mathf.RoundToInt(Mathf.Lerp(rightMergeLeftY, rightMergeRightY, move));
                        if (fillX < 0 || fillY < 0 || fillX >= terrainWidth || fillY >= terrainHeight)
                        {
                            continue;
                        }
                        float curveStrength      = mergeCurve.Evaluate(move);
                        float fillTrackHeight    = fillTrackHeightR;
                        float mergeHeight        = Mathf.Lerp(originalData[fillY, fillX], fillTrackHeight, curveStrength);
                        int   pointLock          = modifiedPointLock[fillY, fillX];
                        float currentMergeHeight = mergeData[fillY, fillX];
                        float currentDifference  = Mathf.Abs(currentMergeHeight - fillTrackHeight);
                        float newDifference      = Mathf.Abs(mergeHeight - fillTrackHeight);
                        if (newDifference < currentDifference && pointLock == 0)
                        {
                            mergeData[fillY, fillX] = mergeHeight;
                        }
                    }
                }
            }
        }

        for (int x = 0; x < terrainWidth; x++)
        {
            for (int y = 0; y < terrainHeight; y++)
            {
                bool isNotEdge = x > 0 && x < terrainWidth - 1 && y > 0 && y < terrainHeight - 1;
                if (mergeData[x, y] == 0)
                {
                    int mergeNeighbours = 0;
                    if (isNotEdge)
                    {
                        mergeNeighbours += (mergeData[x + 1, y] != 0) ? 1 : 0;
                        mergeNeighbours += (mergeData[x - 1, y] != 0) ? 1 : 0;
                        mergeNeighbours += (mergeData[x, y + 1] != 0) ? 1 : 0;
                        mergeNeighbours += (mergeData[x, y - 1] != 0) ? 1 : 0;
                    }
                    if (mergeNeighbours > 1)//if a hole is surounded by rasied terrain in two or more neighbouring places
                    {
                        float mergeHeight = 0;
                        mergeHeight       += (mergeData[x + 1, y] != 0) ? mergeData[x + 1, y] : 0;
                        mergeHeight       += (mergeData[x - 1, y] != 0) ? mergeData[x - 1, y] : 0;
                        mergeHeight       += (mergeData[x, y + 1] != 0) ? mergeData[x, y + 1] : 0;
                        mergeHeight       += (mergeData[x, y - 1] != 0) ? mergeData[x, y - 1] : 0;
                        modifiedData[x, y] = mergeHeight / mergeNeighbours;//clean up holes
                    }
                    else
                    {
                        modifiedData[x, y] = originalData[x, y];//use original
                    }
                }
                else
                {
                    modifiedData[x, y] = mergeData[x, y];
                }
            }
        }

        terrainData.SetHeights(0, 0, modifiedData);
        terrain.terrainData = terrainData;
    }
Пример #14
0
    private static void ExportModel(TrackBuildR track)
    {
        GameObject baseObject = new GameObject(track.exportFilename);

        baseObject.transform.position = CURRENT_TRANSFORM.position;
        baseObject.transform.rotation = CURRENT_TRANSFORM.rotation;
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f);
        track.ForceFullRecalculation();
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.1f);
        try
        {
            TrackBuildRTrack trackData = track.track;

            //check overwrites...
            string newDirectory = ROOT_FOLDER + track.exportFilename;
            if (!CreateFolder(newDirectory))
            {
                EditorUtility.ClearProgressBar();
                return;
            }

            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.15f);

            int              numberOfCurves  = trackData.numberOfCurves;
            float            exportProgress  = 0.75f / (numberOfCurves * 6.0f);
            ExportMaterial[] exportMaterials = new ExportMaterial[1];
            ExportMaterial   exportTexture   = new ExportMaterial();

            string[] dynNames = new [] { "track", "bumper", "boundary", "bottom", "offread", "trackCollider" };
            for (int c = 0; c < numberOfCurves; c++)
            {
                TrackBuildRPoint curve = trackData[c];

                int numberOfDynMeshes = 6;
                DynamicMeshGenericMultiMaterialMesh[] dynMeshes = new DynamicMeshGenericMultiMaterialMesh[6];
                dynMeshes[0] = curve.dynamicTrackMesh;
                dynMeshes[1] = curve.dynamicBumperMesh;
                dynMeshes[2] = curve.dynamicBoundaryMesh;
                dynMeshes[3] = curve.dynamicBottomMesh;
                dynMeshes[4] = curve.dynamicOffroadMesh;
                dynMeshes[5] = curve.dynamicColliderMesh;

                int[] textureIndeices = new int[] { curve.trackTextureStyleIndex, curve.bumperTextureStyleIndex, curve.boundaryTextureStyleIndex, curve.bottomTextureStyleIndex, curve.offroadTextureStyleIndex, 0 };

                for (int d = 0; d < numberOfDynMeshes; d++)
                {
                    if (EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "Exporting Track Curve " + c + " " + dynNames[d], 0.15f + exportProgress * (c * 6 + d)))
                    {
                        EditorUtility.ClearProgressBar();
                        return;
                    }
                    DynamicMeshGenericMultiMaterialMesh exportDynMesh = dynMeshes[d];
                    if (track.includeTangents || exportDynMesh.isEmpty)
                    {
                        exportDynMesh.Build(track.includeTangents);//rebuild with tangents
                    }
                    TrackBuildRTexture texture = trackData.Texture(textureIndeices[d]);
                    exportTexture.name      = texture.customName;
                    exportTexture.material  = texture.material;
                    exportTexture.generated = false;
                    exportTexture.filepath  = texture.filePath;
                    exportMaterials[0]      = exportTexture;

                    int meshCount = exportDynMesh.meshCount;
                    for (int i = 0; i < meshCount; i++)
                    {
                        Mesh exportMesh = exportDynMesh[i].mesh;
                        MeshUtility.Optimize(exportMesh);
                        string filenameSuffix = trackModelName(dynNames[d], c, (meshCount > 1) ? i : -1);// "trackCurve" + c + ((meshCount > 1) ? "_" + i.ToString() : "");
                        string filename       = track.exportFilename + filenameSuffix;
                        Export(filename, ROOT_FOLDER + track.exportFilename + "/", track, exportMesh, exportMaterials);

                        if (track.createPrefabOnExport)
                        {
                            AssetDatabase.Refresh();//ensure the database is up to date...

                            string modelFilePath = ROOT_FOLDER + track.exportFilename + "/" + filename + FILE_EXTENTION;
                            if (d < numberOfDynMeshes - 1)
                            {
                                GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath));
                                newModel.name                    = filename;
                                newModel.transform.parent        = baseObject.transform;
                                newModel.transform.localPosition = Vector3.zero;
                                newModel.transform.localRotation = Quaternion.identity;
                            }
                            else
                            {
                                GameObject colliderObject = new GameObject("trackCollider");
                                colliderObject.AddComponent <MeshCollider>().sharedMesh = (Mesh)AssetDatabase.LoadAssetAtPath(modelFilePath, typeof(Mesh));
                                colliderObject.transform.parent        = baseObject.transform;
                                colliderObject.transform.localPosition = Vector3.zero;
                                colliderObject.transform.localRotation = Quaternion.identity;
                            }
                        }
                    }
                }
            }
            if (track.createPrefabOnExport)
            {
                string prefabPath = ROOT_FOLDER + track.exportFilename + "/" + track.exportFilename + ".prefab";
                Object prefab     = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
                if (prefab == null)
                {
                    prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
                }
                PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
            }

            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.70f);

            AssetDatabase.Refresh();//ensure the database is up to date...
        }
        catch (System.Exception e)
        {
            Debug.LogError("BuildR Export Error: " + e);
            EditorUtility.ClearProgressBar();
        }
        Object.DestroyImmediate(baseObject);
        EditorUtility.ClearProgressBar();
        EditorUtility.UnloadUnusedAssets();
        AssetDatabase.Refresh();
    }
Пример #15
0
    public static void InspectorGUI(TrackBuildR track)
    {
        TrackBuildRTrack trackData = track.track;

        const int guiWidth    = 400;
        const int textWidth   = 348;
        const int toggleWidth = 25;
        const int helpWidth   = 20;

        CURRENT_TRANSFORM = track.transform;
        EditorGUILayout.Space();
        EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Filename", GUILayout.Width(225));
        track.exportFilename = EditorGUILayout.TextField(track.exportFilename, GUILayout.Width(175));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Filetype", GUILayout.Width(350));
        track.fileType = (TrackBuildR.fileTypes)EditorGUILayout.EnumPopup(track.fileType, GUILayout.Width(50));
        switch (track.fileType)
        {
        case TrackBuildR.fileTypes.Obj:
            FILE_EXTENTION = ".obj";
            break;

        case TrackBuildR.fileTypes.Fbx:
            FILE_EXTENTION = ".fbx";
            break;
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Copy Textures into Export Folder", GUILayout.Width(textWidth));
        track.copyTexturesIntoExportFolder = EditorGUILayout.Toggle(track.copyTexturesIntoExportFolder, GUILayout.Width(toggleWidth));
        if (GUILayout.Button("?", GUILayout.Width(helpWidth)))
        {
            string helpTitle = "Help - Copy Textures into Export Folder";
            string helpBody  = "Check this box if you want to copy the textures you are using into the export folder." +
                               "\nThis is useful if you plan to use the exported model elsewhere. Having the model and the textures in one folder will allow you to move this model with ease.";
            EditorUtility.DisplayDialog(helpTitle, helpBody, "close");
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Export Collider");
//        track.exportSimpleCollider = EditorGUILayout.Toggle(track.exportSimpleCollider, GUILayout.Width(toggleWidth));
        track.exportCollider = EditorGUILayout.Toggle(track.exportCollider, GUILayout.Width(toggleWidth));
        if (GUILayout.Button("?", GUILayout.Width(helpWidth)))
        {
            string helpTitle = "Help - Export Collider Mesh";
            string helpBody  = "Check this box if you wish to generate a trackCollider mesh for your model." +
                               "\nThis will generate a mesh to be used with colliders.";
            EditorUtility.DisplayDialog(helpTitle, helpBody, "close");
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Export as Prefab", GUILayout.Width(textWidth));
        track.createPrefabOnExport = EditorGUILayout.Toggle(track.createPrefabOnExport, GUILayout.Width(toggleWidth));
        if (GUILayout.Button("?", GUILayout.Width(helpWidth)))
        {
            string helpTitle = "Help - Export as Prefab";
            string helpBody  = "Select this if you wish to create a prefab of your model." +
                               "\nThis is recommended if you're exporting a trackCollider so they will get packaged together.";
            EditorUtility.DisplayDialog(helpTitle, helpBody, "close");
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space();

        bool usingSubstances  = false;
        int  numberOfTextures = trackData.numberOfTextures;

        for (int i = 0; i < numberOfTextures; i++)
        {
            TrackBuildRTexture texture = trackData.Texture(i);
            if (texture.type == TrackBuildRTexture.Types.Substance)
            {
                usingSubstances = true;
                break;
            }
        }
        if (usingSubstances)
        {
            EditorGUILayout.HelpBox("Model uses Substance textures." +
                                    "\nExporting model to " + track.fileType + " will lose references to this texture and it will be rendered white.",
                                    MessageType.Warning);
        }

        if (GUILayout.Button("Export", GUILayout.Width(guiWidth), GUILayout.Height(40)))
        {
            ExportModel(track);
        }

        EditorGUILayout.Space();
        if (GUILayout.Button("Export to XML"))
        {
            string defaultName = track.name;
            defaultName.Replace(" ", "_");
            string filepath = EditorUtility.SaveFilePanel("Export Track BuildR Track to XML", "Assets/TrackBuildR", defaultName, "xml");

            if (filepath != "")
            {
                using (StreamWriter sw = new StreamWriter(filepath))
                {
                    sw.Write(track.ToXML());//write out contents of data to XML
                }
            }
            AssetDatabase.Refresh();
        }
        if (GUILayout.Button("Import from XML"))
        {
            string xmlpath = EditorUtility.OpenFilePanel("Import Track BuildR Track from XML", "Assets/TrackBuildR/", "xml");
            if (xmlpath != "")
            {
                track.FromXML(xmlpath);
            }
        }
        if (GUILayout.Button("Import from KML"))
        {
            string xmlpath = EditorUtility.OpenFilePanel("Import Google Earth KML", "Assets/TrackBuildR/", "kml");
            if (xmlpath != "")
            {
                track.FromKML(xmlpath);
            }
        }

        CURRENT_TRANSFORM = null;
    }
Пример #16
0
    private static void ExportModel(TrackBuildR track)
    {
        GameObject baseObject = new GameObject(track.exportFilename);

        baseObject.transform.position = CURRENT_TRANSFORM.position;
        baseObject.transform.rotation = CURRENT_TRANSFORM.rotation;
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f);
        track.ForceFullRecalculation();
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.1f);
        try
        {
            TrackBuildRTrack trackData = track.track;

            //check overwrites...
            string newDirectory = ROOT_FOLDER + track.exportFilename;
            if (!CreateFolder(newDirectory))
            {
                EditorUtility.ClearProgressBar();
                return;
            }

            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.15f);

            int              numberOfCurves    = trackData.numberOfCurves;
            int              numberOfDynMeshes = 9;
            float            exportProgress    = 0.75f / (numberOfCurves * numberOfDynMeshes);
            ExportMaterial[] exportMaterials   = new ExportMaterial[1];
            ExportMaterial   exportTexture     = new ExportMaterial();

            TrackBuildRTexture[] textures = trackData.GetTexturesArray();
            int        textureCount       = textures.Length;
            Material[] materials          = new Material[textureCount];
            for (int t = 0; t < textureCount; t++)
            {
                TrackBuildRTexture texture = textures[t];
                if (!texture.isSubstance && !texture.isUSer)
                {
                    string materialPath = string.Format("{0}{1}/{2}.mat", ROOT_FOLDER, track.exportFilename, texture.customName);
                    if (File.Exists(materialPath))
                    {
                        Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material));
                        EditorUtility.CopySerialized(texture.material, mat);
                        AssetDatabase.SaveAssets();
                        materials[t] = mat;
                        continue;
                    }
                    Material tempMat = Object.Instantiate(texture.material);
                    AssetDatabase.CreateAsset(tempMat, materialPath);
                    materials[t] = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material));
                }
                else
                {
                    materials[t] = texture.isUSer ? texture.userMaterial : texture.proceduralMaterial;
                }
            }

            string[] dynNames      = { "track", "bumper", "boundary", "bottom", "offroad", "trackCollider" };
            string[] colliderNames = { "track collider", "wall collider", "offroad collider", "bumper collider" };
            for (int c = 0; c < numberOfCurves; c++)
            {
                TrackBuildRPoint curve = trackData[c];

                DynamicMesh[] dynMeshes = new DynamicMesh[numberOfDynMeshes];
                dynMeshes[0] = curve.dynamicTrackMesh;
                dynMeshes[1] = curve.dynamicBumperMesh;
                dynMeshes[2] = curve.dynamicBoundaryMesh;
                dynMeshes[3] = curve.dynamicBottomMesh;
                dynMeshes[4] = curve.dynamicOffroadMesh;
                dynMeshes[5] = curve.dynamicColliderMesh1; //track surface
                dynMeshes[6] = curve.dynamicColliderMesh2; //walls and roof
                dynMeshes[7] = curve.dynamicColliderMesh3; //track bottom and offroad
                dynMeshes[8] = curve.dynamicColliderMesh4; //bumpers

                int[]            textureIndeices = { curve.trackTextureStyleIndex, curve.bumperTextureStyleIndex, curve.boundaryTextureStyleIndex, curve.bottomTextureStyleIndex, curve.offroadTextureStyleIndex, 0 };
                PhysicMaterial[] physicMaterials = { trackData.Texture(curve.trackTextureStyleIndex).physicMaterial, trackData.Texture(curve.boundaryTextureStyleIndex).physicMaterial, trackData.Texture(curve.offroadTextureStyleIndex).physicMaterial, trackData.Texture(curve.bumperTextureStyleIndex).physicMaterial };

                for (int d = 0; d < numberOfDynMeshes; d++)
                {
                    int textureIndex = Mathf.Clamp(d, 0, 5);
                    if (EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "Exporting Track Curve " + c + " " + dynNames[textureIndex], 0.15f + exportProgress * (c * numberOfDynMeshes + d)))
                    {
                        EditorUtility.ClearProgressBar();
                        return;
                    }

                    DynamicMesh exportDynMesh = dynMeshes[d];
//                    if(track.includeTangents || exportDynMesh.isEmpty)
//                        exportDynMesh.Build();//rebuild with tangents

                    TrackBuildRTexture texture = trackData.Texture(textureIndeices[textureIndex]);
                    exportTexture.name      = texture.customName;
                    exportTexture.material  = texture.material;
                    exportTexture.generated = false;
                    exportTexture.filepath  = texture.filePath;
                    exportMaterials[0]      = exportTexture;

                    Material mat = materials[textureIndeices[textureIndex]];

                    int    meshCount = exportDynMesh.meshCount;
                    Mesh[] meshes    = exportDynMesh.meshes;
                    for (int i = 0; i < meshCount; i++)
                    {
                        Mesh exportMesh = meshes[i];
                        MeshUtility.Optimize(exportMesh);
                        string filenameSuffix = trackModelName(dynNames[textureIndex], c, (meshCount > 1) ? i : -1); // "trackCurve" + c + ((meshCount > 1) ? "_" + i.ToString() : "");
                        if (d > 4)                                                                                   //colliders
                        {
                            filenameSuffix = string.Format("{0}_{1}", filenameSuffix, (d % 5));
                        }
                        string filename = track.exportFilename + filenameSuffix;
                        Export(filename, ROOT_FOLDER + track.exportFilename + "/", track, exportMesh, exportMaterials);

                        if (track.createPrefabOnExport)
                        {
                            AssetDatabase.Refresh();//ensure the database is up to date...

                            string modelFilePath = ROOT_FOLDER + track.exportFilename + "/" + filename + FILE_EXTENTION;
                            if (d < numberOfDynMeshes - 4)
                            {
                                GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath));
                                newModel.name                    = filename;
                                newModel.transform.parent        = baseObject.transform;
                                newModel.transform.localPosition = Vector3.zero;
                                newModel.transform.localRotation = Quaternion.identity;

                                MeshRenderer[] renders = newModel.GetComponentsInChildren <MeshRenderer>();
                                foreach (MeshRenderer rend in renders)
                                {
                                    rend.material = mat;
                                }
                            }
                            else
                            {
                                int          colliderIndex  = d - (numberOfDynMeshes - 4);
                                GameObject   colliderObject = new GameObject(colliderNames[colliderIndex]);
                                MeshCollider collider       = colliderObject.AddComponent <MeshCollider>();
                                collider.sharedMesh                    = (Mesh)AssetDatabase.LoadAssetAtPath(modelFilePath, typeof(Mesh));
                                collider.material                      = physicMaterials[colliderIndex];
                                colliderObject.transform.parent        = baseObject.transform;
                                colliderObject.transform.localPosition = Vector3.zero;
                                colliderObject.transform.localRotation = Quaternion.identity;
                            }
                        }
                    }
                }
            }
            if (track.createPrefabOnExport)
            {
                string prefabPath = ROOT_FOLDER + track.exportFilename + "/" + track.exportFilename + ".prefab";
                Object prefab     = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
                if (prefab == null)
                {
                    prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
                }
                PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
            }

            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.70f);

            AssetDatabase.Refresh();//ensure the database is up to date...
        }
        catch (System.Exception e)
        {
            Debug.LogError("Track BuildR Export Error: " + e);
            EditorUtility.ClearProgressBar();
            AssetDatabase.Refresh();//ensure the database is up to date...
        }
        Object.DestroyImmediate(baseObject);
        EditorUtility.ClearProgressBar();
        EditorUtility.UnloadUnusedAssetsImmediate();
        AssetDatabase.Refresh();
    }
Пример #17
0
    void OnEnable()
    {
        if (target != null)
        {
            _trackBuildR = (TrackBuildR)target;
            _track       = _trackBuildR.track;
        }

        _stageToolbarTexturesA    = new Texture2D[numberOfMenuOptionsA];
        _stageToolbarTexturesA[0] = (Texture2D)Resources.Load("GUI/track");
        _stageToolbarTexturesA[1] = (Texture2D)Resources.Load("GUI/boundary");
        _stageToolbarTexturesA[2] = (Texture2D)Resources.Load("GUI/bumpers");
        _stageToolbarTexturesA[3] = (Texture2D)Resources.Load("GUI/textures");
        _stageToolbarTexturesA[4] = (Texture2D)Resources.Load("GUI/terrain");
        _stageToolbarTexturesB    = new Texture2D[numberOfMenuOptionsB];
        _stageToolbarTexturesB[0] = (Texture2D)Resources.Load("GUI/stunt");
        _stageToolbarTexturesB[1] = (Texture2D)Resources.Load("GUI/diagram");
        _stageToolbarTexturesB[2] = (Texture2D)Resources.Load("GUI/options");
        _stageToolbarTexturesB[3] = (Texture2D)Resources.Load("GUI/export");

        //Preview Camera
        if (_trackBuildR.trackEditorPreview != null)
        {
            DestroyImmediate(_trackBuildR.trackEditorPreview);
        }
        if (!EditorApplication.isPlaying && SystemInfo.supportsRenderTextures)
        {
            _trackBuildR.trackEditorPreview           = new GameObject("Track Preview Cam");
            _trackBuildR.trackEditorPreview.hideFlags = HideFlags.HideAndDontSave;
            _trackBuildR.trackEditorPreview.AddComponent <Camera>();
            _trackBuildR.trackEditorPreview.GetComponent <Camera>().fieldOfView = 80;
            _trackBuildR.trackEditorPreview.GetComponent <Camera>().depth       = -99999;
            //Retreive camera settings from the main camera
            Camera[] cams              = Camera.allCameras;
            bool     sceneHasCamera    = cams.Length > 0;
            Camera   sceneCamera       = null;
            Skybox   sceneCameraSkybox = null;
            if (Camera.main)
            {
                sceneCamera = Camera.main;
            }
            else if (sceneHasCamera)
            {
                sceneCamera = cams[0];
            }

            if (sceneCamera != null)
            {
                if (sceneCameraSkybox == null)
                {
                    sceneCameraSkybox = sceneCamera.GetComponent <Skybox>();
                }
            }
            if (sceneCamera != null)
            {
                _trackBuildR.trackEditorPreview.GetComponent <Camera>().backgroundColor = sceneCamera.backgroundColor;
                if (sceneCameraSkybox != null)
                {
                    _trackBuildR.trackEditorPreview.AddComponent <Skybox>().material = sceneCameraSkybox.material;
                }
                else
                if (RenderSettings.skybox != null)
                {
                    _trackBuildR.trackEditorPreview.AddComponent <Skybox>().material = RenderSettings.skybox;
                }
            }
        }
    }
Пример #18
0
    /// <summary>
    /// unfinished!
    /// </summary>
    /// <param name="track"></param>
    /// <param name="selectedPoint"></param>
    public static void AddTwist(TrackBuildRTrack track, int selectedPoint)
    {
        TrackBuildRPoint atPoint = track[selectedPoint];
        TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1);

        float twistDistance = Mathf.Min((lastPoint.arcLength + atPoint.arcLength) * 0.333f, track.maxJumpLength);
        Vector3 twistDirection = atPoint.trackDirection;
//        Vector3 twistMiddle = atPoint.worldPosition;
        Vector3 twistUp = atPoint.trackUp;
        Vector3 twistAxis = Vector3.Cross(twistDirection, twistUp);
        float twistRadius = track.twistRadius;
        Vector3 twistStartPosition = -twistDirection * (twistDistance * 0.33f);
        Vector3 twistEndPosition = twistDirection * (twistDistance * 0.33f);
//        Vector3 twistCentreHeight = twistUp * twistRadius;
        Quaternion twistAngle = Quaternion.LookRotation(twistDirection, twistUp);
        Vector3 twistCenter = atPoint.worldPosition + Vector3.up * twistRadius;
        float controlPointLength = twistRadius / (Mathf.PI);

        int numberOfPoints = track.twistPoints;
        float arcPercent = 1.0f / numberOfPoints;
        TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[numberOfPoints+1];
        for (int i = 0; i < numberOfPoints; i++)
        {
            float pointArcPercent = arcPercent * i;
            float radA = Mathf.PI * 2 * (pointArcPercent + 0.5f);
            Vector3 pointLoopPosition = twistAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * twistRadius);
            float smoothI = pointArcPercent * pointArcPercent * (3.0f - 2.0f * pointArcPercent);
            Vector3 lateral = Vector3.Lerp(twistStartPosition, twistEndPosition, pointArcPercent + (pointArcPercent - smoothI));
            Vector3 pointPosition = (pointLoopPosition) + lateral;
            Vector3 pointDirection = Vector3.Cross(-pointLoopPosition, twistAxis).normalized;

            TrackBuildRPoint newTrackPoint = track.InsertPoint(selectedPoint + 1 + i);
            newTrackPoint.worldPosition = twistCenter + pointPosition;
            newTrackPoint.trackUpQ = Quaternion.LookRotation(-pointLoopPosition, pointDirection);
            newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength);
            loopPoints[i] = newTrackPoint;
        }
        atPoint.worldPosition += twistStartPosition;
        atPoint.trackUpQ = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection);
        atPoint.forwardControlPoint = atPoint.worldPosition + (twistDirection * controlPointLength) - twistAxis;
        loopPoints[6] = atPoint;
        //                    _trackBuildR.pointMode = TrackBuildR.pointModes.transform;

        for (int i = 0; i < numberOfPoints + 1; i++)
        {
            loopPoints[i].extrudeTrack = true;
            loopPoints[i].extrudeTrackBottom = true;
            loopPoints[i].extrudeLength = 0.5f;
            loopPoints[i].RecalculateStoredValues();
        }
    }
 /// <summary>
 /// Deals with modifing the diagram used in track building
 /// </summary>
 private static void UpdateDiagram(TrackBuildRTrack _track)
 {
     //        Texture texture = _track.diagramMaterial.mainTexture;
     float scaleSize = Vector3.Distance(_track.scalePointB, _track.scalePointA);
     float diagramScale = _track.scale / scaleSize;
     _track.diagramGO.transform.localScale *= diagramScale;
     _track.scalePointA *= diagramScale;
     _track.scalePointB *= diagramScale;
 }
Пример #20
0
    public static void ResetTerrain(TrackBuildRTrack track, Terrain terrain)
    {
        TerrainData terrainData = terrain.terrainData;
        int terrainWidth = terrainData.heightmapWidth;
        int terrainHeight = terrainData.heightmapHeight;

        float[,] tData = terrainData.GetHeights(0, 0, terrainWidth, terrainHeight);
        for(int x = 0; x < terrainWidth; x++)
            for(int y = 0; y< terrainHeight; y++)
                tData[x, y] = 1;

        terrainData.SetHeights(0, 0, tData);
        terrain.terrainData = terrainData;
    }
Пример #21
0
    public static void ConformTrack(TrackBuildRTrack track, Terrain terrain)
    {
        TerrainData terrainData = terrain.terrainData;
        int terrainWidth = terrainData.heightmapWidth;
        int terrainHeight = terrainData.heightmapHeight;
        float terrainHeightmapY = terrain.terrainData.heightmapScale.y;
        float terrainY = terrain.transform.position.y / terrainHeightmapY;
        float conformAccuracy = track.conformAccuracy;

        float[,] originalData = terrainData.GetHeights(0, 0, terrainWidth, terrainHeight);

        Bounds trackBounds = new Bounds();
        int numberOfCurves = track.numberOfCurves;
        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];
            if (curve.holder == null)
                continue;
            Renderer[] rends = curve.holder.GetComponentsInChildren<Renderer>();
            foreach (Renderer rend in rends)
            {
                trackBounds.Encapsulate(rend.bounds);
            }
        }

        Vector3 trackOffset = track.transform.position - terrain.transform.position;
        Vector3 trackScale = new Vector3(trackBounds.size.x / terrainData.size.x, 1.0f / terrain.terrainData.size.y, trackBounds.size.z / terrainData.size.z);

        int realNumberOfPoints = track.realNumberOfPoints;
        for(int i = 0; i < realNumberOfPoints; i++)
        {
            TrackBuildRPoint point = track[i];
            Vector3 trackPointPosition = point.position;
            int pointX = Mathf.RoundToInt(((trackPointPosition.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
            int pointY = Mathf.RoundToInt(((trackPointPosition.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

            pointX = Mathf.Clamp(pointX, 0, terrainWidth-1);
            pointY = Mathf.Clamp(pointY, 0, terrainHeight-1);

            trackPointPosition.y = originalData[pointY, pointX] * terrain.terrainData.size.y - terrainY + conformAccuracy;
            point.position = trackPointPosition;

            Vector3 controlPoint = point.forwardControlPoint;
            pointX = Mathf.RoundToInt(((controlPoint.x + trackOffset.x) / trackBounds.size.x * trackScale.x) * terrainData.heightmapWidth);
            pointY = Mathf.RoundToInt(((controlPoint.z + trackOffset.z) / trackBounds.size.z * trackScale.z) * terrainData.heightmapHeight);

            pointX = Mathf.Clamp(pointX, 0, terrainWidth - 1);
            pointY = Mathf.Clamp(pointY, 0, terrainHeight - 1);

            controlPoint.y = originalData[pointY, pointX] * terrain.terrainData.size.y - terrainY + conformAccuracy;
            point.forwardControlPoint = controlPoint;

            point.isDirty = true;
        }
        track.RecalculateCurves();
    }
Пример #22
0
    public static void AddJumpTwist(TrackBuildRTrack track, int selectedPoint)
    {
        TrackBuildRPoint atPoint = track[selectedPoint];
        TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1);
//        TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1);

        float trackPartDistance = lastPoint.arcLength + atPoint.arcLength;
        float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength);

//        float trackWidth = atPoint.width * 0.5f;
        Vector3 startCross = atPoint.trackCross;
        Vector3 jumpDirection = atPoint.trackDirection;
        Vector3 jumpMiddle = atPoint.worldPosition;
        Quaternion atPointUpQ = atPoint.trackUpQ;
        Quaternion trackUpJump = Quaternion.AngleAxis(track.twistAngle, -jumpDirection);
        Quaternion trackCrossExit = trackUpJump * (atPointUpQ);
        Quaternion trackCrossEntry = Quaternion.Inverse(trackUpJump) * (atPointUpQ);
        Vector3 jumpLateral = startCross * track.twistAngle / 33.3f;

        Vector3 jumpHeight = atPointUpQ * (Vector3.forward * track.jumpHeight);
        Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f) + jumpHeight - jumpLateral;
        Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f) + jumpHeight + jumpLateral;

        lastPoint.extrudeTrack = true;
        lastPoint.extrudeLength = track.jumpHeight;
        lastPoint.extrudeCurveEnd = true;
        lastPoint.extrudeTrackBottom = true;

        atPoint.Reset();
        atPoint.worldPosition = jumpStartPosition;
        atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight;
        atPoint.trackUpQ = trackCrossExit;
        atPoint.render = false;

        TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1);
        jumpEnd.worldPosition = jumpEndPosition;
        jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition - jumpHeight;
        jumpEnd.trackUpQ = trackCrossEntry;
        jumpEnd.extrudeTrack = true;
        jumpEnd.extrudeLength = track.jumpHeight;
        jumpEnd.extrudeCurveEnd = true;
        jumpEnd.extrudeTrackBottom = true;

        atPoint.RecalculateStoredValues();
        jumpEnd.RecalculateStoredValues();
    }
    /// <summary>
    /// A stub of GUI for selecting the texture for a specific part of the track on a specific curve
    /// IE. The track texture, the wall texture, etc...
    /// </summary>
    /// <param customName="_track"></param>
    /// <param customName="textureIndex"></param>
    /// <param customName="label"></param>
    /// <returns></returns>
    private static int CurveTextureSelector(TrackBuildRTrack _track, int textureIndex, string label)
    {
        TrackBuildRTexture[] textures = _track.GetTexturesArray();
        int numberOfTextures = textures.Length;
        string[] textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
            textureNames[t] = textures[t].customName;

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.BeginVertical();
        EditorGUILayout.LabelField(label);
        textureIndex = EditorGUILayout.Popup(Mathf.Clamp(textureIndex,0,numberOfTextures-1), textureNames);
        TrackBuildRTexture tbrTexture = _track.Texture(textureIndex);
        EditorGUILayout.EndVertical();
        GUILayout.Label(tbrTexture.texture, GUILayout.Width(50), GUILayout.Height(50));
        EditorGUILayout.EndHorizontal();

        return textureIndex;
    }
Пример #24
0
    public void Init()
    {
        track = gameObject.AddComponent<TrackBuildRTrack>();
        track.InitTextures();
        track.baseTransform = transform;

        TrackBuildRPoint p0 = gameObject.AddComponent<TrackBuildRPoint>();// ScriptableObject.CreateInstance<TrackBuildRPoint>();
        TrackBuildRPoint p1 = gameObject.AddComponent<TrackBuildRPoint>();//ScriptableObject.CreateInstance<TrackBuildRPoint>();
        TrackBuildRPoint p2 = gameObject.AddComponent<TrackBuildRPoint>();//ScriptableObject.CreateInstance<TrackBuildRPoint>();
        TrackBuildRPoint p3 = gameObject.AddComponent<TrackBuildRPoint>();//ScriptableObject.CreateInstance<TrackBuildRPoint>();

        p0.baseTransform = transform;
        p1.baseTransform = transform;
        p2.baseTransform = transform;
        p3.baseTransform = transform;

        p0.position = new Vector3(-20, 0, -20);
        p1.position = new Vector3(20, 0, -20);
        p2.position = new Vector3(20, 0, 20);
        p3.position = new Vector3(-20, 0, 20);

        p0.forwardControlPoint = new Vector3(0, 0, -20);
        p1.forwardControlPoint = new Vector3(40, 0, -20);
        p2.forwardControlPoint = new Vector3(0, 0, 20);
        p3.forwardControlPoint = new Vector3(-40, 0, 20);

        p0.leftForwardControlPoint = new Vector3(-15, 0, -20);
        p1.leftForwardControlPoint = new Vector3(25, 0, -20);
        p2.leftForwardControlPoint = new Vector3(5, 0, 20);
        p3.leftForwardControlPoint = new Vector3(-35, 0, 20);

        p0.rightForwardControlPoint = new Vector3(15, 0, -20);
        p1.rightForwardControlPoint = new Vector3(55, 0, -20);
        p2.rightForwardControlPoint = new Vector3(-5, 0, 20);
        p3.rightForwardControlPoint = new Vector3(-45, 0, 20);

        track.AddPoint(p0);
        track.AddPoint(p1);
        track.AddPoint(p2);
        track.AddPoint(p3);

        generator = gameObject.AddComponent<TrackBuildRGenerator>();

        ForceFullRecalculation();

        track.diagramMesh = new Mesh();
        track.diagramMesh.vertices = new [] { new Vector3(-1, 0, -1), new Vector3(1, 0, -1), new Vector3(-1, 0, 1), new Vector3(1, 0, 1)};
        track.diagramMesh.uv = new [] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(0,1), new Vector2(1,1)};
        track.diagramMesh.triangles = new []{1,0,2,1,2,3};

        track.diagramGO = new GameObject("Diagram");
        track.diagramGO.transform.parent = transform;
        track.diagramGO.transform.localPosition = Vector3.zero;
        track.diagramGO.AddComponent<MeshFilter>().mesh = track.diagramMesh;
        track.diagramMaterial = new Material(Shader.Find("Unlit/Texture"));
        track.diagramGO.AddComponent<MeshRenderer>().material = track.diagramMaterial;
        track.diagramGO.AddComponent<MeshCollider>().sharedMesh = track.diagramMesh;
    }