/// <summary>
        ///
        /// Meshes
        ///
        /// Parse mesh data
        /// Function decides if we are updating an already existing mesh or creating a new one.
        /// If a new mesh has been created this function will go through stored mesh instances
        /// and check if it can create new mesh instances.
        /// </summary>
        public static void ParseMeshData(System.IntPtr meshDataPtr)
        {
            try
            {
                var meshData = (MeshData)System.Runtime.InteropServices.Marshal.PtrToStructure(meshDataPtr, typeof(MeshData));

                // Convert unmanaged to managed memory
                ManagedMeshData managedMeshData = MeshHandler.ManageMeshMemory(meshData);

                // If all dependants are here, create or update the mesh
                bool dependencySuccess = MeshHandler.DependencyCheck(managedMeshData, meshData.entityToken);
                if (dependencySuccess)
                {
                    ParseMeshData(meshData, managedMeshData);

                    // Delete the data
                    ImportMenu.stpUnityDeleteMeshData(meshDataPtr);
                }
                else
                {
                    // If we are not able to create or update store the mesh data and try later
                    meshDataStore.Add(meshDataPtr);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);

                // Delete the data
                ImportMenu.stpUnityDeleteMeshData(meshDataPtr);
            }
        }
        public static void CreateAndSendMeshInstanceRequest(
            GameObject meshInstanceObj,
            string instanceToken,
            string meshToken,
            string parentToken)
        {
            MeshInstanceData meshInstanceData = new MeshInstanceData();

            meshInstanceData.displayName       = meshInstanceObj.name;
            meshInstanceData.entityToken       = instanceToken;
            meshInstanceData.entityParentToken = parentToken;
            meshInstanceData.originalMesh      = meshToken;

            // Add transformation
            meshInstanceData.xform = MarshalData.GetXFormToUnmanagedArray(meshInstanceObj.transform.localToWorldMatrix);

            System.IntPtr meshInstanceDataPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(meshInstanceData));
            System.Runtime.InteropServices.Marshal.StructureToPtr(meshInstanceData, meshInstanceDataPtr, false);

            Debug.LogFormat("Mesh Instance Push - Token:{0}, Parent:{1}, Mesh:{2}", meshInstanceData.entityToken, meshInstanceData.entityParentToken, meshInstanceData.originalMesh);
            ImportMenu.stpUnitySendMeshInstanceData(meshInstanceDataPtr);

            // Free allocated memory
            System.Runtime.InteropServices.Marshal.FreeHGlobal(meshInstanceData.xform);
            System.Runtime.InteropServices.Marshal.FreeHGlobal(meshInstanceDataPtr);
        }
        /// <summary>
        ///
        /// Material definitions
        ///
        /// Parse material definitions data
        /// Starts material definition node parsing.
        /// If a new material has been created this function will go through stored meshes
        /// and check if it can create new mesh with this material available.
        /// </summary>
        public static void ParseMaterialDefinitionData(System.IntPtr materialDefinitionDataPtr)
        {
            try
            {
                var materialDefinitionData = (MaterialDefinitionData)System.Runtime.InteropServices.Marshal.PtrToStructure(materialDefinitionDataPtr, typeof(MaterialDefinitionData));

                // If all dependants are here, parse object data
                bool dependencySuccess = MaterialDefinitionHandler.DependencyCheck(materialDefinitionData);
                if (dependencySuccess)
                {
                    ParseMaterialDefinitionData(materialDefinitionData);

                    // Delete object data
                    ImportMenu.stpUnityDeleteMaterialDefinitionData(materialDefinitionDataPtr);
                }
                // If we are missing dependants store the object data
                else
                {
                    materialDefinitionDataStore.Add(materialDefinitionDataPtr);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);

                // Delete object data
                ImportMenu.stpUnityDeleteMaterialDefinitionData(materialDefinitionDataPtr);
            }
        }
Beispiel #4
0
        static bool CheckInit()
        {
            if (!ImportMenu.stpUnityIsClientRunning())
            {
                return(true);
            }

            return(false);
        }
