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); }
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); }