public static Vector3 SphericalMercator(this LatLngPoint value) { if (value is null) { throw new ArgumentNullException(nameof(value)); } var lat = Degrees.Radians(value.Latitude); var lng = Degrees.Radians(value.Longitude); var x = DatumWGS_84.equatorialRadius * lng; var y = DatumWGS_84.equatorialRadius * Math.Log(Math.Tan(Math.PI / 4 + lat / 2)); return(new Vector3((float)x, (float)y, value.Altitude)); }
private async Task UpdatePhotosphere() { var euler = (Vector2)avatar.Head.rotation.eulerAngles; var numRequests = 0; for (var f = 0; f < mgr.FOVs.Length && numRequests < MAX_REQUESTS; ++f) { var fov = mgr.FOVs[f]; var overlap = mgr.FOVs.Length - f; var radius = 10 * overlap + 50; var overlapFOV = fov + 2f * overlap; var scale = 2 * radius * Mathf.Tan(Degrees.Radians(overlapFOV / 2)); var testAngles = mgr.fovTestAngles[f]; for (var a = 0; a < testAngles.Length && numRequests < MAX_REQUESTS; ++a) { var testAngle = euler + testAngles[a]; var heading = (int)Mathf.Repeat(fov * Mathf.Round(testAngle.y / fov), 360); var unityPitch = (int)Mathf.Repeat(fov * Mathf.Round(testAngle.x / fov), 360); var pitch = -unityPitch; if (unityPitch >= 270) { pitch += 360; } else if (unityPitch > 90) { pitch += 180; } if (90 < unityPitch && unityPitch < 270) { heading = (int)Mathf.Repeat(heading + 180, 360); } if (Mathf.Abs(pitch) == 90) { heading = 0; } var needLodLevel = !detailContainerCache.ContainsKey(fov); var needSlice = needLodLevel || !detailSliceContainerCache[fov].ContainsKey(heading); var needFrame = needSlice || !detailSliceFrameContainerCache[fov][heading].ContainsKey(pitch); if (needLodLevel || needSlice || needFrame) { if (needLodLevel) { await JuniperSystem.OnMainThreadAsync(() => { var detail = new GameObject(fov.ToString()).transform; detail.SetParent(transform, false); detailContainerCache[fov] = detail; detailSliceContainerCache[fov] = new Dictionary <int, Transform>(); detailSliceFrameContainerCache[fov] = new Dictionary <int, Dictionary <int, Transform> >(); }); } var detailContainer = detailContainerCache[fov]; var sliceContainerCache = detailSliceContainerCache[fov]; var sliceFrameContainerCache = detailSliceFrameContainerCache[fov]; if (needSlice) { await JuniperSystem.OnMainThreadAsync(() => { var slice = new GameObject(heading.ToString()).transform; slice.SetParent(detailContainer, false); sliceContainerCache[heading] = slice; sliceFrameContainerCache[heading] = new Dictionary <int, Transform>(); }); } var sliceContainer = sliceContainerCache[heading]; var frameContainerCache = sliceFrameContainerCache[heading]; if (needFrame) { await JuniperSystem.OnMainThreadAsync(() => { var frame = new GameObject(pitch.ToString()).transform; frame.rotation = Quaternion.Euler(-pitch, heading, 0); frame.position = frame.rotation * (radius *Vector3.forward); frame.SetParent(sliceContainer, false); frameContainerCache[pitch] = frame; }); } if (ImageNeeded != null) { var image = await ImageNeeded(this, (int)overlapFOV, heading, pitch); if (image != null) { await JuniperSystem.OnMainThreadAsync(() => { var frame = GameObject.CreatePrimitive(PrimitiveType.Quad); var renderer = frame.GetComponent <MeshRenderer>(); var properties = new MaterialPropertyBlock(); properties.SetTexture("_MainTex", image); renderer.SetMaterial(material); renderer.SetPropertyBlock(properties); frame.layer = LayerMask.NameToLayer(PHOTOSPHERE_LAYER); var frameContainer = frameContainerCache[pitch]; frame.transform.SetParent(frameContainer, false); frame.transform.localScale = scale *Vector3.one; }); } } // For the lowest detail level, we fill out all of the image angles immediately. // For all other detail levels, we break out of testing angles and continue to // next highest detail level. if (f > 0) { break; } } } } }
public void Degrees_2_radians() { FloatCompare(TAU, Degrees.Radians(360)); }