├── .gitattributes ├── .gitignore ├── Assets ├── Helpers.meta ├── Helpers │ ├── Orbit.js │ └── Orbit.js.meta ├── IcosaHedron.unity ├── IcosaHedron.unity.meta ├── Scripts.meta ├── Scripts │ ├── Planet.cs │ ├── Planet.cs.meta │ ├── PlanetGeneration.cs │ ├── PlanetGeneration.cs.meta │ ├── Subdivide.js │ ├── Subdivide.js.meta │ ├── TestScene.cs │ └── TestScene.cs.meta ├── Shaders.meta ├── Shaders │ ├── UnityVC.meta │ └── UnityVC │ │ ├── Editor.meta │ │ ├── Editor │ │ ├── StandardShaderVCGUI.cs │ │ └── StandardShaderVCGUI.cs.meta │ │ ├── Standard.mat │ │ ├── Standard.mat.meta │ │ ├── StandardFade.mat │ │ ├── StandardFade.mat.meta │ │ ├── StandardVC.shader │ │ ├── StandardVC.shader.meta │ │ ├── UnityVC.cginc │ │ ├── UnityVC.cginc.meta │ │ ├── VertexColorDebugSphere.FBX │ │ ├── VertexColorDebugSphere.FBX.meta │ │ ├── VertexColorDebugSphereAlpha.FBX │ │ ├── VertexColorDebugSphereAlpha.FBX.meta │ │ ├── tiles_diff.png │ │ ├── tiles_diff.png.meta │ │ ├── tiles_norm.png │ │ ├── tiles_norm.png.meta │ │ ├── tiles_spec.png │ │ └── tiles_spec.png.meta ├── Standard Assets.meta ├── Standard Assets │ ├── Scripts.meta │ └── Scripts │ │ ├── Camera Scripts.meta │ │ └── Camera Scripts │ │ ├── MouseOrbit.js │ │ ├── MouseOrbit.js.meta │ │ ├── SmoothFollow.js │ │ ├── SmoothFollow.js.meta │ │ ├── SmoothLookAt.js │ │ └── SmoothLookAt.js.meta ├── UnityVS.meta ├── test.mat ├── test.mat.meta ├── test.unity └── test.unity.meta ├── ProjectSettings ├── AudioManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshLayers.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── QualitySettings.asset ├── TagManager.asset └── TimeManager.asset └── UnityVS.RandomPlanetGenerator.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | bld/ 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # MSTest test Results 20 | [Tt]est[Rr]esult*/ 21 | [Bb]uild[Ll]og.* 22 | 23 | #NUNIT 24 | *.VisualState.xml 25 | TestResult.xml 26 | 27 | # Build Results of an ATL Project 28 | [Dd]ebugPS/ 29 | [Rr]eleasePS/ 30 | dlldata.c 31 | 32 | *_i.c 33 | *_p.c 34 | *_i.h 35 | *.ilk 36 | *.obj 37 | *.pch 38 | *.pdb 39 | *.pgc 40 | *.pgd 41 | *.rsp 42 | *.sbr 43 | *.tlb 44 | *.tli 45 | *.tlh 46 | *.tmp 47 | *.tmp_proj 48 | *.log 49 | *.vspscc 50 | *.vssscc 51 | .builds 52 | *.pidb 53 | *.svclog 54 | *.scc 55 | 56 | # Chutzpah Test files 57 | _Chutzpah* 58 | 59 | # Visual C++ cache files 60 | ipch/ 61 | *.aps 62 | *.ncb 63 | *.opensdf 64 | *.sdf 65 | *.cachefile 66 | 67 | # Visual Studio profiler 68 | *.psess 69 | *.vsp 70 | *.vspx 71 | 72 | # TFS 2012 Local Workspace 73 | $tf/ 74 | 75 | # Guidance Automation Toolkit 76 | *.gpState 77 | 78 | # ReSharper is a .NET coding add-in 79 | _ReSharper*/ 80 | *.[Rr]e[Ss]harper 81 | *.DotSettings.user 82 | 83 | # JustCode is a .NET coding addin-in 84 | .JustCode 85 | 86 | # TeamCity is a build add-in 87 | _TeamCity* 88 | 89 | # DotCover is a Code Coverage Tool 90 | *.dotCover 91 | 92 | # NCrunch 93 | *.ncrunch* 94 | _NCrunch_* 95 | .*crunch*.local.xml 96 | 97 | # MightyMoose 98 | *.mm.* 99 | AutoTest.Net/ 100 | 101 | # Web workbench (sass) 102 | .sass-cache/ 103 | 104 | # Installshield output folder 105 | [Ee]xpress/ 106 | 107 | # DocProject is a documentation generator add-in 108 | DocProject/buildhelp/ 109 | DocProject/Help/*.HxT 110 | DocProject/Help/*.HxC 111 | DocProject/Help/*.hhc 112 | DocProject/Help/*.hhk 113 | DocProject/Help/*.hhp 114 | DocProject/Help/Html2 115 | DocProject/Help/html 116 | 117 | # Click-Once directory 118 | publish/ 119 | 120 | # Publish Web Output 121 | *.[Pp]ublish.xml 122 | *.azurePubxml 123 | 124 | # NuGet Packages Directory 125 | packages/ 126 | ## TODO: If the tool you use requires repositories.config uncomment the next line 127 | #!packages/repositories.config 128 | 129 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 130 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 131 | !packages/build/ 132 | 133 | # Windows Azure Build Output 134 | csx/ 135 | *.build.csdef 136 | 137 | # Windows Store app package directory 138 | AppPackages/ 139 | 140 | # Others 141 | sql/ 142 | *.Cache 143 | ClientBin/ 144 | [Ss]tyle[Cc]op.* 145 | ~$* 146 | *~ 147 | *.dbmdl 148 | *.dbproj.schemaview 149 | *.pfx 150 | *.publishsettings 151 | node_modules/ 152 | 153 | # RIA/Silverlight projects 154 | Generated_Code/ 155 | 156 | # Backup & report files from converting an old project file to a newer 157 | # Visual Studio version. Backup files are not needed, because we have git ;-) 158 | _UpgradeReport_Files/ 159 | Backup*/ 160 | UpgradeLog*.XML 161 | UpgradeLog*.htm 162 | 163 | # SQL Server files 164 | *.mdf 165 | *.ldf 166 | 167 | # Business Intelligence projects 168 | *.rdl.data 169 | *.bim.layout 170 | *.bim_*.settings 171 | 172 | # Microsoft Fakes 173 | FakesAssemblies/ 174 | 175 | # ========================= 176 | # Operating System Files 177 | # ========================= 178 | 179 | # OSX 180 | # ========================= 181 | 182 | .DS_Store 183 | .AppleDouble 184 | .LSOverride 185 | 186 | # Icon must ends with two \r. 187 | Icon 188 | 189 | 190 | # Thumbnails 191 | ._* 192 | 193 | # Files that might appear on external disk 194 | .Spotlight-V100 195 | .Trashes 196 | 197 | # Windows 198 | # ========================= 199 | 200 | # Windows image file caches 201 | Thumbs.db 202 | ehthumbs.db 203 | 204 | # Folder config file 205 | Desktop.ini 206 | 207 | # Recycle Bin used on file shares 208 | $RECYCLE.BIN/ 209 | 210 | # Windows Installer files 211 | *.cab 212 | *.msi 213 | *.msm 214 | *.msp 215 | 216 | # UnityVS 217 | Assets/UnityVS 218 | 219 | # Imported from a previous project 220 | # Note: Might have duplicates 221 | *.booproj 222 | *.csproj 223 | *.exe 224 | *.pdb 225 | *.unityproj 226 | *_Data 227 | .git 228 | .gitattributes 229 | .gitignore 230 | Assembly-CSharp-vs.csproj.user 231 | Library 232 | Release 233 | Temp 234 | obj 235 | sysinfo.txt 236 | taosim_new-csharp.sln.DotSettings.user 237 | 238 | 239 | -------------------------------------------------------------------------------- /Assets/Helpers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f99a3c42bb20e4944a5cd4db8b860231 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Helpers/Orbit.js: -------------------------------------------------------------------------------- 1 | var target : Transform; 2 | var distance = 10.0; 3 | var cameraSpeed = 5; 4 | 5 | var xSpeed = 175.0; 6 | var ySpeed = 75.0; 7 | 8 | var yMinLimit = 20; //Lowest vertical angle in respect with the target. 9 | var yMaxLimit = 80; 10 | 11 | var minDistance = 5; //Min distance of the camera from the target 12 | var maxDistance = 20; 13 | 14 | private var x = 0.0; 15 | private var y = 0.0; 16 | 17 | function Start () { 18 | var angles = transform.eulerAngles; 19 | x = angles.y; 20 | y = angles.x; 21 | 22 | // Make the rigid body not change rotation 23 | if (GetComponent.()) 24 | GetComponent.().freezeRotation = true; 25 | } 26 | 27 | function LateUpdate () { 28 | if (target && GetComponent.()) { 29 | 30 | //Zooming with mouse 31 | distance += Input.GetAxis("Mouse ScrollWheel")*distance; 32 | distance = Mathf.Clamp(distance, minDistance, maxDistance); 33 | 34 | //Detect mouse drag; 35 | if(Input.GetMouseButton(0)) { 36 | 37 | x += Input.GetAxis("Mouse X") * xSpeed * 0.02; 38 | y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; 39 | } 40 | y = ClampAngle(y, yMinLimit, yMaxLimit); 41 | 42 | var rotation = Quaternion.Euler(y, x, 0); 43 | var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; 44 | 45 | transform.position = Vector3.Lerp (transform.position, position, cameraSpeed*Time.deltaTime); 46 | transform.rotation = rotation; 47 | } 48 | } 49 | 50 | static function ClampAngle (angle : float, min : float, max : float) { 51 | if (angle < -360) 52 | angle += 360; 53 | if (angle > 360) 54 | angle -= 360; 55 | return Mathf.Clamp (angle, min, max); 56 | } -------------------------------------------------------------------------------- /Assets/Helpers/Orbit.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c9a9446896ee934eae73593e100b51b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/IcosaHedron.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/IcosaHedron.unity -------------------------------------------------------------------------------- /Assets/IcosaHedron.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f6ed3f235471c54da60ef8e763e960d 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c09ee1fe2fdffe438ec63b29fe7ad78 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Scripts/Planet.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System; 5 | using Random = System.Random; 6 | 7 | public class Planet : MonoBehaviour 8 | { 9 | 10 | private Polyhedra surface; 11 | private Random globalRandom; 12 | private List tectonicPlates; 13 | 14 | public int randomSeed = 5; 15 | public int subdivisionLevel = 2; 16 | public float distortionLevel = 1f; 17 | public int plateCount = 36; 18 | public float oceanicRate = 0.7f; 19 | public float heatLevel = 1.0f; 20 | public float moistureLevel = 1.0f; 21 | 22 | public float PlanetScale 23 | { 24 | get 25 | { 26 | return this.transform.localScale.x; 27 | } 28 | } 29 | 30 | void Awake() 31 | { 32 | //Generate(); 33 | } 34 | 35 | public void Generate() 36 | { 37 | this.globalRandom = new Random(randomSeed); 38 | this.surface = GeneratePlanetPolyhedra(); 39 | this.surface.GeneratePlanetTopology(); 40 | this.surface.topology.GeneratePlanetPartition(); 41 | this.GeneratePlanetTectonicPlates(); 42 | this.GeneratePlanetElevation(); 43 | //DrawTectonicPlates(6000f); 44 | this.GeneratePlanetMesh(false); 45 | } 46 | 47 | void Update() 48 | { 49 | #if UNITY_STANDALONE || UNITY_EDITOR 50 | Tile tile; 51 | this.IntersectRay(Camera.main.ScreenPointToRay(Input.mousePosition), out tile); 52 | if (tile != null) 53 | { 54 | tile.DebugDraw(Color.red, 0, this.transform.localScale.x / 100f, this.transform); 55 | //foreach(var t in tile.plate.tiles) 56 | //{ 57 | // t.DebugDraw(Color.green, 0, this.transform.localScale.x / 150f, this.transform); 58 | //} 59 | } 60 | #endif 61 | } 62 | 63 | void DrawTectonicPlates(float duration) 64 | { 65 | foreach (var p in this.tectonicPlates) 66 | { 67 | Color c = new Color((float)globalRandom.NextDouble(), (float)globalRandom.NextDouble(), (float)globalRandom.NextDouble()); 68 | foreach (var t in p.tiles) 69 | { 70 | t.DebugDraw(c, duration, this.transform.localScale.x / 150f, this.transform); 71 | } 72 | } 73 | } 74 | 75 | private Polyhedra GeneratePlanetPolyhedra() 76 | { 77 | var mesh = Utils.GenerateSubdividedIcosahedron(this.subdivisionLevel); 78 | mesh.planet = this; 79 | var totalDistortion = Math.Ceiling(mesh.edges.Count * this.distortionLevel); 80 | var remainingIterations = 6; 81 | int i; 82 | while (remainingIterations > 0) 83 | { 84 | var iterationDistortion = (int)Math.Floor(totalDistortion / remainingIterations); 85 | totalDistortion -= iterationDistortion; 86 | mesh.DistortMesh(iterationDistortion, globalRandom); 87 | mesh.RelaxMesh(0.5f); 88 | --remainingIterations; 89 | } 90 | 91 | //var initialIntervalIteration = action.intervalIteration; 92 | 93 | var averageNodeRadius = Math.Sqrt(4 * Math.PI / mesh.nodes.Count); 94 | var minShiftDelta = averageNodeRadius / 50000 * mesh.nodes.Count; 95 | var maxShiftDelta = averageNodeRadius / 50 * mesh.nodes.Count; 96 | 97 | float priorShift, shiftDelta; 98 | var currentShift = mesh.RelaxMesh(0.5f); 99 | 100 | do 101 | { 102 | priorShift = currentShift; 103 | currentShift = mesh.RelaxMesh(0.5f); 104 | shiftDelta = Math.Abs(currentShift - priorShift); 105 | } while (shiftDelta >= minShiftDelta /* && action.intervalIteration - initialIntervalIteration < 300*/); 106 | 107 | for (i = 0; i < mesh.faces.Count; ++i) 108 | { 109 | var face = mesh.faces[i]; 110 | var p0 = mesh.nodes[face.n[0]].p; 111 | var p1 = mesh.nodes[face.n[1]].p; 112 | var p2 = mesh.nodes[face.n[2]].p; 113 | face.centroid = Utils.CalculateFaceCentroid(p0, p1, p2).normalized; 114 | } 115 | 116 | for (i = 0; i < mesh.nodes.Count; ++i) 117 | { 118 | var node = mesh.nodes[i]; 119 | var faceIndex = node.f[0]; 120 | for (var j = 1; j < node.f.Count - 1; ++j) 121 | { 122 | faceIndex = Utils.FindNextFaceIndex(mesh, i, faceIndex); 123 | var k = node.f.IndexOf(faceIndex); 124 | node.f[k] = node.f[j]; 125 | node.f[j] = faceIndex; 126 | } 127 | } 128 | this.surface = mesh; 129 | return mesh; 130 | } 131 | private void GeneratePlanetMesh(bool heights) 132 | { 133 | Matrix4x4 trs = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale); 134 | var verts = new List(); 135 | var norms = new List(); 136 | var tris = new List(); 137 | var colors = new List(); 138 | 139 | var tileStart = 0; 140 | foreach (var tile in surface.topology.tiles) 141 | { 142 | if (tileStart >= 64000) 143 | { 144 | GameObject go = new GameObject("child"); 145 | go.transform.parent = this.gameObject.transform; 146 | 147 | var mesh = new Mesh { name = "World Mesh" }; 148 | go.AddComponent().mesh = mesh; 149 | var mr = go.AddComponent(); 150 | mr.material = new Material(Shader.Find("Standard (Vertex Color)")); 151 | //mesh.uv = UV; 152 | 153 | for (int i = 0; i < verts.Count; i++) 154 | { 155 | colors.Add((Vector3.Distance(this.transform.position, verts[i]) > this.PlanetScale) ? Color.green : Color.blue); 156 | verts[i] = (Vector3.Distance(this.transform.position, verts[i]) > this.PlanetScale) ? verts[i] : ((verts[i] - transform.position).normalized * this.PlanetScale * 0.999f) + transform.position; 157 | } 158 | 159 | mesh.vertices = verts.ToArray(); 160 | mesh.triangles = tris.ToArray(); 161 | mesh.normals = norms.ToArray(); 162 | mesh.colors = colors.ToArray(); 163 | 164 | tileStart = 0; 165 | verts.Clear(); 166 | norms.Clear(); 167 | tris.Clear(); 168 | colors.Clear(); 169 | } 170 | var tileNorm = (this.transform.rotation * tile.normal).normalized; 171 | var tileOffset = (heights) ? (tile.elevation) * transform.localScale.x / 30f : 0f; 172 | 173 | 174 | verts.Add(trs.MultiplyPoint3x4(tile.averagePosition) + tileNorm * tileOffset); 175 | 176 | 177 | var mag1 = tileNorm * tileOffset; 178 | 179 | norms.Add(tileNorm); 180 | 181 | tileStart = verts.Count - 1; 182 | int index = 0; 183 | foreach (var corner in tile.corners) 184 | { 185 | if (heights) 186 | { 187 | var cornerNorm = (transform.rotation * corner.position).normalized; 188 | verts.Add(trs.MultiplyPoint3x4(corner.position) + cornerNorm * tileOffset); 189 | norms.Add(tileNorm); 190 | 191 | var nextCorner = tile.corners[(index + 1) % tile.corners.Length]; 192 | var nextCornerNorm = (transform.rotation * nextCorner.position).normalized; 193 | var borderNorm = Vector3.Cross(corner.position, nextCorner.position).normalized; 194 | 195 | //brnkhy false will force tiles' sidepanels to 10% depth instead of 100% 196 | if (true) 197 | { 198 | verts.Add(trs.MultiplyPoint3x4(corner.position) + cornerNorm * tileOffset); 199 | verts.Add(transform.position); 200 | verts.Add(trs.MultiplyPoint3x4(nextCorner.position) + nextCornerNorm * tileOffset); 201 | verts.Add(transform.position); 202 | } 203 | else 204 | { 205 | verts.Add(trs.MultiplyPoint3x4(corner.position) + cornerNorm * tileOffset); 206 | verts.Add((trs.MultiplyPoint3x4(corner.position) - transform.position) * 0.90f + transform.position); 207 | verts.Add(trs.MultiplyPoint3x4(nextCorner.position) + nextCornerNorm * tileOffset); 208 | verts.Add((trs.MultiplyPoint3x4(nextCorner.position) - transform.position) * 0.90f + transform.position); 209 | } 210 | 211 | for (int i = 0; i < 4; i++) norms.Add(borderNorm); 212 | 213 | tris.AddRange(new int[] 214 | { 215 | verts.Count - 4, verts.Count - 2, verts.Count - 3, 216 | verts.Count - 2, verts.Count - 1, verts.Count - 3 217 | }); 218 | //Debug.DrawLine(verts[verts.Count - 4], verts[verts.Count - 4] + borderNorm * 25f, Color.red, 100f); 219 | //Debug.DrawLine(verts[verts.Count - 3], verts[verts.Count - 3] + borderNorm * 25f, Color.green, 100f); 220 | //Debug.DrawLine(verts[verts.Count - 2], verts[verts.Count - 2] + borderNorm * 25f, Color.blue, 100f); 221 | //Debug.DrawLine(verts[verts.Count - 1], verts[verts.Count - 1] + borderNorm * 25f, Color.white, 100f); 222 | } 223 | else 224 | { 225 | var cornerNorm = (transform.rotation * corner.position).normalized; 226 | verts.Add(trs.MultiplyPoint3x4(corner.position) + cornerNorm * corner.elevation * 50); 227 | norms.Add(tileNorm); 228 | } 229 | 230 | index++; 231 | } 232 | 233 | for (int i = 1; i <= tile.corners.Length; i++) 234 | { 235 | if (heights) 236 | { 237 | var mid = (i + 1) % (tile.corners.Length + 1) != 0 238 | ? i + 1 239 | : 1; 240 | 241 | tris.Add(tileStart); 242 | tris.Add(tileStart + (mid - 1) * 5 + 1); 243 | tris.Add(tileStart + (i - 1) * 5 + 1); 244 | } 245 | else 246 | { 247 | var mid = (i + 1) < (tile.corners.Length) 248 | ? i + 1 249 | : (i + 1) % (tile.corners.Length) + 1; 250 | 251 | if (mid == 1) 252 | break; 253 | 254 | tris.Add(tileStart + 1); 255 | tris.Add(tileStart + 1 + mid); 256 | tris.Add(tileStart + 1 + i); 257 | } 258 | } 259 | 260 | // Add skirts for elevated hexagons. 261 | // Currently this is a straightforward implementation 262 | // without any optimizations. 263 | if (false) 264 | { 265 | foreach (var border in tile.borders) 266 | { 267 | var borderNorm = Vector3.Cross(border.corners[1].position, border.corners[0].position).normalized; 268 | borderNorm = this.transform.rotation * borderNorm; 269 | verts.Add(trs.MultiplyPoint3x4(border.corners[1].position)); 270 | } 271 | 272 | } 273 | } 274 | 275 | GameObject ch = new GameObject("child"); 276 | ch.transform.parent = this.gameObject.transform; 277 | var mesh2 = new Mesh { name = "World Mesh" }; 278 | ch.AddComponent().mesh = mesh2; 279 | var mr2 = ch.AddComponent(); 280 | mr2.material = new Material(Shader.Find("Standard (Vertex Color)")); 281 | //mesh.uv = UV; 282 | colors = new List(verts.Count); 283 | 284 | for (int i = 0; i < verts.Count; i++) 285 | { 286 | colors.Add((Vector3.Distance(this.transform.position, verts[i]) > this.PlanetScale) ? Color.green : Color.blue); 287 | verts[i] = (Vector3.Distance(this.transform.position, verts[i]) > this.PlanetScale) ? verts[i] : ((verts[i] - transform.position).normalized * this.PlanetScale * 0.999f) + transform.position; 288 | } 289 | 290 | mesh2.vertices = verts.ToArray(); 291 | mesh2.triangles = tris.ToArray(); 292 | mesh2.normals = norms.ToArray(); 293 | mesh2.colors = colors.ToArray(); 294 | } 295 | 296 | private void GeneratePlanetTerrain() 297 | { 298 | 299 | } 300 | 301 | #region Tectonic Plate Generation 302 | private List GeneratePlanetTectonicPlates() 303 | { 304 | var plates = new List(); 305 | var platelessTiles = new List(); 306 | var platelessTilePlates = new List(); 307 | var topology = this.surface.topology; 308 | 309 | var failedCount = 0; 310 | while (plates.Count < plateCount && failedCount < 10000) 311 | { 312 | var corner = topology.corners[globalRandom.Next(0, topology.corners.Count)]; 313 | var adjacentToExistingPlate = false; 314 | for (var i = 0; i < corner.tiles.Length; ++i) 315 | { 316 | if (corner.tiles[i].plate != null) 317 | { 318 | adjacentToExistingPlate = true; 319 | failedCount += 1; 320 | break; 321 | } 322 | } 323 | if (adjacentToExistingPlate) continue; 324 | 325 | failedCount = 0; 326 | 327 | var oceanic = (globalRandom.NextDouble() < this.oceanicRate); 328 | var plate = new Plate(new Color((float)globalRandom.NextDouble(), (float)globalRandom.NextDouble(), (float)globalRandom.NextDouble()), 329 | Utils.RandomUnitVector(globalRandom), 330 | (float)(globalRandom.NextDouble() * (Math.PI / 15f) - (Math.PI / 30f)), 331 | (float)(globalRandom.NextDouble() * (Math.PI / 15f) - (Math.PI / 30f)), 332 | (float)((oceanic) ? (globalRandom.NextDouble() * 0.5 - 0.8) : (globalRandom.NextDouble() * 0.4 + 0.1)), 333 | oceanic, 334 | corner); 335 | plates.Add(plate); 336 | 337 | for (var i = 0; i < corner.tiles.Length; ++i) 338 | { 339 | corner.tiles[i].plate = plate; 340 | plate.tiles.Add(corner.tiles[i]); 341 | } 342 | for (var i = 0; i < corner.tiles.Length; ++i) 343 | { 344 | var tile = corner.tiles[i]; 345 | for (var j = 0; j < tile.tiles.Length; ++j) 346 | { 347 | var adjacentTile = tile.tiles[j]; 348 | if (adjacentTile.plate == null) 349 | { 350 | platelessTiles.Add(adjacentTile); 351 | platelessTilePlates.Add(plate); 352 | } 353 | } 354 | } 355 | } 356 | 357 | while (platelessTiles.Count > 0) 358 | { 359 | // XXX: Try something else instead of globalRandom.Next() if this fails. 360 | var tileIndex = (int)Math.Floor(Math.Pow(globalRandom.NextDouble(), 2) * platelessTiles.Count); 361 | var tile = platelessTiles[tileIndex]; 362 | var plate = platelessTilePlates[tileIndex]; 363 | platelessTiles.RemoveAt(tileIndex); // splice(tileIndex, 1); 364 | platelessTilePlates.RemoveAt(tileIndex); // splice(tileIndex, 1); 365 | if (tile.plate == null) 366 | { 367 | tile.plate = plate; 368 | plate.tiles.Add(tile); 369 | for (var j = 0; j < tile.tiles.Length; ++j) 370 | { 371 | if (tile.tiles[j].plate == null) 372 | { 373 | platelessTiles.Add(tile.tiles[j]); 374 | platelessTilePlates.Add(plate); 375 | } 376 | } 377 | } 378 | } 379 | calculateCornerDistancesToPlateRoot(plates); 380 | this.tectonicPlates = plates; 381 | return plates; 382 | } 383 | 384 | struct DistanceCorner 385 | { 386 | public Corner corner; 387 | public float distanceToPlateRoot; 388 | public DistanceCorner(Corner c, float d) 389 | { 390 | this.corner = c; 391 | this.distanceToPlateRoot = d; 392 | } 393 | } 394 | 395 | void calculateCornerDistancesToPlateRoot(List plates) 396 | { 397 | var distanceCornerQueue = new List(); 398 | for (var i = 0; i < plates.Count; ++i) 399 | { 400 | var corner = plates[i].root; 401 | corner.distanceToPlateRoot = 0; 402 | for (var j = 0; j < corner.corners.Length; ++j) 403 | { 404 | distanceCornerQueue.Add(new DistanceCorner(corner.corners[j], corner.borders[j].Length())); 405 | } 406 | } 407 | 408 | while (true) 409 | { 410 | if (distanceCornerQueue.Count == 0) return; 411 | 412 | var iEnd = distanceCornerQueue.Count; 413 | for (var i = 0; i < iEnd; ++i) 414 | { 415 | var front = distanceCornerQueue[i]; 416 | var corner = front.corner; 417 | var distanceToPlateRoot = front.distanceToPlateRoot; 418 | if (corner.distanceToPlateRoot == 0 || corner.distanceToPlateRoot > distanceToPlateRoot) 419 | { 420 | corner.distanceToPlateRoot = distanceToPlateRoot; 421 | for (var j = 0; j < corner.corners.Length; ++j) 422 | { 423 | distanceCornerQueue.Add(new DistanceCorner(corner.corners[j], distanceToPlateRoot + corner.borders[j].Length())); 424 | } 425 | } 426 | } 427 | 428 | distanceCornerQueue.RemoveRange(0, iEnd); 429 | distanceCornerQueue.Sort(delegate(DistanceCorner A, DistanceCorner B) 430 | { 431 | return A.distanceToPlateRoot.CompareTo(B.distanceToPlateRoot); 432 | }); 433 | } 434 | } 435 | #endregion 436 | #region PlanetElevation 437 | void GeneratePlanetElevation() 438 | { 439 | IdentifyBoundaryBorders(this.surface.topology.borders); 440 | var boundaryCorners = CollectBoundaryCorners(this.surface.topology.corners); 441 | var boundaryCornerInnerBorderIndices = CalculatePlateBoundaryStress(boundaryCorners); 442 | BlurPlateBoundaryStress(boundaryCorners, 3, 0.4f); 443 | var elevationBorderQueue = PopulateElevationBorderQueue(boundaryCorners, boundaryCornerInnerBorderIndices); 444 | ProcessElevationBorderQueue(elevationBorderQueue); 445 | CalculateTileAverageElevations(this.surface.topology.tiles); 446 | } 447 | void IdentifyBoundaryBorders(List borders) 448 | { 449 | for (var i = 0; i < borders.Count; ++i) 450 | { 451 | var border = borders[i]; 452 | if (border.tiles[0].plate != border.tiles[1].plate) 453 | { 454 | border.betweenPlates = true; 455 | border.corners[0].betweenPlates = true; 456 | border.corners[1].betweenPlates = true; 457 | border.tiles[0].plate.boundaryBorders.Add(border); 458 | border.tiles[1].plate.boundaryBorders.Add(border); 459 | } 460 | } 461 | } 462 | List CollectBoundaryCorners(List corners) 463 | { 464 | var boundaryCorners = new List(); 465 | for (var j = 0; j < corners.Count; ++j) 466 | { 467 | var corner = corners[j]; 468 | if (corner.betweenPlates) 469 | { 470 | boundaryCorners.Add(corner); 471 | corner.tiles[0].plate.boundaryCorners.Add(corner); 472 | if (corner.tiles[1].plate != corner.tiles[0].plate) corner.tiles[1].plate.boundaryCorners.Add(corner); 473 | if (corner.tiles[2].plate != corner.tiles[0].plate && corner.tiles[2].plate != corner.tiles[1].plate) corner.tiles[2].plate.boundaryCorners.Add(corner); 474 | } 475 | } 476 | return boundaryCorners; 477 | } 478 | int[] CalculatePlateBoundaryStress(List boundaryCorners) 479 | { 480 | var boundaryCornerInnerBorderIndices = new int[boundaryCorners.Count]; 481 | for (var i = 0; i < boundaryCorners.Count; ++i) 482 | { 483 | var corner = boundaryCorners[i]; 484 | corner.distanceToPlateBoundary = 0; 485 | 486 | Border innerBorder = null; 487 | int innerBorderIndex = 0; 488 | for (var j = 0; j < corner.borders.Length; ++j) 489 | { 490 | var border = corner.borders[j]; 491 | if (!border.betweenPlates) 492 | { 493 | innerBorder = border; 494 | innerBorderIndex = j; 495 | break; 496 | } 497 | } 498 | 499 | if (innerBorder != null) 500 | { 501 | boundaryCornerInnerBorderIndices[i] = innerBorderIndex; 502 | var outerBorder0 = corner.borders[(innerBorderIndex + 1) % corner.borders.Length]; 503 | var outerBorder1 = corner.borders[(innerBorderIndex + 2) % corner.borders.Length]; 504 | var farCorner0 = outerBorder0.OppositeCorner(corner); 505 | var farCorner1 = outerBorder1.OppositeCorner(corner); 506 | var plate0 = innerBorder.tiles[0].plate; 507 | var plate1 = outerBorder0.tiles[0].plate != plate0 ? outerBorder0.tiles[0].plate : outerBorder0.tiles[1].plate; 508 | var boundaryVector = farCorner0.vectorTo(farCorner1); 509 | var boundaryNormal = Vector3.Cross(boundaryVector, corner.position); 510 | var stress = CalculateStress(plate0.CalculateMovement(corner.position), plate1.CalculateMovement(corner.position), boundaryVector, boundaryNormal); 511 | corner.pressure = stress.pressure; 512 | corner.shear = stress.shear; 513 | } 514 | else 515 | { 516 | boundaryCornerInnerBorderIndices[i] = -1; 517 | var plate0 = corner.tiles[0].plate; 518 | var plate1 = corner.tiles[1].plate; 519 | var plate2 = corner.tiles[2].plate; 520 | var boundaryVector0 = corner.corners[0].vectorTo(corner); 521 | var boundaryVector1 = corner.corners[1].vectorTo(corner); 522 | var boundaryVector2 = corner.corners[2].vectorTo(corner); 523 | var boundaryNormal0 = Vector3.Cross(boundaryVector0, corner.position); 524 | var boundaryNormal1 = Vector3.Cross(boundaryVector1, corner.position); 525 | var boundaryNormal2 = Vector3.Cross(boundaryVector2, corner.position); 526 | var stress0 = CalculateStress(plate0.CalculateMovement(corner.position), plate1.CalculateMovement(corner.position), boundaryVector0, boundaryNormal0); 527 | var stress1 = CalculateStress(plate1.CalculateMovement(corner.position), plate2.CalculateMovement(corner.position), boundaryVector1, boundaryNormal1); 528 | var stress2 = CalculateStress(plate2.CalculateMovement(corner.position), plate0.CalculateMovement(corner.position), boundaryVector2, boundaryNormal2); 529 | 530 | corner.pressure = (stress0.pressure + stress1.pressure + stress2.pressure) / 3f; 531 | corner.shear = (stress0.shear + stress1.shear + stress2.shear) / 3f; 532 | } 533 | } 534 | 535 | return boundaryCornerInnerBorderIndices; 536 | } 537 | struct Stress 538 | { 539 | public float pressure; 540 | public float shear; 541 | public Stress(float p, float s) 542 | { 543 | this.pressure = p; 544 | this.shear = s; 545 | } 546 | } 547 | Stress CalculateStress(Vector3 movement0, Vector3 movement1, Vector3 boundaryVector, Vector3 boundaryNormal) 548 | { 549 | var relativeMovement = movement0 - movement1; 550 | var pressureVector = Vector3.Project(relativeMovement, boundaryNormal); 551 | var pressure = pressureVector.magnitude; 552 | if (Vector3.Dot(pressureVector, boundaryNormal) > 0) pressure = -pressure; 553 | var shear = Vector3.Project(relativeMovement, boundaryVector).magnitude; 554 | return new Stress(2f / (1f + (float)Math.Exp(-pressure / 30f)) - 1f, 2f / (1f + (float)Math.Exp(-shear / 30f)) - 1f); 555 | } 556 | void BlurPlateBoundaryStress(List boundaryCorners, int stressBlurIterations, float stressBlurCenterWeighting) 557 | { 558 | var newCornerPressure = new float[boundaryCorners.Count]; 559 | var newCornerShear = new float[boundaryCorners.Count]; 560 | 561 | for (var i = 0; i < stressBlurIterations; ++i) 562 | { 563 | for (var j = 0; j < boundaryCorners.Count; ++j) 564 | { 565 | var corner = boundaryCorners[j]; 566 | var averagePressure = 0f; 567 | var averageShear = 0f; 568 | var neighborCount = 0; 569 | for (var k = 0; k < corner.corners.Length; ++k) 570 | { 571 | var neighbor = corner.corners[k]; 572 | if (neighbor.betweenPlates) 573 | { 574 | averagePressure += neighbor.pressure; 575 | averageShear += neighbor.shear; 576 | ++neighborCount; 577 | } 578 | } 579 | newCornerPressure[j] = corner.pressure * stressBlurCenterWeighting + (averagePressure / neighborCount) * (1 - stressBlurCenterWeighting); 580 | newCornerShear[j] = corner.shear * stressBlurCenterWeighting + (averageShear / neighborCount) * (1 - stressBlurCenterWeighting); 581 | } 582 | 583 | for (var j = 0; j < boundaryCorners.Count; ++j) 584 | { 585 | var corner = boundaryCorners[j]; 586 | if (corner.betweenPlates) 587 | { 588 | corner.pressure = newCornerPressure[j]; 589 | corner.shear = newCornerShear[j]; 590 | } 591 | } 592 | } 593 | } 594 | struct ElevationBorder 595 | { 596 | public struct Origin 597 | { 598 | public Corner corner; 599 | public float pressure; 600 | public float shear; 601 | public Plate plate; 602 | public Func calculateElevation; 603 | 604 | public Origin(Corner c, Plate p, Func f) 605 | { 606 | this.corner = c; 607 | this.pressure = c.pressure; 608 | this.shear = c.shear; 609 | this.plate = p; 610 | this.calculateElevation = f; 611 | } 612 | } 613 | 614 | public Origin origin; 615 | public Border border; 616 | public Corner corner; 617 | public Corner nextCorner; 618 | public float distanceToPlateBoundary; 619 | 620 | public ElevationBorder(Origin o, Border b, Corner c, Corner n, float d) 621 | { 622 | this.origin = o; 623 | this.border = b; 624 | this.corner = c; 625 | this.nextCorner = n; 626 | this.distanceToPlateBoundary = d; 627 | } 628 | } 629 | List PopulateElevationBorderQueue(List boundaryCorners, int[] boundaryCornerInnerBorderIndices) 630 | { 631 | var elevationBorderQueue = new List(); 632 | for (var i = 0; i < boundaryCorners.Count; ++i) 633 | { 634 | var corner = boundaryCorners[i]; 635 | 636 | var innerBorderIndex = boundaryCornerInnerBorderIndices[i]; 637 | if (innerBorderIndex != -1) 638 | { 639 | var innerBorder = corner.borders[innerBorderIndex]; 640 | var outerBorder0 = corner.borders[(innerBorderIndex + 1) % corner.borders.Length]; 641 | var plate0 = innerBorder.tiles[0].plate; 642 | var plate1 = outerBorder0.tiles[0].plate != plate0 ? outerBorder0.tiles[0].plate : outerBorder0.tiles[1].plate; 643 | 644 | Func calculateElevation; 645 | 646 | if (corner.pressure > 0.3) 647 | { 648 | corner.elevation = Math.Max(plate0.elevation, plate1.elevation) + corner.pressure; 649 | if (plate0.oceanic == plate1.oceanic) 650 | calculateElevation = CalculateCollidingElevation; 651 | else if (plate0.oceanic) 652 | calculateElevation = CalculateSubductingElevation; 653 | else 654 | calculateElevation = CalculateSuperductingElevation; 655 | } 656 | else if (corner.pressure < -0.3) 657 | { 658 | corner.elevation = Math.Max(plate0.elevation, plate1.elevation) - corner.pressure / 4; 659 | calculateElevation = CalculateDivergingElevation; 660 | } 661 | else if (corner.shear > 0.3) 662 | { 663 | corner.elevation = Math.Max(plate0.elevation, plate1.elevation) + corner.shear / 8; 664 | calculateElevation = CalculateShearingElevation; 665 | } 666 | else 667 | { 668 | corner.elevation = (plate0.elevation + plate1.elevation) / 2; 669 | calculateElevation = CalculateDormantElevation; 670 | } 671 | 672 | var nextCorner = innerBorder.OppositeCorner(corner); 673 | if (!nextCorner.betweenPlates) 674 | { 675 | elevationBorderQueue.Add(new ElevationBorder(new ElevationBorder.Origin(corner, plate0, calculateElevation), 676 | innerBorder, corner, nextCorner, innerBorder.Length())); 677 | } 678 | } 679 | else 680 | { 681 | var plate0 = corner.tiles[0].plate; 682 | var plate1 = corner.tiles[1].plate; 683 | var plate2 = corner.tiles[2].plate; 684 | 685 | //elevation = 0; 686 | 687 | if (corner.pressure > 0.3) 688 | { 689 | corner.elevation = Math.Max(plate0.elevation, Math.Max(plate1.elevation, plate2.elevation)) + corner.pressure; 690 | } 691 | else if (corner.pressure < -0.3) 692 | { 693 | corner.elevation = Math.Max(plate0.elevation, Math.Max(plate1.elevation, plate2.elevation)) + corner.pressure / 4f; 694 | } 695 | else if (corner.shear > 0.3) 696 | { 697 | corner.elevation = Math.Max(plate0.elevation, Math.Max(plate1.elevation, plate2.elevation)) + corner.shear / 8f; 698 | } 699 | else 700 | { 701 | corner.elevation = (plate0.elevation + plate1.elevation + plate2.elevation) / 3; 702 | } 703 | } 704 | } 705 | return elevationBorderQueue; 706 | } 707 | // For the following elevation methods i had to use an array 708 | // as argument instead of 6 floats for some implementation issues. 709 | // Func<> implementation did not seem to support functions with more 710 | // than 4 arguments. So the array contains the following in order: 711 | // distanceToPlateBoundary, distanceToPlateRoot, boundaryElevation, plateElevation, pressure, shear 712 | float CalculateCollidingElevation(float[] args) 713 | { 714 | var t = args[0] / (args[0] + args[1]); 715 | if (t < 0.5f) 716 | { 717 | t = t / 0.5f; 718 | return args[3] + (float)Math.Pow(t - 1, 2) * (args[2] - args[3]); 719 | } 720 | else 721 | { 722 | return args[3]; 723 | } 724 | } 725 | float CalculateSuperductingElevation(float[] args) 726 | { 727 | var t = args[0] / (args[0] + args[1]); 728 | if (t < 0.2f) 729 | { 730 | t = t / 0.2f; 731 | return args[2] + t * (args[3] - args[2] + args[4] / 2f); 732 | } 733 | else if (t < 0.5f) 734 | { 735 | t = (t - 0.2f) / 0.3f; 736 | return args[3] + (float)Math.Pow(t - 1, 2) * args[4] / 2f; 737 | } 738 | else 739 | { 740 | return args[3]; 741 | } 742 | } 743 | float CalculateSubductingElevation(float[] args) 744 | { 745 | var t = args[0] / (args[0] + args[1]); 746 | return args[3] + (float)Math.Pow(t - 1, 2) * (args[2] - args[3]); 747 | } 748 | float CalculateDivergingElevation(float[] args) 749 | { 750 | var t = args[0] / (args[0] + args[1]); 751 | if (t < 0.3f) 752 | { 753 | t = t / 0.3f; 754 | return args[3] + (float)Math.Pow(t - 1, 2) * (args[2] - args[3]); 755 | } 756 | else 757 | { 758 | return args[3]; 759 | } 760 | } 761 | float CalculateShearingElevation(float[] args) 762 | { 763 | var t = args[0] / (args[0] + args[1]); 764 | if (t < 0.2f) 765 | { 766 | t = t / 0.2f; 767 | return args[3] + (float)Math.Pow(t - 1, 2) * (args[2] - args[3]); 768 | } 769 | else 770 | { 771 | return args[3]; 772 | } 773 | } 774 | float CalculateDormantElevation(float[] args) 775 | { 776 | var t = args[0] / (args[0] + args[1]); 777 | var elevationDifference = args[2] - args[3]; 778 | var a = 2 * elevationDifference; 779 | var b = -3 * elevationDifference; 780 | return t * t * elevationDifference * (2 * t - 3) + args[2]; 781 | } 782 | void ProcessElevationBorderQueue(List elevationBorderQueue) 783 | { 784 | while (elevationBorderQueue.Count > 0) 785 | { 786 | var iEnd = elevationBorderQueue.Count; 787 | for (var i = 0; i < iEnd; ++i) 788 | { 789 | var front = elevationBorderQueue[i]; 790 | var corner = front.nextCorner; 791 | if (corner.elevation == 0.0f) 792 | { 793 | corner.distanceToPlateBoundary = front.distanceToPlateBoundary; 794 | corner.elevation = front.origin.calculateElevation(new float[6] { 795 | corner.distanceToPlateBoundary, 796 | corner.distanceToPlateRoot, 797 | front.origin.corner.elevation, 798 | front.origin.plate.elevation, 799 | front.origin.pressure, 800 | front.origin.shear}); 801 | 802 | for (var j = 0; j < corner.borders.Length; ++j) 803 | { 804 | var border = corner.borders[j]; 805 | if (!border.betweenPlates) 806 | { 807 | var nextCorner = corner.corners[j]; 808 | var distanceToPlateBoundary = corner.distanceToPlateBoundary + border.Length(); 809 | if (nextCorner.distanceToPlateBoundary == 0.0f || nextCorner.distanceToPlateBoundary > distanceToPlateBoundary) 810 | { 811 | elevationBorderQueue.Add(new ElevationBorder(front.origin, border, corner, nextCorner, distanceToPlateBoundary)); 812 | } 813 | } 814 | } 815 | } 816 | } 817 | elevationBorderQueue.RemoveRange(0, iEnd); 818 | elevationBorderQueue.Sort(delegate(ElevationBorder A, ElevationBorder B) 819 | { 820 | return A.distanceToPlateBoundary.CompareTo(B.distanceToPlateBoundary); 821 | }); 822 | } 823 | } 824 | void CalculateTileAverageElevations(List tiles) 825 | { 826 | for (var i = 0; i < tiles.Count; ++i) 827 | { 828 | var tile = tiles[i]; 829 | var elevation = 0f; 830 | for (var j = 0; j < tile.corners.Length; ++j) 831 | { 832 | elevation += tile.corners[j].elevation; 833 | } 834 | tile.elevation = elevation / tile.corners.Length; 835 | } 836 | } 837 | #endregion 838 | #region Intersection/Tile Selection 839 | public bool IntersectRay(Ray ray, out Tile tile) 840 | { 841 | List partition; 842 | return this.IntersectRay(ray, out tile, out partition); 843 | } 844 | public bool IntersectRay(Ray ray, out Tile tile, out List partition) 845 | { 846 | tile = null; 847 | partition = null; 848 | if (surface.topology.partition.IntersectRay(ray, out tile, out partition, this.transform)) 849 | { 850 | return true; 851 | } 852 | return false; 853 | } 854 | #endregion 855 | } 856 | -------------------------------------------------------------------------------- /Assets/Scripts/Planet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1e40382e405bf64d8aae8096364b1de 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/PlanetGeneration.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEngine; 3 | using System.Collections; 4 | using System; 5 | using System.Collections.Generic; 6 | using Random = System.Random; 7 | 8 | public class Node 9 | { 10 | public Vector3 p; 11 | public List e = new List(); 12 | public List f = new List(); 13 | 14 | public Node() 15 | { 16 | 17 | } 18 | 19 | public Node(Vector3 v) 20 | { 21 | this.p = v; 22 | } 23 | } 24 | public class Edge 25 | { 26 | public int[] n; 27 | public List f = new List(); 28 | public List subdivided_n = new List(); 29 | public List subdivided_e = new List(); 30 | 31 | public Edge() 32 | { 33 | n = new int[2]; 34 | } 35 | 36 | public Edge(int start, int end) 37 | { 38 | this.n = new int[2] { start, end }; 39 | } 40 | 41 | public Edge(int[] e) 42 | { 43 | this.n = e; 44 | } 45 | 46 | 47 | } 48 | public class Face 49 | { 50 | public List n = new List(); 51 | public List e = new List(); 52 | public List children = new List(); 53 | public Vector3 centroid; 54 | 55 | public Vector3 sphereCenter; 56 | public float sphereRadius; 57 | 58 | public Face() 59 | { 60 | 61 | } 62 | 63 | public Face(int[] n, int[] e) 64 | { 65 | this.n = new List(n); 66 | this.e = new List(e); 67 | } 68 | } 69 | public class Polyhedra 70 | { 71 | public Planet planet; 72 | 73 | public List nodes; 74 | public List edges; 75 | public List faces; 76 | public Topology topology = null; 77 | 78 | public Polyhedra(Planet p, List n, List e, List f) 79 | { 80 | this.planet = p; 81 | this.nodes = n; 82 | this.edges = e; 83 | this.faces = f; 84 | } 85 | 86 | public void DebugDraw(float scale, Color color, float duration) 87 | { 88 | foreach(var e in edges) 89 | { 90 | Debug.DrawLine(nodes[e.n[0]].p * scale, nodes[e.n[1]].p * scale, color, duration); 91 | } 92 | } 93 | 94 | // TODO: Replace hardcoded 1000s with a scale variable. 95 | public void GeneratePlanetTopology() 96 | { 97 | List corners = new List(this.faces.Count); 98 | List borders = new List(this.edges.Count); 99 | List tiles = new List(this.nodes.Count); 100 | int i; 101 | for(i = 0; i < this.faces.Count; ++i) 102 | { 103 | var face = this.faces[i]; 104 | corners.Add(new Corner(i, face.centroid /** 1000*/, face.e.Count, face.e.Count, face.n.Count)); 105 | } 106 | 107 | for(i = 0; i < this.edges.Count; ++i) 108 | { 109 | var edge = this.edges[i]; 110 | borders.Add(new Border(i, 2, 4, 2)); //edge.f.Count, this.faces[edge.f[0]].e.Count + this.faces[edge.f[1]].e.Count - 2, edge.n.Count 111 | } 112 | 113 | for(i = 0; i < this.nodes.Count; ++i) 114 | { 115 | var node = this.nodes[i]; 116 | tiles.Add(new Tile(i, node.p /** 1000*/, node.f.Count, node.e.Count, node.e.Count)); 117 | } 118 | 119 | for(i = 0; i < corners.Count; ++i) 120 | { 121 | var corner = corners[i]; 122 | var face = this.faces[i]; 123 | for(var j = 0; j < face.e.Count; ++j) 124 | { 125 | corner.borders[j] = (borders[face.e[j]]); 126 | } 127 | for(var j = 0; j < face.n.Count; ++j) 128 | { 129 | corner.tiles[j] = (tiles[face.n[j]]); 130 | } 131 | } 132 | 133 | for(i = 0; i < borders.Count; ++i) 134 | { 135 | var border = borders[i]; 136 | var edge = this.edges[i]; 137 | var averageCorner = new Vector3(0, 0, 0); 138 | var n = 0; 139 | for (var j = 0; j < edge.f.Count; ++j) 140 | { 141 | var corner = corners[edge.f[j]]; 142 | averageCorner += corner.position; 143 | border.corners[j] = corner; 144 | for (var k = 0; k < corner.borders.Length; ++k) 145 | { 146 | if (corner.borders[k] != border) border.borders[n++] = corner.borders[k]; 147 | } 148 | } 149 | border.midpoint = averageCorner / border.corners.Length; 150 | for (var j = 0; j < edge.n.Length; ++j) 151 | { 152 | border.tiles[j] = tiles[edge.n[j]]; 153 | } 154 | } 155 | 156 | for (i = 0; i < corners.Count; ++i) 157 | { 158 | var corner = corners[i]; 159 | for (var j = 0; j < corner.borders.Length; ++j) 160 | { 161 | corner.corners[j] = corner.borders[j].OppositeCorner(corner); 162 | } 163 | } 164 | 165 | for (i = 0; i < tiles.Count; ++i) 166 | { 167 | var tile = tiles[i]; 168 | var node = this.nodes[i]; 169 | for (var j = 0; j < node.f.Count; ++j) 170 | { 171 | tile.corners[j] = corners[node.f[j]]; 172 | } 173 | for (var j = 0; j < node.e.Count; ++j) 174 | { 175 | var border = borders[node.e[j]]; 176 | if (border.tiles[0] == tile) 177 | { 178 | for (var k = 0; k < tile.corners.Length; ++k) 179 | { 180 | var corner0 = tile.corners[k]; 181 | var corner1 = tile.corners[(k + 1) % tile.corners.Length]; 182 | if (border.corners[1] == corner0 && border.corners[0] == corner1) 183 | { 184 | border.corners[0] = corner0; 185 | border.corners[1] = corner1; 186 | } 187 | else if (border.corners[0] != corner0 || border.corners[1] != corner1) 188 | { 189 | continue; 190 | } 191 | tile.borders[k] = border; 192 | tile.tiles[k] = border.OppositeTile(tile); 193 | break; 194 | } 195 | } 196 | else 197 | { 198 | for (var k = 0; k < tile.corners.Length; ++k) 199 | { 200 | var corner0 = tile.corners[k]; 201 | var corner1 = tile.corners[(k + 1) % tile.corners.Length]; 202 | if (border.corners[0] == corner0 && border.corners[1] == corner1) 203 | { 204 | border.corners[1] = corner0; 205 | border.corners[0] = corner1; 206 | } 207 | else if (border.corners[1] != corner0 || border.corners[0] != corner1) 208 | { 209 | continue; 210 | } 211 | tile.borders[k] = border; 212 | tile.tiles[k] = border.OppositeTile(tile); 213 | break; 214 | } 215 | } 216 | } 217 | 218 | tile.averagePosition = new Vector3(0, 0, 0); 219 | for (var j = 0; j < tile.corners.Length; ++j) 220 | { 221 | tile.averagePosition += tile.corners[j].position; 222 | } 223 | tile.averagePosition /= tile.corners.Length; 224 | 225 | var maxDistanceToCorner = 0f; 226 | for (var j = 0; j < tile.corners.Length; ++j) 227 | { 228 | maxDistanceToCorner = Math.Max(maxDistanceToCorner, Vector3.Distance(tile.corners[j].position, tile.averagePosition)); 229 | } 230 | 231 | var area = 0f; 232 | for (var j = 0; j < tile.borders.Length; ++j) 233 | { 234 | area += Utils.CalculateTriangleArea(tile.position, tile.borders[j].corners[0].position, tile.borders[j].corners[1].position); 235 | } 236 | tile.area = area; 237 | 238 | tile.normal = tile.position.normalized; 239 | tile.radius = maxDistanceToCorner; 240 | } 241 | 242 | for (i = 0; i < corners.Count; ++i) 243 | { 244 | var corner = corners[i]; 245 | corner.area = 0; 246 | for (var j = 0; j < corner.tiles.Length; ++j) 247 | { 248 | corner.area += corner.tiles[j].area / corner.tiles[j].corners.Length; 249 | } 250 | } 251 | 252 | this.topology = new Topology(this.planet, corners, borders, tiles); 253 | } 254 | 255 | public bool DistortMesh(int degree, Random random) 256 | { 257 | double totalSurfaceArea = 4 * Math.PI; 258 | double idealFaceArea = totalSurfaceArea / this.faces.Count; 259 | double idealEdgeLength = Math.Sqrt(idealFaceArea * 4 / Math.Sqrt(3)); 260 | double idealFaceHeight = idealEdgeLength * Math.Sqrt(3) / 2; 261 | 262 | var rotationPredicate = new Func((oldNode0, oldNode1, newNode0, newNode1) => 263 | { 264 | if (newNode0.f.Count >= 7 || 265 | newNode1.f.Count >= 7 || 266 | oldNode0.f.Count <= 5 || 267 | oldNode1.f.Count <= 5) return false; 268 | 269 | var oldEdgeLength = Vector3.Distance(oldNode0.p, oldNode1.p); 270 | var newEdgeLength = Vector3.Distance(newNode0.p, newNode1.p); 271 | var ratio = oldEdgeLength / newEdgeLength; 272 | if (ratio >= 2 || ratio <= 0.5) return false; 273 | var v0 = (oldNode1.p - oldNode0.p) / oldEdgeLength; 274 | var v1 = (newNode0.p - oldNode0.p).normalized; 275 | var v2 = (newNode1.p - oldNode0.p).normalized; 276 | if (Vector3.Dot(v0, v1) < 0.2 || Vector3.Dot(v0, v2) < 0.2) return false; 277 | v0 *= -1; 278 | var v3 = (newNode0.p - oldNode1.p).normalized; 279 | var v4 = (newNode1.p - oldNode1.p).normalized; 280 | if (Vector3.Dot(v0, v3) < 0.2 || Vector3.Dot(v0, v4) < 0.2) return false; 281 | 282 | return true; 283 | }); 284 | 285 | var i = 0; 286 | 287 | while(i < degree) 288 | { 289 | var consecutiveFailedAttempts = 0; 290 | var edgeIndex = random.Next(0, this.edges.Count); 291 | while(!this.ConditionalRotateEdge(edgeIndex, rotationPredicate)) 292 | { 293 | if (++consecutiveFailedAttempts >= this.edges.Count) return false; 294 | edgeIndex = (edgeIndex + 1) % this.edges.Count; 295 | } 296 | ++i; 297 | } 298 | return true; 299 | } 300 | 301 | public float RelaxMesh(float multiplier) 302 | { 303 | var totalSurfaceArea = 4 * Math.PI; 304 | var idealFaceArea = totalSurfaceArea / this.faces.Count; 305 | var idealEdgeLength = Math.Sqrt(idealFaceArea * 4 / Math.Sqrt(3)); 306 | var idealDistanceToCentroid = idealEdgeLength * Math.Sqrt(3) / 3 * 0.9; 307 | 308 | var pointShifts = new List(this.nodes.Count); 309 | int i = 0; 310 | for (i = 0; i < this.nodes.Count; i++) 311 | { 312 | pointShifts.Add(new Vector3(0, 0, 0)); 313 | } 314 | 315 | i = 0; 316 | while(i < this.faces.Count) 317 | { 318 | var face = this.faces[i]; 319 | var n0 = this.nodes[face.n[0]]; 320 | var n1 = this.nodes[face.n[1]]; 321 | var n2 = this.nodes[face.n[2]]; 322 | var p0 = n0.p; 323 | var p1 = n1.p; 324 | var p2 = n2.p; 325 | var e0 = Vector3.Distance(p1, p0) / idealEdgeLength; // p1.distanceTo(p0) / idealEdgeLength; 326 | var e1 = Vector3.Distance(p2, p1) / idealEdgeLength; // p2.distanceTo(p1) / idealEdgeLength; 327 | var e2 = Vector3.Distance(p0, p2) / idealEdgeLength; // p0.distanceTo(p2) / idealEdgeLength; 328 | var centroid = Utils.CalculateFaceCentroid(p0, p1, p2).normalized; 329 | var v0 = centroid - p0; // centroid.clone().sub(p0); 330 | var v1 = centroid - p1; 331 | var v2 = centroid - p2; 332 | var length0 = v0.magnitude; 333 | var length1 = v1.magnitude; 334 | var length2 = v2.magnitude; 335 | v0 *= (float)(multiplier * (length0 - idealDistanceToCentroid) / length0); 336 | v1 *= (float)(multiplier * (length1 - idealDistanceToCentroid) / length1); 337 | v2 *= (float)(multiplier * (length2 - idealDistanceToCentroid) / length2); 338 | pointShifts[face.n[0]] += (v0); 339 | pointShifts[face.n[1]] += (v1); 340 | pointShifts[face.n[2]] += (v2); 341 | 342 | ++i; 343 | } 344 | 345 | var origin = new Vector3(0, 0, 0); 346 | for (i = 0; i < this.nodes.Count; ++i) 347 | { 348 | pointShifts[i] = (this.nodes[i].p + (Utils.ProjectPointOnPlane(this.nodes[i].p, origin, pointShifts[i]))).normalized; 349 | } 350 | 351 | var rotationSupressions = new List(); 352 | for(i = 0; i < this.nodes.Count; ++i) 353 | { 354 | rotationSupressions.Add(0); 355 | } 356 | 357 | i = 0; 358 | while(i predicate) 389 | { 390 | var edge = this.edges[edgeIndex]; 391 | var face0 = this.faces[edge.f[0]]; 392 | var face1 = this.faces[edge.f[1]]; 393 | var farNodeFaceIndex0 = Utils.GetFaceOppositeNodeIndex(face0, edge); 394 | var farNodeFaceIndex1 = Utils.GetFaceOppositeNodeIndex(face1, edge); 395 | var newNodeIndex0 = face0.n[farNodeFaceIndex0]; 396 | var oldNodeIndex0 = face0.n[(farNodeFaceIndex0 + 1) % 3]; 397 | var newNodeIndex1 = face1.n[farNodeFaceIndex1]; 398 | var oldNodeIndex1 = face1.n[(farNodeFaceIndex1 + 1) % 3]; 399 | var oldNode0 = this.nodes[oldNodeIndex0]; 400 | var oldNode1 = this.nodes[oldNodeIndex1]; 401 | var newNode0 = this.nodes[newNodeIndex0]; 402 | var newNode1 = this.nodes[newNodeIndex1]; 403 | var newEdgeIndex0 = face1.e[(farNodeFaceIndex1 + 2) % 3]; 404 | var newEdgeIndex1 = face0.e[(farNodeFaceIndex0 + 2) % 3]; 405 | var newEdge0 = this.edges[newEdgeIndex0]; 406 | var newEdge1 = this.edges[newEdgeIndex1]; 407 | 408 | if (!predicate(oldNode0, oldNode1, newNode0, newNode1)) return false; 409 | 410 | oldNode0.e.RemoveAt(oldNode0.e.IndexOf(edgeIndex)); 411 | oldNode1.e.RemoveAt(oldNode1.e.IndexOf(edgeIndex)); 412 | newNode0.e.Add(edgeIndex); 413 | newNode1.e.Add(edgeIndex); 414 | 415 | edge.n[0] = newNodeIndex0; 416 | edge.n[1] = newNodeIndex1; 417 | 418 | newEdge0.f.RemoveAt(newEdge0.f.IndexOf(edge.f[1])); 419 | newEdge1.f.RemoveAt(newEdge1.f.IndexOf(edge.f[0])); 420 | newEdge0.f.Add(edge.f[0]); 421 | newEdge1.f.Add(edge.f[1]); 422 | 423 | oldNode0.f.RemoveAt(oldNode0.f.IndexOf(edge.f[1])); 424 | oldNode1.f.RemoveAt(oldNode1.f.IndexOf(edge.f[0])); 425 | newNode0.f.Add(edge.f[1]); 426 | newNode1.f.Add(edge.f[0]); 427 | 428 | face0.n[(farNodeFaceIndex0 + 2) % 3] = newNodeIndex1; 429 | face1.n[(farNodeFaceIndex1 + 2) % 3] = newNodeIndex0; 430 | 431 | face0.e[(farNodeFaceIndex0 + 1) % 3] = newEdgeIndex0; 432 | face1.e[(farNodeFaceIndex1 + 1) % 3] = newEdgeIndex1; 433 | face0.e[(farNodeFaceIndex0 + 2) % 3] = edgeIndex; 434 | face1.e[(farNodeFaceIndex1 + 2) % 3] = edgeIndex; 435 | 436 | return true; 437 | } 438 | 439 | } 440 | public class Corner 441 | { 442 | public int id; 443 | public Vector3 position; 444 | public Corner[] corners; 445 | public Border[] borders; 446 | public Tile[] tiles; 447 | public float area; 448 | public float distanceToPlateRoot; 449 | public float distanceToPlateBoundary; 450 | public bool betweenPlates; 451 | public float pressure; 452 | public float shear; 453 | public float elevation; 454 | 455 | public Corner(int id, Vector3 position, int cornerCount, int borderCount, int tileCount) 456 | { 457 | this.id = id; 458 | this.position = position; 459 | this.corners = new Corner[cornerCount]; 460 | this.borders = new Border[borderCount]; 461 | this.tiles = new Tile[tileCount]; 462 | } 463 | 464 | public Vector3 vectorTo(Corner corner) 465 | { 466 | return corner.position - this.position; 467 | } 468 | } 469 | public class Border 470 | { 471 | int id; 472 | public Corner[] corners; 473 | public Border[] borders; 474 | public Tile[] tiles; 475 | public Vector3 midpoint; 476 | public bool betweenPlates; 477 | 478 | public Border(int id, int cornerCount, int borderCount, int tileCount) 479 | { 480 | this.id = id; 481 | this.corners = new Corner[cornerCount]; 482 | this.borders = new Border[borderCount]; 483 | this.tiles = new Tile[tileCount]; 484 | } 485 | 486 | public Corner OppositeCorner(Corner corner) 487 | { 488 | return (this.corners[0] == corner) ? this.corners[1] : this.corners[0]; 489 | } 490 | 491 | public Tile OppositeTile(Tile tile) 492 | { 493 | return (this.tiles[0] == tile) ? this.tiles[1] : this.tiles[0]; 494 | } 495 | 496 | public float Length() 497 | { 498 | return Vector3.Distance(this.corners[0].position, this.corners[1].position); 499 | } 500 | } 501 | public class Tile 502 | { 503 | public int id; 504 | public Vector3 position; 505 | public Vector3 averagePosition; 506 | public Vector3 normal; 507 | public float area; 508 | public float radius; 509 | public Corner[] corners; 510 | public Border[] borders; 511 | public Tile[] tiles; 512 | public Plate plate; 513 | public float elevation; 514 | 515 | public Tile(int id, Vector3 position, int cornerCount, int borderCount, int tileCount) 516 | { 517 | this.id = id; 518 | this.position = position; 519 | this.corners = new Corner[cornerCount]; 520 | this.borders = new Border[borderCount]; 521 | this.tiles = new Tile[tileCount]; 522 | this.plate = null; 523 | } 524 | 525 | // TODO: These methods should keep up with Position, Rotation and Scale updates. 526 | public bool IntersectRay(Ray ray, Transform transform) 527 | { 528 | Matrix4x4 trs = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale); 529 | 530 | var avgPosition = trs.MultiplyPoint3x4(this.averagePosition); 531 | var norm = (transform.rotation * this.normal).normalized; 532 | var r = this.radius * Math.Max(transform.localScale.x, Math.Max(transform.localScale.y, transform.localScale.z)); 533 | 534 | if (!Utils.IntersectRayWithSphere(ray, avgPosition/*this.averagePosition*/, r /*this.radius*/)) return false; 535 | 536 | if (Utils.SignedDistancePlanePoint(norm /*this.normal*/, avgPosition/*this.averagePosition*/, ray.origin) <= 0) return false; 537 | 538 | var denominator = Vector3.Dot(norm /*this.normal*/, ray.direction); 539 | if (denominator == 0) return false; 540 | 541 | 542 | var t = -(Vector3.Dot(ray.origin, norm /*this.normal*/) + Utils.PlaneConstant(norm /*this.normal*/, avgPosition /*this.averagePosition*/)) / denominator; 543 | var point = (ray.direction * t) + ray.origin; 544 | var origin = Vector3.zero; 545 | for(var i = 0; i < this.corners.Length; ++i) 546 | { 547 | var j = (i + 1) % this.corners.Length; 548 | var sideNormal = transform.rotation * Vector3.Cross(this.corners[j].position, this.corners[i].position); 549 | var sideOrigin = transform.position; //origin; 550 | 551 | if (Utils.SignedDistancePlanePoint(sideNormal, sideOrigin, point) < 0) return false; 552 | } 553 | return true; 554 | } 555 | 556 | public void DebugDraw(Color color, float duration, float offset, Transform t) 557 | { 558 | Matrix4x4 trs = Matrix4x4.TRS(t.position, t.rotation, t.localScale); 559 | var pos = trs.MultiplyPoint3x4(this.averagePosition); 560 | var norm = (t.rotation * this.normal).normalized; 561 | foreach(var b in this.borders) 562 | { 563 | if (b.corners.Length != 2) 564 | continue; 565 | 566 | Debug.DrawLine(trs.MultiplyPoint3x4(b.corners[0].position) + norm /*this.normal*/ * offset, trs.MultiplyPoint3x4(b.corners[1].position) + norm * offset, color, duration); 567 | } 568 | //Debug.DrawLine(pos, pos + norm * t.localScale.x * (this.elevation + 1), Color.magenta); 569 | } 570 | } 571 | public class Topology 572 | { 573 | public Planet planet; 574 | 575 | public List corners; 576 | public List borders; 577 | public List tiles; 578 | public SpatialPartition partition; 579 | public Topology() 580 | { 581 | corners = new List(); 582 | borders = new List(); 583 | tiles = new List(); 584 | } 585 | 586 | public Topology(Planet p, List corners, List borders, List tiles) 587 | { 588 | this.planet = p; 589 | this.corners = corners; 590 | this.borders = borders; 591 | this.tiles = tiles; 592 | } 593 | 594 | public void DebugDraw(float scale, Color color, float duration) 595 | { 596 | foreach(var b in borders) 597 | { 598 | if(b.corners.Length != 2) 599 | { 600 | Debug.Log("Invalid borders - " + b.corners.Length); 601 | } 602 | else 603 | { 604 | Debug.DrawLine(b.corners[0].position * scale, b.corners[1].position * scale, color, duration); 605 | } 606 | } 607 | } 608 | 609 | public SpatialPartition GeneratePlanetPartition() 610 | { 611 | var icosahedron = Utils.GenerateIcosahedron(); 612 | 613 | // TODO: Change these 1000s with a global scale; 614 | for (var i = 0; i < icosahedron.faces.Count; ++i) 615 | { 616 | var face = icosahedron.faces[i]; 617 | var p0 = icosahedron.nodes[face.n[0]].p /** 1000*/; 618 | var p1 = icosahedron.nodes[face.n[1]].p /** 1000*/; 619 | var p2 = icosahedron.nodes[face.n[2]].p /** 1000*/; 620 | var center = (p0 + p1 + p2) / 3; 621 | var radius = Math.Max(Vector3.Distance(center, p0), Math.Max(Vector3.Distance(center, p2), Vector3.Distance(center, p2))); 622 | face.sphereCenter = center; 623 | face.sphereRadius = radius; 624 | face.children = new List(); 625 | } 626 | 627 | var unparentedTiles = new List(); 628 | var maxDistanceFromOrigin = 0f; 629 | 630 | for(var i = 0; i < this.tiles.Count; ++i) 631 | { 632 | var tile = this.tiles[i]; 633 | maxDistanceFromOrigin = Math.Max(maxDistanceFromOrigin, tile.averagePosition.magnitude + tile.radius); 634 | 635 | var parentFound = false; 636 | for (var j = 0; j < icosahedron.faces.Count; ++j) 637 | { 638 | var face = icosahedron.faces[j]; 639 | var distance = Vector3.Distance(tile.averagePosition, face.sphereCenter) + tile.radius; 640 | if (distance < face.sphereRadius) 641 | { 642 | face.children.Add(tile); 643 | parentFound = true; 644 | break; 645 | } 646 | } 647 | if (!parentFound) 648 | { 649 | unparentedTiles.Add(tile); 650 | } 651 | } 652 | 653 | SpatialPartition rootPartition = new SpatialPartition(Vector3.zero, maxDistanceFromOrigin, new List(), unparentedTiles); 654 | for(var i = 0; i < icosahedron.faces.Count; ++i) 655 | { 656 | var face = icosahedron.faces[i]; 657 | rootPartition.partitions.Add(new SpatialPartition(face.sphereCenter, face.sphereRadius, new List(), face.children)); 658 | } 659 | 660 | this.partition = rootPartition; 661 | return rootPartition; 662 | } 663 | } 664 | public class SpatialPartition 665 | { 666 | public Vector3 sphereCenter; 667 | public float sphereRadius; 668 | public List tiles; 669 | public List partitions; 670 | 671 | public SpatialPartition(Vector3 center, float radius, List partitions, List tiles) 672 | { 673 | this.sphereCenter = center; 674 | this.sphereRadius = radius; 675 | this.partitions = partitions; 676 | this.tiles = tiles; 677 | } 678 | 679 | // TODO: These methods should keep up with Position, Rotation and Scale updates. 680 | public bool IntersectRay(Ray ray, out Tile tile, out List partition, Transform t) 681 | { 682 | Matrix4x4 trs = Matrix4x4.TRS(t.position, t.rotation, t.localScale); 683 | var sCenter = trs.MultiplyPoint3x4(this.sphereCenter); 684 | var sRadius = this.sphereRadius * Math.Max(t.localScale.x, Math.Max(t.localScale.y, t.localScale.z)); 685 | 686 | tile = null; 687 | partition = null; 688 | if(Utils.IntersectRayWithSphere(ray, sCenter /*this.sphereCenter*/, sRadius /*this.sphereRadius*/)) 689 | { 690 | for(var i = 0; i < this.partitions.Count; ++i) 691 | { 692 | Tile result; 693 | List part; 694 | var intersection = this.partitions[i].IntersectRay(ray, out result, out part, t); 695 | if(intersection) 696 | { 697 | partition = part; 698 | tile = result; 699 | return true; 700 | } 701 | } 702 | 703 | for(var i = 0; i < this.tiles.Count; ++i) 704 | { 705 | if (this.tiles[i].IntersectRay(ray, t)) 706 | { 707 | partition = this.tiles; 708 | tile = this.tiles[i]; 709 | return true; 710 | } 711 | } 712 | } 713 | return false; 714 | } 715 | } 716 | public class Plate 717 | { 718 | public Color color; 719 | public Vector3 driftAxis; 720 | public float driftRate; 721 | public float spinRate; 722 | public float elevation; 723 | public bool oceanic; 724 | public Corner root; 725 | 726 | public List tiles; 727 | public List boundaryCorners; 728 | public List boundaryBorders; 729 | 730 | public Plate(Color color, Vector3 driftAxis, float driftRate, float spinRate, float elevation, bool oceanic, Corner root) 731 | { 732 | this.color = color; 733 | this.driftAxis = driftAxis; 734 | this.driftRate = driftRate; 735 | this.spinRate = spinRate; 736 | this.elevation = elevation; 737 | this.oceanic = oceanic; 738 | this.root = root; 739 | this.tiles = new List(); 740 | this.boundaryCorners = new List(); 741 | this.boundaryBorders = new List(); 742 | } 743 | 744 | public Vector3 CalculateMovement(Vector3 position) 745 | { 746 | var movement = Vector3.Cross(this.driftAxis, position).normalized * (this.driftRate * Vector3.Distance(Vector3.Project(position, this.driftAxis), position)); 747 | movement += Vector3.Cross(this.root.position, position).normalized * (this.spinRate * Vector3.Distance(Vector3.Project(position, this.root.position), position)); 748 | return movement; 749 | } 750 | 751 | } 752 | public static class Utils 753 | { 754 | public static bool IntersectRayWithSphere(Ray ray, Vector3 sCenter, float sRadius) 755 | { 756 | var v1 = sCenter - ray.origin; 757 | var v2 = Vector3.Project(v1, ray.direction); 758 | var d = Vector3.SqrMagnitude(v1 - v2); 759 | return (d <= sRadius * sRadius); 760 | } 761 | 762 | public static Quaternion RandomQuaternion(Random random) 763 | { 764 | var theta = random.NextDouble() * Math.PI * 2; // real(0, Math.PI * 2); 765 | var phi = Math.Acos(random.NextDouble() * 2 - 1); // realInclusive(-1, 1)); 766 | var sinPhi = Math.Sin(phi); 767 | var gamma = random.NextDouble() * Math.PI * 2; // real(0, Math.PI * 2); 768 | var sinGamma = Math.Sin(gamma); 769 | return new Quaternion( 770 | (float)(Math.Cos(theta) * sinPhi * sinGamma), 771 | (float)(Math.Sin(theta) * sinPhi * sinGamma), 772 | (float)(Math.Cos(phi) * sinGamma), 773 | (float)Math.Cos(gamma)); 774 | } 775 | 776 | public static Vector3 RandomUnitVector(Random random) 777 | { 778 | var theta = random.NextDouble() * Math.PI * 2; // real(0, Math.PI * 2); 779 | var phi = Math.Acos(random.NextDouble() * 2 - 1); // realInclusive(-1, 1)); 780 | var sinPhi = Math.Sin(phi); 781 | return new Vector3( 782 | (float)(Math.Cos(theta) * sinPhi), 783 | (float)(Math.Sin(theta) * sinPhi), 784 | (float)Math.Cos(phi)); 785 | } 786 | 787 | //This function returns a point which is a projection from a point to a plane. 788 | public static Vector3 ProjectPointOnPlane(Vector3 planeNormal, Vector3 planePoint, Vector3 point) 789 | { 790 | 791 | float distance; 792 | Vector3 translationVector; 793 | 794 | //First calculate the distance from the point to the plane: 795 | distance = SignedDistancePlanePoint(planeNormal, planePoint, point); 796 | 797 | //Reverse the sign of the distance 798 | distance *= -1; 799 | 800 | //Get a translation vector 801 | translationVector = SetVectorLength(planeNormal, distance); 802 | 803 | //Translate the point to form a projection 804 | return point + translationVector; 805 | } 806 | 807 | //create a vector of direction "vector" with length "size" 808 | public static Vector3 SetVectorLength(Vector3 vector, float size) 809 | { 810 | 811 | //normalize the vector 812 | Vector3 vectorNormalized = Vector3.Normalize(vector); 813 | 814 | //scale the vector 815 | return vectorNormalized *= size; 816 | } 817 | 818 | public static float CalculateTriangleArea(Vector3 pa, Vector3 pb, Vector3 pc) 819 | { 820 | float A = Vector3.Distance(pa, pb); 821 | float B = Vector3.Distance(pb, pc); 822 | float C = Vector3.Distance(pc, pa); 823 | 824 | float s = (A + B + C) / 2; 825 | float perimeter = A + B + C; 826 | float area = (float) Math.Sqrt(s * (s - A) * (s - B) * (s - C)); 827 | return area; 828 | } 829 | 830 | //Get the shortest distance between a point and a plane. The output is signed so it holds information 831 | //as to which side of the plane normal the point is. 832 | public static float SignedDistancePlanePoint(Vector3 planeNormal, Vector3 planePoint, Vector3 point) 833 | { 834 | return Vector3.Dot(planeNormal, (point - planePoint)); 835 | } 836 | 837 | //The negative distance from the origin to the plane along the normal vector. 838 | public static float PlaneConstant(Vector3 planeNormal, Vector3 planePoint) 839 | { 840 | return - Vector3.Dot(planePoint, planeNormal.normalized); 841 | } 842 | 843 | public static Polyhedra GenerateSubdividedIcosahedron(int degree) 844 | { 845 | var icosahedron = GenerateIcosahedron(); 846 | 847 | List nodes = new List(); 848 | for(int i = 0; i < icosahedron.nodes.Count; ++i) 849 | { 850 | nodes.Add(new Node(icosahedron.nodes[i].p)); 851 | } 852 | 853 | List edges = new List(); 854 | for (var i = 0; i < icosahedron.edges.Count; ++i) 855 | { 856 | var edge = icosahedron.edges[i]; 857 | //edge.subdivided_n = new List(); 858 | //edge.subdivided_e = []; 859 | var n0 = icosahedron.nodes[edge.n[0]]; 860 | var n1 = icosahedron.nodes[edge.n[1]]; 861 | var p0 = n0.p; 862 | var p1 = n1.p; 863 | var delta = p1 - p0; //p1.clone().sub(p0); 864 | nodes[edge.n[0]].e.Add(edges.Count); 865 | var priorNodeIndex = edge.n[0]; 866 | for (var s = 1; s < degree; ++s) 867 | { 868 | var edgeIndex = edges.Count; 869 | var nodeIndex = nodes.Count; 870 | edge.subdivided_e.Add(edgeIndex); 871 | edge.subdivided_n.Add(nodeIndex); 872 | edges.Add(new Edge(priorNodeIndex, nodeIndex)); // { n: [ priorNodeIndex, nodeIndex ], f: [] }); 873 | priorNodeIndex = nodeIndex; 874 | Node newnode = new Node(Vector3.Slerp(p0, p1, (float)s / degree)); 875 | newnode.e = new List() { edgeIndex, edgeIndex + 1 }; 876 | nodes.Add(newnode); // { p: slerp(p0, p1, s / degree), e: [ edgeIndex, edgeIndex + 1 ], f: [] }); 877 | } 878 | edge.subdivided_e.Add(edges.Count); 879 | nodes[edge.n[1]].e.Add(edges.Count); 880 | edges.Add(new Edge(priorNodeIndex, edge.n[1])); // { n: [ priorNodeIndex, edge.n[1] ], f: [] }); 881 | } 882 | 883 | List faces = new List(); 884 | for (var i = 0; i < icosahedron.faces.Count; ++i) 885 | { 886 | var face = icosahedron.faces[i]; 887 | var edge0 = icosahedron.edges[face.e[0]]; 888 | var edge1 = icosahedron.edges[face.e[1]]; 889 | var edge2 = icosahedron.edges[face.e[2]]; 890 | var point0 = icosahedron.nodes[face.n[0]].p; 891 | var point1 = icosahedron.nodes[face.n[1]].p; 892 | var point2 = icosahedron.nodes[face.n[2]].p; 893 | var delta = point1 - point0; // point1.clone().sub(point0); 894 | 895 | 896 | var getEdgeNode0 = (face.n[0] == edge0.n[0]) 897 | ? new Func((k) => { return edge0.subdivided_n[k]; }) 898 | : new Func((k) => { return edge0.subdivided_n[degree - 2 - k]; }); 899 | var getEdgeNode1 = (face.n[1] == edge1.n[0]) 900 | ? new Func((k) => { return edge1.subdivided_n[k]; }) 901 | : new Func((k) => { return edge1.subdivided_n[degree - 2 - k]; }); 902 | var getEdgeNode2 = (face.n[0] == edge2.n[0]) 903 | ? new Func((k) => { return edge2.subdivided_n[k]; }) 904 | : new Func((k) => { return edge2.subdivided_n[degree - 2 - k]; }); 905 | 906 | var faceNodes = new List(); 907 | faceNodes.Add(face.n[0]); 908 | for (var j = 0; j < edge0.subdivided_n.Count; ++j) 909 | faceNodes.Add(getEdgeNode0(j)); 910 | faceNodes.Add(face.n[1]); 911 | for (var s = 1; s < degree; ++s) 912 | { 913 | faceNodes.Add(getEdgeNode2(s - 1)); 914 | var p0 = nodes[getEdgeNode2(s - 1)].p; 915 | var p1 = nodes[getEdgeNode1(s - 1)].p; 916 | for (var t = 1; t < degree - s; ++t) 917 | { 918 | faceNodes.Add(nodes.Count); 919 | nodes.Add(new Node(Vector3.Slerp(p0, p1, (float)t / (degree - s)))); // { p: slerp(p0, p1, t / (degree - s)), e: [], f: [], }); 920 | } 921 | faceNodes.Add(getEdgeNode1(s - 1)); 922 | } 923 | faceNodes.Add(face.n[2]); 924 | 925 | var getEdgeEdge0 = (face.n[0] == edge0.n[0]) 926 | ? new Func((k) => { return edge0.subdivided_e[k]; }) 927 | : new Func((k) => { return edge0.subdivided_e[degree - 1 - k]; }); 928 | var getEdgeEdge1 = (face.n[1] == edge1.n[0]) 929 | ? new Func((k) => { return edge1.subdivided_e[k]; }) 930 | : new Func((k) => { return edge1.subdivided_e[degree - 1 - k]; }); 931 | var getEdgeEdge2 = (face.n[0] == edge2.n[0]) 932 | ? new Func((k) => { return edge2.subdivided_e[k]; }) 933 | : new Func((k) => { return edge2.subdivided_e[degree - 1 - k]; }); 934 | 935 | var faceEdges0 = new List(); 936 | for (var j = 0; j < degree; ++j) 937 | faceEdges0.Add(getEdgeEdge0(j)); 938 | var nodeIndex = degree + 1; 939 | for (var s = 1; s < degree; ++s) 940 | { 941 | for (var t = 0; t < degree - s; ++t) 942 | { 943 | faceEdges0.Add(edges.Count); 944 | var edge = new Edge(faceNodes[nodeIndex], faceNodes[nodeIndex + 1]); 945 | nodes[edge.n[0]].e.Add(edges.Count); 946 | nodes[edge.n[1]].e.Add(edges.Count); 947 | edges.Add(edge); 948 | ++nodeIndex; 949 | } 950 | ++nodeIndex; 951 | } 952 | 953 | var faceEdges1 = new List(); 954 | 955 | nodeIndex = 1; 956 | for (var s = 0; s < degree; ++s) 957 | { 958 | for (var t = 1; t < degree - s; ++t) 959 | { 960 | faceEdges1.Add(edges.Count); 961 | var edge = new Edge(faceNodes[nodeIndex], faceNodes[nodeIndex + degree - s]); 962 | nodes[edge.n[0]].e.Add(edges.Count); 963 | nodes[edge.n[1]].e.Add(edges.Count); 964 | edges.Add(edge); 965 | ++nodeIndex; 966 | } 967 | faceEdges1.Add(getEdgeEdge1(s)); 968 | nodeIndex += 2; 969 | } 970 | 971 | var faceEdges2 = new List(); 972 | nodeIndex = 1; 973 | for (var s = 0; s < degree; ++s) 974 | { 975 | faceEdges2.Add(getEdgeEdge2(s)); 976 | for (var t = 1; t < degree - s; ++t) 977 | { 978 | faceEdges2.Add(edges.Count); 979 | var edge = new Edge(faceNodes[nodeIndex], faceNodes[nodeIndex + degree - s + 1]); 980 | nodes[edge.n[0]].e.Add(edges.Count); 981 | nodes[edge.n[1]].e.Add(edges.Count); 982 | edges.Add(edge); 983 | ++nodeIndex; 984 | } 985 | nodeIndex += 2; 986 | } 987 | 988 | nodeIndex = 0; 989 | var edgeIndex = 0; 990 | for (var s = 0; s < degree; ++s) 991 | { 992 | for (var t = 1; t < degree - s + 1; ++t) 993 | { 994 | var subFace = new Face(new int[] { faceNodes[nodeIndex], faceNodes[nodeIndex + 1], faceNodes[nodeIndex + degree - s + 1] } 995 | , new int[] { faceEdges0[edgeIndex], faceEdges1[edgeIndex], faceEdges2[edgeIndex] }); 996 | //{n: [ faceNodes[nodeIndex], faceNodes[nodeIndex + 1], faceNodes[nodeIndex + degree - s + 1], ], 997 | //e: [ faceEdges0[edgeIndex], faceEdges1[edgeIndex], faceEdges2[edgeIndex], ], }; 998 | nodes[subFace.n[0]].f.Add(faces.Count); 999 | nodes[subFace.n[1]].f.Add(faces.Count); 1000 | nodes[subFace.n[2]].f.Add(faces.Count); 1001 | edges[subFace.e[0]].f.Add(faces.Count); 1002 | edges[subFace.e[1]].f.Add(faces.Count); 1003 | edges[subFace.e[2]].f.Add(faces.Count); 1004 | faces.Add(subFace); 1005 | ++nodeIndex; 1006 | ++edgeIndex; 1007 | } 1008 | ++nodeIndex; 1009 | } 1010 | 1011 | nodeIndex = 1; 1012 | edgeIndex = 0; 1013 | for (var s = 1; s < degree; ++s) 1014 | { 1015 | for (var t = 1; t < degree - s + 1; ++t) 1016 | { 1017 | var subFace = new Face(new int[] { faceNodes[nodeIndex], faceNodes[nodeIndex + degree - s + 2], faceNodes[nodeIndex + degree - s + 1] } 1018 | , new int[] { faceEdges2[edgeIndex + 1], faceEdges0[edgeIndex + degree - s + 1], faceEdges1[edgeIndex] }); 1019 | //n: [ faceNodes[nodeIndex], faceNodes[nodeIndex + degree - s + 2], faceNodes[nodeIndex + degree - s + 1], ], 1020 | //e: [ faceEdges2[edgeIndex + 1], faceEdges0[edgeIndex + degree - s + 1], faceEdges1[edgeIndex], ], }; 1021 | nodes[subFace.n[0]].f.Add(faces.Count); 1022 | nodes[subFace.n[1]].f.Add(faces.Count); 1023 | nodes[subFace.n[2]].f.Add(faces.Count); 1024 | edges[subFace.e[0]].f.Add(faces.Count); 1025 | edges[subFace.e[1]].f.Add(faces.Count); 1026 | edges[subFace.e[2]].f.Add(faces.Count); 1027 | faces.Add(subFace); 1028 | ++nodeIndex; 1029 | ++edgeIndex; 1030 | } 1031 | nodeIndex += 2; 1032 | edgeIndex += 1; 1033 | } 1034 | } 1035 | return new Polyhedra(null, nodes, edges, faces); 1036 | } 1037 | 1038 | public static Polyhedra GenerateIcosahedron() 1039 | { 1040 | var phi = (float) ((1.0 + Math.Sqrt(5.0)) / 2.0); 1041 | float du =(float) (1.0 / Math.Sqrt(phi * phi + 1.0)); 1042 | float dv =(float) (phi * du); 1043 | 1044 | //Vector3[] vertices = new Vector3[] { new Vector3(0, +dv, +du), 1045 | // new Vector3(0, +dv, -du), 1046 | // new Vector3(0, -dv, +du), 1047 | // new Vector3(0, -dv, -du), 1048 | // new Vector3(+du, 0, +dv), 1049 | // new Vector3(-du, 0, +dv), 1050 | // new Vector3(+du, 0, -dv), 1051 | // new Vector3(-du, 0, -dv), 1052 | // new Vector3(+dv, +du, 0), 1053 | // new Vector3(+dv, -du, 0), 1054 | // new Vector3(-dv, +du, 0), 1055 | // new Vector3(-dv, -du, 0)}; 1056 | //int[] tris = new int[] { 0, 1, 8, 1057 | // 0, 4, 5, 1058 | // 0, 5, 10, 1059 | // 0, 8, 4, 1060 | // 0, 10, 1, 1061 | // 1, 6, 8, 1062 | // 1, 7, 6, 1063 | // 1, 10, 7, 1064 | // 2, 3, 11, 1065 | // 2, 4, 9, 1066 | // 2, 5, 4, 1067 | // 2, 9, 3, 1068 | // 2, 11, 5, 1069 | // 3, 6, 7, 1070 | // 3, 7, 11, 1071 | // 3, 9, 6, 1072 | // 4, 8, 9, 1073 | // 5, 11, 10, 1074 | // 6, 9, 8, 1075 | // 7, 10, 11}; 1076 | //Mesh icosahedron = new Mesh(); 1077 | //icosahedron.vertices = vertices; 1078 | //icosahedron.SetTriangles(tris, 0); 1079 | //icosahedron.RecalculateNormals(); 1080 | //icosahedron.RecalculateBounds(); 1081 | 1082 | var nodes = new List() { 1083 | new Node(new Vector3(0, +dv, +du)), 1084 | new Node(new Vector3(0, +dv, -du)), 1085 | new Node(new Vector3(0, -dv, +du)), 1086 | new Node(new Vector3(0, -dv, -du)), 1087 | new Node(new Vector3(+du, 0, +dv)), 1088 | new Node(new Vector3(-du, 0, +dv)), 1089 | new Node(new Vector3(+du, 0, -dv)), 1090 | new Node(new Vector3(-du, 0, -dv)), 1091 | new Node(new Vector3(+dv, +du, 0)), 1092 | new Node(new Vector3(+dv, -du, 0)), 1093 | new Node(new Vector3(-dv, +du, 0)), 1094 | new Node(new Vector3(-dv, -du, 0))}; 1095 | 1096 | var edges = new List() { 1097 | new Edge(0, 1), 1098 | new Edge(0, 4), 1099 | new Edge(0, 5), 1100 | new Edge(0, 8), 1101 | new Edge(0, 10), 1102 | new Edge(1, 6), 1103 | new Edge(1, 7), 1104 | new Edge(1, 8), 1105 | new Edge(1, 10), 1106 | new Edge(2, 3), 1107 | new Edge(2, 4), 1108 | new Edge(2, 5), 1109 | new Edge(2, 9), 1110 | new Edge(2, 11), 1111 | new Edge(3, 6), 1112 | new Edge(3, 7), 1113 | new Edge(3, 9), 1114 | new Edge(3, 11), 1115 | new Edge(4, 5), 1116 | new Edge(4, 8), 1117 | new Edge(4, 9), 1118 | new Edge(5, 10), 1119 | new Edge(5, 11), 1120 | new Edge(6, 7), 1121 | new Edge(6, 8), 1122 | new Edge(6, 9), 1123 | new Edge(7, 10), 1124 | new Edge(7, 11), 1125 | new Edge(8, 9), 1126 | new Edge(10, 11)}; 1127 | 1128 | var faces = new List() { 1129 | new Face(new int[] {0, 1, 8 },new int[] { 0, 7, 3 }), 1130 | new Face(new int[] {0, 4, 5 },new int[] { 1, 18, 2 }), 1131 | new Face(new int[] {0, 5, 10 },new int[] { 2, 21, 4 }), 1132 | new Face(new int[] {0, 8, 4 },new int[] { 3, 19, 1 }), 1133 | new Face(new int[] {0, 10, 1 },new int[] { 4, 8, 0 }), 1134 | new Face(new int[] {1, 6, 8 },new int[] { 5, 24, 7 }), 1135 | new Face(new int[] {1, 7, 6 },new int[] { 6, 23, 5 }), 1136 | new Face(new int[] {1, 10, 7 },new int[] { 8, 26, 6 }), 1137 | new Face(new int[] {2, 3, 11 },new int[] { 9, 17, 13 }), 1138 | new Face(new int[] {2, 4, 9 },new int[] {10, 20, 12 }), 1139 | new Face(new int[] {2, 5, 4 },new int[] {11, 18, 10 }), 1140 | new Face(new int[] {2, 9, 3 },new int[] {12, 16, 9 }), 1141 | new Face(new int[] {2, 11, 5 },new int[] {13, 22, 11 }), 1142 | new Face(new int[] {3, 6, 7 },new int[] {14, 23, 15 }), 1143 | new Face(new int[] {3, 7, 11 },new int[] {15, 27, 17 }), 1144 | new Face(new int[] {3, 9, 6 },new int[] {16, 25, 14 }), 1145 | new Face(new int[] {4, 8, 9 },new int[] {19, 28, 20 }), 1146 | new Face(new int[] {5, 11, 10 },new int[] {22, 29, 21 }), 1147 | new Face(new int[] {6, 9, 8 },new int[] {25, 28, 24 }), 1148 | new Face(new int[] {7, 10, 11 },new int[] {26, 29, 27 }) 1149 | }; 1150 | 1151 | for (var i = 0; i < edges.Count; ++i) 1152 | for (var j = 0; j < edges[i].n.Length; ++j) 1153 | nodes[j].e.Add(i); 1154 | 1155 | for (var i = 0; i < faces.Count; ++i) 1156 | for (var j = 0; j < faces[i].n.Count; ++j) 1157 | nodes[j].f.Add(i); 1158 | 1159 | for (var i = 0; i < faces.Count; ++i) 1160 | for (var j = 0; j < faces[i].e.Count; ++j) 1161 | edges[j].f.Add(i); 1162 | 1163 | 1164 | return new Polyhedra(null, nodes, edges, faces); 1165 | } 1166 | public static Vector3 CalculateFaceCentroid(Vector3 pa, Vector3 pb, Vector3 pc) 1167 | { 1168 | var vabHalf = (pb - pa) / 2; 1169 | var pabHalf = pa + vabHalf; 1170 | var centroid = ((pc - pabHalf) / 3) + pabHalf; 1171 | return centroid; 1172 | } 1173 | 1174 | public static int GetFaceOppositeNodeIndex(Face face, Edge edge) 1175 | { 1176 | if (face.n[0] != edge.n[0] && face.n[0] != edge.n[1]) return 0; 1177 | if (face.n[1] != edge.n[0] && face.n[1] != edge.n[1]) return 1; 1178 | if (face.n[2] != edge.n[0] && face.n[2] != edge.n[1]) return 2; 1179 | else return -1; 1180 | } 1181 | 1182 | public static int GetEdgeOppositeFaceIndex(Edge edge, int faceIndex) 1183 | { 1184 | if (edge.f[0] == faceIndex) return edge.f[1]; 1185 | if (edge.f[1] == faceIndex) return edge.f[0]; 1186 | else return -1; 1187 | } 1188 | 1189 | public static int FindNextFaceIndex(Polyhedra mesh, int nodeIndex, int faceIndex) 1190 | { 1191 | var node = mesh.nodes[nodeIndex]; 1192 | var face = mesh.faces[faceIndex]; 1193 | var nodeFaceIndex = face.n.IndexOf(nodeIndex); 1194 | var edge = mesh.edges[face.e[(nodeFaceIndex + 2) % 3]]; 1195 | return GetEdgeOppositeFaceIndex(edge, faceIndex); 1196 | } 1197 | } 1198 | -------------------------------------------------------------------------------- /Assets/Scripts/PlanetGeneration.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f4c87f2a5c0f45478db55206903d430 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Subdivide.js: -------------------------------------------------------------------------------- 1 | //var material : Material; 2 | var buildmesh : boolean = false; 3 | private var verts : Vector3[]; 4 | private var norms : Vector3[]; 5 | private var uvs : Vector2[]; 6 | private var trigs : int[]; 7 | private var mesh : Mesh; 8 | private var originalMesh : Mesh; 9 | //var subdivision : boolean = false; 10 | //var useobjectsmaterial : boolean = false; 11 | //var forceaddmeshcollider : boolean = false; 12 | //var sides : boolean = false; 13 | //var middle : boolean = false; 14 | 15 | function Update () { 16 | if(Input.GetKeyDown("1")) 17 | subdivide(false); 18 | if(Input.GetKeyDown("2")) 19 | subdivide(true); 20 | if(Input.GetKeyDown("x")){ 21 | CopyMesh(originalMesh, mesh); 22 | } 23 | } 24 | 25 | function Awake() { 26 | 27 | /////////////////////////////////////////////////////////// 28 | //// initialize 29 | /////////////////////////////////////////////////////////// 30 | //var buildmesh=false; 31 | if(GetComponent(MeshFilter) == null){ 32 | buildmesh=true; 33 | gameObject.AddComponent(MeshFilter); 34 | } 35 | if(GetComponent(MeshRenderer) == null) 36 | gameObject.AddComponent(MeshRenderer); 37 | //if(forceaddmeshcollider) { 38 | // if(GetComponent(MeshCollider) == null) 39 | // gameObject.AddComponent(MeshCollider); 40 | //} 41 | 42 | updatemesh(); 43 | 44 | //if(!useobjectsmaterial) 45 | // GetComponent(MeshRenderer).material = material; 46 | 47 | /////////////////////////////////////////////////////////// 48 | //// build mesh 49 | /////////////////////////////////////////////////////////// 50 | 51 | if(buildmesh) { 52 | 53 | //// vertices 54 | 55 | verts = [Vector3(0,-1,0),Vector3(1,1,0),Vector3(-1,1,0) 56 | ,Vector3(0,1,-1)]; 57 | 58 | //// uvs 59 | 60 | uvs = [Vector2(0,0),Vector2(0,1),Vector2(1,0),Vector2(0,0)]; 61 | 62 | //// triangles 63 | 64 | trigs = [0,1,2,1,3,2]; 65 | 66 | applymesh(); 67 | mesh.RecalculateNormals(); 68 | 69 | Debug.Log(verts.length); 70 | } 71 | 72 | originalMesh=new Mesh(); 73 | CopyMesh(mesh, originalMesh); 74 | } 75 | 76 | function subdivide(center : boolean) { 77 | 78 | verts = mesh.vertices; 79 | trigs = mesh.triangles; 80 | uvs = mesh.uv; 81 | norms = mesh.normals; 82 | 83 | Debug.Log("enter subdividing: "+verts.length); 84 | 85 | var nv = new Array(verts); 86 | var nt = new Array(trigs); 87 | var nu = new Array(uvs); 88 | var nn = new Array(norms); 89 | 90 | if(!center) { 91 | 92 | for(var i : int = 2;i 65000){ 235 | Debug.Log("Exiting... Too many vertices"); 236 | return; 237 | } 238 | mesh.Clear(); 239 | mesh.vertices = verts; 240 | mesh.uv = uvs; 241 | if(mesh.uv2 != null) 242 | mesh.uv2 = uvs; 243 | mesh.normals = norms; 244 | mesh.triangles = trigs; 245 | mesh.RecalculateBounds(); 246 | if(GetComponent(MeshCollider) != null) 247 | GetComponent(MeshCollider).sharedMesh = mesh; 248 | updatemesh(); 249 | } 250 | 251 | function CopyMesh(fromMesh : Mesh, toMesh : Mesh){ 252 | toMesh.Clear(); 253 | toMesh.vertices=fromMesh.vertices; 254 | toMesh.normals=fromMesh.normals; 255 | toMesh.uv=fromMesh.uv; 256 | toMesh.triangles=fromMesh.triangles; 257 | } -------------------------------------------------------------------------------- /Assets/Scripts/Subdivide.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 171a26f69a8e06b419f08b15b99bdd37 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/TestScene.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | public class TestScene : MonoBehaviour { 6 | 7 | public int planetCount; 8 | public float minScale; 9 | public float maxScale; 10 | public Vector3 extents; 11 | 12 | private List planets; 13 | 14 | // Use this for initialization 15 | void Start () { 16 | this.planets = new List(); 17 | for(int i = 0; i (); 22 | p.subdivisionLevel = Random.Range(100, 100); 23 | p.plateCount = (int)Mathf.Floor(p.subdivisionLevel * Random.Range(.2f, 2f)); 24 | go.transform.position = new Vector3(Random.Range(-extents.x, extents.x), Random.Range(-extents.y, extents.y), Random.Range(-extents.z, -extents.z)); 25 | float scale = Random.Range(minScale, maxScale); 26 | go.transform.localScale = Vector3.one * scale; 27 | p.Generate(); 28 | } 29 | 30 | Camera.main.rect = new Rect(0, 0, Screen.width, Screen.height); 31 | SmoothFollow sf = Camera.main.GetComponent(); 32 | int index = Random.Range(0, planets.Count - 1); 33 | sf.target = planets[index].transform; 34 | sf.distance = 2 * sf.target.localScale.x; 35 | sf.height = 0; 36 | } 37 | 38 | // Update is called once per frame 39 | void Update () { 40 | 41 | SmoothFollow sf = Camera.main.GetComponent(); 42 | MouseOrbit mo = Camera.main.GetComponent(); 43 | 44 | if(sf.enabled) 45 | { 46 | if(Vector3.Distance(sf.target.position, Camera.main.transform.position) - sf.distance < sf.distance / 100f) 47 | { 48 | sf.enabled = false; 49 | mo.enabled = true; 50 | mo.target = sf.target; 51 | mo.distance = sf.distance; 52 | } 53 | } 54 | 55 | #if UNITY_EDITOR || UNITY_STANDALONE 56 | if(Input.GetKeyDown(KeyCode.Space)) 57 | #elif UNITY_ANDROID 58 | if(Input.GetTouch(0).tapCount == 2) 59 | #endif 60 | { 61 | mo.enabled = false; 62 | int index = Random.Range(0, planets.Count - 1); 63 | sf.target = planets[index].transform; 64 | sf.distance = 2 * sf.target.localScale.x; 65 | sf.height = 0; 66 | sf.enabled = true; 67 | 68 | } 69 | #if UNITY_ANDROID 70 | //if(Input.GetTouch(0).tapCount == 1) 71 | //{ 72 | // Touch t = Input.GetTouch(0); 73 | // Input. 74 | //} 75 | #endif 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /Assets/Scripts/TestScene.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e4b13c9f17ce6b34faf8e86792eac4e3 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 564939a0341440b4293f85862905334e 3 | folderAsset: yes 4 | timeCreated: 1436384423 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bea4bbbeb896c7e4fbeb190be2c4b223 3 | folderAsset: yes 4 | timeCreated: 1436384423 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 630decd44a984034193df992985279aa 3 | folderAsset: yes 4 | timeCreated: 1436384423 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/Editor/StandardShaderVCGUI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace UnityEditor 5 | { 6 | public class StandardShaderVCGUI : ShaderGUI 7 | { 8 | private enum WorkflowMode 9 | { 10 | Specular, 11 | Metallic, 12 | Dielectric 13 | } 14 | 15 | public enum BlendMode 16 | { 17 | Opaque, 18 | Cutout, 19 | Fade, // Old school alpha-blending mode, fresnel does not affect amount of transparency 20 | Transparent // Physically plausible transparency mode, implemented as alpha pre-multiply 21 | } 22 | 23 | private static class Styles 24 | { 25 | public static GUIStyle optionsButton = "PaneOptions"; 26 | public static GUIContent uvSetLabel = new GUIContent("UV Set"); 27 | public static GUIContent[] uvSetOptions = new GUIContent[] { new GUIContent("UV channel 0"), new GUIContent("UV channel 1") }; 28 | 29 | public static string emptyTootip = ""; 30 | public static GUIContent albedoText = new GUIContent("Albedo", "Albedo (RGB) and Transparency (A)"); 31 | public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff"); 32 | public static GUIContent specularMapText = new GUIContent("Specular", "Specular (RGB) and Smoothness (A)"); 33 | public static GUIContent metallicMapText = new GUIContent("Metallic", "Metallic (R) and Smoothness (A)"); 34 | public static GUIContent smoothnessText = new GUIContent("Smoothness", ""); 35 | public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map"); 36 | public static GUIContent heightMapText = new GUIContent("Height Map", "Height Map (G)"); 37 | public static GUIContent occlusionText = new GUIContent("Occlusion", "Occlusion (G)"); 38 | public static GUIContent emissionText = new GUIContent("Emission", "Emission (RGB)"); 39 | public static GUIContent detailMaskText = new GUIContent("Detail Mask", "Mask for Secondary Maps (A)"); 40 | public static GUIContent detailAlbedoText = new GUIContent("Detail Albedo x2", "Albedo (RGB) multiplied by 2"); 41 | public static GUIContent detailNormalMapText = new GUIContent("Normal Map", "Normal Map"); 42 | 43 | public static string whiteSpaceString = " "; 44 | public static string primaryMapsText = "Main Maps"; 45 | public static string secondaryMapsText = "Secondary Maps"; 46 | public static string renderingMode = "Rendering Mode"; 47 | public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive."); 48 | public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect."); 49 | public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode)); 50 | public static GUIContent vcLabel = new GUIContent("Vertex Color", "Vertex Color Intensity"); 51 | } 52 | 53 | MaterialProperty blendMode = null; 54 | MaterialProperty albedoMap = null; 55 | MaterialProperty albedoColor = null; 56 | MaterialProperty alphaCutoff = null; 57 | MaterialProperty specularMap = null; 58 | MaterialProperty specularColor = null; 59 | MaterialProperty metallicMap = null; 60 | MaterialProperty metallic = null; 61 | MaterialProperty smoothness = null; 62 | MaterialProperty bumpScale = null; 63 | MaterialProperty bumpMap = null; 64 | MaterialProperty occlusionStrength = null; 65 | MaterialProperty occlusionMap = null; 66 | MaterialProperty heigtMapScale = null; 67 | MaterialProperty heightMap = null; 68 | MaterialProperty emissionScaleUI = null; 69 | MaterialProperty emissionColorUI = null; 70 | MaterialProperty emissionColorForRendering = null; 71 | MaterialProperty emissionMap = null; 72 | MaterialProperty detailMask = null; 73 | MaterialProperty detailAlbedoMap = null; 74 | MaterialProperty detailNormalMapScale = null; 75 | MaterialProperty detailNormalMap = null; 76 | MaterialProperty uvSetSecondary = null; 77 | MaterialProperty vertexColor = null; 78 | 79 | MaterialEditor m_MaterialEditor; 80 | WorkflowMode m_WorkflowMode = WorkflowMode.Specular; 81 | 82 | bool m_FirstTimeApply = true; 83 | 84 | public void FindProperties(MaterialProperty[] props) 85 | { 86 | blendMode = FindProperty("_Mode", props); 87 | albedoMap = FindProperty("_MainTex", props); 88 | albedoColor = FindProperty("_Color", props); 89 | alphaCutoff = FindProperty("_Cutoff", props); 90 | specularMap = FindProperty("_SpecGlossMap", props, false); 91 | specularColor = FindProperty("_SpecColor", props, false); 92 | metallicMap = FindProperty("_MetallicGlossMap", props, false); 93 | metallic = FindProperty("_Metallic", props, false); 94 | if (specularMap != null && specularColor != null) 95 | m_WorkflowMode = WorkflowMode.Specular; 96 | else if (metallicMap != null && metallic != null) 97 | m_WorkflowMode = WorkflowMode.Metallic; 98 | else 99 | m_WorkflowMode = WorkflowMode.Dielectric; 100 | smoothness = FindProperty("_Glossiness", props); 101 | bumpScale = FindProperty("_BumpScale", props); 102 | bumpMap = FindProperty("_BumpMap", props); 103 | heigtMapScale = FindProperty("_Parallax", props); 104 | heightMap = FindProperty("_ParallaxMap", props); 105 | occlusionStrength = FindProperty("_OcclusionStrength", props); 106 | occlusionMap = FindProperty("_OcclusionMap", props); 107 | emissionScaleUI = FindProperty("_EmissionScaleUI", props); 108 | emissionColorUI = FindProperty("_EmissionColorUI", props); 109 | emissionColorForRendering = FindProperty("_EmissionColor", props); 110 | emissionMap = FindProperty("_EmissionMap", props); 111 | detailMask = FindProperty("_DetailMask", props); 112 | detailAlbedoMap = FindProperty("_DetailAlbedoMap", props); 113 | detailNormalMapScale = FindProperty("_DetailNormalMapScale", props); 114 | detailNormalMap = FindProperty("_DetailNormalMap", props); 115 | uvSetSecondary = FindProperty("_UVSec", props); 116 | vertexColor = FindProperty("_IntensityVC", props); 117 | } 118 | 119 | public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) 120 | { 121 | FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly 122 | m_MaterialEditor = materialEditor; 123 | Material material = materialEditor.target as Material; 124 | 125 | ShaderPropertiesGUI(material); 126 | 127 | // Make sure that needed keywords are set up if we're switching some existing 128 | // material to a standard shader. 129 | if (m_FirstTimeApply) 130 | { 131 | SetMaterialKeywords(material, m_WorkflowMode); 132 | m_FirstTimeApply = false; 133 | } 134 | } 135 | 136 | public void ShaderPropertiesGUI(Material material) 137 | { 138 | // Use default labelWidth 139 | EditorGUIUtility.labelWidth = 0f; 140 | 141 | // Detect any changes to the material 142 | EditorGUI.BeginChangeCheck(); 143 | { 144 | BlendModePopup(); 145 | 146 | // Primary properties 147 | GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel); 148 | DoAlbedoArea(material); 149 | DoSpecularMetallicArea(); 150 | m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ? bumpScale : null); 151 | m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap, heightMap.textureValue != null ? heigtMapScale : null); 152 | m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap, occlusionMap.textureValue != null ? occlusionStrength : null); 153 | DoEmissionArea(material); 154 | m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask); 155 | EditorGUI.BeginChangeCheck(); 156 | m_MaterialEditor.TextureScaleOffsetProperty(albedoMap); 157 | if (EditorGUI.EndChangeCheck()) 158 | emissionMap.textureScaleAndOffset = albedoMap.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake 159 | 160 | EditorGUILayout.Space(); 161 | 162 | // Secondary properties 163 | GUILayout.Label(Styles.secondaryMapsText, EditorStyles.boldLabel); 164 | m_MaterialEditor.TexturePropertySingleLine(Styles.detailAlbedoText, detailAlbedoMap); 165 | m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, detailNormalMap, detailNormalMapScale); 166 | m_MaterialEditor.TextureScaleOffsetProperty(detailAlbedoMap); 167 | m_MaterialEditor.ShaderProperty(uvSetSecondary, Styles.uvSetLabel.text); 168 | 169 | EditorGUILayout.Space(); 170 | 171 | m_MaterialEditor.ShaderProperty(vertexColor, "Vertex Color"); 172 | } 173 | if (EditorGUI.EndChangeCheck()) 174 | { 175 | foreach (var obj in blendMode.targets) 176 | MaterialChanged((Material)obj, m_WorkflowMode); 177 | } 178 | } 179 | 180 | internal void DetermineWorkflow(MaterialProperty[] props) 181 | { 182 | if (FindProperty("_SpecGlossMap", props, false) != null && FindProperty("_SpecColor", props, false) != null) 183 | m_WorkflowMode = WorkflowMode.Specular; 184 | else if (FindProperty("_MetallicGlossMap", props, false) != null && FindProperty("_Metallic", props, false) != null) 185 | m_WorkflowMode = WorkflowMode.Metallic; 186 | else 187 | m_WorkflowMode = WorkflowMode.Dielectric; 188 | } 189 | 190 | void BlendModePopup() 191 | { 192 | EditorGUI.showMixedValue = blendMode.hasMixedValue; 193 | var mode = (BlendMode)blendMode.floatValue; 194 | 195 | EditorGUI.BeginChangeCheck(); 196 | mode = (BlendMode)EditorGUILayout.Popup(Styles.renderingMode, (int)mode, Styles.blendNames); 197 | if (EditorGUI.EndChangeCheck()) 198 | { 199 | m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Mode"); 200 | blendMode.floatValue = (float)mode; 201 | } 202 | 203 | EditorGUI.showMixedValue = false; 204 | } 205 | 206 | void DoAlbedoArea(Material material) 207 | { 208 | m_MaterialEditor.TexturePropertySingleLine(Styles.albedoText, albedoMap, albedoColor); 209 | if (((BlendMode)material.GetFloat("_Mode") == BlendMode.Cutout)) 210 | { 211 | m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1); 212 | } 213 | } 214 | 215 | void DoEmissionArea(Material material) 216 | { 217 | bool showEmissionColorAndGIControls = emissionScaleUI.floatValue > 0f; 218 | bool hadEmissionTexture = emissionMap.textureValue != null; 219 | 220 | // Do controls 221 | m_MaterialEditor.TexturePropertySingleLine(Styles.emissionText, emissionMap, showEmissionColorAndGIControls ? emissionColorUI : null, emissionScaleUI); 222 | 223 | // Set default emissionScaleUI if texture was assigned 224 | if (emissionMap.textureValue != null && !hadEmissionTexture && emissionScaleUI.floatValue <= 0f) 225 | emissionScaleUI.floatValue = 1.0f; 226 | 227 | // Dynamic Lightmapping mode 228 | if (showEmissionColorAndGIControls) 229 | { 230 | bool shouldEmissionBeEnabled = ShouldEmissionBeEnabled(EvalFinalEmissionColor(material)); 231 | EditorGUI.BeginDisabledGroup(!shouldEmissionBeEnabled); 232 | 233 | m_MaterialEditor.LightmapEmissionProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1); 234 | 235 | EditorGUI.EndDisabledGroup(); 236 | } 237 | 238 | if (!HasValidEmissiveKeyword(material)) 239 | { 240 | EditorGUILayout.HelpBox(Styles.emissiveWarning.text, MessageType.Warning); 241 | } 242 | 243 | } 244 | 245 | void DoSpecularMetallicArea() 246 | { 247 | if (m_WorkflowMode == WorkflowMode.Specular) 248 | { 249 | if (specularMap.textureValue == null) 250 | m_MaterialEditor.TexturePropertyTwoLines(Styles.specularMapText, specularMap, specularColor, Styles.smoothnessText, smoothness); 251 | else 252 | m_MaterialEditor.TexturePropertySingleLine(Styles.specularMapText, specularMap); 253 | 254 | } 255 | else if (m_WorkflowMode == WorkflowMode.Metallic) 256 | { 257 | if (metallicMap.textureValue == null) 258 | m_MaterialEditor.TexturePropertyTwoLines(Styles.metallicMapText, metallicMap, metallic, Styles.smoothnessText, smoothness); 259 | else 260 | m_MaterialEditor.TexturePropertySingleLine(Styles.metallicMapText, metallicMap); 261 | } 262 | } 263 | 264 | public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode) 265 | { 266 | switch (blendMode) 267 | { 268 | case BlendMode.Opaque: 269 | material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); 270 | material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); 271 | material.SetInt("_ZWrite", 1); 272 | material.DisableKeyword("_ALPHATEST_ON"); 273 | material.DisableKeyword("_ALPHABLEND_ON"); 274 | material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); 275 | material.renderQueue = -1; 276 | break; 277 | case BlendMode.Cutout: 278 | material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); 279 | material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); 280 | material.SetInt("_ZWrite", 1); 281 | material.EnableKeyword("_ALPHATEST_ON"); 282 | material.DisableKeyword("_ALPHABLEND_ON"); 283 | material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); 284 | material.renderQueue = 2450; 285 | break; 286 | case BlendMode.Fade: 287 | material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); 288 | material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); 289 | material.SetInt("_ZWrite", 0); 290 | material.DisableKeyword("_ALPHATEST_ON"); 291 | material.EnableKeyword("_ALPHABLEND_ON"); 292 | material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); 293 | material.renderQueue = 3000; 294 | break; 295 | case BlendMode.Transparent: 296 | material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); 297 | material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); 298 | material.SetInt("_ZWrite", 0); 299 | material.DisableKeyword("_ALPHATEST_ON"); 300 | material.DisableKeyword("_ALPHABLEND_ON"); 301 | material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); 302 | material.renderQueue = 3000; 303 | break; 304 | } 305 | } 306 | 307 | // Calculate final HDR _EmissionColor (gamma space) from _EmissionColorUI (LDR, gamma) & _EmissionScaleUI (gamma) 308 | static Color EvalFinalEmissionColor(Material material) 309 | { 310 | return material.GetColor("_EmissionColorUI") * material.GetFloat("_EmissionScaleUI"); 311 | } 312 | 313 | static bool ShouldEmissionBeEnabled(Color color) 314 | { 315 | return color.grayscale > (0.1f / 255.0f); 316 | } 317 | 318 | static void SetMaterialKeywords(Material material, WorkflowMode workflowMode) 319 | { 320 | // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation 321 | // (MaterialProperty value might come from renderer material property block) 322 | SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap")); 323 | if (workflowMode == WorkflowMode.Specular) 324 | SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap")); 325 | else if (workflowMode == WorkflowMode.Metallic) 326 | SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap")); 327 | SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); 328 | SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); 329 | 330 | bool shouldEmissionBeEnabled = ShouldEmissionBeEnabled(material.GetColor("_EmissionColor")); 331 | SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); 332 | 333 | // Setup lightmap emissive flags 334 | MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags; 335 | if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) 336 | { 337 | flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; 338 | if (!shouldEmissionBeEnabled) 339 | flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; 340 | 341 | material.globalIlluminationFlags = flags; 342 | } 343 | 344 | SetKeyword(material, "_VERTEXCOLOR", material.GetFloat("_IntensityVC") > 0f); 345 | } 346 | 347 | bool HasValidEmissiveKeyword(Material material) 348 | { 349 | // Material animation might be out of sync with the material keyword. 350 | // So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning. 351 | // (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering)) 352 | bool hasEmissionKeyword = material.IsKeywordEnabled("_EMISSION"); 353 | if (!hasEmissionKeyword && ShouldEmissionBeEnabled(emissionColorForRendering.colorValue)) 354 | return false; 355 | else 356 | return true; 357 | } 358 | 359 | static void MaterialChanged(Material material, WorkflowMode workflowMode) 360 | { 361 | // Clamp EmissionScale to always positive 362 | if (material.GetFloat("_EmissionScaleUI") < 0.0f) 363 | material.SetFloat("_EmissionScaleUI", 0.0f); 364 | 365 | // Apply combined emission value 366 | Color emissionColorOut = EvalFinalEmissionColor(material); 367 | material.SetColor("_EmissionColor", emissionColorOut); 368 | 369 | // Handle Blending modes 370 | SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode")); 371 | 372 | SetMaterialKeywords(material, workflowMode); 373 | } 374 | 375 | static void SetKeyword(Material m, string keyword, bool state) 376 | { 377 | if (state) 378 | m.EnableKeyword(keyword); 379 | else 380 | m.DisableKeyword(keyword); 381 | } 382 | } 383 | } -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/Editor/StandardShaderVCGUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e16b7f6ade63b574099d8493e8b57613 3 | timeCreated: 1428329973 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/Standard.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/Standard.mat -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/Standard.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 272f8d89d7bfcfc40a47153f49d9e553 3 | timeCreated: 1433403822 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/StandardFade.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/StandardFade.mat -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/StandardFade.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9cc1c8a7447273742a2a6971c781b1f1 3 | timeCreated: 1433403830 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/StandardVC.shader: -------------------------------------------------------------------------------- 1 | Shader "Standard (Vertex Color)" { 2 | 3 | Properties 4 | { 5 | _Color("Color", Color) = (1,1,1,1) 6 | _MainTex("Albedo", 2D) = "white" {} 7 | 8 | _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 9 | 10 | _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 11 | [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 12 | _MetallicGlossMap("Metallic", 2D) = "white" {} 13 | 14 | _BumpScale("Scale", Float) = 1.0 15 | _BumpMap("Normal Map", 2D) = "bump" {} 16 | 17 | _Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02 18 | _ParallaxMap ("Height Map", 2D) = "black" {} 19 | 20 | _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 21 | _OcclusionMap("Occlusion", 2D) = "white" {} 22 | 23 | _EmissionColor("Color", Color) = (0,0,0) 24 | _EmissionMap("Emission", 2D) = "white" {} 25 | 26 | _DetailMask("Detail Mask", 2D) = "white" {} 27 | 28 | _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {} 29 | _DetailNormalMapScale("Scale", Float) = 1.0 30 | _DetailNormalMap("Normal Map", 2D) = "bump" {} 31 | 32 | [Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0 33 | 34 | // UI-only data 35 | [HideInInspector] _EmissionScaleUI("Scale", Float) = 0.0 36 | [HideInInspector] _EmissionColorUI("Color", Color) = (1,1,1) 37 | 38 | // Blending state 39 | [HideInInspector] _Mode ("__mode", Float) = 0.0 40 | [HideInInspector] _SrcBlend ("__src", Float) = 1.0 41 | [HideInInspector] _DstBlend ("__dst", Float) = 0.0 42 | [HideInInspector] _ZWrite ("__zw", Float) = 1.0 43 | } 44 | 45 | CGINCLUDE 46 | #define UNITY_SETUP_BRDF_INPUT MetallicSetup 47 | ENDCG 48 | 49 | SubShader 50 | { 51 | Tags { "RenderType"="Opaque" "PerformanceChecks"="False" } 52 | LOD 300 53 | 54 | 55 | // ------------------------------------------------------------------ 56 | // Base forward pass (directional light, emission, lightmaps, ...) 57 | Pass 58 | { 59 | Name "FORWARD" 60 | Tags { "LightMode" = "ForwardBase" } 61 | 62 | Blend [_SrcBlend] [_DstBlend] 63 | ZWrite [_ZWrite] 64 | 65 | CGPROGRAM 66 | #pragma target 3.0 67 | // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT 68 | #pragma exclude_renderers gles 69 | 70 | // ------------------------------------- 71 | 72 | #pragma shader_feature _NORMALMAP 73 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 74 | #pragma shader_feature _EMISSION 75 | #pragma shader_feature _METALLICGLOSSMAP 76 | #pragma shader_feature ___ _DETAIL_MULX2 77 | #pragma shader_feature _PARALLAXMAP 78 | 79 | #pragma multi_compile_fwdbase 80 | #pragma multi_compile_fog 81 | 82 | #pragma vertex vertForwardBase_VC 83 | #pragma fragment fragForwardBase_VC 84 | 85 | #include "UnityStandardCore.cginc" 86 | #include "UnityVC.cginc" 87 | 88 | ENDCG 89 | } 90 | // ------------------------------------------------------------------ 91 | // Additive forward pass (one light per pass) 92 | Pass 93 | { 94 | Name "FORWARD_DELTA" 95 | Tags { "LightMode" = "ForwardAdd" } 96 | Blend [_SrcBlend] One 97 | Fog { Color (0,0,0,0) } // in additive pass fog should be black 98 | ZWrite Off 99 | ZTest LEqual 100 | 101 | CGPROGRAM 102 | #pragma target 3.0 103 | // GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT 104 | #pragma exclude_renderers gles 105 | 106 | // ------------------------------------- 107 | 108 | 109 | #pragma shader_feature _NORMALMAP 110 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 111 | #pragma shader_feature _METALLICGLOSSMAP 112 | #pragma shader_feature ___ _DETAIL_MULX2 113 | #pragma shader_feature _PARALLAXMAP 114 | 115 | #pragma multi_compile_fwdadd_fullshadows 116 | #pragma multi_compile_fog 117 | 118 | #pragma vertex vertForwardAdd 119 | #pragma fragment fragForwardAdd 120 | 121 | #include "UnityStandardCore.cginc" 122 | 123 | ENDCG 124 | } 125 | // ------------------------------------------------------------------ 126 | // Shadow rendering pass 127 | Pass { 128 | Name "ShadowCaster" 129 | Tags { "LightMode" = "ShadowCaster" } 130 | 131 | ZWrite On ZTest LEqual 132 | 133 | CGPROGRAM 134 | #pragma target 3.0 135 | // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT 136 | #pragma exclude_renderers gles 137 | 138 | // ------------------------------------- 139 | 140 | 141 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 142 | #pragma multi_compile_shadowcaster 143 | 144 | #pragma vertex vertShadowCaster 145 | #pragma fragment fragShadowCaster 146 | 147 | #include "UnityStandardShadow.cginc" 148 | 149 | ENDCG 150 | } 151 | // ------------------------------------------------------------------ 152 | // Deferred pass 153 | Pass 154 | { 155 | Name "DEFERRED" 156 | Tags { "LightMode" = "Deferred" } 157 | 158 | CGPROGRAM 159 | #pragma target 3.0 160 | // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT 161 | #pragma exclude_renderers nomrt gles 162 | 163 | 164 | // ------------------------------------- 165 | 166 | #pragma shader_feature _NORMALMAP 167 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 168 | #pragma shader_feature _EMISSION 169 | #pragma shader_feature _METALLICGLOSSMAP 170 | #pragma shader_feature ___ _DETAIL_MULX2 171 | #pragma shader_feature _PARALLAXMAP 172 | 173 | #pragma multi_compile ___ UNITY_HDR_ON 174 | #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON 175 | #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE 176 | #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON 177 | 178 | #pragma vertex vertDeferred_VC 179 | #pragma fragment fragDeferred_VC 180 | 181 | #include "UnityStandardCore.cginc" 182 | #include "UnityVC.cginc" 183 | 184 | ENDCG 185 | } 186 | 187 | // ------------------------------------------------------------------ 188 | // Extracts information for lightmapping, GI (emission, albedo, ...) 189 | // This pass it not used during regular rendering. 190 | Pass 191 | { 192 | Name "META" 193 | Tags { "LightMode"="Meta" } 194 | 195 | Cull Off 196 | 197 | CGPROGRAM 198 | #pragma vertex vert_meta 199 | #pragma fragment frag_meta 200 | 201 | #pragma shader_feature _EMISSION 202 | #pragma shader_feature _METALLICGLOSSMAP 203 | #pragma shader_feature ___ _DETAIL_MULX2 204 | 205 | #include "UnityStandardMeta.cginc" 206 | ENDCG 207 | } 208 | } 209 | 210 | SubShader 211 | { 212 | Tags { "RenderType"="Opaque" "PerformanceChecks"="False" } 213 | LOD 150 214 | 215 | // ------------------------------------------------------------------ 216 | // Base forward pass (directional light, emission, lightmaps, ...) 217 | Pass 218 | { 219 | Name "FORWARD" 220 | Tags { "LightMode" = "ForwardBase" } 221 | 222 | Blend [_SrcBlend] [_DstBlend] 223 | ZWrite [_ZWrite] 224 | 225 | CGPROGRAM 226 | #pragma target 2.0 227 | 228 | #pragma shader_feature _NORMALMAP 229 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 230 | #pragma shader_feature _EMISSION 231 | #pragma shader_feature _METALLICGLOSSMAP 232 | #pragma shader_feature ___ _DETAIL_MULX2 233 | // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP 234 | 235 | #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE 236 | 237 | #pragma multi_compile_fwdbase 238 | #pragma multi_compile_fog 239 | 240 | #pragma vertex vertForwardBase_VC 241 | #pragma fragment fragForwardBase_VC 242 | 243 | #include "UnityStandardCore.cginc" 244 | #include "UnityVC.cginc" 245 | 246 | ENDCG 247 | } 248 | // ------------------------------------------------------------------ 249 | // Additive forward pass (one light per pass) 250 | Pass 251 | { 252 | Name "FORWARD_DELTA" 253 | Tags { "LightMode" = "ForwardAdd" } 254 | Blend [_SrcBlend] One 255 | Fog { Color (0,0,0,0) } // in additive pass fog should be black 256 | ZWrite Off 257 | ZTest LEqual 258 | 259 | CGPROGRAM 260 | #pragma target 2.0 261 | 262 | #pragma shader_feature _NORMALMAP 263 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 264 | #pragma shader_feature _METALLICGLOSSMAP 265 | #pragma shader_feature ___ _DETAIL_MULX2 266 | // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP 267 | #pragma skip_variants SHADOWS_SOFT 268 | 269 | #pragma multi_compile_fwdadd_fullshadows 270 | #pragma multi_compile_fog 271 | 272 | #pragma vertex vertForwardAdd 273 | #pragma fragment fragForwardAdd 274 | 275 | #include "UnityStandardCore.cginc" 276 | 277 | ENDCG 278 | } 279 | // ------------------------------------------------------------------ 280 | // Shadow rendering pass 281 | Pass { 282 | Name "ShadowCaster" 283 | Tags { "LightMode" = "ShadowCaster" } 284 | 285 | ZWrite On ZTest LEqual 286 | 287 | CGPROGRAM 288 | #pragma target 2.0 289 | 290 | #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON 291 | #pragma skip_variants SHADOWS_SOFT 292 | #pragma multi_compile_shadowcaster 293 | 294 | #pragma vertex vertShadowCaster 295 | #pragma fragment fragShadowCaster 296 | 297 | #include "UnityStandardShadow.cginc" 298 | 299 | ENDCG 300 | } 301 | 302 | // ------------------------------------------------------------------ 303 | // Extracts information for lightmapping, GI (emission, albedo, ...) 304 | // This pass it not used during regular rendering. 305 | Pass 306 | { 307 | Name "META" 308 | Tags { "LightMode"="Meta" } 309 | 310 | Cull Off 311 | 312 | CGPROGRAM 313 | #pragma vertex vert_meta 314 | #pragma fragment frag_meta 315 | 316 | #pragma shader_feature _EMISSION 317 | #pragma shader_feature _METALLICGLOSSMAP 318 | #pragma shader_feature ___ _DETAIL_MULX2 319 | 320 | #include "UnityStandardMeta.cginc" 321 | ENDCG 322 | } 323 | } 324 | 325 | FallBack "Standard" 326 | CustomEditor "StandardShaderGUI" 327 | } -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/StandardVC.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 466466a0175d2e340b26817200194fc0 3 | timeCreated: 1428218860 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/UnityVC.cginc: -------------------------------------------------------------------------------- 1 | #ifndef UNITY_VC_INCLUDED 2 | #define UNITY_VC_INCLUDED 3 | 4 | struct VertexInput_VC 5 | { 6 | float4 vertex : POSITION; 7 | fixed4 color : COLOR; 8 | half3 normal : NORMAL; 9 | float2 uv0 : TEXCOORD0; 10 | float2 uv1 : TEXCOORD1; 11 | #if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META) 12 | float2 uv2 : TEXCOORD2; 13 | #endif 14 | #ifdef _TANGENT_TO_WORLD 15 | half4 tangent : TANGENT; 16 | #endif 17 | }; 18 | 19 | float4 TexCoords_VC(VertexInput_VC v) 20 | { 21 | float4 texcoord; 22 | texcoord.xy = TRANSFORM_TEX(v.uv0, _MainTex); // Always source from uv0 23 | texcoord.zw = TRANSFORM_TEX(((_UVSec == 0) ? v.uv0 : v.uv1), _DetailAlbedoMap); 24 | return texcoord; 25 | } 26 | 27 | //Forward Pass 28 | struct VertexOutputForwardBase_VC 29 | { 30 | float4 pos : SV_POSITION; 31 | float4 tex : TEXCOORD0; 32 | half3 eyeVec : TEXCOORD1; 33 | half4 tangentToWorldAndParallax[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] 34 | half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV 35 | SHADOW_COORDS(6) 36 | UNITY_FOG_COORDS(7) 37 | 38 | fixed4 color : COLOR; 39 | // next ones would not fit into SM2.0 limits, but they are always for SM3.0+ 40 | #if UNITY_SPECCUBE_BOX_PROJECTION 41 | float3 posWorld : TEXCOORD8; 42 | #endif 43 | }; 44 | 45 | VertexOutputForwardBase_VC vertForwardBase_VC (VertexInput_VC v) 46 | { 47 | VertexOutputForwardBase_VC o; 48 | UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase_VC, o); 49 | 50 | float4 posWorld = mul(_Object2World, v.vertex); 51 | #if UNITY_SPECCUBE_BOX_PROJECTION 52 | o.posWorld = posWorld.xyz; 53 | #endif 54 | o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 55 | o.tex = TexCoords_VC(v); 56 | o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); 57 | float3 normalWorld = UnityObjectToWorldNormal(v.normal); 58 | #ifdef _TANGENT_TO_WORLD 59 | float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); 60 | 61 | float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); 62 | o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0]; 63 | o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1]; 64 | o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2]; 65 | #else 66 | o.tangentToWorldAndParallax[0].xyz = 0; 67 | o.tangentToWorldAndParallax[1].xyz = 0; 68 | o.tangentToWorldAndParallax[2].xyz = normalWorld; 69 | #endif 70 | //We need this for shadow receving 71 | TRANSFER_SHADOW(o); 72 | 73 | // Static lightmaps 74 | #ifndef LIGHTMAP_OFF 75 | o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; 76 | o.ambientOrLightmapUV.zw = 0; 77 | // Sample light probe for Dynamic objects only (no static or dynamic lightmaps) 78 | #elif UNITY_SHOULD_SAMPLE_SH 79 | #if UNITY_SAMPLE_FULL_SH_PER_PIXEL 80 | o.ambientOrLightmapUV.rgb = 0; 81 | #elif (SHADER_TARGET < 30) 82 | o.ambientOrLightmapUV.rgb = ShadeSH9(half4(normalWorld, 1.0)); 83 | #else 84 | // Optimization: L2 per-vertex, L0..L1 per-pixel 85 | o.ambientOrLightmapUV.rgb = ShadeSH3Order(half4(normalWorld, 1.0)); 86 | #endif 87 | // Add approximated illumination from non-important point lights 88 | #ifdef VERTEXLIGHT_ON 89 | o.ambientOrLightmapUV.rgb += Shade4PointLights ( 90 | unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, 91 | unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, 92 | unity_4LightAtten0, posWorld, normalWorld); 93 | #endif 94 | #endif 95 | 96 | #ifdef DYNAMICLIGHTMAP_ON 97 | o.ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; 98 | #endif 99 | 100 | #ifdef _PARALLAXMAP 101 | TANGENT_SPACE_ROTATION; 102 | half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex)); 103 | o.tangentToWorldAndParallax[0].w = viewDirForParallax.x; 104 | o.tangentToWorldAndParallax[1].w = viewDirForParallax.y; 105 | o.tangentToWorldAndParallax[2].w = viewDirForParallax.z; 106 | #endif 107 | 108 | o.color = v.color; 109 | 110 | UNITY_TRANSFER_FOG(o,o.pos); 111 | return o; 112 | } 113 | 114 | half4 fragForwardBase_VC (VertexOutputForwardBase_VC i) : SV_Target 115 | { 116 | FRAGMENT_SETUP(s) 117 | UnityLight mainLight = MainLight (s.normalWorld); 118 | half atten = SHADOW_ATTENUATION(i); 119 | 120 | half occlusion = Occlusion(i.tex.xy); 121 | UnityGI gi = FragmentGI ( 122 | s.posWorld, occlusion, i.ambientOrLightmapUV, atten, s.oneMinusRoughness, s.normalWorld, s.eyeVec, mainLight); 123 | 124 | half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect); 125 | 126 | c *= i.color; 127 | 128 | c.rgb += UNITY_BRDF_GI (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, occlusion, gi); 129 | c.rgb += Emission(i.tex.xy); 130 | 131 | UNITY_APPLY_FOG(i.fogCoord, c.rgb); 132 | return OutputForward (c, s.alpha * i.color.a); 133 | } 134 | 135 | //Deferred Pass 136 | struct VertexOutputDeferred_VC 137 | { 138 | float4 pos : SV_POSITION; 139 | fixed4 color : COLOR; 140 | float4 tex : TEXCOORD0; 141 | half3 eyeVec : TEXCOORD1; 142 | half4 tangentToWorldAndParallax[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] 143 | half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UVs 144 | #if UNITY_SPECCUBE_BOX_PROJECTION 145 | float3 posWorld : TEXCOORD6; 146 | #endif 147 | }; 148 | 149 | VertexOutputDeferred_VC vertDeferred_VC (VertexInput_VC v) 150 | { 151 | VertexOutputDeferred_VC o; 152 | UNITY_INITIALIZE_OUTPUT(VertexOutputDeferred_VC, o); 153 | 154 | float4 posWorld = mul(_Object2World, v.vertex); 155 | #if UNITY_SPECCUBE_BOX_PROJECTION 156 | o.posWorld = posWorld; 157 | #endif 158 | o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 159 | o.tex = TexCoords_VC(v); 160 | o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); 161 | float3 normalWorld = UnityObjectToWorldNormal(v.normal); 162 | #ifdef _TANGENT_TO_WORLD 163 | float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); 164 | 165 | float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); 166 | o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0]; 167 | o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1]; 168 | o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2]; 169 | #else 170 | o.tangentToWorldAndParallax[0].xyz = 0; 171 | o.tangentToWorldAndParallax[1].xyz = 0; 172 | o.tangentToWorldAndParallax[2].xyz = normalWorld; 173 | #endif 174 | 175 | #ifndef LIGHTMAP_OFF 176 | o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; 177 | o.ambientOrLightmapUV.zw = 0; 178 | #elif UNITY_SHOULD_SAMPLE_SH 179 | #if (SHADER_TARGET < 30) 180 | o.ambientOrLightmapUV.rgb = ShadeSH9(half4(normalWorld, 1.0)); 181 | #else 182 | // Optimization: L2 per-vertex, L0..L1 per-pixel 183 | o.ambientOrLightmapUV.rgb = ShadeSH3Order(half4(normalWorld, 1.0)); 184 | #endif 185 | #endif 186 | 187 | #ifdef DYNAMICLIGHTMAP_ON 188 | o.ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; 189 | #endif 190 | 191 | #ifdef _PARALLAXMAP 192 | TANGENT_SPACE_ROTATION; 193 | half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex)); 194 | o.tangentToWorldAndParallax[0].w = viewDirForParallax.x; 195 | o.tangentToWorldAndParallax[1].w = viewDirForParallax.y; 196 | o.tangentToWorldAndParallax[2].w = viewDirForParallax.z; 197 | #endif 198 | o.color = v.color; 199 | 200 | return o; 201 | } 202 | 203 | void fragDeferred_VC ( 204 | VertexOutputDeferred_VC i, 205 | out half4 outDiffuse : SV_Target0, // RT0: diffuse color (rgb), occlusion (a) 206 | out half4 outSpecSmoothness : SV_Target1, // RT1: spec color (rgb), smoothness (a) 207 | out half4 outNormal : SV_Target2, // RT2: normal (rgb), --unused, very low precision-- (a) 208 | out half4 outEmission : SV_Target3 // RT3: emission (rgb), --unused-- (a) 209 | ) 210 | { 211 | #if (SHADER_TARGET < 30) 212 | outDiffuse = 1; 213 | outSpecSmoothness = 1; 214 | outNormal = 0; 215 | outEmission = 0; 216 | return; 217 | #endif 218 | 219 | FRAGMENT_SETUP(s) 220 | 221 | // no analytic lights in this pass 222 | UnityLight dummyLight = DummyLight (s.normalWorld); 223 | half atten = 1; 224 | 225 | // only GI 226 | half occlusion = Occlusion(i.tex.xy); 227 | UnityGI gi = FragmentGI ( 228 | s.posWorld, occlusion, i.ambientOrLightmapUV, atten, s.oneMinusRoughness, s.normalWorld, s.eyeVec, dummyLight); 229 | 230 | half3 color = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb; 231 | color *= i.color; 232 | color += UNITY_BRDF_GI (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, occlusion, gi); 233 | 234 | #ifdef _EMISSION 235 | color += Emission (i.tex.xy); 236 | #endif 237 | 238 | #ifndef UNITY_HDR_ON 239 | color.rgb = exp2(-color.rgb); 240 | #endif 241 | 242 | outDiffuse = half4(s.diffColor * i.color.rgb, occlusion); 243 | outSpecSmoothness = half4(s.specColor * i.color.rgb, s.oneMinusRoughness); 244 | outNormal = half4(s.normalWorld*0.5+0.5,1); 245 | outEmission = half4(color, 1); 246 | } 247 | 248 | #endif -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/UnityVC.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2a6c61abcc5796241b098499a0f9281d 3 | timeCreated: 1428235817 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/VertexColorDebugSphere.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/VertexColorDebugSphere.FBX -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/VertexColorDebugSphere.FBX.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6908aba7388e2194e9f052ee85144055 3 | timeCreated: 1428235182 4 | licenseType: Free 5 | ModelImporter: 6 | serializedVersion: 18 7 | fileIDToRecycleName: 8 | 100000: //RootNode 9 | 400000: //RootNode 10 | 2300000: //RootNode 11 | 3300000: //RootNode 12 | 4300000: Sphere01 13 | materials: 14 | importMaterials: 0 15 | materialName: 1 16 | materialSearch: 0 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | optimizeGameObjects: 0 21 | motionNodeName: 22 | animationCompression: 1 23 | animationRotationError: .5 24 | animationPositionError: .5 25 | animationScaleError: .5 26 | animationWrapMode: 0 27 | extraExposedTransformPaths: [] 28 | clipAnimations: [] 29 | isReadable: 1 30 | meshes: 31 | lODScreenPercentages: [] 32 | globalScale: 1 33 | meshCompression: 0 34 | addColliders: 0 35 | importBlendShapes: 1 36 | swapUVChannels: 0 37 | generateSecondaryUV: 0 38 | useFileUnits: 1 39 | optimizeMeshForGPU: 1 40 | keepQuads: 0 41 | weldVertices: 1 42 | secondaryUVAngleDistortion: 8 43 | secondaryUVAreaDistortion: 15.000001 44 | secondaryUVHardAngle: 88 45 | secondaryUVPackMargin: 4 46 | useFileScale: 1 47 | tangentSpace: 48 | normalSmoothAngle: 60 49 | splitTangentsAcrossUV: 1 50 | normalImportMode: 0 51 | tangentImportMode: 1 52 | importAnimation: 1 53 | copyAvatar: 0 54 | humanDescription: 55 | human: [] 56 | skeleton: [] 57 | armTwist: .5 58 | foreArmTwist: .5 59 | upperLegTwist: .5 60 | legTwist: .5 61 | armStretch: .0500000007 62 | legStretch: .0500000007 63 | feetSpacing: 0 64 | rootMotionBoneName: 65 | lastHumanDescriptionAvatarSource: {instanceID: 0} 66 | animationType: 0 67 | additionalBone: 0 68 | userData: 69 | assetBundleName: 70 | assetBundleVariant: 71 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/VertexColorDebugSphereAlpha.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/VertexColorDebugSphereAlpha.FBX -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/VertexColorDebugSphereAlpha.FBX.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ff9898e1dc3167489f83b4d7288fd7d 3 | timeCreated: 1428999536 4 | licenseType: Free 5 | ModelImporter: 6 | serializedVersion: 18 7 | fileIDToRecycleName: 8 | 100000: //RootNode 9 | 400000: //RootNode 10 | 2300000: //RootNode 11 | 3300000: //RootNode 12 | 4300000: Sphere01 13 | materials: 14 | importMaterials: 0 15 | materialName: 0 16 | materialSearch: 1 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | optimizeGameObjects: 0 21 | motionNodeName: 22 | animationCompression: 1 23 | animationRotationError: .5 24 | animationPositionError: .5 25 | animationScaleError: .5 26 | animationWrapMode: 0 27 | extraExposedTransformPaths: [] 28 | clipAnimations: [] 29 | isReadable: 1 30 | meshes: 31 | lODScreenPercentages: [] 32 | globalScale: 1 33 | meshCompression: 0 34 | addColliders: 0 35 | importBlendShapes: 1 36 | swapUVChannels: 0 37 | generateSecondaryUV: 0 38 | useFileUnits: 1 39 | optimizeMeshForGPU: 1 40 | keepQuads: 0 41 | weldVertices: 1 42 | secondaryUVAngleDistortion: 8 43 | secondaryUVAreaDistortion: 15.000001 44 | secondaryUVHardAngle: 88 45 | secondaryUVPackMargin: 4 46 | useFileScale: 1 47 | tangentSpace: 48 | normalSmoothAngle: 60 49 | splitTangentsAcrossUV: 1 50 | normalImportMode: 0 51 | tangentImportMode: 1 52 | importAnimation: 1 53 | copyAvatar: 0 54 | humanDescription: 55 | human: [] 56 | skeleton: [] 57 | armTwist: .5 58 | foreArmTwist: .5 59 | upperLegTwist: .5 60 | legTwist: .5 61 | armStretch: .0500000007 62 | legStretch: .0500000007 63 | feetSpacing: 0 64 | rootMotionBoneName: 65 | lastHumanDescriptionAvatarSource: {instanceID: 0} 66 | animationType: 0 67 | additionalBone: 0 68 | userData: 69 | assetBundleName: 70 | assetBundleVariant: 71 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/tiles_diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/tiles_diff.png -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/tiles_diff.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1223b34f95ccef140988a60b68c87c0a 3 | timeCreated: 1435667488 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: .25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 8 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: .5, y: .5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: -1 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | sprites: [] 52 | spritePackingTag: 53 | userData: 54 | assetBundleName: 55 | assetBundleVariant: 56 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/tiles_norm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/tiles_norm.png -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/tiles_norm.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5baab790477371499d58388584017a5 3 | timeCreated: 1435667488 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 1 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 1 19 | externalNormalMap: 1 20 | heightScale: .200000003 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 8 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: .5, y: .5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 1 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | sprites: [] 52 | spritePackingTag: 53 | userData: 54 | assetBundleName: 55 | assetBundleVariant: 56 | -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/tiles_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/Shaders/UnityVC/tiles_spec.png -------------------------------------------------------------------------------- /Assets/Shaders/UnityVC/tiles_spec.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57b2585fca985ab47b6f30b68f994c71 3 | timeCreated: 1435667916 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: .25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 8 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: .5, y: .5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: -1 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | sprites: [] 52 | spritePackingTag: 53 | userData: 54 | assetBundleName: 55 | assetBundleVariant: 56 | -------------------------------------------------------------------------------- /Assets/Standard Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fca1a5391abc8ca46b5dca68fddd2120 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cadc5c144b6941fd9b94e6f6cbaa3cc 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6685d213dcd37451eaa7643f63089046 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts/MouseOrbit.js: -------------------------------------------------------------------------------- 1 | var target : Transform; 2 | var distance = 10.0; 3 | 4 | var xSpeed = 250.0; 5 | var ySpeed = 120.0; 6 | 7 | var yMinLimit = -20; 8 | var yMaxLimit = 80; 9 | 10 | private var x = 0.0; 11 | private var y = 0.0; 12 | 13 | @script AddComponentMenu("Camera-Control/Mouse Orbit") 14 | 15 | function Start () { 16 | var angles = transform.eulerAngles; 17 | x = angles.y; 18 | y = angles.x; 19 | 20 | // Make the rigid body not change rotation 21 | if (GetComponent.()) 22 | GetComponent.().freezeRotation = true; 23 | 24 | this.transform.position = target.position - Vector3.forward * distance; 25 | this.transform.LookAt(target); 26 | } 27 | 28 | function LateUpdate () { 29 | if (target && Input.GetMouseButton(0)) { 30 | #if UNITY_EDITOR || UNITY_STANDALONE 31 | x += Input.GetAxis("Mouse X") * xSpeed * 0.02; 32 | y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; 33 | #elif UNITY_ANDROID 34 | x += Input.GetTouch(0).deltaPosition.x; 35 | y -= Input.GetTouch(0).deltaPosition.y; 36 | #endif 37 | 38 | y = ClampAngle(y, yMinLimit, yMaxLimit); 39 | 40 | var rotation = Quaternion.Euler(y, x, 0); 41 | var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; 42 | 43 | transform.rotation = rotation; 44 | transform.position = position; 45 | } 46 | } 47 | 48 | static function ClampAngle (angle : float, min : float, max : float) { 49 | if (angle < -360) 50 | angle += 360; 51 | if (angle > 360) 52 | angle -= 360; 53 | return Mathf.Clamp (angle, min, max); 54 | } -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts/MouseOrbit.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27acebc9ad1110f6d00074c88d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts/SmoothFollow.js: -------------------------------------------------------------------------------- 1 | /* 2 | This camera smoothes out rotation around the y-axis and height. 3 | Horizontal Distance to the target is always fixed. 4 | 5 | There are many different ways to smooth the rotation but doing it this way gives you a lot of control over how the camera behaves. 6 | 7 | For every of those smoothed values we calculate the wanted value and the current value. 8 | Then we smooth it using the Lerp function. 9 | Then we apply the smoothed values to the transform's position. 10 | */ 11 | 12 | // The target we are following 13 | var target : Transform; 14 | // The distance in the x-z plane to the target 15 | var distance = 10.0; 16 | // the height we want the camera to be above the target 17 | var height = 5.0; 18 | // How much we 19 | var heightDamping = 2.0; 20 | var rotationDamping = 3.0; 21 | 22 | // Place the script in the Camera-Control group in the component menu 23 | @script AddComponentMenu("Camera-Control/Smooth Follow") 24 | 25 | 26 | function LateUpdate () { 27 | // Early out if we don't have a target 28 | if (!target) 29 | return; 30 | 31 | // Calculate the current rotation angles 32 | var wantedRotationAngle = target.eulerAngles.y; 33 | var wantedHeight = target.position.y + height; 34 | 35 | var currentRotationAngle = transform.eulerAngles.y; 36 | var currentHeight = transform.position.y; 37 | 38 | // Damp the rotation around the y-axis 39 | currentRotationAngle = Mathf.LerpAngle (currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime); 40 | 41 | // Damp the height 42 | currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime); 43 | 44 | // Convert the angle into a rotation 45 | var currentRotation = Quaternion.Euler (0, currentRotationAngle, 0); 46 | 47 | // Set the position of the camera on the x-z plane to: 48 | // distance meters behind the target 49 | transform.position = target.position; 50 | transform.position -= currentRotation * Vector3.forward * distance; 51 | 52 | // Set the height of the camera 53 | transform.position.y = currentHeight; 54 | 55 | // Always look at the target 56 | transform.LookAt (target); 57 | } -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts/SmoothFollow.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 885b1972ad11a921d000d37b8d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts/SmoothLookAt.js: -------------------------------------------------------------------------------- 1 | var target : Transform; 2 | var damping = 6.0; 3 | var smooth = true; 4 | 5 | @script AddComponentMenu("Camera-Control/Smooth Look At") 6 | 7 | function LateUpdate () { 8 | if (target) { 9 | if (smooth) 10 | { 11 | // Look at and dampen the rotation 12 | var rotation = Quaternion.LookRotation(target.position - transform.position); 13 | transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping); 14 | } 15 | else 16 | { 17 | // Just lookat 18 | transform.LookAt(target); 19 | } 20 | } 21 | } 22 | 23 | function Start () { 24 | // Make the rigid body not change rotation 25 | if (GetComponent.()) 26 | GetComponent.().freezeRotation = true; 27 | } -------------------------------------------------------------------------------- /Assets/Standard Assets/Scripts/Camera Scripts/SmoothLookAt.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a4debc9ad1110f6d00074c88d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnityVS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02fe78e962405814a83b8ba6c9471d32 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/test.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/test.mat -------------------------------------------------------------------------------- /Assets/test.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 926a472c03e968a4883b0c4219a4a64d 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/test.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/Assets/test.unity -------------------------------------------------------------------------------- /Assets/test.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12d277bd1429164429cfeb39b28ab337 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alprkskn/RandomPlanetGenerator/f3b7f884d9209a80812f0785c420177b3d356043/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /UnityVS.RandomPlanetGenerator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityVS.RandomPlanetGenerator.CSharp", "UnityVS.RandomPlanetGenerator.CSharp.csproj", "{6E5A9DEA-930B-D6D8-0856-4437BEAC9DFF}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {6E5A9DEA-930B-D6D8-0856-4437BEAC9DFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {6E5A9DEA-930B-D6D8-0856-4437BEAC9DFF}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {6E5A9DEA-930B-D6D8-0856-4437BEAC9DFF}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {6E5A9DEA-930B-D6D8-0856-4437BEAC9DFF}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | --------------------------------------------------------------------------------