/// <summary>
        /// Clear a condition from the active list - Used only for simple Conditions.
        /// </summary>
        /// <param name="code">The native code</param>
        /// <returns>true if the activation is found</returns>
        public bool Clear(string code)
        {
            // Find the activation.
            Active found = mActiveList.Find(delegate(Active ak) { return(ak.mNativeCode == code); });

            if (found != null)
            {
                // If we've removed the last activation, go back to normal.
                if (mActiveList.Count == 1)
                {
                    Add(Level.NORMAL);
                }
                else
                {
                    // Otherwise, just clear this one.
                    found.Set(Level.NORMAL);
                    // Clear makes the activation be removed next sweep.
                    found.Clear();
                }
                mChanged = true;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 2
0
        public bool Clear(string code)
        {
            Active active = this.mActiveList.Find(ak => ak.mNativeCode == code);

            if (active != null)
            {
                if (this.mActiveList.Count <Active>() == 1)
                {
                    this.Add(Level.NORMAL, "", "", "", "");
                }
                else
                {
                    active.Set(Level.NORMAL, "", "", "");
                    active.Clear();
                }
                base.mChanged = true;
                return(true);
            }
            return(false);
        }
Exemplo n.º 3
0
        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;
        }