Skip to content

Commit 5139f5d

Browse files
authored
Code to create Elevation Angle and Azimuth Angle maps, plus base texture and other textures for mapping purposes
1.png = base terrain texture (supplied by NASA) bunchofnumbers..._darkblue.png = second terrain texture dark-blue-color-solid-background.png = third terrain texture images.png = fourth terrain texture
1 parent 5b3789d commit 5139f5d

10 files changed

+463
-0
lines changed

1.png

2.9 MB
Loading
Loading

ElevationMaterial.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
5+
public class ElevationMaterial : MonoBehaviour
6+
{
7+
public Material[] material;
8+
public Renderer rend;
9+
// Start is called before the first frame update
10+
void Start()
11+
{
12+
rend = GetComponent<Renderer>();
13+
rend.enabled = true;
14+
rend.sharedMaterial = material[0];
15+
}
16+
17+
// Update is called once per frame
18+
void MapElevation()
19+
{
20+
21+
}
22+
void SetPoints()
23+
{
24+
rend.sharedMaterial = material[1];
25+
}
26+
}

ElevationMaterial.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MakeTerrainMapAzimuth.cs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using System.Linq;
5+
6+
public class MakeTerrainMap : MonoBehaviour
7+
{
8+
// Start is called before the first frame update
9+
10+
// System.Obsolete to minimize errors
11+
[System.Obsolete]
12+
void Start () {
13+
// Get the attached terrain component
14+
Terrain terrain = GetComponent<Terrain>();
15+
16+
// Get a reference to the terrain data
17+
TerrainData terrainData = terrain.terrainData;
18+
19+
// Splatmap data is stored internally as a 3d array of floats, so declare a new empty array ready for your custom splatmap data:
20+
float[, ,] splatmapData = new float[terrainData.alphamapWidth, terrainData.alphamapHeight, terrainData.alphamapLayers];
21+
// Declare constants for earth and lunar values
22+
const float lunarRadius = 1737.4f;
23+
const float earthX = 1623.678285f;
24+
const float earthY = 590.9705659f;
25+
const float earthZ = -181.6077521f;
26+
const float earthLatitude = -6f;
27+
const float earthLongitude = 20f;
28+
const float minLatitude = -88.44359886830375f;
29+
const float maxLatitude = -89.17347901603343f;
30+
const float minLongitude = 107.5300786165378f;
31+
const float maxLongitude = 141.8371251025832f;
32+
const float slopeDistance = 0.1f;
33+
Vector3 earth = new Vector3(earthX, earthY, earthZ);
34+
// Loops through points to find elevation angle at each point
35+
for (int y = 0; y < terrainData.alphamapHeight; y++)
36+
{
37+
for (int x = 0; x < terrainData.alphamapWidth; x++)
38+
{
39+
// Normalise x/y coordinates to range 0-1
40+
float y_01 = (float)y/(float)terrainData.alphamapHeight;
41+
float x_01 = (float)x/(float)terrainData.alphamapWidth;
42+
43+
// Calculate the normal of the terrain (note this is in normalised coordinates relative to the overall terrain dimensions)
44+
Vector3 normal = terrainData.GetInterpolatedNormal(y_01,x_01);
45+
float terrainwidth = terrainData.size.x;
46+
float terrainlength = terrainData.size.z;
47+
float terrainpositionx = x_01 * terrainwidth;
48+
float terrainpositionz = y_01 * terrainlength;
49+
Vector3 worldposition = new Vector3(terrainpositionx, 0, terrainpositionz);
50+
51+
// Calculate the steepness of the terrain
52+
float steepness = terrainData.GetSteepness(y_01,x_01);
53+
54+
// Setup an array to record the mix of texture weights at this point
55+
float[] splatWeights = new float[terrainData.alphamapLayers];
56+
57+
// Texture[0] has constant influence
58+
splatWeights[0] = 0.5f;
59+
60+
// Assign elevation angles to a SplatMap texture
61+
62+
63+
splatWeights[1] = AzimuthToEarth(terrainpositionz, terrainpositionx);
64+
65+
66+
// Sum of all textures weights must add to 1, so calculate normalization factor from sum of weights
67+
float z = splatWeights.Sum();
68+
69+
// Loop through each terrain texture
70+
for(int i = 0; i<terrainData.alphamapLayers; i++){
71+
72+
// Normalize so that sum of all texture weights = 1
73+
splatWeights[i] /= z;
74+
75+
// Assign this point to the splatmap array
76+
splatmapData[x, y, i] = splatWeights[i];
77+
}
78+
}
79+
}
80+
81+
float GetElevationAngle(Vector3 point)
82+
{
83+
(float latitude, float longitude) = FindLatitudeLongitudeOfUnityPoint(point);
84+
85+
Vector3 cartesianPoint = CartesianConversion(latitude, longitude);
86+
87+
float azimuthToEarth = AzimuthToEarth(latitude, longitude);
88+
float elevationAngleToEarth = ElevationAngleToEarth(cartesianPoint);
89+
float elevationAngleOfTerrain = ElevationAngleOfTerrain(cartesianPoint, azimuthToEarth);
90+
91+
return elevationAngleOfTerrain;
92+
}
93+
94+
(float latitude, float longitude) FindLatitudeLongitudeOfUnityPoint(Vector3 point)
95+
{
96+
float unityX = point.x;
97+
float unityY = point.y;
98+
99+
float interpolatedX = Mathf.InverseLerp(0, 2499, unityX);
100+
float interpolatedY = Mathf.InverseLerp(0, 2499, unityY);
101+
102+
float latitude = Mathf.Lerp(minLatitude, maxLatitude, interpolatedX);
103+
float longitude = Mathf.Lerp(minLongitude, maxLongitude, interpolatedY);
104+
105+
return (latitude, longitude);
106+
}
107+
108+
Vector3 CartesianConversion(float latitude, float longitude)
109+
{
110+
float x = lunarRadius * Mathf.Cos(latitude) * Mathf.Cos(longitude);
111+
float y = lunarRadius * Mathf.Cos(latitude) * Mathf.Sin(longitude);
112+
float z = lunarRadius * Mathf.Sin(latitude);
113+
114+
return new Vector3(x, y, z);
115+
}
116+
117+
float AzimuthToEarth(float latitude, float longitude)
118+
{
119+
float latitudeInRadians = DegreesToRadians(latitude);
120+
float longitudeInRadians = DegreesToRadians(longitude);
121+
float x = Mathf.Sin(longitudeInRadians - earthLongitude) * Mathf.Cos(earthLatitude);
122+
float y = (Mathf.Cos(latitudeInRadians) * Mathf.Sin(earthLatitude)) - (Mathf.Sin(latitudeInRadians) * Mathf.Cos(earthLatitude) * Mathf.Cos(earthLongitude - longitudeInRadians));
123+
float azimuthAngle = Mathf.Atan2(y, x);
124+
125+
return azimuthAngle;
126+
}
127+
128+
float DegreesToRadians(float degreeValue)
129+
{
130+
return degreeValue * Mathf.PI / 180f;
131+
}
132+
133+
float ElevationAngleOfTerrain(Vector3 point, float azimuthAngle)
134+
{
135+
float xDistanceForSlope = slopeDistance * Mathf.Cos(azimuthAngle);
136+
float yDistanceForSlope = slopeDistance * Mathf.Sin(azimuthAngle);
137+
138+
Vector3 slopeSamplePoint = PointFromClosestTerrain(new Vector3(point.x + xDistanceForSlope, 0f, point.z + yDistanceForSlope));
139+
float heightForSlope = point.y - slopeSamplePoint.y;
140+
141+
float elevationAngle = Mathf.Atan(heightForSlope / slopeDistance);
142+
143+
return elevationAngle;
144+
}
145+
146+
float ElevationAngleToEarth(Vector3 point)
147+
{
148+
float xPointToEarth = point.x - earth.x;
149+
float yPointToEarth = point.y - earth.y;
150+
float zPointToEarth = point.z - earth.z;
151+
152+
float range = Mathf.Sqrt(Mathf.Pow(xPointToEarth, 2f) + Mathf.Pow(yPointToEarth, 2f) + Mathf.Pow(zPointToEarth, 2f));
153+
float rz = (Mathf.Cos(earthLatitude) * Mathf.Cos(earthLongitude)) + (Mathf.Cos(earthLatitude) * Mathf.Sin(earthLongitude)) + Mathf.Sin(earthLongitude);
154+
155+
return Mathf.Asin(rz / range);
156+
}
157+
158+
Vector3 PointFromClosestTerrain(Vector3 position)
159+
{
160+
Terrain terrain = GetClosestCurrentTerrain(position);
161+
162+
position.y = terrain.SampleHeight(position);
163+
164+
return position;
165+
}
166+
167+
Terrain GetClosestCurrentTerrain(Vector3 position)
168+
{
169+
//Get all terrain
170+
Terrain[] terrains = Terrain.activeTerrains;
171+
172+
//Make sure that terrains length is ok
173+
if (terrains.Length == 0)
174+
return null;
175+
176+
//If just one, return that one terrain
177+
if (terrains.Length == 1)
178+
return terrains[0];
179+
180+
//Get the closest one to the player
181+
float lowDist = (terrains[0].GetPosition() - position).sqrMagnitude;
182+
var terrainIndex = 0;
183+
184+
for (int i = 1; i < terrains.Length; i++)
185+
{
186+
Terrain terrain = terrains[i];
187+
Vector3 terrainPos = terrain.GetPosition();
188+
189+
//Find the distance and check if it is lower than the last one then store it
190+
var dist = (terrainPos - position).sqrMagnitude;
191+
if (dist < lowDist)
192+
{
193+
lowDist = dist;
194+
terrainIndex = i;
195+
}
196+
}
197+
return terrains[terrainIndex];
198+
}
199+
// Finally assign the new splatmap to the terrainData:
200+
terrainData.SetAlphamaps(0, 0, splatmapData);
201+
}
202+
}

MakeTerrainMapAzimuth.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)