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