/// <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); } }
static bool CheckInit() { if (!ImportMenu.stpUnityIsClientRunning()) { return(true); } return(false); }
/// <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); }