using System.Collections.Generic; using UnityEngine; using sam; using System; [ExecuteInEditMode] public class PointVariable3DVisualizer : MonoBehaviour { public MeshFilter linesMeshFilter; public MeshFilter pointsMeshFilter; public float heightGap; public float scaleFactor = 1.0f; public Color lineColor; public Color pointColor; public int preferredSampleInterval = 360; public float hist2dHeightFraction = 0.35f; public float distanceCoveredEstimate; protected PointVariableSubsession pvls; //Transform canvasTransform; void Awake() { pvls = GetComponentInParent(); //canvasTransform = pvls.canvas.GetComponent(); } public void OnVariableSelected(int vi) { GenerateMeshes(); } public void OnScaleFactorChanged(float f) { ScaleMeshes(); } void ComputeSatelliteSpeed() { int sampleInterval = Math.Min(preferredSampleInterval, pvls.data.dataPoints.Count - 1); DateTime firstTimestamp = pvls.data.dataPoints[0].time; DateTime lastTimestamp = pvls.data.dataPoints[sampleInterval].time; int timeInterval = (int)(lastTimestamp - firstTimestamp).TotalSeconds; var dp1 = pvls.data.dataPoints[0]; float val1 = dp1.variables[pvls.variableIndex]; Vector3 geoCoords1 = new Vector3(dp1.longitude, dp1.latitude, heightGap); Vector3 firstPos = Utils.DegLonLatHgtToXYZ(geoCoords1, true); var dp2 = pvls.data.dataPoints[sampleInterval]; float val2 = dp2.variables[pvls.variableIndex]; Vector3 geoCoords2 = new Vector3(dp2.longitude, dp2.latitude, heightGap); Vector3 lastPos = Utils.DegLonLatHgtToXYZ(geoCoords2, true); float angle = Mathf.Abs(Vector3.Angle(firstPos, lastPos)); float anglePerSec = angle / timeInterval; float distancePerSec = anglePerSec * (float)Math.PI * 2.0f; float panelH = ((float)Screen.height) * hist2dHeightFraction; distanceCoveredEstimate = panelH * distancePerSec /* * canvasTransform.localScale.x*/ ; Debug.Log($"SliderScale: {pvls.scaleFactor} distanceCoveredEstimate: {distanceCoveredEstimate}"); } void GenerateMeshes() { var mesh = new Mesh(); mesh.name = pvls.prodvar.name; ComputeSatelliteSpeed(); float valscale = distanceCoveredEstimate * (pvls.scaleFactor * scaleFactor) / pvls.prodvar.scaledRange; List verts = new List(); List colors = new List(); List inds = new List(); // also create a mesh for POINTs var pmesh = new Mesh(); pmesh.name = pvls.prodvar.name; List pverts = new List(); //List pcolors = new List(); List pinds = new List(); foreach (var dp in pvls.data.dataPoints) { float val = dp.variables[pvls.variableIndex]; float scaledElevation = (val - pvls.prodvar.scaledMinValue) * valscale; Vector3 geoCoords = new Vector3(dp.longitude, dp.latitude, heightGap); Vector3 xyzBott = Utils.DegLonLatHgtToXYZ(geoCoords, true); geoCoords = new Vector3(dp.longitude, dp.latitude, heightGap + scaledElevation); Vector3 xyzTop = Utils.DegLonLatHgtToXYZ(geoCoords, true); Color finalLineColor = pvls.GetDataPointColor(dp); verts.Add(xyzBott); colors.Add(finalLineColor); inds.Add(inds.Count); verts.Add(xyzTop); colors.Add(finalLineColor); inds.Add(inds.Count); pverts.Add(xyzTop); //pcolors.Add(pointColor); pinds.Add(pinds.Count); } mesh.vertices = verts.ToArray(); mesh.colors = colors.ToArray(); mesh.SetIndices(inds.ToArray(), MeshTopology.Lines, 0, true); linesMeshFilter.mesh = mesh; pmesh.vertices = pverts.ToArray(); //pmesh.colors = pcolors.ToArray(); pmesh.SetIndices(pinds.ToArray(), MeshTopology.Points, 0, true); pointsMeshFilter.mesh = pmesh; } void ScaleMeshes() { ComputeSatelliteSpeed(); Vector3[] verts = linesMeshFilter.mesh.vertices; Vector3[] pverts = pointsMeshFilter.mesh.vertices; //Debug.Log($"SliderScale: {pvls.scaleFactor} distanceCoveredEstimate: {distanceCoveredEstimate}"); float valscale = distanceCoveredEstimate * (pvls.scaleFactor * scaleFactor) / pvls.prodvar.scaledRange; //float valscale = (pvls.scaleFactor * scaleFactor) / pvls.prodvar.scaledRange; int i = 0; foreach (var dp in pvls.data.dataPoints) { float val = dp.variables[pvls.variableIndex]; float elev = (val - pvls.prodvar.scaledMinValue) * valscale; Vector3 geoCoords = new Vector3(dp.longitude, dp.latitude, heightGap + elev); Vector3 xyzTop = Utils.DegLonLatHgtToXYZ(geoCoords, true); verts[i * 2 + 1] = xyzTop; pverts[i] = xyzTop; i++; } linesMeshFilter.mesh.vertices = verts; linesMeshFilter.mesh.RecalculateBounds(); pointsMeshFilter.mesh.vertices = pverts; pointsMeshFilter.mesh.RecalculateBounds(); } public void OnScreenSizeChanged() { ScaleMeshes(); } }