internal void HandleSurfaceUpdated(SpatialMeshInfo surface) { var model = GenerateModelFromSpatialSurface(surface); InvokeOnMain(() => OnSurfaceAddedOrUpdated(surface, model)); }
public virtual void OnSurfaceAddedOrUpdated(SpatialMeshInfo surface, Model generatedModel) { }
/// <summary> /// NOTE: called from a background thread /// </summary> public virtual Model GenerateModelFromSpatialSurface(SpatialMeshInfo surface) { return(CreateModelFromVertexData(surface.VertexData, surface.IndexData)); }
async Task ProcessSurface(SpatialSurfaceInfo surface) { var mesh = await surface.TryComputeLatestMeshAsync(trianglesPerCubicMeter, options).AsTask().ConfigureAwait(false); if (observer == null || mesh == null) { RemoveSurfaceFromCache(surface.Id); return; } var bounds = mesh.SurfaceInfo.TryGetBounds(currentCoordinateSystem); if (bounds == null) { RemoveSurfaceFromCache(surface.Id); return; } var transform = mesh.CoordinateSystem.TryGetTransformTo(currentCoordinateSystem); if (transform == null) { RemoveSurfaceFromCache(surface.Id); return; } //1. TriangleIndices var trianglesBytes = mesh.TriangleIndices.Data.ToArray(); var indeces = new short[mesh.TriangleIndices.ElementCount]; int indexOffset = 0; for (int i = 0; i < mesh.TriangleIndices.ElementCount; i++) { //DirectXPixelFormat.R16UInt var index = BitConverter.ToInt16(trianglesBytes, indexOffset); indexOffset += 2; indeces[i] = index; } var vertexCount = mesh.VertexPositions.ElementCount; var vertexRawData = mesh.VertexPositions.Data.ToArray(); var vertexScale = mesh.VertexPositionScale; var normalsRawData = mesh.VertexNormals.Data.ToArray(); var vertexColor = DefaultColor.ToUInt(); var vertexData = new SpatialVertex[vertexCount]; var boundsRotation = new Quaternion(-bounds.Value.Orientation.X, -bounds.Value.Orientation.Y, bounds.Value.Orientation.Z, bounds.Value.Orientation.W); var boundsCenter = new Vector3(bounds.Value.Center.X, bounds.Value.Center.Y, -bounds.Value.Center.Z); var boundsExtents = new Vector3(bounds.Value.Extents.X, bounds.Value.Extents.Y, bounds.Value.Extents.Z); var transformValue = transform.Value; Matrix4 transformUrhoMatrix; unsafe { transformUrhoMatrix = *(Matrix4 *)(void *)&transformValue; } //these values won't change, let's declare them as consts const int vertexStride = 16; // (int) mesh.VertexPositions.Stride; const int normalStride = 16; // (int) mesh.VertexNormals.Stride; //2,3 - VertexPositions and Normals for (int i = 0; i < vertexCount; i++) { var positionX = BitConverter.ToSingle(vertexRawData, i * vertexStride + 0); var positionY = BitConverter.ToSingle(vertexRawData, i * vertexStride + 4); //4 per X,Y,Z,W (stride is 16) var positionZ = BitConverter.ToSingle(vertexRawData, i * vertexStride + 8); //also, we don't need the W component. var normalX = BitConverter.ToSingle(normalsRawData, i * normalStride + 0); var normalY = BitConverter.ToSingle(normalsRawData, i * normalStride + 4); var normalZ = BitConverter.ToSingle(normalsRawData, i * normalStride + 8); //merge vertex+normals for Urho3D (also, change RH to LH coordinate systems) vertexData[i].PositionX = positionX * vertexScale.X; vertexData[i].PositionY = positionY * vertexScale.Y; vertexData[i].PositionZ = -positionZ * vertexScale.Z; vertexData[i].NormalX = normalX; vertexData[i].NormalY = normalY; vertexData[i].NormalZ = -normalZ; //Vertex color (for VCol techniques) vertexData[i].ColorUint = vertexColor; } var surfaceInfo = new SharpReality.SpatialMeshInfo { SurfaceId = surface.Id.ToString(), Date = surface.UpdateTime, VertexData = vertexData, IndexData = indeces, BoundsCenter = boundsCenter, BoundsRotation = boundsRotation, Extents = boundsExtents, Transform = transformUrhoMatrix, }; currentHoloApp.HandleSurfaceUpdated(surfaceInfo); }