Exemplo n.º 1
0
        /// <summary>
        /// Compute position normal mesh
        /// </summary>
        /// <param name="surfaceMesh">The position mesh</param>
        /// <returns>A <see cref="VertexBuffer"/> that represents the surface mesh with normals.</returns>
        private VertexBuffer ComputePositionNormalMesh(SpatialSurfaceMesh surfaceMesh)
        {
            var          surfacePositions = surfaceMesh.VertexPositions;
            var          surfaceNormals   = surfaceMesh.VertexNormals;
            VertexBuffer vertexBuffer     = new VertexBuffer(VertexPositionNormal.VertexFormat);

            VertexPositionNormal[] vertices = new VertexPositionNormal[surfacePositions.ElementCount];

            using (var positionStream = surfacePositions.Data.AsStream())
                using (var normalStream = surfaceNormals.Data.AsStream())
                    using (var positionReader = new BinaryReader(positionStream))
                        using (var normalReader = new BinaryReader(normalStream))
                        {
                            for (int i = 0; i < vertices.Length; i++)
                            {
                                // Read position
                                vertices[i].Position.X = positionReader.ReadSingle();
                                vertices[i].Position.Y = positionReader.ReadSingle();
                                vertices[i].Position.Z = positionReader.ReadSingle();
                                positionReader.ReadSingle(); // Unused 4th float

                                // Read normal
                                vertices[i].Normal.X = normalReader.ReadSingle();
                                vertices[i].Normal.Y = normalReader.ReadSingle();
                                vertices[i].Normal.Z = normalReader.ReadSingle();
                                normalReader.ReadSingle(); // Unused 4th float
                            }
                        }

            vertexBuffer.SetData(vertices);

            return(vertexBuffer);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Update the surface
        /// </summary>
        /// <param name="handler">The handler to receive the surface information</param>
        /// <param name="change">The surface change</param>
        /// <param name="surface">The surface to update</param>
        /// <param name="trianglesPerCubicMeter">The max triangles per cubic meter</param>
        /// <param name="surfaceInfo">The surface info</param>
        /// <param name="surfaceOptions">The mesh options</param>
        private async void UpdateSurface(OnSurfaceChangedHandler handler, SurfaceChange change, SpatialMappingSurfaceInternal surface, float trianglesPerCubicMeter, SpatialSurfaceInfo surfaceInfo, SpatialSurfaceMeshOptions surfaceOptions)
        {
            if (surface.IsProcessing)
            {
                return;
            }

            try
            {
                surface.IsProcessing = true;

                // Generate the mesh from the MixedReality surface info
                SpatialSurfaceMesh surfaceMesh = await surfaceInfo.TryComputeLatestMeshAsync(trianglesPerCubicMeter, surfaceOptions);

                if (surfaceMesh != null && surface.UpdateTime < surfaceMesh.SurfaceInfo.UpdateTime)
                {
                    // Update the surface mesh
                    surface.UpdateSurfaceMesh(surfaceMesh);

                    if (handler != null)
                    {
                        handler(surface.Id, surface, change, surface.UpdateTime);
                    }
                }
            }
            finally
            {
                surface.IsProcessing = false;
            }
        }
Exemplo n.º 3
0
        void UpdateMesh(ref Mesh mesh, SpatialSurfaceMesh src)
        {
            // Extract vertex positions from the mesh buffer
            byte[] data = new byte[src.VertexPositions.Data.Length];
            DataReader.FromBuffer(src.VertexPositions.Data).ReadBytes(data);
            Vertex[] verts = new Vertex[data.Length / (sizeof(float) * 4)];
            int      b     = 0;

            for (int i = 0; i < verts.Length; i++)
            {
                float x = BitConverter.ToSingle(data, b); b += sizeof(float);
                float y = BitConverter.ToSingle(data, b); b += sizeof(float);
                float z = BitConverter.ToSingle(data, b); b += sizeof(float);
                b       += sizeof(float);
                verts[i] = new Vertex {
                    pos = new Vector3(x, y, z) * src.VertexPositionScale,
                    col = Color.White
                };
            }

            // Extract indices from the mesh buffer
            data = new byte[src.TriangleIndices.Data.Length];
            DataReader.FromBuffer(src.TriangleIndices.Data).ReadBytes(data);
            uint[] inds = new uint[data.Length / sizeof(uint)];
            for (int i = 0; i < inds.Length; i += 3)
            {
                inds[i + 2] = BitConverter.ToUInt32(data, (i) * sizeof(uint));
                inds[i + 1] = BitConverter.ToUInt32(data, (i + 1) * sizeof(uint));
                inds[i]     = BitConverter.ToUInt32(data, (i + 2) * sizeof(uint));
            }

            // Update the StereoKit mesh
            mesh.SetVerts(verts);
            mesh.SetInds(inds);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Compute position mesh
        /// </summary>
        /// <param name="surfaceMesh">The position mesh</param>
        /// <returns>A <see cref="VertexBuffer"/> that represents the surface mesh.</returns>
        private VertexBuffer ComputePositionMesh(SpatialSurfaceMesh surfaceMesh)
        {
            var          surfacePositions = surfaceMesh.VertexPositions;
            VertexBuffer vertexBuffer     = new VertexBuffer(VertexPositionW.VertexFormat);

            vertexBuffer.SetData(surfacePositions.Data.ToArray(), (int)surfacePositions.ElementCount);

            return(vertexBuffer);
        }
Exemplo n.º 5
0
        public void CalculateAllVertices(SpatialSurfaceMesh mesh)
        {
            VertexPositionColor[] vertices;
            ushort[]  indices;
            Matrix4x4 transformMatrix;

            CalculateVertices(mesh, out vertices, out indices, out transformMatrix);
            _transformMatrix = transformMatrix;

            SetVertices(vertices, indices);

            NeedsUpdate = true;
        }
Exemplo n.º 6
0
        private void StepUWP()
        {
            // Mesh updates need to be on the main thread. There are plans to
            // make this unnecessary in the future.
            for (int i = 0; i < queuedUpdates.Count; i++)
            {
                SpatialSurfaceMesh s    = queuedUpdates[i];
                SurfaceMesh        mesh = meshes.Find(m => m.id == s.SurfaceInfo.Id);
                UpdateMesh(ref mesh.mesh, s);

                mesh.localTransform = s.CoordinateSystem.TryGetTransformTo(frame.CoordinateSystem) ?? Matrix.Identity;
                mesh.transform      = mesh.localTransform * root;
            }
            queuedUpdates.Clear();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Update surface mesh
        /// </summary>
        /// <param name="spatialSurfaceMesh">The mesh</param>
        internal void UpdateSurfaceMesh(SpatialSurfaceMesh spatialSurfaceMesh)
        {
            this.InternalSurface = spatialSurfaceMesh;

            // Creates the index buffer
            IndexBuffer indexBuffer = this.ComputeIndexbuffer(spatialSurfaceMesh);

            // Creates the VertexBuffer
            VertexBuffer vertexBuffer;

            if (spatialSurfaceMesh.VertexNormals == null)
            {
                vertexBuffer = this.ComputePositionMesh(spatialSurfaceMesh);
            }
            else
            {
                vertexBuffer = this.ComputePositionNormalMesh(spatialSurfaceMesh);
            }

            this.ResetMesh();

            this.Mesh = new Mesh(vertexBuffer, indexBuffer, PrimitiveType.TriangleList)
            {
                Name         = "SpatialMesh",
                DisableBatch = true
            };

            this.UpdateTime = spatialSurfaceMesh.SurfaceInfo.UpdateTime;

            // Update the surface transform
            Vector3    scale       = spatialSurfaceMesh.VertexPositionScale.ToWave();
            Quaternion orientation = Quaternion.Identity;
            Vector3    position    = Vector3.One;

            var referenceTransform = spatialSurfaceMesh.CoordinateSystem.TryGetTransformTo(WaveServices.GetService <MixedRealityService>().ReferenceFrame.CoordinateSystem);

            if (referenceTransform.HasValue)
            {
                Matrix transform;
                referenceTransform.Value.ToWave(out transform);
                position    = transform.Translation;
                orientation = Quaternion.CreateFromRotationMatrix(transform);
            }

            this.Position    = position;
            this.Orientation = orientation;
            this.Scale       = scale;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Compute index buffer
        /// </summary>
        /// <param name="surfaceMesh">The surface mesh</param>
        /// <returns>The index buffer.</returns>
        private IndexBuffer ComputeIndexbuffer(SpatialSurfaceMesh surfaceMesh)
        {
            var surfaceIndices = surfaceMesh.TriangleIndices;
            var indices        = new ushort[surfaceIndices.ElementCount];

            using (var stream = surfaceIndices.Data.AsStream())
                using (var dataReader = new BinaryReader(stream))
                {
                    for (int i = 0; i < indices.Length; i++)
                    {
                        indices[i] = (ushort)dataReader.ReadInt16();
                    }
                }

            return(new IndexBuffer(indices));
        }
Exemplo n.º 9
0
        void CalculateVertices(SpatialSurfaceMesh mesh,
                               out VertexPositionColor[] vertices,
                               out ushort[] indices,
                               out Matrix4x4 finalMatrix)
        {
            var transformMatrix = Matrix4x4.Identity;
            var tryTransform    = mesh.CoordinateSystem.TryGetTransformTo(CoordinateSystem);

            if (tryTransform != null)
            {
                transformMatrix = tryTransform.Value;
            }

            var vertexByteArray = mesh.VertexPositions.Data.ToArray();
            var vertexStride    = (int)mesh.VertexPositions.Stride;
            var vertexCount     = mesh.VertexPositions.ElementCount;

            var triangleIndexByteArray = mesh.TriangleIndices.Data.ToArray();
            var triangleCount          = mesh.TriangleIndices.ElementCount;

            var vertexScale = mesh.VertexPositionScale;
            var scaleMatrix = Matrix4x4.CreateScale(vertexScale);

            finalMatrix = Matrix4x4.Transpose(scaleMatrix * transformMatrix);

            vertices = new VertexPositionColor[vertexCount];
            for (var i = 0; i < vertexCount; i++)
            {
                TranslateVertices(vertices, vertexByteArray, vertexStride, color, i);
            }

            indices = new ushort[triangleCount];

            var indexOffset = 0;

            for (var i = 0; i < triangleCount; i++)
            {
                var index = BitConverter.ToUInt16(triangleIndexByteArray, indexOffset);
                indexOffset += 2;
                indices[i]   = index;
            }
        }
Exemplo n.º 10
0
        public static async void surfaceModified(Guid id, SpatialSurfaceInfo info)
        {
            SpatialSurfaceMesh mesh = await info.TryComputeLatestMeshAsync(2);

            if (mesh != null)
            {
                Vector3   scale               = mesh.VertexPositionScale;
                Matrix4x4 coordinateSystem    = (Matrix4x4)mesh.CoordinateSystem.TryGetTransformTo(currentCoordinateSystem);
                byte[]    vertexPositions     = mesh.VertexPositions.Data.ToArray();
                byte[]    triangleIndices     = mesh.TriangleIndices.Data.ToArray();
                var       triangleIndicesList = new List <int>();
                var       vertexPositionsList = new List <Vector3>();
                for (int i = 0; i < triangleIndices.Length; i += (int)mesh.TriangleIndices.Stride)
                {
                    int j = (int)System.BitConverter.ToUInt16(triangleIndices, i);
                    triangleIndicesList.Add(j);
                }
                for (int i = 0; i < vertexPositions.Length;)
                {
                    float x = (float)System.BitConverter.ToInt16(vertexPositions, i);
                    i += 2;
                    float y = (float)System.BitConverter.ToInt16(vertexPositions, i);
                    i += 2;
                    float z = (float)System.BitConverter.ToInt16(vertexPositions, i);
                    i += 2;
                    float w = (float)System.BitConverter.ToInt16(vertexPositions, i);
                    i += 2;

                    Vector3 position = Vector3.Transform(new Vector3(x / w, y / w, z / w) * scale, coordinateSystem);
                    vertexPositionsList.Add(position / Spritesheet.positionScaleFactor);
                }
                List <Object> message = new List <object>()
                {
                    "surfaceModified", id, vertexPositionsList, triangleIndicesList
                };
                sendMessage(JsonConvert.SerializeObject(message));
            }
        }