/// <summary> /// /// </summary> /// <param name="control"></param> public override void Load(Control control) { base.Load(control); camera = new PerspectiveCamera(27, control.Width / (float)control.Height, 5, 3500); this.camera.Position.Z = 2750; scene = new Scene(); scene.Fog = new Fog((Color)colorConvertor.ConvertFromString("#050505"), 2000, 3500); // const int Particles = 500000; var positions = new float[Particles * 3]; var colors = new float[Particles * 3]; var n = 1000; var n2 = n / 2; // particles spread in the cube for (var i = 0; i < positions.Length; i += 3) { // positions var x = Mat.Random() * n - n2; var y = Mat.Random() * n - n2; var z = Mat.Random() * n - n2; positions[i + 0] = x; positions[i + 1] = y; positions[i + 2] = z; // colors var vx = (x / n) + 0.5f; var vy = (y / n) + 0.5f; var vz = (z / n) + 0.5f; colors[i + 0] = vx; colors[i + 1] = vy; colors[i + 2] = vz; } var geometry = new BufferGeometry(); geometry.AddAttribute("position", new BufferAttribute <float>(positions, 3)); geometry.AddAttribute("color", new BufferAttribute <float>(colors, 3)); geometry.ComputeBoundingSphere(); // var material = new PointCloudMaterial() { Size = 15, VertexColors = Three.VertexColors }; particleSystem = new PointCloud(geometry, material); scene.Add(particleSystem); // renderer.SetClearColor(scene.Fog.Color); }
public override void Reset() { Active.ForEach(req => { req.Readback.WaitForCompletion(); req.TextureSet.Release(); }); Active.Clear(); Jobs.ForEach(job => job.Complete()); Jobs.Clear(); foreach (var tex in AvailableRenderTextures) { tex.Release(); } ; AvailableRenderTextures.Clear(); foreach (var tex in AvailableTextures) { Destroy(tex); } ; AvailableTextures.Clear(); if (PointCloudBuffer != null) { PointCloudBuffer.Release(); PointCloudBuffer = null; } if (Points.IsCreated) { Points.Dispose(); } AngleStart = 0.0f; // Assuming center of view frustum is horizontal, find the vertical FOV (of view frustum) that can encompass the tilted Lidar FOV. // "MaxAngle" is half of the vertical FOV of view frustum. if (VerticalRayAngles.Count == 0) { MaxAngle = Mathf.Abs(CenterAngle) + FieldOfView / 2.0f; StartLatitudeAngle = 90.0f + MaxAngle; //If the Lidar is tilted up, ignore lower part of the vertical FOV. if (CenterAngle < 0.0f) { StartLatitudeAngle -= MaxAngle * 2.0f - FieldOfView; } EndLatitudeAngle = StartLatitudeAngle - FieldOfView; } else { LaserCount = VerticalRayAngles.Count; StartLatitudeAngle = 90.0f - VerticalRayAngles.Min(); EndLatitudeAngle = 90.0f - VerticalRayAngles.Max(); FieldOfView = StartLatitudeAngle - EndLatitudeAngle; MaxAngle = Mathf.Max(StartLatitudeAngle - 90.0f, 90.0f - EndLatitudeAngle); } float startLongitudeAngle = 90.0f + HorizontalAngleLimit / 2.0f; SinStartLongitudeAngle = Mathf.Sin(startLongitudeAngle * Mathf.Deg2Rad); CosStartLongitudeAngle = Mathf.Cos(startLongitudeAngle * Mathf.Deg2Rad); // The MaxAngle above is the calculated at the center of the view frustum. // Because the scan curve for a particular laser ray is a hyperbola (intersection of a conic surface and a vertical plane), // the vertical FOV should be enlarged toward left and right ends. float startFovAngle = CalculateFovAngle(StartLatitudeAngle, startLongitudeAngle); float endFovAngle = CalculateFovAngle(EndLatitudeAngle, startLongitudeAngle); MaxAngle = Mathf.Max(MaxAngle, Mathf.Max(startFovAngle, endFovAngle)); // Calculate sin/cos of latitude angle of each ray. if (SinLatitudeAngles.IsCreated) { SinLatitudeAngles.Dispose(); } if (CosLatitudeAngles.IsCreated) { CosLatitudeAngles.Dispose(); } SinLatitudeAngles = new NativeArray <float>(LaserCount, Allocator.Persistent); CosLatitudeAngles = new NativeArray <float>(LaserCount, Allocator.Persistent); int totalCount = LaserCount * MeasurementsPerRotation; PointCloudBuffer = new ComputeBuffer(totalCount, UnsafeUtility.SizeOf <Vector4>()); PointCloudMaterial?.SetBuffer("_PointCloud", PointCloudBuffer); Points = new NativeArray <Vector4>(totalCount, Allocator.Persistent); CurrentLaserCount = LaserCount; CurrentMeasurementsPerRotation = MeasurementsPerRotation; CurrentFieldOfView = FieldOfView; CurrentVerticalRayAngles = new List <float>(VerticalRayAngles); CurrentCenterAngle = CenterAngle; CurrentMinDistance = MinDistance; CurrentMaxDistance = MaxDistance; IgnoreNewRquests = 0; // If VerticalRayAngles array is not provided, use uniformly distributed angles. if (VerticalRayAngles.Count == 0) { float deltaLatitudeAngle = FieldOfView / LaserCount; int index = 0; float angle = StartLatitudeAngle; while (index < LaserCount) { SinLatitudeAngles[index] = Mathf.Sin(angle * Mathf.Deg2Rad); CosLatitudeAngles[index] = Mathf.Cos(angle * Mathf.Deg2Rad); index++; angle -= deltaLatitudeAngle; } } else { for (int index = 0; index < LaserCount; index++) { SinLatitudeAngles[index] = Mathf.Sin((90.0f - VerticalRayAngles[index]) * Mathf.Deg2Rad); CosLatitudeAngles[index] = Mathf.Cos((90.0f - VerticalRayAngles[index]) * Mathf.Deg2Rad); } } int count = Mathf.CeilToInt(HorizontalAngleLimit / (360.0f / MeasurementsPerRotation)); float deltaLongitudeAngle = (float)HorizontalAngleLimit / (float)count; SinDeltaLongitudeAngle = Mathf.Sin(deltaLongitudeAngle * Mathf.Deg2Rad); CosDeltaLongitudeAngle = Mathf.Cos(deltaLongitudeAngle * Mathf.Deg2Rad); // Enlarged the texture by some factors to mitigate alias. RenderTextureHeight = 16 * Mathf.CeilToInt(2.0f * MaxAngle * LaserCount / FieldOfView); RenderTextureWidth = 8 * Mathf.CeilToInt(HorizontalAngleLimit / (360.0f / MeasurementsPerRotation)); // View frustum size at the near plane. float frustumWidth = 2 * MinDistance * Mathf.Tan(HorizontalAngleLimit / 2.0f * Mathf.Deg2Rad); float frustumHeight = 2 * MinDistance * Mathf.Tan(MaxAngle * Mathf.Deg2Rad); XScale = frustumWidth / RenderTextureWidth; YScale = frustumHeight / RenderTextureHeight; // construct custom aspect ratio projection matrix // math from https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix float v = 1.0f / Mathf.Tan(MaxAngle * Mathf.Deg2Rad); float h = 1.0f / Mathf.Tan(HorizontalAngleLimit * Mathf.Deg2Rad / 2.0f); float a = (MaxDistance + MinDistance) / (MinDistance - MaxDistance); float b = 2.0f * MaxDistance * MinDistance / (MinDistance - MaxDistance); var projection = new Matrix4x4( new Vector4(h, 0, 0, 0), new Vector4(0, v, 0, 0), new Vector4(0, 0, a, -1), new Vector4(0, 0, b, 0)); SensorCamera.nearClipPlane = MinDistance; SensorCamera.farClipPlane = MaxDistance; SensorCamera.projectionMatrix = projection; }