Example #1
0
    public void AddTexture()
    {
#if UNITY_EDITOR
        TrackBuildRTexture newTexture = Undo.AddComponent <TrackBuildRTexture>(gameObject);
#else
        TrackBuildRTexture newTexture = gameObject.AddComponent <TrackBuildRTexture>();
#endif
        newTexture.customName = "new texture " + (_textures.Count + 1);
        _textures.Add(newTexture);
    }
Example #2
0
    public void InitTextures()
    {
        TrackBuildRTexture newTrackTexture = gameObject.AddComponent <TrackBuildRTexture>();

        newTrackTexture.customName = "Track Texture";
        _textures.Add(newTrackTexture);
        TrackBuildRTexture newOffroadTexture = gameObject.AddComponent <TrackBuildRTexture>();

        newOffroadTexture.customName = "Offroad Texture";
        _textures.Add(newOffroadTexture);
        TrackBuildRTexture newWallTexture = gameObject.AddComponent <TrackBuildRTexture>();

        newWallTexture.customName = "Wall Texture";
        _textures.Add(newWallTexture);
        TrackBuildRTexture newBumperTexture = gameObject.AddComponent <TrackBuildRTexture>();

        newBumperTexture.customName = "Bumper Texture";
        _textures.Add(newBumperTexture);
    }
Example #3
0
    public TrackBuildRTexture Duplicate(string newName)
    {
        TrackBuildRTexture newTexture = gameObject.AddComponent <TrackBuildRTexture>();

        newTexture.customName = "Track Texture";

        newTexture.tiled              = true;
        newTexture.patterned          = false;
        newTexture.tileUnitUV         = _tileUnitUV;
        newTexture.textureUnitSize    = _textureUnitSize;
        newTexture.tiledX             = tiledX;
        newTexture.tiledY             = tiledY;
        newTexture.maxUVTile          = maxUVTile;
        newTexture.material           = new Material(material);
        newTexture.proceduralMaterial = _proceduralMaterial;
        newTexture.userMaterial       = userMaterial;

        return(newTexture);
    }
