GetInterpolatedNormal() public method

Get an interpolated normal at a given location.

public GetInterpolatedNormal ( float x, float y ) : Vector3
x float
y float
return Vector3
コード例 #1
0
    /// <summary>
    /// </summary>
    /// <param name="terrainData"></param>
    /// <param name="position">Location in the XZ plane (not the XY plane!)</param>
    /// <param name="sphereRadius"></param>
    /// <returns></returns>
    private static Vector3 AdjustSpawnPositionForTerrainShape(TerrainData terrainData, Vector2 position, float sphereRadius)
    {
        var height = terrainData.GetInterpolatedHeight(position.x, position.y);
        var normal = terrainData.GetInterpolatedNormal(position.x, position.y);

        var offsetAlongNormal = normal * sphereRadius;
        var positionOnTerrain = new Vector3(position.x, height, position.y);
        return positionOnTerrain + offsetAlongNormal;
    }
コード例 #2
0
    private static Texture2D GenerateTerrainNormalTexture(TerrainData data, int width, int height)
    {
        Texture2D normalTex = null;
        #if UNITY_EDITOR
        string normalTexturePath = UnityEditor.AssetDatabase.GetAssetPath(data);
        foreach (var asset in UnityEditor.AssetDatabase.LoadAllAssetsAtPath(normalTexturePath))
        {
            if (asset.name.Contains("NormalMap"))
            {
                normalTex = asset as Texture2D;
                break;
            }
        }
        #endif
        // if its null, it's not created yet
        if (normalTex == null || normalTex.width != width || normalTex.height != height)
        {
            bool overwrite = normalTex != null;
            if (!overwrite)
            {
                normalTex = new Texture2D(width, height, TextureFormat.RGBA32, false);
        #if UNITY_EDITOR
                normalTex.name = "NormalMap";
                UnityEditor.AssetDatabase.AddObjectToAsset(normalTex, data);
                UnityEditor.AssetDatabase.ImportAsset(normalTexturePath);
        #endif
            }
            else
            {
                normalTex.Resize(width, height);
            }

        }
        Color[] normalData = new Color[normalTex.width * normalTex.height];

        for (int x = 0; x < normalTex.width; x++)
        {
            for (int y = 0; y < normalTex.height; y++)
            {
                float xCoord = x / (float)normalTex.width;
                float yCoord = y / (float)normalTex.width;
                Vector3 normal = data.GetInterpolatedNormal(xCoord, yCoord);

                int index = x + y * normalTex.width;
                normalData[index].r = normal.x;
                normalData[index].g = normal.y;
                normalData[index].b = normal.z;

            }
        }
        normalTex.SetPixels(normalData);

        normalTex.Apply();
        return normalTex;
    }
    void OnGUI()
    {
        if (finalize) {
            // select created texture
            Selection.activeObject=AssetDatabase.LoadAssetAtPath(save_path, typeof(Texture2D));
            finalize=false;
        }

        EditorGUILayout.Space();
        sourceTerrain = EditorGUILayout.ObjectField("Source Terrain Data", sourceTerrain, typeof(TerrainData), false) as TerrainData;

        EditorGUILayout.Space();
        if (sourceTerrain) {
            bool render_flag=false;
            bool render_flag_npot=false;
            if (GUILayout.Button("Render heights")) {
                render_flag=true;
            }
            if (GUILayout.Button("Render heights (NPOT exact size 2^n+1)")) {
                render_flag_npot=true;
            }
            if (render_flag || render_flag_npot) {
                rendered_tex=new Texture2D(sourceTerrain.heightmapResolution-(render_flag_npot ? 0:1), sourceTerrain.heightmapResolution-(render_flag_npot ? 0:1), TextureFormat.RGBA32, false, true);
                Color32[] cols=new Color32[rendered_tex.width * rendered_tex.height];
                for( int x = 0; x < rendered_tex.width; x++ ) {
                    for( int y = 0; y < rendered_tex.height; y++ ) {

                        float _x = 1.0f*x/(rendered_tex.width-1);
                        float _y = 1.0f*y/(rendered_tex.height-1);

                        int _hiP,_loP;
                        float hgt = sourceTerrain.GetInterpolatedHeight( _x,_y )/sourceTerrain.size.y;
                        _hiP = Mathf.FloorToInt( hgt*255.0f );
                        _loP = Mathf.FloorToInt( (hgt*255.0f - _hiP)*255.0f );

                        int _Nx, _Nz;
                        Vector3 norm = sourceTerrain.GetInterpolatedNormal( _x,_y );
                        _Nx = Mathf.RoundToInt( Mathf.Clamp01(norm.x*0.5f+0.5f)*255.0f );
                        _Nz = Mathf.RoundToInt( Mathf.Clamp01(norm.z*0.5f+0.5f)*255.0f );
                        cols[y * rendered_tex.width + x] = new Color32( (byte)_hiP, (byte)_loP, (byte)_Nx, (byte)_Nz );
                    }
                }
                rendered_tex.SetPixels32(cols);
                rendered_tex.Apply(false,false);
                if (Selection.activeObject is Texture2D && AssetDatabase.GetAssetPath(Selection.activeObject as Texture2D)!="") {
                    save_path=AssetDatabase.GetAssetPath(Selection.activeObject as Texture2D);
                    directory=Path.GetDirectoryName(save_path);
                    file=Path.GetFileNameWithoutExtension(save_path)+".png";
                } else {
                    if (save_path=="") {
                        directory=Path.GetDirectoryName(AssetDatabase.GetAssetPath(sourceTerrain));
                        file=Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(sourceTerrain))+".png";
                    }
                }
            }

        }
        if (rendered_tex) {
            EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Height(RG) & normal(BA) texture", GUILayout.MinWidth(200));
                EditorGUILayout.ObjectField(rendered_tex, typeof(Texture2D), false, GUILayout.MinWidth(150), GUILayout.MinHeight(150), GUILayout.MaxWidth(150), GUILayout.MaxHeight(150));
            EditorGUILayout.EndHorizontal();
            if (GUILayout.Button("Save texture")) {
                if (save_path=="") {
                    directory=Path.GetDirectoryName(AssetDatabase.GetAssetPath(sourceTerrain));
                    file=Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(sourceTerrain))+".png";
                }
                SaveTexture(directory, file);
            }
        }
    }
