So for the past couple days i’ve been working on an AR app that will replace the area that you scan with some arbitrary materials. The goal of the application is just to see how your floor might look with a new tile/rug/whatever without having to go out and buy anything. One thing I was annoyed with was that while ARCore is amazing at surface tracking, it seriously bugged me when it would over scan an area because the contrast in surfaces was too low. So, i figured why not just outline the area that I want to replace? This posed the problem of drawing and editing a polygon at run time. I’m not doing anything fancy, just a bunch of triangles set in place. The markers will be plonked by the user, and move around on the tracked plane.
As you can see, it doesnt work perfectly. something I’d like to change is having the indece location change to the two closest markers, to prevent the entire polygon from disappearing when it detects that you’ve effed up it’s triangles. Another thing I’d like to change a little down the road is so that the shape only updates when the points move. That shouldnt be too difficult, just check if the users touching the screen, or if any of the positions of the markers have changed.
In order to do this, I relied heavily on this script, written by a user named runevision, link below
http://wiki.unity3d.com/index.php?title=Triangulator
Below is the script that I use in order to manipulate the verts of a game object. Just make sure that the gameobject has a mesh renderer, and it should work fine. You can find the code for Triangulator at the link above, I didn’t edit it for my purposes.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FloorMeshOutlineManipulator : MonoBehaviour { #region Variables #endregion #region Unity Functions private void Update() { CreateTheShape(); } #endregion #region Custom Functions private void CreateTheShape() { Mesh mesh = new Mesh(); List<Vector3> userPlacedMarkers = FindPlacementMarkers(); List<Vector2> userPlacedMarkersOnZeroHeight = ConvertMarkerPositionToZeroPlane(userPlacedMarkers); Vector3[] Verticies = CreateVertices(userPlacedMarkersOnZeroHeight.ToArray(),out int[] indeces); mesh.vertices = userPlacedMarkers.ToArray(); mesh.uv = CalculateUVs(Verticies.Length).ToArray(); mesh.triangles = indeces; GetComponent<MeshFilter>().mesh = mesh; } private List<Vector3> FindPlacementMarkers() { List<Vector3> tempVertHolder = new List<Vector3>(); foreach (GameObject markerPos in GameObject.FindGameObjectsWithTag("MeshMorpherMarker")) tempVertHolder.Add(markerPos.transform.position); return tempVertHolder; } private List<Vector2> ConvertMarkerPositionToZeroPlane(List<Vector3> markerPositions) { List<Vector2> positionsOnPlane = new List<Vector2>(); foreach (Vector3 x in markerPositions) positionsOnPlane.Add(new Vector2(x.x, x.z)); return positionsOnPlane; } private Vector3[] CreateVertices(Vector2[] pointsOnPlane, out int[] indeces) { List<Vector3> markerPositions = FindPlacementMarkers(); Vector3[] verticies = new Vector3[markerPositions.Count]; Triangulator tr = new Triangulator(pointsOnPlane); indeces = tr.Triangulate(); for (int i = 0; i < verticies.Length; i++) verticies[i] = new Vector3(markerPositions[i].x, 0, markerPositions[i].z); return verticies; } private List<Vector2> CalculateUVs(int numberOfIndices) { List<Vector2> uvs = new List<Vector2>(); for (int i = 0; i < numberOfIndices; i++) uvs.Add(Vector2.zero); return uvs; } #endregion }