public static Color BakeNormal(Terrain t, float u, float v) { Color c = new Color(0, 0, 1, 1); #if UNITY_EDITOR if (t.terrainData == null) { MTLog.LogError("terrain data doesn't exist"); return(c); } int matCount = t.terrainData.alphamapTextureCount; if (matCount <= 0) { return(c); } //base pass Vector3 normal = BakeLayerNormal(t, 0, 0, u, v); for (int i = 1; i < matCount; ++i) { normal += BakeLayerNormal(t, i, i * 4, u, v); } normal = normal.normalized; c.r = 0.5f * (normal.x + 1f); c.g = 0.5f * (normal.y + 1f); c.b = 1; c.a = 1; #endif return(c); }
public void Add(T item) { if (Data == null || Length >= Data.Length) { MTLog.LogError("MTArray overflow : " + typeof(T)); } Data[Length] = item; ++Length; }
void ITerrainTreeScaner.Run(Vector3 center, out Vector3 hitpos, out Vector3 hitnormal) { hitpos = center; hitnormal = Vector3.up; RaycastHit hit = new RaycastHit(); if (Physics.Raycast(center, Vector3.down, out hit, CheckRayLen)) { hitpos = hit.point; hitnormal = hit.normal; } else { MTLog.LogError("scan didn't hit terrain"); } }
private void RayCastBoundary(float fx, float fz, int x, int z, byte bk, SamplerTree sampler) { Vector3 top = vCheckTop + fx * Vector3.right + fz * Vector3.forward; RaycastHit hit = new RaycastHit(); if (Physics.Raycast(top, Vector3.down, out hit, CheckRayLen)) { SampleVertexData vert = new SampleVertexData(); vert.Position = hit.point; vert.Normal = hit.normal; vert.UV = new Vector2(fx / maxX / gridSize[0], fz / maxZ / gridSize[1]); sampler.AddBoundary(subdivision, x, z, bk, vert); } else { MTLog.LogError("RayCastBoundary didn't hit terrain"); } }
public static void SaveMaterials(string dataName, Terrain t) { if (t.terrainData == null) { MTLog.LogError("terrain data doesn't exist"); return; } int matCount = t.terrainData.alphamapTextureCount; if (matCount <= 0) { return; } //base pass SaveMaterail(dataName, t, 0, 0, "MT/Standard-BasePass"); for (int i = 1; i < matCount; ++i) { SaveMaterail(dataName, t, i, i * 4, "MT/Standard-AddPass"); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
public void StitchBorder(byte flag, byte nflag, float minDis, SamplerTree neighbour) { if (neighbour == null) { return; } if (flag <= RBCorner || nflag <= RBCorner) { return; } if (!Boundaries.ContainsKey(flag)) { MTLog.LogError("SamplerTree boundary doesn't contains corner : " + flag); return; } if (!neighbour.Boundaries.ContainsKey(nflag)) { MTLog.LogError("SamplerTree neighbour boundary doesn't contains corner : " + nflag); return; } if (StitchedBorders.Contains(flag) && neighbour.StitchedBorders.Contains(nflag)) { return; } if (Boundaries[flag].Count > neighbour.Boundaries[nflag].Count) { neighbour.Boundaries[nflag].Clear(); neighbour.Boundaries[nflag].AddRange(Boundaries[flag]); } else { Boundaries[flag].Clear(); Boundaries[flag].AddRange(neighbour.Boundaries[nflag]); } // StitchedBorders.Add(flag); neighbour.StitchedBorders.Add(nflag); }
public static Color BakePixel(Terrain t, float u, float v) { Color c = Color.black; #if UNITY_EDITOR if (t.terrainData == null) { MTLog.LogError("terrain data doesn't exist"); return(c); } int matCount = t.terrainData.alphamapTextureCount; if (matCount <= 0) { return(c); } //base pass for (int i = 0; i < matCount; ++i) { c += BakeLayerPixel(t, i, i * 4, u, v); } #endif return(c); }
private void StitchCorner(int x, int z) { SamplerTree center = GetSubTree(x, z); if (!center.Boundaries.ContainsKey(SamplerTree.LBCorner)) { MTLog.LogError("boundary data missing"); return; } SamplerTree right = GetSubTree(x + 1, z); SamplerTree left = GetSubTree(x - 1, z); SamplerTree right_top = GetSubTree(x + 1, z + 1); SamplerTree top = GetSubTree(x, z + 1); SamplerTree left_top = GetSubTree(x - 1, z + 1); SamplerTree left_down = GetSubTree(x - 1, z - 1); SamplerTree down = GetSubTree(x, z - 1); SamplerTree right_down = GetSubTree(x + 1, z - 1); if (!center.StitchedBorders.Contains(SamplerTree.LBCorner)) { MergeCorners(center.Boundaries[SamplerTree.LBCorner], left != null ? left.Boundaries[SamplerTree.RBCorner] : null, left_down != null ? left_down.Boundaries[SamplerTree.RTCorner] : null, down != null ? down.Boundaries[SamplerTree.LTCorner] : null); center.StitchedBorders.Add(SamplerTree.LBCorner); if (left != null) { left.StitchedBorders.Add(SamplerTree.RBCorner); } if (left_down != null) { left_down.StitchedBorders.Add(SamplerTree.RTCorner); } if (down != null) { left.StitchedBorders.Add(SamplerTree.LTCorner); } } if (!center.StitchedBorders.Contains(SamplerTree.RBCorner)) { MergeCorners(center.Boundaries[SamplerTree.RBCorner], right != null ? right.Boundaries[SamplerTree.LBCorner] : null, right_down != null ? right_down.Boundaries[SamplerTree.LTCorner] : null, down != null ? down.Boundaries[SamplerTree.RTCorner] : null); center.StitchedBorders.Add(SamplerTree.RBCorner); if (right != null) { right.StitchedBorders.Add(SamplerTree.LBCorner); } if (right_down != null) { right_down.StitchedBorders.Add(SamplerTree.LTCorner); } if (down != null) { down.StitchedBorders.Add(SamplerTree.RTCorner); } } if (!center.StitchedBorders.Contains(SamplerTree.LTCorner)) { MergeCorners(center.Boundaries[SamplerTree.LTCorner], left != null ? left.Boundaries[SamplerTree.RTCorner] : null, left_top != null ? left_top.Boundaries[SamplerTree.RBCorner] : null, top != null ? top.Boundaries[SamplerTree.LBCorner] : null); center.StitchedBorders.Add(SamplerTree.LTCorner); if (left != null) { left.StitchedBorders.Add(SamplerTree.RTCorner); } if (left_top != null) { left_top.StitchedBorders.Add(SamplerTree.RBCorner); } if (top != null) { top.StitchedBorders.Add(SamplerTree.LBCorner); } } if (!center.StitchedBorders.Contains(SamplerTree.RTCorner)) { MergeCorners(center.Boundaries[SamplerTree.RTCorner], right != null ? right.Boundaries[SamplerTree.LTCorner] : null, right_top != null ? right_top.Boundaries[SamplerTree.LBCorner] : null, top != null ? top.Boundaries[SamplerTree.RBCorner] : null); center.StitchedBorders.Add(SamplerTree.RTCorner); if (right != null) { right.StitchedBorders.Add(SamplerTree.LTCorner); } if (right_top != null) { right_top.StitchedBorders.Add(SamplerTree.LBCorner); } if (top != null) { top.StitchedBorders.Add(SamplerTree.RBCorner); } } }
private static void SaveMaterail(string path, string dataName, Terrain t, int matIdx, int layerStart, string shaderName) { #if UNITY_EDITOR if (matIdx >= t.terrainData.alphamapTextureCount) { return; } string mathPath = string.Format("{0}/{1}_{2}.mat", path, dataName, matIdx); Material mat = AssetDatabase.LoadAssetAtPath <Material>(mathPath); if (mat != null) { AssetDatabase.DeleteAsset(mathPath); } //alpha map byte[] alphaMapData = t.terrainData.alphamapTextures[matIdx].EncodeToTGA(); string alphaMapSavePath = string.Format("{0}/{1}_alpha{2}.tga", path, dataName, matIdx); if (File.Exists(alphaMapSavePath)) { File.Delete(alphaMapSavePath); } FileStream stream = File.Open(alphaMapSavePath, FileMode.Create); stream.Write(alphaMapData, 0, alphaMapData.Length); stream.Close(); AssetDatabase.Refresh(); string alphaMapPath = string.Format("{0}/{1}_alpha{2}.tga", path, dataName, matIdx); //the alpha map texture has to be set to best compression quality, otherwise the black spot may //show on the ground TextureImporter importer = AssetImporter.GetAtPath(alphaMapPath) as TextureImporter; if (importer == null) { MTLog.LogError("export terrain alpha map failed"); return; } importer.textureCompression = TextureImporterCompression.Uncompressed; importer.textureType = TextureImporterType.Default; importer.wrapMode = TextureWrapMode.Clamp; EditorUtility.SetDirty(importer); importer.SaveAndReimport(); Texture2D alphaMap = AssetDatabase.LoadAssetAtPath <Texture2D>(alphaMapPath); // Material tMat = new Material(Shader.Find(shaderName)); tMat.SetTexture("_Control", alphaMap); if (tMat == null) { MTLog.LogError("export terrain material failed"); return; } for (int l = layerStart; l < layerStart + 4 && l < t.terrainData.terrainLayers.Length; ++l) { int idx = l - layerStart; TerrainLayer layer = t.terrainData.terrainLayers[l]; Vector2 tiling = new Vector2(t.terrainData.size.x / layer.tileSize.x, t.terrainData.size.z / layer.tileSize.y); tMat.SetTexture(string.Format("_Splat{0}", idx), layer.diffuseTexture); tMat.SetTextureOffset(string.Format("_Splat{0}", idx), layer.tileOffset); tMat.SetTextureScale(string.Format("_Splat{0}", idx), tiling); tMat.SetTexture(string.Format("_Normal{0}", idx), layer.normalMapTexture); tMat.SetFloat(string.Format("_NormalScale{0}", idx), layer.normalScale); tMat.SetFloat(string.Format("_Metallic{0}", idx), layer.metallic); tMat.SetFloat(string.Format("_Smoothness{0}", idx), layer.smoothness); } AssetDatabase.CreateAsset(tMat, mathPath); #endif }
public static void LoadMesh(Mesh[] meshes, string dataName, int meshId) { string path = string.Format("{0}/MightyTerrainMesh/Resources/{1}_{2}.bytes", Application.dataPath, dataName, meshId); FileStream stream = File.Open(path, FileMode.Open); _vec2Cache.Clear(); _intCache.Clear(); //lods byte[] nBuff = new byte[sizeof(int)]; stream.Read(nBuff, 0, sizeof(int)); int lods = BitConverter.ToInt32(nBuff, 0); if (meshes.Length != lods) { MTLog.LogError("meshes length does not match lods"); return; } for (int l = 0; l < lods; ++l) { meshes[l] = new Mesh(); //vertices _vec3Cache.Clear(); nBuff = new byte[sizeof(int)]; stream.Read(nBuff, 0, sizeof(int)); int len = BitConverter.ToInt32(nBuff, 0); for (int i = 0; i < len; ++i) { _vec3Cache.Add(ReadVector3(stream)); } meshes[l].vertices = _vec3Cache.ToArray(); //normals _vec3Cache.Clear(); stream.Read(nBuff, 0, sizeof(int)); len = BitConverter.ToInt32(nBuff, 0); for (int i = 0; i < len; ++i) { _vec3Cache.Add(ReadVector3(stream)); } meshes[l].normals = _vec3Cache.ToArray(); //uvs _vec2Cache.Clear(); stream.Read(nBuff, 0, sizeof(int)); len = BitConverter.ToInt32(nBuff, 0); for (int i = 0; i < len; ++i) { _vec2Cache.Add(ReadVector2(stream)); } meshes[l].uv = _vec2Cache.ToArray(); //faces _intCache.Clear(); stream.Read(nBuff, 0, sizeof(int)); len = BitConverter.ToInt32(nBuff, 0); byte[] fBuff = new byte[sizeof(int)]; for (int i = 0; i < len; ++i) { stream.Read(fBuff, 0, sizeof(int)); _intCache.Add(BitConverter.ToInt32(fBuff, 0)); } meshes[l].triangles = _intCache.ToArray(); } stream.Close(); }