private static void InitProgress(Module.Import.Assimp.Context context, Module.ProgressCallback callback, aiScene scene) { uint nb_textures = 0; using (aiMaterialArray assimp_materials = scene.Materials) { uint nb_materials = assimp_materials.Size(); for (uint i = 0; i < nb_materials; i++) { using (aiMaterial material = assimp_materials.Get(i)) { foreach (KeyValuePair <string, aiTextureType> pair in Assimp.Convert.textureTypes) { using (aiString texture_name = new aiString()) { if (material.GetTexturePath(pair.Value, 0, texture_name)) { nb_textures++; } } } } } } uint nb_steps = Node.ASSIMP_PROGRESS_FACTOR * CountNodes(scene.mRootNode); nb_steps += Mesh.ASSIMP_PROGRESS_FACTOR * scene.Meshes.Size(); nb_steps += Material.ASSIMP_PROGRESS_FACTOR * scene.Materials.Size(); nb_steps += Texture.ASSIMP_PROGRESS_FACTOR * nb_textures; nb_steps = (uint)(nb_steps / (1f - assimpNativeLoadingPrecentage)); context.progress.Init(nb_steps, callback); }
public static void FromAssimp(Module.Import.Assimp.Context context, aiScene scene) { if (scene.HasMaterials()) { using (aiMaterialArray assimp_materials = scene.Materials) { uint material_size = assimp_materials.Size(); // Reserve the right amount of memory context.scene.materials = new Material[(int)material_size + 1]; // Create a material for lines Material line_material = new Material(); line_material.name = "Line"; line_material.shader = defaultAssimpLineShader; line_material.floats = new Dictionary <string, float>(); line_material.colors = new Dictionary <string, Color>(); line_material.floats.Add(defaultAssimpLineShaderWidth, unityLineWidth); line_material.colors.Add(Assimp.Convert.unityDiffuseColorName, Color.black); context.scene.materials[(int)material_size] = line_material; // Load all the materials for (uint i = 0; i < material_size; i++) { aiMaterial material = assimp_materials.Get(i); // LoadMaterial must dispose of the given material afterward // We must use a proxy method for saving the result into the array because the index i is captured by the lambda otherwise and it's value is indefinite across multiple threads. context.threads.ExecAndSaveToArray(context.scene.materials, (int)i, () => FromAssimp(context, scene, material)); } } } }
internal static Dictionary <string, SetColor> SetColors(aiMaterial material) { Dictionary <string, SetColor> color_types = new Dictionary <string, SetColor> { { unityDiffuseColorName, material.SetColorDiffuse }, { unitySpecularColorName, material.SetColorSpecular }, { unityEmissiveColorName, material.SetColorEmissive }, //{"_???", material.SetColorAmbient}, //{"_???", material.SetColorTransparent}, //{"_???", material.SetColorReflective}, }; return(color_types); }
public static void ToAssimp(Module.Export.Assimp.Context context, Scene scene) { if (scene.materials != null && scene.materials.Length > 0) { using (aiMaterialArray materials = context.scene.Materials) { uint count = (uint)scene.materials.Length; materials.Reserve(count, true); for (uint i = 0; i < count; i++) { uint index = i; // To avoid problems of lambda expression getting 'for' variable by reference (even if uint are not ref normaly!) aiMaterial assimp_material = new aiMaterial(); // Allocation in another thread fails so we must do it before starting the task materials.Set(index, assimp_material.Unmanaged()); context.threads.AddTask(() => scene.materials[index].ToAssimp(context, scene, assimp_material)); } } } }
internal static HandleRef getCPtr(aiMaterial obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; }
internal static HandleRef getCPtr(aiMaterial obj) { return((obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr); }
private static Material FromAssimp(Module.Import.Assimp.Context context, aiScene scene, aiMaterial material_data) { Material material = new Material(); // Initialize dictionaries before hand because we do not know in advance wich ones we will need material.floats = new Dictionary <string, float>(); material.colors = new Dictionary <string, Color>(); material.textures = new Dictionary <string, TextureParams>(); // Name using (aiString material_name = new aiString()) { if (material_data.GetName(material_name)) { material.name = material_name.ToString(); } } // shader material.shader = Constants.defaultAssimpShader; // Shininess float shininess; if (material_data.GetShininess(out shininess)) { aiShadingMode shading; if (material_data.GetShadingModel(out shading)) { if (shading != aiShadingMode.aiShadingMode_Blinn && shading != aiShadingMode.aiShadingMode_Phong) { // Unsupported shading model Debug.LogWarningFormat("The shading model for material {0} is not supported. The value for the shininess is likely to be incorrect.", material.name); } } const int factor = 128; // unity shader factor shininess /= factor; } // Gloss float gloss; if (material_data.GetShininessStrength(out gloss)) { shininess *= gloss; } // Reflectivity float reflectivity; if (material_data.GetReflectivity(out reflectivity)) { material.floats.Add(Assimp.Convert.unityMetallicValueName, reflectivity); } material.floats.Add(Assimp.Convert.unityGlossinessValueName, Smoothness(shininess, reflectivity)); // Colors foreach (KeyValuePair <string, Assimp.Convert.GetColor> pair in Assimp.Convert.GetColors(material_data)) { using (aiColor4D color = new aiColor4D()) { if (pair.Value(color)) { Color unity_color = Assimp.Convert.AssimpToUnity.Color(color); bool set_color = true; switch (pair.Key) { case Assimp.Convert.unityDiffuseColorName: // Global opacity float opacity; if (material_data.GetOpacity(out opacity) && opacity < 1.0f) { unity_color.a = opacity; material.floats.Add(Assimp.Convert.unityRenderModeName, (float)CLARTE.Shaders.Standard.Utility.BlendMode.TRANSPARENT); } break; case Assimp.Convert.unitySpecularColorName: // Specular color must be very close to black unity_color = 0.1f * unity_color; break; case Assimp.Convert.unityEmissiveColorName: if (!CLARTE.Shaders.Standard.Utility.ShouldEmissionBeEnabled(unity_color)) { set_color = false; } break; } if (set_color) { material.colors.Add(pair.Key, unity_color); } } } } // Textures foreach (KeyValuePair <string, aiTextureType> pair in Assimp.Convert.textureTypes) { // Make a copy to avoid problem of loop variable captured by reference by lambda expression string texture_key = pair.Key; aiTextureType texture_type = pair.Value; context.threads.AddTask(() => Texture.FromAssimp(context, material, scene, material_data, texture_key, texture_type, reflectivity)); } // We must dispose of the given parameter to free unused memory. However other tasks may still be using this material (i.e. textures), so we will let the garbage collector do it's job. //material_data.Dispose(); context.progress.Update(ASSIMP_PROGRESS_FACTOR); return(material); }
private void ToAssimp(Module.Export.Assimp.Context context, Scene scene, aiMaterial assimp_material) { // Name if (!string.IsNullOrEmpty(name)) { using (aiString assimp_material_name = new aiString(name)) { assimp_material.SetName(assimp_material_name.Unmanaged()); } } // Set flag for transparent texture if the shader use transparency if (renderQueue == (int)UnityEngine.Rendering.RenderQueue.Transparent) { assimp_material.SetTextureFlags(aiTextureType.aiTextureType_DIFFUSE, 0, aiTextureFlags.aiTextureFlags_UseAlpha); } // Reflectivity float reflectivity; if (floats == null || !floats.TryGetValue("_Metallic", out reflectivity)) { reflectivity = 0f; } assimp_material.SetReflectivity(reflectivity); // Shininess float smoothness; if (floats == null || !floats.TryGetValue("_Glossiness", out smoothness)) { smoothness = 0f; } float shininess = 2.0f * smoothness - (reflectivity > 0.0f ? reflectivity : 0.0f); if (shininess > 0.0f) { const int factor = 128; // unity shader factor assimp_material.SetShadingModel(aiShadingMode.aiShadingMode_Phong); assimp_material.SetShininess(shininess * factor); assimp_material.SetShininessStrength(1.0f); } else { assimp_material.SetShadingModel(aiShadingMode.aiShadingMode_Gouraud); } // Colors if (colors != null) { foreach (KeyValuePair <string, Assimp.Convert.SetColor> pair in Assimp.Convert.SetColors(assimp_material)) { if (colors.ContainsKey(pair.Key)) { Color unity_color = colors[pair.Key]; switch (pair.Key) { case Assimp.Convert.unityDiffuseColorName: if (unity_color.a < 1.0f) { assimp_material.SetOpacity(unity_color.a); } break; case Assimp.Convert.unitySpecularColorName: // Revert specular color to original value unity_color = 10.0f * unity_color; break; default: break; } using (aiColor4D color = Assimp.Convert.UnityToAssimp.Color(unity_color)) { pair.Value(color); } } } } // Textures if (textures != null) { Dictionary <Texture, aiTextureType> textures_types = new Dictionary <Texture, aiTextureType>(); // Get supported textures foreach (KeyValuePair <string, aiTextureType> pair in Assimp.Convert.textureTypes) { if (textures.ContainsKey(pair.Key)) { Texture texture = scene.textures[textures[pair.Key].index]; if (texture != null) { textures_types.Add(texture, pair.Value); } } } // Export each supported textures foreach (KeyValuePair <Texture, aiTextureType> texture_pair in textures_types) { // Make a copy to avoid problem of loop variable captured by reference by lambda expression Texture texture = texture_pair.Key; aiTextureType texture_type = texture_pair.Value; context.threads.AddTask(() => texture.ToAssimp(context, texture_type, assimp_material)); } } context.progress.Update(ASSIMP_PROGRESS_FACTOR); }
public static void CopyPropertyList(aiMaterial pcDest, aiMaterial pcSrc) { AssimpPINVOKE.aiMaterial_CopyPropertyList(aiMaterial.getCPtr(pcDest), aiMaterial.getCPtr(pcSrc)); }
private void ToAssimp(Module.Export.Assimp.Context context, string texture_name, aiTextureType texture_type, aiMaterial material) { if (!string.IsNullOrEmpty(texture_name)) { string final_texture_name = null; if (texture_name.Length >= 1 && texture_name[0] == '*') { // Special textures if (texture_name.Length >= 3 && texture_name[1] == '*') { switch (texture_name[2]) { case 'N': // New normal texture generated from height map texture_type = aiTextureType.aiTextureType_HEIGHT; final_texture_name = texture_name.Substring(3); break; case 'A': // Secondary texture encoded in alpha channel string[] textures = texture_name.Substring(3).Split('|'); if (textures.Length == 2) { ToAssimp(context, textures[0], texture_type, material); switch (texture_type) { case aiTextureType.aiTextureType_DIFFUSE: texture_type = aiTextureType.aiTextureType_OPACITY; break; case aiTextureType.aiTextureType_SPECULAR: texture_type = aiTextureType.aiTextureType_SHININESS; break; default: break; } ToAssimp(context, textures[1], texture_type, material); } else { throw new FormatException("The texture + alpha should contain identifiers to only two original textures"); } break; case 'E': // Empty texture break; default: break; } } else // Embeded texture { if (unityTexture != null) { using (aiTextureArray textures = context.scene.Textures) { uint index = textures.Size(); final_texture_name = "*" + index; using (aiTexture texture = new aiTexture()) { texture.data = unityTexture.EncodeToPNG(); texture.achFormatHint = "png"; textures.Set(index, texture.Unmanaged()); } } } } } else { final_texture_name = texture_name; } if (final_texture_name != null) { using (aiString assimp_texture_name = new aiString(final_texture_name)) { lock (material) { material.SetTexturePath(texture_type, 0, assimp_texture_name.Unmanaged()); } } context.progress.Update(ASSIMP_PROGRESS_FACTOR); } } }
public void ToAssimp(Module.Export.Assimp.Context context, aiTextureType texture_type, aiMaterial material) { ToAssimp(context, filename, texture_type, material); }
private static void FromAssimpNormalsFromHeightmap(Module.Import.Assimp.Context context, Material material, aiMaterial material_data, aiScene scene) { if (material_data.GetTextureCount(Assimp.Convert.textureTypes[Assimp.Convert.unityBumpName]) <= 0) { using (aiString texture_name = new aiString()) { if (material_data.GetTexturePath(aiTextureType.aiTextureType_HEIGHT, 0, texture_name)) { string filename = string.Format("**N{0}", texture_name.C_Str()); material.AddTextureParams(Assimp.Convert.unityBumpName, new Material.TextureParams(context.scene.GetAssimpTexture(filename, () => { Texture texture = new Texture(context, texture_name.C_Str(), scene).HeightmapToNormals(0.5).Blur(0.5); texture.filename = filename; return(texture); }).Item2)); } } } }
private static void FromAssimpAlphaTexture(Module.Import.Assimp.Context context, Material material, aiMaterial material_data, aiScene scene, string unity_property, aiTextureType texture_type, Color default_color, Func <Color, float> op) { if (material_data.GetTextureCount(texture_type) > 0) { using (aiString texture_name = new aiString()) { if (material_data.GetTexturePath(texture_type, 0, texture_name)) { Texture alpha = new Texture(context, texture_name.ToString(), scene); Texture base_tex = null; Material.TextureParams param = material.GetTextureParams(unity_property); if (param != null) { CLARTE.Backport.Tuple <Texture, uint> res = context.scene.GetAssimpTexture(param.index); if (res != null) { base_tex = res.Item1; } else { Debug.LogErrorFormat("Invalid texture index. '{0}' was registered for material '{1}' as texture with index '{2}'. However no texture was found with this index.", unity_property, material.Name, param.index); } } else { CLARTE.Backport.Tuple <Texture, uint> assimp_tex = context.scene.GetAssimpTexture(Guid.NewGuid().ToString(), () => new Texture("**E", alpha.width, alpha.height, default_color)); material.AddTextureParams(unity_property, new Material.TextureParams(assimp_tex.Item2)); base_tex = assimp_tex.Item1; } if (base_tex != null) { base_tex.AddToAlpha(alpha, op); base_tex.filename = string.Format("**A{0}|{1}", base_tex.filename, texture_name.C_Str()); } } } } }
public static void FromAssimp(Module.Import.Assimp.Context context, Material material, aiScene scene, aiMaterial material_data, string texture_key, aiTextureType texture_type, float reflectivity) { if (texture_type != aiTextureType.aiTextureType_NONE && material_data.GetTextureCount(texture_type) > 0) { using (aiString texture_name = new aiString()) { if (material_data.GetTexturePath(texture_type, 0, texture_name)) { string filename = texture_name.C_Str(); uint index = context.scene.GetAssimpTexture(filename, () => new Texture(context, filename, scene)).Item2; material.AddTextureParams(texture_key, new Material.TextureParams(index)); context.progress.Update(ASSIMP_PROGRESS_FACTOR); } } } Color default_color; // Add textures as alpha channel of existing textures, or compute normal map from heightmap if not defined. switch (texture_key) { case Assimp.Convert.unityMainTexName: default_color = Color.white; Color?diffuse = material.GetColor(Assimp.Convert.unityDiffuseColorName); if (diffuse.HasValue) { default_color = diffuse.Value; } // Opacity as main texture alpha channel FromAssimpAlphaTexture(context, material, material_data, scene, Assimp.Convert.unityMainTexName, aiTextureType.aiTextureType_OPACITY, default_color, c => c.grayscale); break; case Assimp.Convert.unityMetallicGlossName: default_color = Color.black; float?metallic = material.GetFloat(Assimp.Convert.unityMetallicValueName); if (metallic.HasValue) { default_color = new Color(metallic.Value, metallic.Value, metallic.Value, 1f); } // Shininess as alpha channel of metallic gloss map FromAssimpAlphaTexture(context, material, material_data, scene, Assimp.Convert.unityMetallicGlossName, aiTextureType.aiTextureType_SHININESS, default_color, c => Material.Smoothness(c.grayscale, reflectivity)); break; case Assimp.Convert.unitySpecGlossName: default_color = Color.black; Color?specular = material.GetColor(Assimp.Convert.unitySpecularColorName); if (specular.HasValue) { default_color = specular.Value; } // Shininess as alpha channel of specular gloss map FromAssimpAlphaTexture(context, material, material_data, scene, Assimp.Convert.unitySpecGlossName, aiTextureType.aiTextureType_SHININESS, default_color, c => Material.Smoothness(c.grayscale, reflectivity)); break; case Assimp.Convert.unityBumpName: // Bump mapping from heightmap if not defined from normals FromAssimpNormalsFromHeightmap(context, material, material_data, scene); break; } }
public static aiReturn aiGetMaterialUVTransform(aiMaterial pMat, string pKey, uint type, uint index, aiUVTransform pOut) { aiReturn ret = (aiReturn)assimp_swigPINVOKE.aiGetMaterialUVTransform(aiMaterial.getCPtr(pMat), pKey, type, index, aiUVTransform.getCPtr(pOut)); return(ret); }