Example #4
0
    public void RemoveTexture(TrackBuildRTexture texture)
    {
        int textureIndex = _textures.IndexOf(texture);


#if UNITY_EDITOR
        Undo.IncrementCurrentGroup();
        Undo.RecordObject(this, "Remove Texture");
        _textures.Remove(texture);
        Undo.DestroyObjectImmediate(texture);
        Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
#else
        _textures.Remove(texture);
#endif

        //ensure that curves are not referenceing textures that no longer exist
        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = _points[i];

            if (curve.trackTextureStyleIndex > textureIndex)
            {
                curve.trackTextureStyleIndex--;
            }
            if (curve.offroadTextureStyleIndex > textureIndex)
            {
                curve.offroadTextureStyleIndex--;
            }
            if (curve.bumperTextureStyleIndex > textureIndex)
            {
                curve.bumperTextureStyleIndex--;
            }
            if (curve.boundaryTextureStyleIndex > textureIndex)
            {
                curve.boundaryTextureStyleIndex--;
            }
            if (curve.bottomTextureStyleIndex > textureIndex)
            {
                curve.bottomTextureStyleIndex--;
            }
        }
    }
    /// <summary>
    /// The Texture display GUI
    /// </summary>
    /// <param customName="texture"></param>
    /// <returns>True if this texture was modified</returns>
    private static bool TextureGUI(ref TrackBuildRTexture texture)
    {
        if(texture.material == null)
            texture.material = new Material(Shader.Find("Diffuse"));

        bool isModified = false;
        string textureName = texture.customName;
        textureName = EditorGUILayout.TextField("Name", textureName);
        if (texture.customName != textureName)
        {
            texture.customName = textureName;
        }

        
        texture.type = (TrackBuildRTexture.Types)EditorGUILayout.EnumPopup("Type", texture.type);

        //Shader Time
        Shader[] tempshaders = (Shader[])Resources.FindObjectsOfTypeAll(typeof(Shader));
        List<string> shaderNames = new List<string>(ShaderProperties.NAMES);
        foreach (Shader shader in tempshaders)
        {
            if (!string.IsNullOrEmpty(shader.name) && !shader.name.StartsWith("__") && !shader.name.Contains("hidden"))
                shaderNames.Add(shader.name);
        }
        int selectedShaderIndex = shaderNames.IndexOf(texture.material.shader.name);
        int newSelectedShaderIndex = EditorGUILayout.Popup("Shader", selectedShaderIndex, shaderNames.ToArray());
        if (selectedShaderIndex != newSelectedShaderIndex)
        {
            texture.material.shader = Shader.Find(shaderNames[newSelectedShaderIndex]);
        }

        texture.physicMaterial = EditorGUILayout.ObjectField("Physics Material", texture.physicMaterial, typeof(PhysicMaterial), false) as PhysicMaterial;

        switch(texture.type)
        {
            case TrackBuildRTexture.Types.Basic:
                Shader selectedShader = texture.material.shader;
                int propertyCount = ShaderUtil.GetPropertyCount(selectedShader);

                for (int s = 0; s < propertyCount; s++)
                {
                    ShaderUtil.ShaderPropertyType propertyTpe = ShaderUtil.GetPropertyType(selectedShader, s);
                    string shaderPropertyName = ShaderUtil.GetPropertyName(selectedShader, s);
                    switch (propertyTpe)
                    {
                        case ShaderUtil.ShaderPropertyType.TexEnv:
                            Texture shaderTexture = texture.material.GetTexture(shaderPropertyName);
                            Texture newShaderTexture = (Texture)EditorGUILayout.ObjectField(shaderPropertyName, shaderTexture, typeof(Texture), false);
                            if (shaderTexture != newShaderTexture)
                            {
                                texture.material.SetTexture(shaderPropertyName, newShaderTexture);
                            }
                            break;

                        case ShaderUtil.ShaderPropertyType.Color:
                            Color shaderColor = texture.material.GetColor(shaderPropertyName);
                            Color newShaderColor = EditorGUILayout.ColorField(shaderPropertyName, shaderColor);
                            if (shaderColor != newShaderColor)
                            {
                                texture.material.SetColor(shaderPropertyName, newShaderColor);
                            }
                            break;

                        case ShaderUtil.ShaderPropertyType.Float:
                            float shaderFloat = texture.material.GetFloat(shaderPropertyName);
                            float newShaderFloat = EditorGUILayout.FloatField(shaderPropertyName, shaderFloat);
                            if (shaderFloat != newShaderFloat)
                            {
                                texture.material.SetFloat(shaderPropertyName, newShaderFloat);
                            }
                            break;

                        case ShaderUtil.ShaderPropertyType.Range:
                            float shaderRange = texture.material.GetFloat(shaderPropertyName);
                            float rangeMin = ShaderUtil.GetRangeLimits(selectedShader, s, 1);
                            float rangeMax = ShaderUtil.GetRangeLimits(selectedShader, s, 2);
                            float newShaderRange = EditorGUILayout.Slider(shaderPropertyName, shaderRange, rangeMin, rangeMax);
                            if (shaderRange != newShaderRange)
                            {
                                texture.material.SetFloat(shaderPropertyName, newShaderRange);
                            }
                            break;

                        case ShaderUtil.ShaderPropertyType.Vector:
                            Vector3 shaderVector = texture.material.GetVector(shaderPropertyName);
                            Vector3 newShaderVector = EditorGUILayout.Vector3Field(shaderPropertyName, shaderVector);
                            if (shaderVector != newShaderVector)
                            {
                                texture.material.SetVector(shaderPropertyName, newShaderVector);
                            }
                            break;
                    }
                }

                if(texture.texture == null)
                    return isModified;

                
            break;

            case TrackBuildRTexture.Types.Substance:

                texture.proceduralMaterial = (ProceduralMaterial)EditorGUILayout.ObjectField("Procedural Material", texture.proceduralMaterial, typeof(ProceduralMaterial), false);

                if (texture.proceduralMaterial != null)
                {
//                    ProceduralMaterial pMat = texture.proceduralMaterial;
//                    GUILayout.Label(pMat.GetGeneratedTexture(pMat.mainTexture.name), GUILayout.Width(400));
                }
                else
                    EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error);
            break;

            case TrackBuildRTexture.Types.User:
                texture.userMaterial = (Material)EditorGUILayout.ObjectField("User Material", texture.userMaterial, typeof(Material), false);

                if (texture.userMaterial != null)
                {
//                    Material mat = texture.userMaterial;
//                    GUILayout.Label(mat.mainTexture, GUILayout.Width(400));
                }
                else
                    EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error);
            break;
        }

        bool textureflipped = EditorGUILayout.Toggle("Flip Clockwise", texture.flipped);
        if (textureflipped != texture.flipped)
        {
            isModified = true;
            texture.flipped = textureflipped;
        }

        Vector2 textureUnitSize = texture.textureUnitSize;
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("trackTexture width", GUILayout.Width(175));//, GUILayout.Width(42));
        float textureUnitSizex = EditorGUILayout.FloatField(texture.textureUnitSize.x, GUILayout.Width(25));
        if (textureUnitSizex != textureUnitSize.x)
        {
            isModified = true;
            textureUnitSize.x = textureUnitSizex;
        }
        EditorGUILayout.LabelField("metres", GUILayout.Width(40));//, GUILayout.Width(42));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("trackTexture height", GUILayout.Width(175));//, GUILayout.Width(42));
        float textureUnitSizey = EditorGUILayout.FloatField(texture.textureUnitSize.y, GUILayout.Width(25));
        if (textureUnitSizey != textureUnitSize.y)
        {
            isModified = true;
            textureUnitSize.y = textureUnitSizey;
        }
        EditorGUILayout.LabelField("metres", GUILayout.Width(40));
        EditorGUILayout.EndHorizontal();
        texture.textureUnitSize = textureUnitSize;

        const int previewTextureUnitSize = 120;
        const int previewPadding = 25;

        EditorGUILayout.LabelField("1 Metre Squared", GUILayout.Width(previewTextureUnitSize));
        GUILayout.Space(previewPadding);
        EditorGUILayout.Space();

        Rect texturePreviewPostion = new Rect(0, 0, 0, 0);
        if (Event.current.type == EventType.Repaint)
            texturePreviewPostion = GUILayoutUtility.GetLastRect();

        Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
        Rect sourceRect = new Rect(0, 0, (1.0f / textureUnitSize.x), (1.0f / textureUnitSize.y));

        GUILayout.Space(previewTextureUnitSize);

        switch(texture.type)
        {
            case TrackBuildRTexture.Types.Basic:
                Graphics.DrawTexture(previewRect, texture.texture, sourceRect, 0, 0, 0, 0);
                break;

#if !UNITY_WEBGL
            case TrackBuildRTexture.Types.Substance:

                if(texture.proceduralMaterial != null)
                {
                    ProceduralMaterial pMat = texture.proceduralMaterial;
//                    GUILayout.Label(pMat.GetGeneratedTexture(pMat.mainTexture.name), GUILayout.Width(400));
                    Graphics.DrawTexture(previewRect, pMat.mainTexture, sourceRect, 0, 0, 0, 0);
                }
                else
                    EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error);
                break;
