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);
        }
        /// <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);
        }
        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);
        }
Exemple #4
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);
        }