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);
        }
Example #2
0
        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);
        }
Example #4
0
        /// <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);
        }
Example #6
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
        }