#endif

            case TrackBuildRTexture.Types.User:

                if(texture.userMaterial != null)
                {
                    Material mat = texture.userMaterial;
//                    GUILayout.Label(mat.mainTexture, GUILayout.Width(400));
                    Graphics.DrawTexture(previewRect, mat.mainTexture, sourceRect, 0, 0, 0, 0);
                }
                else
                    EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error);
                break;
        }
        if (isModified)
            GUI.changed = true;

        return isModified;
    }
Example #6
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;
    }
Example #7
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();
    }
Example #8
0
    public virtual void FromXML(XmlNode node)
    {
        XmlNodeList textureNodes = node.SelectNodes("textures/texture");

        foreach (XmlNode textureNode in textureNodes)
        {
            TrackBuildRTexture newTexture = gameObject.AddComponent <TrackBuildRTexture>();
            newTexture.FromXML(textureNode);
            _textures.Add(newTexture);
        }

        XmlNodeList trackPointNodes = node.SelectNodes("trackpoints/trackpoint");

        foreach (XmlNode trackPointNode in trackPointNodes)
        {
            TrackBuildRPoint point = gameObject.AddComponent <TrackBuildRPoint>();
            point.FromXML(trackPointNode);
            point.baseTransform = baseTransform;
            point.isDirty       = true;
            _points.Add(point);
        }

        if (node["meshResolution"] != null)
        {
            _meshResolution = float.Parse(node["meshResolution"].FirstChild.Value);
        }
        if (node["includeCollider"] != null)
        {
            includeCollider = bool.Parse(node["includeCollider"].FirstChild.Value);
        }
        if (node["includeColliderRoof"] != null)
        {
            includeColliderRoof = bool.Parse(node["includeColliderRoof"].FirstChild.Value);
        }
        if (node["trackColliderWallHeight"] != null)
        {
            trackColliderWallHeight = float.Parse(node["trackColliderWallHeight"].FirstChild.Value);
        }
        if (node["trackBumpers"] != null)
        {
            trackBumpers = bool.Parse(node["trackBumpers"].FirstChild.Value);
        }
        if (node["bumperHeight"] != null)
        {
            bumperHeight = float.Parse(node["bumperHeight"].FirstChild.Value);
        }
        if (node["bumperWidth"] != null)
        {
            bumperWidth = float.Parse(node["bumperWidth"].FirstChild.Value);
        }
        if (node["bumperAngleThresold"] != null)
        {
            bumperAngleThresold = float.Parse(node["bumperAngleThresold"].FirstChild.Value);
        }
        if (node["disconnectBoundary"] != null)
        {
            _disconnectBoundary = bool.Parse(node["disconnectBoundary"].FirstChild.Value);
        }
        if (node["renderBoundaryWallReverse"] != null)
        {
            _renderBoundaryWallReverse = bool.Parse(node["renderBoundaryWallReverse"].FirstChild.Value);
        }


        RecalculateCurves();
    }
    public void RemoveTexture(TrackBuildRTexture texture)
    {
        int textureIndex = _textures.IndexOf(texture);


#if UNITY_EDITOR
        Undo.IncrementCurrentGroup();
        Undo.RecordObject(this, "Remove Texture");
        _textures.Remove(texture);
        Undo.DestroyObjectImmediate(texture);
        Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
#else
        _textures.Remove(texture);
#endif

        //ensure that curves are not referenceing textures that no longer exist
        for(int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = _points[i];

            if (curve.trackTextureStyleIndex > textureIndex)
                curve.trackTextureStyleIndex--;
            if (curve.offroadTextureStyleIndex > textureIndex)
                curve.offroadTextureStyleIndex--;
            if (curve.bumperTextureStyleIndex > textureIndex)
                curve.bumperTextureStyleIndex--;
            if (curve.boundaryTextureStyleIndex > textureIndex)
                curve.boundaryTextureStyleIndex--;
            if (curve.bottomTextureStyleIndex > textureIndex)
                curve.bottomTextureStyleIndex--;
        }
    }
        /// <summary>
        /// Atlas the specified modifySubmeshes using newTextureCoords and textures.
        /// </summary>
        /// <param customName='modifySubmeshes'>
        /// Submeshes indicies to atlas.
        /// </param>
        /// <param customName='newTextureCoords'>
        /// New trackTexture coords generated from Pack Textures.
        /// </param>
        /// <param customName='textures'>
        /// BuildR Textures library reference.
        /// </param>
        public void Atlas(int[] modifySubmeshes, Rect[] newTextureCoords, TrackBuildRTexture[] textures)
        {
            if (modifySubmeshes.Length == 0)
            {
                Debug.Log("No submeshes to atlas!");
                return;
            }
            List <int> atlasedSubmesh            = new List <int>();
            int        numberOfSubmeshesToModify = modifySubmeshes.Length;

            for (int s = 0; s < numberOfSubmeshesToModify; s++)
            {
                int  submeshIndex = modifySubmeshes[s];
                Rect textureRect  = newTextureCoords[s];
                if (!subTriangles.ContainsKey(submeshIndex))
                {
                    continue;
                }
                int[] submeshIndices = subTriangles[submeshIndex].ToArray();
                subTriangles.Remove(submeshIndex);
                atlasedSubmesh.AddRange(submeshIndices);

                TrackBuildRTexture bTexture    = textures[submeshIndex];
                List <int>         ModifiedUVs = new List <int>();
                foreach (int index in submeshIndices)
                {
                    if (ModifiedUVs.Contains(index))
                    {
                        continue;//don't move the UV more than once
                    }
                    Vector2 uvCoords = uv[index];
                    float   xUV      = uvCoords.x / bTexture.maxUVTile.x;
                    float   yUV      = uvCoords.y / bTexture.maxUVTile.y;
                    if (xUV > 1)
                    {
                        bTexture.maxUVTile.x = uvCoords.x;
                        xUV = 1.0f;
                    }
                    if (yUV > 1)
                    {
                        bTexture.maxUVTile.y = uvCoords.y;
                        yUV = 1;
                    }

                    uvCoords.x = Mathf.Lerp(textureRect.xMin, textureRect.xMax, xUV);
                    uvCoords.y = Mathf.Lerp(textureRect.yMin, textureRect.yMax, yUV);

                    if (float.IsNaN(uvCoords.x))
                    {
                        uvCoords.x = 1;
                    }
                    if (float.IsNaN(uvCoords.y))
                    {
                        uvCoords.y = 1;
                    }
                    uv[index] = uvCoords;
                    ModifiedUVs.Add(index);//keep nextNormIndex record of moved UVs
                }
            }
            subMeshCount = subMeshCount - modifySubmeshes.Length + 1;
            subTriangles.Add(modifySubmeshes[0], atlasedSubmesh);
        }
        /// <summary>
        /// Atlas the specified modifySubmeshes using newTextureCoords and textures.
        /// </summary>
        /// <param customName='modifySubmeshes'>
        /// Submeshes indicies to atlas.
        /// </param>
        /// <param customName='newTextureCoords'>
        /// New trackTexture coords generated from Pack Textures.
        /// </param>
        /// <param customName='textures'>
        /// BuildR Textures library reference.
        /// </param>
        public void Atlas(int[] modifySubmeshes, Rect[] newTextureCoords, TrackBuildRTexture[] textures)
        {
            if (modifySubmeshes.Length == 0)
            {
                Debug.Log("No submeshes to atlas!");
                return;
            }
            List<int> atlasedSubmesh = new List<int>();
            int numberOfSubmeshesToModify = modifySubmeshes.Length;
            for (int s = 0; s < numberOfSubmeshesToModify; s++)
            {
                int submeshIndex = modifySubmeshes[s];
                Rect textureRect = newTextureCoords[s];
                if (!subTriangles.ContainsKey(submeshIndex))
                    continue;
                int[] submeshIndices = subTriangles[submeshIndex].ToArray();
                subTriangles.Remove(submeshIndex);
                atlasedSubmesh.AddRange(submeshIndices);

                TrackBuildRTexture bTexture = textures[submeshIndex];
                List<int> ModifiedUVs = new List<int>();
                foreach (int index in submeshIndices)
                {
                    if (ModifiedUVs.Contains(index))
                        continue;//don't move the UV more than once
                    Vector2 uvCoords = uv[index];
                    float xUV = uvCoords.x / bTexture.maxUVTile.x;
                    float yUV = uvCoords.y / bTexture.maxUVTile.y;
                    if (xUV > 1)
                    {
                        bTexture.maxUVTile.x = uvCoords.x;
                        xUV = 1.0f;
                    }
                    if (yUV > 1)
                    {
                        bTexture.maxUVTile.y = uvCoords.y;
                        yUV = 1;
                    }

                    uvCoords.x = Mathf.Lerp(textureRect.xMin, textureRect.xMax, xUV);
                    uvCoords.y = Mathf.Lerp(textureRect.yMin, textureRect.yMax, yUV);

                    if (float.IsNaN(uvCoords.x))
                    {
                        uvCoords.x = 1;
                    }
                    if (float.IsNaN(uvCoords.y))
                    {
                        uvCoords.y = 1;
                    }
                    uv[index] = uvCoords;
                    ModifiedUVs.Add(index);//keep nextNormIndex record of moved UVs
                }
            }
            subMeshCount = subMeshCount - modifySubmeshes.Length + 1;
            subTriangles.Add(modifySubmeshes[0], atlasedSubmesh);
        }
 /// <summary>
 ///  Atlas the entire mesh using newTextureCoords and textures.
 /// </summary>
 /// <param customName="newTextureCoords"></param>
 /// <param customName="textures"></param>
 public void Atlas(Rect[] newTextureCoords, TrackBuildRTexture[] textures)
 {
     List<int> keys = new List<int>(subTriangles.Keys);
     Atlas(keys.ToArray(), newTextureCoords, textures);
 }
        /// <summary>
        /// Checks the Max UV values used in this model for each trackTexture.
        /// </summary>
        /// <param customName='data'>
        /// BuildR Data.
        /// </param>
        public void CheckMaxTextureUVs(TrackBuildRTexture[] textures)
        {
            Vector2[] subMeshUVOffsets = new Vector2[subMeshCount];
            int[] subMeshIDs = new List<int>(subTriangles.Keys).ToArray();
            int numberOfSubmeshIDs = subMeshIDs.Length;
            for (int sm = 0; sm < numberOfSubmeshIDs; sm++)
            {
                int subMeshID = subMeshIDs[sm];
                if (subTriangles.ContainsKey(subMeshID))
                {
                    int[] submeshIndices = subTriangles[subMeshID].ToArray();
                    subMeshUVOffsets[sm] = Vector2.zero;
                    foreach (int index in submeshIndices)
                    {
                        if (uv[index].x < subMeshUVOffsets[sm].x)
                            subMeshUVOffsets[sm].x = uv[index].x;
                        if (uv[index].y < subMeshUVOffsets[sm].y)
                            subMeshUVOffsets[sm].y = uv[index].y;
                    }

                    List<int> UVsOffset = new List<int>();
                    foreach (int uvindex in subTriangles[subMeshID])
                    {
                        if (!UVsOffset.Contains(uvindex))
                        {
                            uv[uvindex] += -subMeshUVOffsets[sm];//offset the UV to ensure it isn't negative
                            UVsOffset.Add(uvindex);
                        }
                        textures[subMeshID].CheckMaxUV(uv[uvindex]);
                    }
                }
                else
                {
                    Debug.Log("Mesh does not contain key for trackTexture " + textures[subMeshID].customName);
                }
            }
        }
Example #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();
    }
 /// <summary>
 /// Atlas the specified modifySubmeshes using newTextureCoords and textures.
 /// </summary>
 /// <param customName='modifySubmeshes'>
 /// Submeshes indicies to atlas.
 /// </param>
 /// <param customName='newTextureCoords'>
 /// New trackTexture coords generated from Pack Textures.
 /// </param>
 /// <param customName='textures'>
 /// BuildR Textures library reference.
 /// </param>
 public void Atlas(int[] modifySubmeshes, Rect[] newTextureCoords, TrackBuildRTexture[] textures)
 {
     foreach (DynamicMeshGenericMultiMaterial mesh in _meshes)
         mesh.Atlas(modifySubmeshes, newTextureCoords, textures);
 }
 /// <summary>
 /// Checks the Max UV values used in this model for each trackTexture.
 /// </summary>
 /// <param customName='data'>
 /// BuildR Data.
 /// </param>
 public void CheckMaxTextureUVs(TrackBuildRTexture[] textures)
 {
     foreach(DynamicMeshGenericMultiMaterial mesh in _meshes)
         mesh.CheckMaxTextureUVs(textures);
 }