コード例 #1
0
        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);
        }
コード例 #2
0
 public void Add(T item)
 {
     if (Data == null || Length >= Data.Length)
     {
         MTLog.LogError("MTArray overflow : " + typeof(T));
     }
     Data[Length] = item;
     ++Length;
 }
コード例 #3
0
        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");
            }
        }
コード例 #4
0
        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");
            }
        }
コード例 #5
0
        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();
        }
コード例 #6
0
 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);
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
                }
            }
        }
コード例 #9
0
        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
        }
コード例 #10
0
        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();
        }