6 using System.Collections.Generic;
11 #if UNITY_2017_2_OR_NEWER 28 [Tooltip(
"Indicate the time in seconds between mesh imports, during the scanning phase. A value of zero will disable pulling meshes from the DLL")]
29 public float ImportMeshPeriod = 1.0f;
32 [Tooltip(
"Material used to render the custom mesh generated by the DLL")]
33 private Material meshMaterial;
35 public Material MeshMaterial
47 for (
int i = 0; i < SurfaceObjects.Count; ++i)
49 SurfaceObjects[i].Renderer.sharedMaterial = meshMaterial;
58 [Tooltip(
"Max time per frame in milliseconds to spend processing the mesh")]
59 public float MaxFrameTime = 5.0f;
60 private float MaxFrameTimeInSeconds
62 get {
return (MaxFrameTime / 1000); }
68 public bool CreateMeshColliders =
true;
70 private bool drawProcessedMesh =
true;
76 public bool DrawProcessedMesh
80 return drawProcessedMesh;
84 drawProcessedMesh = value;
85 for (
int i = 0; i < SurfaceObjects.Count; ++i)
87 SurfaceObjects[i].Renderer.enabled = drawProcessedMesh;
95 public bool HasMeshSectors {
get {
return meshSectors != null && meshSectors.Count > 0; } }
100 public bool IsImportActive {
get;
private set; }
105 protected override Material RenderMaterial {
get {
return MeshMaterial; } }
110 private float timeLastImportedMesh = 0;
121 private Dictionary<Vector3, MeshData> meshSectors =
new Dictionary<Vector3, MeshData>();
127 private class MeshData
132 private readonly List<Vector3> verts =
new List<Vector3>();
133 private readonly List<int> tris =
new List<int>();
138 public readonly Mesh MeshObject =
new Mesh();
144 public MeshCollider SpatialCollider = null;
150 public bool CreateMeshCollider =
false;
169 MeshObject.SetVertices(verts);
170 MeshObject.SetTriangles(tris, 0);
171 MeshObject.RecalculateNormals();
172 MeshObject.RecalculateBounds();
174 SpatialCollider.sharedMesh = null;
175 if (CreateMeshCollider)
177 SpatialCollider.sharedMesh = MeshObject;
178 SpatialCollider.enabled =
true;
182 SpatialCollider.enabled =
false;
193 public void AddTriangle(Vector3 point1, Vector3 point2, Vector3 point3)
200 if (verts.Count < 65000)
202 tris.Add(verts.Count);
205 tris.Add(verts.Count);
208 tris.Add(verts.Count);
213 Debug.LogError(
"Mesh would have more vertices than Unity supports");
222 if (gameObject.GetComponent<WorldAnchor>() == null)
224 gameObject.AddComponent<WorldAnchor>();
229 private void Update()
241 private void AddTriangleToSector(Vector3 sector, Vector3 point1, Vector3 point2, Vector3 point3)
244 MeshData nextSectorData;
245 if (!meshSectors.TryGetValue(sector, out nextSectorData))
247 nextSectorData =
new MeshData();
248 nextSectorData.CreateMeshCollider = CreateMeshColliders;
250 int surfaceObjectIndex = SurfaceObjects.Count;
253 mesh: nextSectorData.MeshObject,
254 objectName:
string.Format(
"SurfaceUnderstanding Mesh-{0}", surfaceObjectIndex),
255 parentObject: transform,
256 meshID: surfaceObjectIndex,
257 drawVisualMeshesOverride: DrawProcessedMesh);
259 nextSectorData.SpatialCollider = surfaceObject.
Collider;
261 AddSurfaceObject(surfaceObject);
264 meshSectors.Add(sector, nextSectorData);
268 nextSectorData.AddTriangle(point1, point2, point3);
277 var stopwatch =
System.Diagnostics.Stopwatch.StartNew();
278 int startFrameCount = Time.frameCount;
285 IsImportActive =
true;
289 Vector3[] meshVertices = null;
290 Vector3[] meshNormals = null;
291 Int32[] meshIndices = null;
301 meshVertices =
new Vector3[vertCount];
302 IntPtr vertPos = dll.
PinObject(meshVertices);
303 meshNormals =
new Vector3[vertCount];
304 IntPtr vertNorm = dll.
PinObject(meshNormals);
305 meshIndices =
new Int32[idxCount];
306 IntPtr indices = dll.
PinObject(meshIndices);
317 if ((meshVertices != null) &&
318 (meshVertices.Length > 0) &&
319 (meshIndices != null) &&
320 (meshIndices.Length > 0))
323 foreach (MeshData meshdata
in meshSectors.Values)
328 float startTime = Time.realtimeSinceStartup;
331 for (
int index = 0; index < meshIndices.Length; index += 3)
333 Vector3 firstVertex = meshVertices[meshIndices[index]];
334 Vector3 secondVertex = meshVertices[meshIndices[index + 1]];
335 Vector3 thirdVertex = meshVertices[meshIndices[index + 2]];
340 Vector3 firstSector = VectorToSector(firstVertex);
342 AddTriangleToSector(firstSector, firstVertex, secondVertex, thirdVertex);
345 Vector3 secondSector = VectorToSector(secondVertex);
346 if (secondSector != firstSector)
348 AddTriangleToSector(secondSector, firstVertex, secondVertex, thirdVertex);
353 Vector3 thirdSector = VectorToSector(thirdVertex);
354 if (thirdSector != firstSector && thirdSector != secondSector)
356 AddTriangleToSector(thirdSector, firstVertex, secondVertex, thirdVertex);
361 if ((index % 30 == 0) && ((Time.realtimeSinceStartup - startTime) > MaxFrameTimeInSeconds))
367 startTime = Time.realtimeSinceStartup;
371 startTime = Time.realtimeSinceStartup;
375 foreach (MeshData meshData
in meshSectors.Values)
381 if ((Time.realtimeSinceStartup - startTime) > MaxFrameTimeInSeconds)
386 startTime = Time.realtimeSinceStartup;
400 IsImportActive =
false;
403 timeLastImportedMesh = Time.time;
406 int deltaFrameCount = (Time.frameCount - startFrameCount + 1);
408 if (stopwatch.Elapsed.TotalSeconds > 0.75)
410 Debug.LogWarningFormat(
"Import_UnderstandingMesh took {0:N0} frames ({1:N3} ms)",
412 stopwatch.Elapsed.TotalMilliseconds
423 private Vector3 VectorToSector(Vector3 vector)
425 return new Vector3(Mathf.FloorToInt(vector.x), Mathf.FloorToInt(vector.y), Mathf.FloorToInt(vector.z));
432 private void Update_MeshImport()
435 if (IsImportActive || (ImportMeshPeriod <= 0.0f) ||
436 ((Time.time - timeLastImportedMesh) < ImportMeshPeriod) ||
442 StartCoroutine(Import_UnderstandingMesh());
445 private void OnDestroy()