public static GameObject CreateMeshInstance(MeshInstanceData meshInstanceData) { Debug.LogFormat("Mesh Instance - Token:{0}, Name:{1} Parent:{2}, Mesh:{3}", meshInstanceData.entityToken, meshInstanceData.displayName, meshInstanceData.entityParentToken, meshInstanceData.originalMesh); var transform = MarshalData.GetXFormFromUnmanagedArray(meshInstanceData.xform); // Find mesh prefab Object meshPrefabObj = PackageMapper.GetObjectFromToken(meshInstanceData.originalMesh); // Create a new game object GameObject meshInst = Object.Instantiate(meshPrefabObj as GameObject); // Remove the "(Clone)" string from name that Unity automatically adds when instantiating // and apply the actual display name of the instance meshInst.name = meshInstanceData.displayName; // Find instance parent Object parentObj = PackageMapper.GetObjectFromToken(meshInstanceData.entityParentToken); SceneTransmissionProtocolUtilities.UpdateObjectHierarchy(meshInst, parentObj as GameObject, transform); // Add token store PackageMapper.AddUniqueTokenStore(meshInst, meshInstanceData.entityToken); return(meshInst); }
public static GameObject CreateCamera(CameraData cameraData) { CameraProjectionType camType = (CameraProjectionType)cameraData.type; Debug.LogFormat("Camera - Token:{0}, Name:{1}, Projection Type:{2}, VerticalFov:{3}, AspectRatio:{4}, HorizontalMag:{5}, NearClip:{6}, FarClip:{7}", cameraData.entityToken, cameraData.displayName, camType, cameraData.verticalFov, cameraData.aspectRatio, cameraData.horizontalMag, cameraData.nearClip, cameraData.farClip); // Get transformation data var transform = MarshalData.GetXFormFromUnmanagedArray(cameraData.xform); // Create a new game object GameObject cameraInst = new GameObject(cameraData.displayName); // Set transformation SceneTransmissionProtocolUtilities.UpdateObjectHierarchy(cameraInst, null, transform); // Add camera component Camera camera = cameraInst.AddComponent <Camera>(); SetCameraData(camera, cameraData); // Add token store PackageMapper.AddUniqueTokenStore(cameraInst, cameraData.entityToken); return(cameraInst); }
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> /// Dependency check /// Checks if all of the dependencies of the mesh are available in Unity /// </summary> public static bool DependencyCheck(MaterialDefinitionData materialDefinitionData) { // Check if we have textures available var currentReadPtr = materialDefinitionData.parameters; var parameterDataSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(MaterialDefinitionParameterData)); for (var i = 0; i < materialDefinitionData.parameterCount; ++i) { // Marshal parameter data MaterialDefinitionParameterData parameterData = (MaterialDefinitionParameterData)System.Runtime.InteropServices.Marshal.PtrToStructure(currentReadPtr, typeof(MaterialDefinitionParameterData)); currentReadPtr = MarshalData.AddToIntPtr(currentReadPtr, parameterDataSize); // Get the parameter type ParamType type = (ParamType)parameterData.type; if (type == ParamType.Texture) { // Check if we have a texture ready for this material definition if (!PackageMapper.GetTexture2DFromToken(parameterData.textureToken)) { // TODO: messages slow down the recieve mechanism and spam the log //Debug.LogWarningFormat("Texture '{0}' for '{1}' material has not yet been created!", // parameterData.textureToken, // materialDefinitionData.entityToken); return(false); } } } return(true); }
public static int[] MarshallTriangleIndices(int numIndices, System.IntPtr indices) { var managedIndices = new int[numIndices]; int index_offset = 0; // This part could be optimized by not needing to change the winding order for (var i = 0; i < numIndices; i++) { var index0 = MarshalData.GetIntFromUnmanagedArray(indices, index_offset); index_offset += MarshalData.sizeOfInt; managedIndices[i] = index0; } return(managedIndices); }
private static void UpdateTextureData(Texture2D texture, TextureData textureData, ImgFormat imgFormat) { // Fill image colors per pixel Color[] colorList = new Color[textureData.width * textureData.height]; int positionOffset = 0; // Flip image pixels due to Unity SetPixels texture method flipping the image // First color in the color list will be the last pixel in the image // and the resulting image will be flipped and mirrored for (int height = textureData.height - 1; height >= 0; height--) { for (int width = 0; width < textureData.width; width++) { int pixelIndex = height * textureData.width + width; // Convert STP image format to Unity texture format switch (imgFormat) { case ImgFormat.RawRGBA: colorList[pixelIndex].r = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; colorList[pixelIndex].g = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; colorList[pixelIndex].b = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; colorList[pixelIndex].a = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; break; case ImgFormat.RawRGB: colorList[pixelIndex].r = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; colorList[pixelIndex].g = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; colorList[pixelIndex].b = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; break; case ImgFormat.RawGray: colorList[pixelIndex].r = MarshalData.GetByteFromUnmanagedArray(textureData.imgData, positionOffset) / 255.0f; positionOffset += MarshalData.sizeOfByte; break; } } } texture.SetPixels(colorList); texture.Apply(true); }
public static List <Vector2> MarshallUVData(int numUVs, System.IntPtr uvData) { var managedUVData = new List <Vector2>(); int index_offset = 0; // This part could be optimized by not needing to change the winding order for (var i = 0; i < numUVs; i += 2) { var u = MarshalData.GetFloatFromUnmanagedArray(uvData, index_offset); index_offset += MarshalData.sizeOfInt; var v = 1.0f - MarshalData.GetFloatFromUnmanagedArray(uvData, index_offset); index_offset += MarshalData.sizeOfInt; managedUVData.Add(new Vector2(u, v)); } return(managedUVData); }
public static bool UpdateMeshInstance(MeshInstanceData meshInstanceData) { Debug.LogFormat("Mesh Instance Update - Token:{0}, Parent:{1}, Mesh:{2}", meshInstanceData.entityToken, meshInstanceData.entityParentToken, meshInstanceData.originalMesh); Object meshInstObj = PackageMapper.GetObjectFromToken(meshInstanceData.entityToken); var meshInst = meshInstObj as GameObject; var transform = MarshalData.GetXFormFromUnmanagedArray(meshInstanceData.xform); // Update the transformation of the item, ignore hierarchy updates for now // TODO: Work on hierarchy control systems Transform parentTrs = meshInst.transform.parent; GameObject parent = null; if (parentTrs) { parent = parentTrs.gameObject; } SceneTransmissionProtocolUtilities.UpdateObjectHierarchy(meshInst, parent, transform); // Update mesh filter Mesh mesh = PackageMapper.GetMeshFromToken(meshInstanceData.originalMesh); var meshFilter = meshInst.GetComponent <MeshFilter>(); if (meshFilter) { meshFilter.sharedMesh = mesh; } // Update mesh renderer GameObject meshPrefab = PackageMapper.GetObjectFromToken(meshInstanceData.originalMesh) as GameObject; var meshRenderer = meshPrefab.GetComponent <MeshRenderer>(); var meshInstRenderer = meshInst.GetComponent <MeshRenderer>(); if (meshRenderer && meshInstRenderer) { meshInstRenderer.sharedMaterials = meshRenderer.sharedMaterials; } return(true); }
public static Vector3[] MarshallNormals(int num_normals, System.IntPtr normals) { var managed_normals = new Vector3[num_normals]; int normalOffset = 0; // translate unmanaged normal data into managed Vector3s for (var i = 0; i < num_normals; ++i) { var x = MarshalData.GetFloatFromUnmanagedArray(normals, normalOffset); normalOffset += MarshalData.sizeOfInt; var y = MarshalData.GetFloatFromUnmanagedArray(normals, normalOffset); normalOffset += MarshalData.sizeOfInt; var z = MarshalData.GetFloatFromUnmanagedArray(normals, normalOffset); normalOffset += MarshalData.sizeOfInt; managed_normals[i] = new Vector3(x, z, -y); } return(managed_normals); }
/// <summary> /// /// Marshal data methods /// /// </summary> public static Vector3[] MarshallPositions(int numPositions, System.IntPtr positions) { var managed_positions = new Vector3[numPositions]; int positionOffset = 0; // translate unmanaged position data into managed Vector3s for (var i = 0; i < numPositions; ++i) { var x = MarshalData.GetFloatFromUnmanagedArray(positions, positionOffset); positionOffset += MarshalData.sizeOfInt; var y = MarshalData.GetFloatFromUnmanagedArray(positions, positionOffset); positionOffset += MarshalData.sizeOfInt; var z = MarshalData.GetFloatFromUnmanagedArray(positions, positionOffset); positionOffset += MarshalData.sizeOfInt; managed_positions[i] = new Vector3(x, z, -y); managed_positions[i].Scale(MarshalData.scaleFromSTPtoUnity); } return(managed_positions); }
/// <summary> /// Manage mesh memory /// Converts the marshaled unmanaged mesh memory to managed /// </summary> public static ManagedMeshData ManageMeshMemory(MeshData meshData) { ManagedMeshData managedMeshData = new ManagedMeshData(); managedMeshData.positions = MarshallPositions((int)meshData.positionsNum, meshData.positions); managedMeshData.normals = ((int)meshData.normalsNum > 0) ? MarshallNormals((int)meshData.normalsNum, meshData.normals) : null; managedMeshData.materials = new StringCollection(); managedMeshData.indices = new List <int[]>(); var facesetdataSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(FacesetData)); var currentReadPtr = meshData.facesets; for (var i = 0; i < (int)meshData.facesetsNum; ++i) { FacesetData fs = (FacesetData)System.Runtime.InteropServices.Marshal.PtrToStructure(currentReadPtr, typeof(FacesetData)); managedMeshData.materials.Add(fs.materialName); managedMeshData.indices.Add(MarshallTriangleIndices((int)fs.indicesNum, fs.indices)); currentReadPtr = MarshalData.AddToIntPtr(currentReadPtr, facesetdataSize); } managedMeshData.facesetNum = (int)meshData.facesetsNum; managedMeshData.uvs = new List <List <Vector2> >(); currentReadPtr = meshData.uvSets; var uvSetDataSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(UVData)); for (var i = 0; i < (int)meshData.uvSetNum; ++i) { UVData uvData = (UVData)System.Runtime.InteropServices.Marshal.PtrToStructure(currentReadPtr, typeof(UVData)); // Note: Not currently using triangle indices //managedMeshData.indices.Add(MarshallTriangleIndices((int)uvData.indicesNum, uvData.indices)); managedMeshData.uvs.Add(MarshallUVData((int)uvData.uvsNum, uvData.uvs)); currentReadPtr = MarshalData.AddToIntPtr(currentReadPtr, uvSetDataSize); } managedMeshData.uvNum = (int)meshData.uvSetNum; return(managedMeshData); }
public static bool UpdateCamera(CameraData cameraData) { CameraProjectionType camType = (CameraProjectionType)cameraData.type; Debug.LogFormat("Camera Update - Token:{0}, Name:{1}, Projection Type:{2}, VerticalFov:{3}, AspectRatio:{4}, HorizontalMag:{5}, NearClip:{6}, FarClip:{7}", cameraData.entityToken, cameraData.displayName, camType, cameraData.verticalFov, cameraData.aspectRatio, cameraData.horizontalMag, cameraData.nearClip, cameraData.farClip); // Get transformation data var transform = MarshalData.GetXFormFromUnmanagedArray(cameraData.xform); // Get camera game object GameObject cameraInst = PackageMapper.GetObjectFromToken(cameraData.entityToken) as GameObject; if (cameraInst) { // Set transformation SceneTransmissionProtocolUtilities.UpdateObjectHierarchy(cameraInst, null, transform); // Get camera component Camera camera = cameraInst.GetComponent <Camera>(); if (camera) { SetCameraData(camera, cameraData); } else { Debug.LogErrorFormat("Camera Update error! Camera component not found! Token:{0}"); return(false); } } else { Debug.LogErrorFormat("Camera Update error! Camera game object not found! Token:{0}"); return(false); } return(true); }
public static Object CreateMaterial(MaterialDefinitionData materialDefinitionData) { ShaderModel shaderModel = (ShaderModel)materialDefinitionData.shaderModel; BlendMode blendMode = (BlendMode)materialDefinitionData.blendMode; Debug.LogFormat("Material Definition - Token:{0} Display Name:{1}, {2} shader model {3} blend mode {4} parameter count", materialDefinitionData.entityToken, materialDefinitionData.displayName, shaderModel, blendMode, materialDefinitionData.parameterCount); // Create a new Unity material with "Standard" Unity shader // Shader string names are assumed to use the Unity Standard shader code Material newMaterial = new Material(Shader.Find("Standard")); // Set blend mode options switch (blendMode) { case BlendMode.ModeUnknown: case BlendMode.Opaque: // Default blend mode, skip modification break; case BlendMode.Translucent: // Code taken from https://answers.unity.com/questions/1004666/change-material-rendering-mode-in-runtime.html // Changes what options are available in Unity shader GUI newMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); newMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); newMaterial.SetInt("_ZWrite", 0); newMaterial.DisableKeyword("_ALPHATEST_ON"); newMaterial.DisableKeyword("_ALPHABLEND_ON"); newMaterial.EnableKeyword("_ALPHAPREMULTIPLY_ON"); newMaterial.renderQueue = 3000; break; } var currentReadPtr = materialDefinitionData.parameters; var parameterDataSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(MaterialDefinitionParameterData)); for (var i = 0; i < materialDefinitionData.parameterCount; ++i) { // Marshal parameter data MaterialDefinitionParameterData parameterData = (MaterialDefinitionParameterData)System.Runtime.InteropServices.Marshal.PtrToStructure(currentReadPtr, typeof(MaterialDefinitionParameterData)); currentReadPtr = MarshalData.AddToIntPtr(currentReadPtr, parameterDataSize); // Get the parameter type ParamType type = (ParamType)parameterData.type; Debug.LogFormat("Material Parameter - Name:{0} Type:{1} Target:{2}, {3} texture token", parameterData.name, type, parameterData.target, parameterData.textureToken); // Get the right shader input and connect parameter data string shaderStringTarget; Vector4 vect; int offset = 0; switch (type) { case ParamType.Float: shaderStringTarget = FindScalarInput(parameterData.target); if (System.String.IsNullOrEmpty(shaderStringTarget)) { break; } newMaterial.SetFloat(shaderStringTarget, MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset)); break; case ParamType.Float2: shaderStringTarget = FindVectorInput(parameterData.target); if (System.String.IsNullOrEmpty(shaderStringTarget)) { break; } vect.x = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); offset += MarshalData.sizeOfInt; vect.y = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); vect.z = 0.0f; vect.w = 0.0f; newMaterial.SetVector(shaderStringTarget, vect); break; case ParamType.Float3: shaderStringTarget = FindVectorInput(parameterData.target); if (System.String.IsNullOrEmpty(shaderStringTarget)) { break; } vect.x = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); offset += MarshalData.sizeOfInt; vect.y = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); offset += MarshalData.sizeOfInt; vect.z = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); vect.w = 0.0f; newMaterial.SetVector(shaderStringTarget, vect); break; case ParamType.Float4: case ParamType.RGBA8: shaderStringTarget = FindVectorInput(parameterData.target); if (System.String.IsNullOrEmpty(shaderStringTarget)) { break; } vect.x = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); offset += MarshalData.sizeOfInt; vect.y = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); offset += MarshalData.sizeOfInt; vect.z = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); offset += MarshalData.sizeOfInt; vect.w = MarshalData.GetFloatFromUnmanagedArray(parameterData.floatData, offset); newMaterial.SetVector(shaderStringTarget, vect); break; case ParamType.Texture: shaderStringTarget = FindTextureInput(parameterData.target); if (System.String.IsNullOrEmpty(shaderStringTarget)) { break; } Texture texture = PackageMapper.GetTexture2DFromToken(parameterData.textureToken); newMaterial.SetTexture(shaderStringTarget, texture); // TODO: Emission keyword doesn't work in Unity 2018.2.15f1 as it doesn't enable // emission checkbox for some reason // Special case for emission textures, enable the emission map on the shader if (shaderStringTarget == ShaderEmissionTexture) { newMaterial.EnableKeyword("_EMISSION"); } break; } } // Create material default STP folders if they don't exist PackageMapper.CreateAssetFolders(MaterialDefinitionHandler.assetPath); // Generate a unique material name string materialPath = Application.dataPath + "/" + MaterialDefinitionHandler.assetPath; string uniqueMaterialName; GenUniqueMaterialAssetName(materialPath, materialDefinitionData.displayName, out uniqueMaterialName); // Set the unique material name as the display name newMaterial.name = uniqueMaterialName; // Create a GameObject prefab object and use it as a database item of STP used materials GameObject materialPrefab = new GameObject(uniqueMaterialName); // Add Foundry unique token storage component, store unique material token var tokenStorage = materialPrefab.AddComponent <FoundryUniqueToken>(); tokenStorage.uniqueToken = materialDefinitionData.entityToken; // Create the prefab asset var localPrefabPath = System.String.Format("{0}/{1}/{2}", PackageMapper.rootPath, MaterialDefinitionHandler.assetPath, uniqueMaterialName); string prefabPath; PackageMapper.GenUniquePrefabAssetPath(localPrefabPath, out prefabPath); #if UNITY_2018_3_OR_NEWER Object prefabAsset = PrefabUtility.SaveAsPrefabAsset(materialPrefab, prefabPath); #else Object prefabAsset = PrefabUtility.CreatePrefab(prefabPath, materialPrefab); #endif // Map the prefab to the material PackageMapper.MapMaterialToPrefab(newMaterial, prefabAsset); AssetDatabase.AddObjectToAsset(newMaterial, prefabAsset); AssetDatabase.SaveAssets(); // Remove game object that's used for creating a prefab from scene hierarchy Object.DestroyImmediate(materialPrefab); return(prefabAsset); }