/// <summary> /// Calculate "distance" of cloud at determined pose /// TODO - It's actually slower than SISD. Need more parallelism. /// </summary> /// <param name="cloud">Cloud of points</param> /// <param name="pose">Pose of cloud</param> /// <returns></returns> private int CalculateDistanceSSE41(ScanCloud cloud, Vector3 pose) { int nb_points = 0; long sum = 0; float px = pose.X * HoleMap.Scale; float py = pose.Y * HoleMap.Scale; float c = MathF.Cos(pose.Z) * HoleMap.Scale; float s = MathF.Sin(pose.Z) * HoleMap.Scale; Vector128 <float> sincos = Vector128.Create(c, -s, s, c); Vector128 <float> posxy = Vector128.Create(px, py, px, py); // Translate and rotate scan to robot position and compute the "distance" for (int i = 0; i < cloud.Points.Count; i++) { Vector128 <float> xy = Vector128.Create(cloud.Points[i].X, cloud.Points[i].Y, cloud.Points[i].X, cloud.Points[i].Y); xy = Sse41.Multiply(sincos, xy); xy = Sse41.HorizontalAdd(xy, xy); xy = Sse41.Add(xy, posxy); xy = Sse41.RoundToNearestInteger(xy); int x = (int)xy.GetElement(0); int y = (int)xy.GetElement(1); // Check boundaries if ((x >= 0) && (x < HoleMap.Size) && (y >= 0) && (y < HoleMap.Size)) { sum += HoleMap.Pixels[y * HoleMap.Size + x]; nb_points++; } } if (nb_points > 0) { return((int)((sum * 1024) / cloud.Points.Count)); } else { return(int.MaxValue); } }