コード例 #4
0
        /// <summary>
        /// Generate textures for the terrain
        /// </summary>
        float[,,] GenerateAlphaMap(TerrainData data)
        {
            //make sure textures have been set
            if (_splatPrototypes.Length < 1)
            {
                return null;
            }

            //create map
            var width = data.alphamapWidth;
            var height = data.alphamapHeight;
            var layers = data.alphamapLayers - 1; //ignore the road layer
            var alphamap = new float[width, height, layers + 1];

            for (int x = 0; x < width; ++x)
            {
                for (int z = 0; z < height; ++z)
                {
                    var xNorm = (float)x / (float)width;
                    var zNorm = (float)z / (float)height;

                    //sample height at this location
                    var h = data.GetHeight(z, x);

                    //get normalized coordinates relative to the overall terrain dimensions
                    var normal = data.GetInterpolatedNormal(zNorm, xNorm);

                    //get steepnes at the coordinate
                    var angle = data.GetSteepness(zNorm, xNorm);

                    var weights = new float[layers];

                    if (layers > 1)
                    {
                        weights[0] = 0.5f;
                    }

                    if (layers > 2)
                    {
                        //more influence at steep heights
                        weights[1] = angle / 90f;
                    }

                    if (layers > 3 && h < 0.4f)
                    {
                        weights[2] = 1f;
                    }

                    float sum = weights.Sum();

                    //go over all terrain textures
                    for (int i = 1; i < layers; i++)
                    {
                        //normalize
                        weights[i - 1] /= sum;

                        //set weight for correct texture
                        alphamap[x, z, i] = weights[i - 1];
                    }
                }
            }

            return alphamap;
        }