Beispiel #5
0
        /// <summary>
        /// Create and send material definition request
        /// Parses data for building of material deifintion request
        /// and invokes native plugin to send the request to the server
        /// </summary>
        public static void CreateAndSendMaterialDefinitionRequest(Material material, string token)
        {
            MaterialDefinitionData materialDefinitionData = new MaterialDefinitionData();

            materialDefinitionData.displayName = material.name;
            materialDefinitionData.entityToken = token;

            System.IntPtr materialDefinitionDataPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(materialDefinitionData));
            System.Runtime.InteropServices.Marshal.StructureToPtr(materialDefinitionData, materialDefinitionDataPtr, false);

            Debug.LogFormat("Material Definition Push - Token:{0}", materialDefinitionData.entityToken);
            ImportMenu.stpUnitySendMaterialDefinitionData(materialDefinitionDataPtr);

            System.Runtime.InteropServices.Marshal.FreeHGlobal(materialDefinitionDataPtr);
        }
        /// <summary>
        ///
        /// Textures
        ///
        /// Parse texture data
        /// Function decides if we are updating an already existing texture or creating a new one.
        /// If a new texture has been created this function will go through stored materials
        /// and check if it can create a new material with this texture available.
        /// </summary>
        public static void ParseTextureData(System.IntPtr textureDataPtr)
        {
            try
            {
                var textureData = (TextureData)System.Runtime.InteropServices.Marshal.PtrToStructure(textureDataPtr, typeof(TextureData));

                // If all dependants are here, create or update the mesh
                ParseTextureData(textureData);
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);
            }

            ImportMenu.stpUnityDeleteTextureData(textureDataPtr);
        }
        /// <summary>
        ///
        /// Cameras
        ///
        /// Parse camera data
        /// Function decides if we are updating an already existing camera or creating a new one.
        /// </summary>
        public static void ParseCameraData(System.IntPtr cameraDataPtr)
        {
            try
            {
                var cameraData = (CameraData)System.Runtime.InteropServices.Marshal.PtrToStructure(cameraDataPtr, typeof(CameraData));

                // Create or update the camera
                ParseCameraData(cameraData);

                // Delete the data
                ImportMenu.stpUnityDeleteCameraData(cameraDataPtr);
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);

                // Delete the data
                ImportMenu.stpUnityDeleteCameraData(cameraDataPtr);
            }
        }
        // Iterate through material store that were missing dependants and check if we can create new material objects
        // or update existing material objects
        public static void IterateMaterialDefinitionStore()
        {
            for (int i = materialDefinitionDataStore.Count - 1; i >= 0; i--)
            {
                MaterialDefinitionData materialDefinitionData = (MaterialDefinitionData)System.Runtime.InteropServices.Marshal.PtrToStructure(materialDefinitionDataStore[i], typeof(MaterialDefinitionData));

                // If all dependants are here, create the material
                bool dependencySuccess = MaterialDefinitionHandler.DependencyCheck(materialDefinitionData);
                if (dependencySuccess)
                {
                    ParseMaterialDefinitionData(materialDefinitionData);

                    // Delete object data
                    ImportMenu.stpUnityDeleteMaterialDefinitionData(materialDefinitionDataStore[i]);

                    // Remove from the store
                    materialDefinitionDataStore.RemoveAt(i);
                }
            }
        }
        // Iterate through mesh store that were missing dependants and check if we can create new mesh objects
        // or update existing mesh objects
        public static void IterateMeshStore()
        {
            for (int i = meshDataStore.Count - 1; i >= 0; i--)
            {
                MeshData meshData = (MeshData)System.Runtime.InteropServices.Marshal.PtrToStructure(meshDataStore[i], typeof(MeshData));

                // Convert unmanaged to managed memory
                ManagedMeshData managedMeshData = MeshHandler.ManageMeshMemory(meshData);

                // If all dependants are here, create or update the mesh
                if (MeshHandler.DependencyCheck(managedMeshData, meshData.entityToken))
                {
                    ParseMeshData(meshData, managedMeshData);

                    // Delete the data
                    ImportMenu.stpUnityDeleteMeshData(meshDataStore[i]);

                    // Remove from the store
                    meshDataStore.RemoveAt(i);
                }
            }
        }
        /// <summary>
        ///
        /// Mesh Instances
        ///
        /// Parse mesh instance data
        /// Function decides if we are updating an already existing mesh instance ( GameObject ) or creating a new one.
        /// </summary>
        public static void ParseMeshInstanceData(System.IntPtr meshInstanceDataPtr)
        {
            try
            {
                var meshInstanceData = (MeshInstanceData)System.Runtime.InteropServices.Marshal.PtrToStructure(meshInstanceDataPtr, typeof(MeshInstanceData));

                // If all dependants are here, create or update the mesh instance
                if (MeshInstanceHandler.DependencyCheck(meshInstanceData))
                {
                    bool newItemCreated;
                    ParseMeshInstanceData(meshInstanceData, out newItemCreated);

                    // Delete the data
                    ImportMenu.stpUnityDeleteMeshInstanceData(meshInstanceDataPtr);

                    // This loop starts over if we created a parent and a child is waiting in the store
                    while (newItemCreated)
                    {
                        // Iterate through mesh instance store and try to create or update
                        // mesh instances that this mesh instance is a dependent of
                        IterateMeshInstanceStore(out newItemCreated);
                    }
                }
                else
                {
                    // If we are not able to create or update store the mesh data and try later
                    meshInstanceDataStore.Add(meshInstanceDataPtr);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);

                // Delete the data
                ImportMenu.stpUnityDeleteMeshInstanceData(meshInstanceDataPtr);
            }
        }
        // Iterate through mesh instance store that were missing dependants
        // and check if we can create new mesh instance objects or update existing mesh objects
        public static void IterateMeshInstanceStore(out bool newItemCreated)
        {
            newItemCreated = false;
            for (int i = meshInstanceDataStore.Count - 1; i >= 0; i--)
            {
                MeshInstanceData meshInstanceData = (MeshInstanceData)System.Runtime.InteropServices.Marshal.PtrToStructure(meshInstanceDataStore[i], typeof(MeshInstanceData));
                // If all dependants are here, create or update the mesh
                bool currentItemCreated = false;
                bool dependencySuccess  = MeshInstanceHandler.DependencyCheck(meshInstanceData);
                if (dependencySuccess)
                {
                    ParseMeshInstanceData(meshInstanceData, out currentItemCreated);

                    // Delete the data
                    ImportMenu.stpUnityDeleteMeshInstanceData(meshInstanceDataStore[i]);

                    // Remove from the store
                    meshInstanceDataStore.RemoveAt(i);
                }

                // True if at least one item was created
                newItemCreated = newItemCreated || currentItemCreated;
            }
        }
        public static void CreateAndSendMeshRequest(Mesh mesh, List <string> materialTokens, string token)
        {
            MeshData meshData = new MeshData();

            meshData.entityToken       = token;
            meshData.entityParentToken = "";
            meshData.displayName       = mesh.name;

            // Add positions, first convert from Unity to STP
            Vector3[] vertices = new Vector3[mesh.vertices.Length];
            System.Array.Copy(mesh.vertices, vertices, mesh.vertices.Length);
            int vertCount = vertices.Length;

            for (int i = vertCount - 1; i >= 0; i--)
            {
                float tempY = vertices[i].y;
                vertices[i].y = -vertices[i].z;
                vertices[i].z = tempY;
                vertices[i].Scale(MarshalData.scaleFromUnitytoSTP);
            }

            System.Runtime.InteropServices.GCHandle pinnedVerticesArray =
                System.Runtime.InteropServices.GCHandle.Alloc(vertices, System.Runtime.InteropServices.GCHandleType.Pinned);
            meshData.positions    = pinnedVerticesArray.AddrOfPinnedObject();
            meshData.positionsNum = (System.UIntPtr)(vertices.Length * verticesDataStride);

            // Add normals
            Vector3[] normals = new Vector3[mesh.normals.Length];
            System.Array.Copy(mesh.normals, normals, mesh.normals.Length);
            int normalCount = mesh.normals.Length;

            for (int i = normalCount - 1; i >= 0; i--)
            {
                float tempY = normals[i].y;
                normals[i].y = -normals[i].z;
                normals[i].z = tempY;
            }

            System.Runtime.InteropServices.GCHandle pinnedNormalsArray =
                System.Runtime.InteropServices.GCHandle.Alloc(normals, System.Runtime.InteropServices.GCHandleType.Pinned);
            meshData.normals    = pinnedNormalsArray.AddrOfPinnedObject();
            meshData.normalsNum = (System.UIntPtr)(normals.Length * normalsDataStride);

            // Add indices
            meshData.facesetsNum = (System.IntPtr)mesh.subMeshCount;
            System.Runtime.InteropServices.GCHandle[] pinnedIndicesArrays = new System.Runtime.InteropServices.GCHandle[(int)meshData.facesetsNum];

            // Add facesets
            FacesetData[] faceSets   = new FacesetData[(int)meshData.facesetsNum];
            int           structSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(FacesetData));

            meshData.facesets = System.Runtime.InteropServices.Marshal.AllocHGlobal((int)meshData.facesetsNum * structSize);
            System.IntPtr facesetsPtr = meshData.facesets;

            // Change the winding order of indices
            int[][] indices     = new int[(int)meshData.facesetsNum][];
            var     materialNum = materialTokens.Count;

            for (var i = 0; i < (int)meshData.facesetsNum; ++i)
            {
                int[] indicesList = mesh.GetTriangles(i);
                indices[i] = new int[indicesList.Length];
                for (var indicePos = 0; indicePos < indicesList.Length; indicePos += indicesStride)
                {
                    indices[i][indicePos + 0] = indicesList[indicePos + 0];
                    indices[i][indicePos + 1] = indicesList[indicePos + 2];
                    indices[i][indicePos + 2] = indicesList[indicePos + 1];
                }

                pinnedIndicesArrays[i] =
                    System.Runtime.InteropServices.GCHandle.Alloc(
                        indices[i],
                        System.Runtime.InteropServices.GCHandleType.Pinned
                        );
                faceSets[i].indices = pinnedIndicesArrays[i].AddrOfPinnedObject();

                // Marshaling needs to use UIntPtr for size_t
                int indicesNum = indicesList.Length;
                //faceSets[i].indicesNum = (System.UIntPtr)indicesNum;
                faceSets[i].indicesNum = (ulong)indicesNum;

                // Marshal material tokens
                if (i < materialNum)
                {
                    faceSets[i].materialName = materialTokens[i];
                }
                else
                {
                    faceSets[i].materialName = "";
                }

                System.Runtime.InteropServices.Marshal.StructureToPtr(faceSets[i], facesetsPtr, false);
                facesetsPtr = (System.IntPtr)((long)facesetsPtr + structSize);
            }

            // Add UVs
            List <Vector2>[] meshUVs = new List <Vector2> [maxUV];
            int uvCount = 0;

            for (int i = 0; i < maxUV; i++)
            {
                meshUVs[i] = new List <Vector2>();
                mesh.GetUVs(i, meshUVs[i]);

                if (meshUVs[i].Count == 0)
                {
                    break;
                }

                uvCount++;
            }

            UVData[]  uvSets    = new UVData[uvCount];
            float[][] uvDataArr = new float[uvCount][];
            structSize        = System.Runtime.InteropServices.Marshal.SizeOf(typeof(UVData));
            meshData.uvSetNum = (System.IntPtr)uvCount;
            meshData.uvSets   = System.Runtime.InteropServices.Marshal.AllocHGlobal(uvCount * structSize);
            System.IntPtr uvSetsPtr = meshData.uvSets;

            System.Runtime.InteropServices.GCHandle[] pinnedUVArrays = new System.Runtime.InteropServices.GCHandle[uvCount];

            for (int i = 0; i < uvCount; i++)
            {
                uvDataArr[i] = new float[meshUVs[i].Count * uvDataStride];

                for (int uvInd = 0; uvInd < meshUVs[i].Count; uvInd++)
                {
                    int uvDataInd = uvInd * uvDataStride;
                    uvDataArr[i][uvDataInd]     = meshUVs[i][uvInd].x;
                    uvDataArr[i][uvDataInd + 1] = 1.0f - meshUVs[i][uvInd].y; // Convert UV from Unity to STP
                }

                // We are not using UV indices due to Unity not supporting them
                uvSets[i].indicesNum = 0;

                pinnedUVArrays[i] =
                    System.Runtime.InteropServices.GCHandle.Alloc(
                        uvDataArr[i],
                        System.Runtime.InteropServices.GCHandleType.Pinned
                        );
                uvSets[i].uvs    = pinnedUVArrays[i].AddrOfPinnedObject();
                uvSets[i].uvsNum = (ulong)uvDataArr[i].Length;

                System.Runtime.InteropServices.Marshal.StructureToPtr(uvSets[i], uvSetsPtr, false);
                uvSetsPtr = (System.IntPtr)((long)uvSetsPtr + structSize);
            }

            System.IntPtr meshDataPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(meshData));
            System.Runtime.InteropServices.Marshal.StructureToPtr(meshData, meshDataPtr, false);

            Debug.LogFormat("Mesh Push - Token:{0}, Parent:{1}, {2} positions, {3} facesets", meshData.entityToken, meshData.entityParentToken, (int)meshData.positionsNum, (int)meshData.facesetsNum);
            ImportMenu.stpUnitySendMeshData(meshDataPtr);

            // Free memory
            pinnedVerticesArray.Free();
            pinnedNormalsArray.Free();

            foreach (var pin in pinnedIndicesArrays)
            {
                pin.Free();
            }

            System.Runtime.InteropServices.Marshal.FreeHGlobal(meshData.facesets);
            System.Runtime.InteropServices.Marshal.FreeHGlobal(meshDataPtr);
        }