private GameObject GetPositionOnSurface(Ray ray, PointCloud cloud, Vector3 cameraPos, out int xIndex, out int yIndex, out float zIndex) { xIndex = 0; yIndex = 0; zIndex = 0; RenderedCloudContainer container = pointCloudContainer.GetComponent <RenderedCloudContainer>(); // TODO: Need a KD Tree or something to speed up this O(n^2) solution: Vector3 p00 = container.GetPointObject(0, 0).transform.position; Vector3 p11 = container.GetPointObject(1, 1).transform.position; p00.y = 0; p11.y = 0; float distThreshold = Vector3.Distance(p00, p11) / 2f; // Get points close to ray List <Point> points = new List <Point>(); for (int y = 0; y < container.Height; y++) { for (int x = 0; x < container.Width; x++) { float dist = Vector3.Cross(ray.direction, container.GetPointObject(x, y).transform.position - ray.origin).magnitude; if (dist < distThreshold) { points.Add(container.GetPointCloudPosition(x, y)); } } } // Debug.Log("Selected Points:" + points.Count); // foreach (var p in points) // { // Debug.Log(string.Format("({0}, {1})", p.X, p.Y)); // } if (points.Count == 0) { return(null); } // Order Points by closest to camera points = points.OrderBy(o => Vector3.Distance(container.GetPointObject(o.X, o.Y).transform.position, cameraPos)).ToList(); xIndex = points[0].X; yIndex = points[0].Y; return(container.GetPointObject(points[0].X, points[0].Y)); }
// Update is called once per frame void Update() { if (pointCloud == null) { return; } if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject()) { isEditing = true; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); int xi, yi; float zi; GameObject point = GetPositionOnSurface(ray, pointCloud, Camera.main.transform.position, out xi, out yi, out zi); if (tool == Tools.MINUTIAE_3D) { currentFeature = Instantiate(minutiaePrefab, point.transform.position, Quaternion.identity); currentFeature.transform.localScale = point.transform.localScale; Minutiae3D minutiae = currentFeature.GetComponent <Minutiae3D>(); minutiae.X = xi; minutiae.Y = yi; minutiae.Z = zi; features.Add(currentFeature); } else if (tool == Tools.DELETE) { int best = -1; float bestDist = float.PositiveInfinity; for (int i = 0; i < features.Count; i++) { float dist = Vector3.Cross(ray.direction, features[i].transform.position - ray.origin).magnitude; if (dist < bestDist) { best = i; bestDist = dist; } } Vector3 p00 = cloudContainer.GetPointObject(0, 0).transform.position; Vector3 p11 = cloudContainer.GetPointObject(1, 1).transform.position; p00.y = 0; p11.y = 0; float distThreshold = Vector3.Distance(p00, p11) / 2f; if (bestDist < distThreshold) { Destroy(features[best]); features.RemoveAt(best); } } } else if (Input.GetMouseButton(0) && isEditing) { if (tool == Tools.MINUTIAE_3D) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); float dist = Vector3.Distance(Camera.main.transform.position, currentFeature.transform.position); currentFeature.transform.LookAt(ray.GetPoint(dist)); } } else if (Input.GetMouseButtonUp(0) && isEditing) { isEditing = false; currentFeature = null; } }