Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        async Task ProcessSurface(SpatialSurfaceInfo surface, bool convertToLH)
        {
            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;
            }

            // convert from RH to LH coordinate system
            int rhToLh = convertToLH ? -1 : 1;

            //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];

            //2,3 - VertexPositions and Normals
            for (int i = 0; i < vertexCount; i++)
            {
                //VertexPositions: DirectXPixelFormat.R16G16B16A16IntNormalized
                short x = BitConverter.ToInt16(vertexRawData, i * 8 + 0);
                short y = BitConverter.ToInt16(vertexRawData, i * 8 + 2);
                short z = BitConverter.ToInt16(vertexRawData, i * 8 + 4);

                //short to float:
                float xx = (x == -32768) ? -1.0f : x * 1.0f / (32767.0f);
                float yy = (y == -32768) ? -1.0f : y * 1.0f / (32767.0f);
                float zz = (z == -32768) ? -1.0f : z * 1.0f / (32767.0f);

                //Normals: DirectXPixelFormat.R8G8B8A8IntNormalized
                var normalX = normalsRawData[i * 4 + 0];
                var normalY = normalsRawData[i * 4 + 1];
                var normalZ = normalsRawData[i * 4 + 2];

                //merge vertex+normals for Urho3D (also, change RH to LH coordinate systems)
                vertexData[i].PositionX = xx * vertexScale.X;
                vertexData[i].PositionY = yy * vertexScale.Y;
                vertexData[i].PositionZ = rhToLh * zz * vertexScale.Z;
                vertexData[i].NormalX   = normalX == 0 ? 0 :  255 / normalX;
                vertexData[i].NormalY   = normalY == 0 ? 0 :  255 / normalY;
                vertexData[i].NormalZ   = normalZ == 0 ? 0 : rhToLh * 255 / normalZ;

                //Vertex color
                vertexData[i].ColorUint = vertexColor;
            }

            var boundsRotation = new Quaternion(rhToLh * bounds.Value.Orientation.X, rhToLh * bounds.Value.Orientation.Y, bounds.Value.Orientation.Z, bounds.Value.Orientation.W);
            var boundsCenter   = new Vector3(bounds.Value.Center.X, bounds.Value.Center.Y, rhToLh * 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; }

            var surfaceInfo = new HoloLens.SpatialMeshInfo
            {
                SurfaceId      = surface.Id.ToString(),
                Date           = surface.UpdateTime,
                VertexData     = vertexData,
                IndexData      = indeces,
                BoundsCenter   = boundsCenter,
                BoundsRotation = boundsRotation,
                Extents        = boundsExtents,
                Transform      = transformUrhoMatrix,
            };

            currentHoloApp.HandleSurfaceUpdated(surfaceInfo);
        }