public ModelComponent(string name,List<Vector3D> vertices, int[] indices, List<Vector3D> uv, List<Vector3D> normals, List<Vector3D> tangents, List<Vector3D> bitangents, Material material) { Vertices = new Vector3[vertices.Count]; for(int i = 0; i < vertices.Count; i++) { Vertices[i].X = vertices[i].X; Vertices[i].Y = vertices[i].Y; Vertices[i].Z = vertices[i].Z; } UV = new Vector2[uv.Count]; for(int i = 0; i < uv.Count; i++) { UV[i].X = uv[i].X; UV[i].Y = uv[i].Y; } Normals = new Vector3[normals.Count]; for (int i = 0; i < normals.Count; i++) { Normals[i].X = normals[i].X; Normals[i].Y = normals[i].Y; Normals[i].Z = normals[i].Z; } Tangents = new Vector3[tangents.Count]; for (int i = 0; i < tangents.Count; i++) { Tangents[i].X = tangents[i].X; Tangents[i].Y = tangents[i].Y; Tangents[i].Z = tangents[i].Z; } BiTangents = new Vector3[bitangents.Count]; for (int i = 0; i < bitangents.Count; i++) { BiTangents[i].X = bitangents[i].X; BiTangents[i].Y = bitangents[i].Y; BiTangents[i].Z = bitangents[i].Z; } Diffuse = new Vector4() { X = material.ColorDiffuse.R, Y = material.ColorDiffuse.G, Z = material.ColorDiffuse.B, W = material.ColorDiffuse.A }; Emissive = new Vector4() { X = material.ColorEmissive.R, Y = material.ColorEmissive.G, Z = material.ColorEmissive.B, W = material.ColorEmissive.A }; Specular = new Vector4() { X = material.ColorSpecular.R, Y = material.ColorSpecular.G, Z = material.ColorSpecular.B, W = material.ColorSpecular.A }; Indices = indices; TexturePath = material.TextureDiffuse.FilePath; }
private void LoadTexturesFromScene(Assimp.Scene scene, string model_directory) { foreach (Assimp.Mesh mesh in scene.Meshes) { Assimp.Material mat = scene.Materials[mesh.MaterialIndex]; if (mat.HasTextureDiffuse) { BinaryTextureImage img = new BinaryTextureImage(); img.Load(mat.TextureDiffuse, model_directory); Textures.Add(img); } } }
public static RealtimeMaterial ToRealtimeMaterial(this Assimp.Material material) { return(new RealtimeMaterial( material.ColorAmbient.ToVector4(), material.ColorDiffuse.ToVector4(), material.ColorSpecular.ToVector4(), material.ColorEmissive.ToVector4(), material.ColorTransparent.ToVector4(), new Vector4(material.Shininess, material.ShininessStrength, material.Opacity, material.Reflectivity), material.TextureDiffuse.FilePath, material.TextureNormal.FilePath, material.TextureHeight.FilePath, material.TextureSpecular.FilePath)); }
public override void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { ShaderGen.GenFlags flags = 0; if (textured) { flags |= ShaderGen.GenFlags.ColorMap; } if (shaded) { flags |= ShaderGen.GenFlags.Lighting; } Shader shader = _shaderGen.GenerateOrGetFromCache(flags); shader.BindIfNecessary(); }
private static Ai.Material CreateAiMaterialFromMaterial(Material material, TextureSet textureSet) { var aiMaterial = new Ai.Material(); aiMaterial.Name = material.Name; aiMaterial.ColorDiffuse = material.Diffuse.ToAssimp(); aiMaterial.ColorAmbient = material.Ambient.ToAssimp(); aiMaterial.ColorSpecular = material.Ambient.ToAssimp(); aiMaterial.ColorEmissive = material.Emission.ToAssimp(); aiMaterial.Shininess = material.Shininess; aiMaterial.IsTwoSided = material.DoubleSided; var exportedTypes = new HashSet <MaterialTextureType>(); foreach (var materialTexture in material.MaterialTextures) { if (!sTextureTypeMap.TryGetValue(materialTexture.Type, out var type) || exportedTypes.Contains(materialTexture.Type)) { continue; } exportedTypes.Add(materialTexture.Type); var texture = textureSet?.Textures?.FirstOrDefault(x => x.Id == materialTexture.TextureId); if (texture == null) { continue; } var aiTextureSlot = new Ai.TextureSlot(); if (TextureFormatUtilities.IsBlockCompressed(texture.Format) && !texture.IsYCbCr) { aiTextureSlot.FilePath = texture.Name + ".dds"; } else { aiTextureSlot.FilePath = texture.Name + ".png"; } aiTextureSlot.TextureType = type; aiMaterial.AddMaterialTexture(in aiTextureSlot); } return(aiMaterial); }
/// <summary> /// Check if a given assimp material requires alpha-blending for rendering /// </summary> /// <param name="material"></param> /// <returns></returns> public bool IsAlphaMaterial(Material material) { if (material.HasOpacity && IsTransparent(material.Opacity)) { return true; } // Also treat material as (potentially) semi-transparent if the alpha // components of any of the diffuse, specular, ambient and emissive // colors are non-1. It is not very well-defined how assimp handles // these values so better count them into transparency as well. // // Ignore color values with alpha=0, however. These are most likely // not intended to be fully transparent. if (material.HasColorDiffuse && IsTransparent(material.ColorDiffuse.A)) { return true; } if (material.HasColorSpecular && IsTransparent(material.ColorSpecular.A)) { return true; } if (material.HasColorAmbient && IsTransparent(material.ColorAmbient.A)) { return true; } if (material.HasColorEmissive && IsTransparent(material.ColorEmissive.A)) { return true; } if (material.GetMaterialTextureCount(TextureType.Diffuse) > 0) { TextureSlot tex; material.GetMaterialTexture(TextureType.Diffuse, 0, out tex); var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath); if(gtex.HasAlpha == Texture.AlphaState.HasAlpha) { return true; } } return false; }
private PhysicallyBasedMaterial CreatePbrMaterial(AssimpMaterial assimpMaterial, string filePath, string customTexturesFolder, bool useStrictFileNameMatch, bool supportDDSTextures) { PhysicallyBasedMaterial physicallyBasedMaterial; if (_dxMaterials.TryGetValue(assimpMaterial, out physicallyBasedMaterial)) // Is PhysicallyBasedMaterial already creared { Log($" Material: {assimpMaterial.Name ?? ""} (already defined)"); return(physicallyBasedMaterial); } //if (!assimpMaterial.HasTextureDiffuse) //{ // Log($" Material {assimpMaterial.Name ?? ""} does not define a diffuse texture"); // return null; //} Log($" Material {assimpMaterial.Name ?? ""}:"); physicallyBasedMaterial = new PhysicallyBasedMaterial(); // When materials has diffuse texture defined, then we also try to find other PBR textures if (assimpMaterial.HasTextureDiffuse) { AddPBRTextures(assimpMaterial, filePath, customTexturesFolder, useStrictFileNameMatch, supportDDSTextures, physicallyBasedMaterial); } // Set BaseColor based on the DiffuseColor if (assimpMaterial.HasColorDiffuse) { physicallyBasedMaterial.BaseColor = new Color4(assimpMaterial.ColorDiffuse.R, assimpMaterial.ColorDiffuse.G, assimpMaterial.ColorDiffuse.B, assimpMaterial.ColorDiffuse.A); } // When there is no Metalness texture defined, then set Metalness to zero - use plastic if (!physicallyBasedMaterial.HasTextureMap(TextureMapTypes.Metalness)) { physicallyBasedMaterial.Metalness = 0; } _disposables.Add(physicallyBasedMaterial); _dxMaterials.Add(assimpMaterial, physicallyBasedMaterial); AddTextureMapSelections(assimpMaterial.Name, physicallyBasedMaterial); return(physicallyBasedMaterial); }
public int Initialize(string rootPath, string modelName, int viewStep, Assimp.Material meterial) { Name = modelName + "." + meterial.Name; ViewStep = viewStep; Color.Opacity = meterial.Opacity; Color.Shininess = meterial.Shininess; for (int i = 0; i < 4; i++) { Color.Ambient[i] = meterial.ColorAmbient[i]; Color.Diffuse[i] = meterial.ColorDiffuse[i]; Color.Emissive[i] = meterial.ColorEmissive[i]; Color.Reflective[i] = meterial.ColorReflective[i]; Color.Specular[i] = meterial.ColorSpecular[i]; Color.Transparent[i] = meterial.ColorTransparent[i]; } SetTexture(rootPath, meterial); return(viewStep + 5 * Engine.Instance.Core.Device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView)); }
private Ai.Material ConvertMaterial(Material material) { var aiMaterial = new Ai.Material { Name = AssimpConverterCommon.EscapeName(material.Name), ColorAmbient = new Ai.Color4D(material.Ambient.X, material.Ambient.Y, material.Ambient.Z, material.Ambient.W), ColorDiffuse = new Ai.Color4D(material.Diffuse.X, material.Diffuse.Y, material.Diffuse.Z, material.Diffuse.W), ColorSpecular = new Ai.Color4D(material.Specular.X, material.Specular.Y, material.Specular.Z, material.Specular.W), ColorEmissive = new Ai.Color4D(material.Emissive.X, material.Emissive.Y, material.Emissive.Z, material.Emissive.W) }; if (material.Flags.HasFlag(MaterialFlags.HasDiffuseMap)) { aiMaterial.TextureDiffuse = new Ai.TextureSlot( Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.DiffuseMap.Name)), Ai.TextureType.Diffuse, 0, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0); } if (material.Flags.HasFlag(MaterialFlags.HasNormalMap)) { aiMaterial.TextureNormal = new Ai.TextureSlot( Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.NormalMap.Name)), Ai.TextureType.Normals, 1, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0); } if (material.Flags.HasFlag(MaterialFlags.HasSpecularMap)) { aiMaterial.TextureSpecular = new Ai.TextureSlot( Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.SpecularMap.Name)), Ai.TextureType.Specular, 2, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0); } if (material.Flags.HasFlag(MaterialFlags.HasReflectionMap)) { aiMaterial.TextureReflection = new Ai.TextureSlot( Path.Combine(mTextureBaseRelativeDirectoryPath, AssimpConverterCommon.EscapeName(material.ReflectionMap.Name)), Ai.TextureType.Reflection, 3, Ai.TextureMapping.FromUV, 0, 0, Ai.TextureOperation.Add, Ai.TextureWrapMode.Wrap, Ai.TextureWrapMode.Wrap, 0); } // todo: add more textures return(aiMaterial); }
/// <summary> /// Constructs a MaterialPreviewRenderer to obtain a preview image /// for one given material. /// </summary> /// <param name="window">Window instance that hosts the primary Gl context</param> /// <param name="scene">Scene instance that the material belongs to</param> /// <param name="material">Material to render a preview image for</param> /// <param name="width">Requested width of the preview image, in pixels</param> /// <param name="height">Requested height of the preview image, in pixels</param> public MaterialPreviewRenderer(MainWindow window, Scene scene, Material material, uint width, uint height) { Debug.Assert(window != null); Debug.Assert(material != null); Debug.Assert(scene != null); Debug.Assert(width >= 1); Debug.Assert(height >= 1); _scene = scene; _material = material; _width = width; _height = height; _state = CompletionState.Pending; window.Renderer.GlExtraDrawJob += (sender) => { _state = !RenderPreview() ? CompletionState.Failed : CompletionState.Done; OnPreviewAvailable(); }; }
void WriteMaterial (Material mat, BinaryWriter writer, Dictionary<string,string> textures, int boneCount, int boneSlotCount) { writer.Write(mat.Name); writer.Write(mat.IsTwoSided); writer.Write(mat.IsWireFrameEnabled); writer.Write((int)mat.ShadingMode); writer.Write((int)mat.BlendMode); writer.Write(mat.Opacity); writer.Write(mat.Shininess); writer.Write(mat.ShininessStrength); writer.Write(mat.ColorAmbient); writer.Write(mat.ColorDiffuse); writer.Write(mat.ColorSpecular); writer.Write(mat.ColorEmissive); writer.Write(mat.ColorTransparent); writer.Write(boneCount); writer.Write(boneSlotCount); this.WriteTextureStack(mat, TextureType.Diffuse, writer, textures); this.WriteTextureStack(mat, TextureType.Normals, writer, textures); this.WriteTextureStack(mat, TextureType.Specular, writer, textures); this.WriteTextureStack(mat, TextureType.Emissive, writer, textures); }
private Material ConvertMaterial(Assimp.Material m) { return(new Material { ColorAmbient = m.HasColorAmbient ? (Color?)ConvertMaterialColor(m.ColorAmbient) : null, ColorDiffuse = m.HasColorDiffuse ? (Color?)ConvertMaterialColor(m.ColorDiffuse) : null, ColorSpecular = m.HasColorSpecular ? (Color?)ConvertMaterialColor(m.ColorSpecular) : null, ColorEmissive = m.HasColorEmissive ? (Color?)ConvertMaterialColor(m.ColorEmissive) : null, ColorTransparent = m.HasColorTransparent ? (Color?)ConvertMaterialColor(m.ColorTransparent) : null, ColorReflective = m.HasColorReflective ? (Color?)ConvertMaterialColor(m.ColorReflective) : null, TextureEmissive = m.HasTextureDiffuse ? ConvertMaterialTexture(m.TextureEmissive) : null, TextureAmbient = m.HasTextureAmbient ? ConvertMaterialTexture(m.TextureAmbient) : null, TextureDisplacement = m.HasTextureDisplacement ? ConvertMaterialTexture(m.TextureDisplacement) : null, TextureSpecular = m.HasTextureSpecular ? ConvertMaterialTexture(m.TextureSpecular) : null, TextureDiffuse = m.HasTextureDiffuse ? ConvertMaterialTexture(m.TextureDiffuse) : null, TextureHeight = m.HasTextureHeight ? ConvertMaterialTexture(m.TextureHeight) : null, TextureLightMap = m.HasTextureLightMap ? ConvertMaterialTexture(m.TextureLightMap) : null, TextureNormal = m.HasTextureNormal ? ConvertMaterialTexture(m.TextureNormal) : null, TextureOpacity = m.HasTextureOpacity ? ConvertMaterialTexture(m.TextureOpacity) : null, TextureReflection = m.HasTextureReflection ? ConvertMaterialTexture(m.TextureReflection) : null, PowerSpecular = m.HasShininess ? (float?)(m.Shininess / 255f) : null, }); }
public static Model <T, RealtimeMaterial> LoadFromFileWithRealtimeMaterial <T>(string baseDirectory, string localPath, VertexRuntimeTypes vertexType, PostProcessSteps flags = DefaultPostProcessSteps) where T : struct, VertexLocateable { if (!Verifier.VerifyVertexStruct <T>(vertexType)) { throw new ArgumentException($"Vertex Type Mismatch AssimpLoader"); } string filePath = Path.Combine(baseDirectory, localPath); string[] directoryStructure = localPath.Split('/'); string modelDir = directoryStructure[0]; AssimpContext assimpContext = new AssimpContext(); Assimp.Scene pScene = assimpContext.ImportFile(filePath, flags); int meshCount = pScene.MeshCount; Mesh <T>[] meshes = new Mesh <T> [meshCount]; RealtimeMaterial[] materials = new RealtimeMaterial[meshCount]; ushort[][] meshIndicies = new ushort[meshCount][]; for (int i = 0; i < meshCount; i++) { var aiMesh = pScene.Meshes[i]; var vertexCount = aiMesh.VertexCount; if (vertexCount == 0) { continue; } Assimp.Material aiMaterial = pScene.Materials[aiMesh.MaterialIndex]; var material = aiMaterial.ToRealtimeMaterial(); T[] meshDefinition = new T[vertexCount]; for (int j = 0; j < vertexCount; j++) { byte[] bytes = GenerateVertexBytesArrayFromAssimp(vertexType, aiMesh, j); meshDefinition[j] = ByteMarshal.ByteArrayToStructure <T>(bytes); } materials[i] = material; var faceCount = aiMesh.FaceCount; meshIndicies[i] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndicies[i][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndicies[i][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndicies[i][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshes[i] = new Mesh <T>(meshDefinition, meshIndicies[i]); } return(new Model <T, RealtimeMaterial>(modelDir, meshes, materials)); }
private static Material ConvertMaterialFromAiMaterial(Ai.Material aiMaterial, string texturesDirectory, TextureSet textureSet) { Material material = new Material(); material.Shader = "BLINN"; material.Field02 = 2688; material.Name = aiMaterial.Name; material.Field25 = 1; if (aiMaterial.HasColorDiffuse) { material.DiffuseColor = aiMaterial.ColorDiffuse.ToMML(); } else { material.DiffuseColor = new Color(1, 1, 1, 1); } if (aiMaterial.HasColorAmbient) { material.AmbientColor = aiMaterial.ColorAmbient.ToMML(); } else { material.AmbientColor = new Color(1, 1, 1, 1); } if (aiMaterial.HasColorSpecular) { material.SpecularColor = aiMaterial.ColorSpecular.ToMML(); } else { material.SpecularColor = new Color(0.5f, 0.5f, 0.5f, 1); } if (aiMaterial.HasColorEmissive) { material.EmissionColor = aiMaterial.ColorEmissive.ToMML(); } else { material.EmissionColor = new Color(0, 0, 0, 1); } if (aiMaterial.HasShininess && aiMaterial.ShadingMode == Ai.ShadingMode.Phong) { material.Shininess = aiMaterial.Shininess; } else { material.Shininess = 50f; } Texture texture; if (aiMaterial.HasTextureDiffuse && (texture = ConvertTexture(aiMaterial.TextureDiffuse.FilePath, texturesDirectory, textureSet)) != null) { material.Field00 |= 1; material.Diffuse.TextureId = texture.Id; material.Diffuse.Field02 = 241; } if (aiMaterial.HasTextureAmbient && (texture = ConvertTexture(aiMaterial.TextureAmbient.FilePath, texturesDirectory, textureSet)) != null) { material.Ambient.TextureId = texture.Id; material.Ambient.Field02 = 241; } if (aiMaterial.HasTextureNormal && (texture = ConvertTexture(aiMaterial.TextureNormal.FilePath, texturesDirectory, textureSet)) != null) { material.Field00 |= 256; material.Normal.TextureId = texture.Id; material.Normal.Field02 = 242; } if (aiMaterial.HasTextureSpecular && (texture = ConvertTexture(aiMaterial.TextureSpecular.FilePath, texturesDirectory, textureSet)) != null) { material.Field00 |= 128; material.Specular.TextureId = texture.Id; material.Specular.Field02 = 243; } if (aiMaterial.HasTextureReflection && (texture = ConvertTexture(aiMaterial.TextureReflection.FilePath, texturesDirectory, textureSet)) != null) { material.Field00 |= 33832; material.Reflection.TextureId = texture.Id; material.Reflection.Field02 = 1017; } if (aiMaterial.GetMaterialTexture(Ai.TextureType.Shininess, 0, out Ai.TextureSlot shininess) && (texture = ConvertTexture(shininess.FilePath, texturesDirectory, textureSet)) != null) { material.Field00 |= 8192; material.Tangent.TextureId = texture.Id; material.Tangent.Field02 = 246; } foreach (var materialTexture in material.MaterialTextures) { if (materialTexture == material.Diffuse) { materialTexture.Field00 = materialTexture.IsActive ? 82288 : 48; } materialTexture.Field05 = 1; if (materialTexture.IsActive) { materialTexture.Field01 = 0x2418C3; materialTexture.Field06 = 1; materialTexture.Field11 = 1; materialTexture.Field16 = 1; materialTexture.Field21 = 1; } } return(material); }
private static MaterialTexture CreateMaterialTextureFromAiTextureSlot(Ai.TextureSlot aiTextureSlot, Ai.Material aiMaterial, Material material, TextureSet textureSet, string texturesDirectoryPath) { MaterialTextureType type; MaterialFlags flags; // skyth y u no use dictionary switch (aiTextureSlot.TextureType) { case Ai.TextureType.Diffuse: case Ai.TextureType.Ambient: type = MaterialTextureType.Color; flags = MaterialFlags.Color; break; case Ai.TextureType.Specular: type = MaterialTextureType.Specular; flags = MaterialFlags.Specular; break; case Ai.TextureType.Normals: type = MaterialTextureType.Normal; flags = MaterialFlags.Normal; break; case Ai.TextureType.Opacity: type = MaterialTextureType.Transparency; flags = MaterialFlags.Transparency; break; case Ai.TextureType.Reflection: type = MaterialTextureType.Reflection; flags = MaterialFlags.Environment; break; default: return(null); } int materialTextureIndex = -1; for (int i = 0; i < material.MaterialTextures.Length; i++) { if (material.MaterialTextures[i].Type != MaterialTextureType.None) { continue; } materialTextureIndex = i; break; } if (materialTextureIndex == -1) { return(null); } var texture = CreateTextureFromFilePath(aiTextureSlot.FilePath, type == MaterialTextureType.Normal ? TextureFormat.ATI2 : TextureFormat.Unknown, texturesDirectoryPath, textureSet); if (texture == null) { return(null); } var materialTexture = new MaterialTexture(); materialTexture.RepeatU = aiTextureSlot.WrapModeU == Ai.TextureWrapMode.Wrap; materialTexture.RepeatV = aiTextureSlot.WrapModeV == Ai.TextureWrapMode.Wrap; materialTexture.MirrorU = aiTextureSlot.WrapModeU == Ai.TextureWrapMode.Mirror; materialTexture.MirrorV = aiTextureSlot.WrapModeV == Ai.TextureWrapMode.Mirror; materialTexture.ClampToEdge = aiTextureSlot.WrapModeU == Ai.TextureWrapMode.Clamp && aiTextureSlot.WrapModeV == Ai.TextureWrapMode.Clamp; if (texture.ArraySize == 6 || aiTextureSlot.Mapping == Ai.TextureMapping.Box) { materialTexture.TextureCoordinateTranslationType = MaterialTextureCoordinateTranslationType.Cube; if (type == MaterialTextureType.Reflection) { type = MaterialTextureType.EnvironmentCube; } } else if (aiTextureSlot.Mapping == Ai.TextureMapping.Sphere) { materialTexture.TextureCoordinateTranslationType = MaterialTextureCoordinateTranslationType.Sphere; if (type == MaterialTextureType.Reflection) { type = MaterialTextureType.EnvironmentSphere; } } materialTexture.Blend = type == MaterialTextureType.Specular ? 1u : 7; materialTexture.Filter = 2; materialTexture.MipMap = 2; materialTexture.Type = type; materialTexture.TextureId = texture.Id; material.Flags |= flags; material.MaterialTextures[materialTextureIndex] = materialTexture; return(materialTexture); }
private static Mesh ConvertAssimpMeshToGeometry(Ai.Mesh aiMesh, Ai.Material material, Dictionary <string, NodeInfo> nodeLookup, ref int nextBoneIndex, Dictionary <int, List <int> > nodeToBoneIndices, List <Matrix4x4> boneInverseBindMatrices, ref Matrix4x4 nodeWorldTransform, ref Matrix4x4 nodeInverseWorldTransform, List <Vector3> transformedVertices, ModelConverterOptions options) { if (!aiMesh.HasVertices) { throw new Exception("Assimp mesh has no vertices"); } var geometry = new Mesh(); var geometryTransformedVertices = new Vector3[aiMesh.VertexCount]; geometry.Vertices = aiMesh.Vertices .Select(x => new Vector3(x.X, x.Y, x.Z)) .ToArray(); for (int i = 0; i < geometry.Vertices.Length; i++) { geometryTransformedVertices[i] = Vector3.Transform(geometry.Vertices[i], nodeWorldTransform); } transformedVertices.AddRange(geometryTransformedVertices); if (aiMesh.HasNormals) { geometry.Normals = aiMesh.Normals .Select(x => new Vector3(x.X, x.Y, x.Z)) .ToArray(); } if (aiMesh.HasTextureCoords(0)) { geometry.TexCoordsChannel0 = aiMesh.TextureCoordinateChannels[0] .Select(x => new Vector2(x.X, x.Y)) .ToArray(); } if (aiMesh.HasTextureCoords(1)) { geometry.TexCoordsChannel1 = aiMesh.TextureCoordinateChannels[1] .Select(x => new Vector2(x.X, x.Y)) .ToArray(); } if (aiMesh.HasTextureCoords(2)) { geometry.TexCoordsChannel2 = aiMesh.TextureCoordinateChannels[2] .Select(x => new Vector2(x.X, x.Y)) .ToArray(); } if (aiMesh.HasVertexColors(0)) { geometry.ColorChannel0 = aiMesh.VertexColorChannels[0] .Select(x => ( uint )(( byte )(x.B * 255f) | ( byte )(x.G * 255f) << 8 | ( byte )(x.R * 255f) << 16 | ( byte )(x.A * 255f) << 24)) .ToArray(); } else if (options.GenerateVertexColors) { geometry.ColorChannel0 = new uint[geometry.VertexCount]; for (int i = 0; i < geometry.ColorChannel0.Length; i++) { geometry.ColorChannel0[i] = 0xFFFFFFFF; } } if (aiMesh.HasVertexColors(1)) { geometry.ColorChannel1 = aiMesh.VertexColorChannels[1] .Select(x => ( uint )(( byte )(x.B * 255f) | ( byte )(x.G * 255f) << 8 | ( byte )(x.R * 255f) << 16 | ( byte )(x.A * 255f) << 24)) .ToArray(); } if (aiMesh.HasFaces) { geometry.TriangleIndexFormat = aiMesh.VertexCount <= ushort.MaxValue ? TriangleIndexFormat.UInt16 : TriangleIndexFormat.UInt32; geometry.Triangles = aiMesh.Faces .Select(x => new Triangle(( uint )x.Indices[0], ( uint )x.Indices[1], ( uint )x.Indices[2])) .ToArray(); } if (aiMesh.HasBones) { geometry.VertexWeights = new VertexWeight[geometry.VertexCount]; for (int i = 0; i < geometry.VertexWeights.Length; i++) { geometry.VertexWeights[i].Indices = new byte[4]; geometry.VertexWeights[i].Weights = new float[4]; } var vertexWeightCounts = new int[geometry.VertexCount]; for (var i = 0; i < aiMesh.Bones.Count; i++) { var aiMeshBone = aiMesh.Bones[i]; // Find node index for the bone var boneLookupData = nodeLookup[AssimpConverterCommon.UnescapeName(aiMeshBone.Name)]; int nodeIndex = boneLookupData.Index; // Calculate inverse bind matrix var boneNode = boneLookupData.Node; var bindMatrix = boneNode.WorldTransform * nodeInverseWorldTransform; if (options.ConvertSkinToZUp) { bindMatrix *= YToZUpMatrix; } Matrix4x4.Invert(bindMatrix, out var inverseBindMatrix); // Get bone index int boneIndex; if (!nodeToBoneIndices.TryGetValue(nodeIndex, out var boneIndices)) { // No entry for the node was found, so we add a new one boneIndex = nextBoneIndex++; nodeToBoneIndices.Add(nodeIndex, new List <int>() { boneIndex }); boneInverseBindMatrices.Add(inverseBindMatrix); } else { // Entry for the node was found // Try to find the bone index based on whether the inverse bind matrix matches boneIndex = -1; foreach (int index in boneIndices) { if (boneInverseBindMatrices[index].Equals(inverseBindMatrix)) { boneIndex = index; } } if (boneIndex == -1) { // None matching inverse bind matrix was found, so we add a new entry boneIndex = nextBoneIndex++; nodeToBoneIndices[nodeIndex].Add(boneIndex); boneInverseBindMatrices.Add(inverseBindMatrix); } } foreach (var aiVertexWeight in aiMeshBone.VertexWeights) { int vertexWeightCount = vertexWeightCounts[aiVertexWeight.VertexID]++; geometry.VertexWeights[aiVertexWeight.VertexID].Indices[vertexWeightCount] = ( byte )boneIndex; geometry.VertexWeights[aiVertexWeight.VertexID].Weights[vertexWeightCount] = aiVertexWeight.Weight; } } } geometry.MaterialName = AssimpConverterCommon.UnescapeName(material.Name); geometry.BoundingBox = BoundingBox.Calculate(geometry.Vertices); geometry.BoundingSphere = BoundingSphere.Calculate(geometry.BoundingBox.Value, geometry.Vertices); geometry.Flags |= GeometryFlags.Flag80000000; return(geometry); }
private void AddPBRTextures(AssimpMaterial assimpMaterial, string filePath, string customTexturesFolder, bool useStrictFileNameMatch, bool supportDDSTextures, PhysicallyBasedMaterial physicallyBasedMaterial) { //PhysicallyBasedMaterial physicallyBasedMaterial; string diffuseTextureFileName = assimpMaterial.TextureDiffuse.FilePath; if (!string.IsNullOrEmpty(customTexturesFolder)) { diffuseTextureFileName = System.IO.Path.Combine(customTexturesFolder, System.IO.Path.GetFileName(diffuseTextureFileName)); } else if (!System.IO.Path.IsPathRooted(diffuseTextureFileName)) { diffuseTextureFileName = System.IO.Path.Combine(filePath, diffuseTextureFileName); } string folderName = System.IO.Path.GetDirectoryName(diffuseTextureFileName); if (!System.IO.Directory.Exists(folderName)) { Log($" Folder for diffuse texture does not exist: {folderName ?? ""}:"); return; } if (_folderImageFiles == null) { _folderImageFiles = new Dictionary <string, string[]>(); } string[] allFilesInFolder; if (!_folderImageFiles.TryGetValue(folderName, out allFilesInFolder)) { allFilesInFolder = System.IO.Directory.GetFiles(folderName, "*.*", SearchOption.TopDirectoryOnly); _folderImageFiles.Add(folderName, allFilesInFolder); } //TextureMapTypes textureMapType = KnownTextureFiles.GetTextureType(diffuseTextureFileName); string fileNameWithoutKnownSuffix = KnownTextureFiles.GetFileNameWithoutKnownSuffix(diffuseTextureFileName); // Get material files that start with the diffuse texture file name without a suffix List <string> materialFiles; if (useStrictFileNameMatch) { materialFiles = allFilesInFolder.Where(f => fileNameWithoutKnownSuffix == KnownTextureFiles.GetFileNameWithoutKnownSuffix(f)).ToList(); } else { materialFiles = allFilesInFolder.Where(f => f.IndexOf(fileNameWithoutKnownSuffix, 0, StringComparison.OrdinalIgnoreCase) != -1).ToList(); } _textureFiles.Clear(); if (materialFiles.Count == 0) { Log($" Folder ({folderName}) for {assimpMaterial.Name ?? ""} material does not define any texture files"); return; } else { bool hasDiffuseTexture = false; foreach (var materialFile in materialFiles) { if (!TextureLoader.IsSupportedFile(materialFile, supportDDSTextures)) // Skip unsupported files { continue; } var textureMapType = KnownTextureFiles.GetTextureType(materialFile); if (textureMapType == TextureMapTypes.Unknown) { if (!hasDiffuseTexture) { textureMapType = TextureMapTypes.DiffuseColor; // First unknown file type is considered to be diffuse texture file } else { continue; // Unknown file type } } bool isDiffuseTexture = (textureMapType == TextureMapTypes.DiffuseColor || textureMapType == TextureMapTypes.Albedo || textureMapType == TextureMapTypes.BaseColor); string existingTextureFileName; if (_textureFiles.TryGetValue(textureMapType, out existingTextureFileName)) { // Map for this texture type already exist var existingFileExtension = System.IO.Path.GetExtension(existingTextureFileName); if (existingFileExtension != null && existingFileExtension.Equals(".dds", StringComparison.OrdinalIgnoreCase)) { continue; // DDS texture already found for this texture type - we will use existing dds texture } } hasDiffuseTexture |= isDiffuseTexture; _textureFiles.Add(textureMapType, materialFile); Log(" " + textureMapType + ": " + System.IO.Path.GetFileName(materialFile)); } if (_textureFiles.Count > 0) { foreach (var oneTextureFile in _textureFiles) { var textureType = oneTextureFile.Key; var oneFileName = oneTextureFile.Value; ShaderResourceView shaderResourceView; if (!_texturesCache.TryGetValue(oneFileName, out shaderResourceView)) { var isBaseColor = (textureType == TextureMapTypes.BaseColor || textureType == TextureMapTypes.Albedo || textureType == TextureMapTypes.DiffuseColor); // To load a texture from file, you can use the TextureLoader.LoadShaderResourceView (this supports loading standard image files and also loading dds files). // This method returns a ShaderResourceView and it can also set a textureInfo parameter that defines some of the properties of the loaded texture (bitmap size, dpi, format, hasTransparency). TextureInfo textureInfo; shaderResourceView = Ab3d.DirectX.TextureLoader.LoadShaderResourceView(MainDXViewportView.DXScene.Device, oneFileName, loadDdsIfPresent: true, convertTo32bppPRGBA: isBaseColor, generateMipMaps: true, textureInfo: out textureInfo); physicallyBasedMaterial.TextureMaps.Add(new TextureMapInfo((Ab3d.DirectX.Materials.TextureMapTypes)textureType, shaderResourceView, null, oneFileName)); if (isBaseColor) { // Get recommended BlendState based on HasTransparency and HasPreMultipliedAlpha values. // Possible values are: CommonStates.Opaque, CommonStates.PremultipliedAlphaBlend or CommonStates.NonPremultipliedAlphaBlend. var recommendedBlendState = MainDXViewportView.DXScene.DXDevice.CommonStates.GetRecommendedBlendState(textureInfo.HasTransparency, textureInfo.HasPremultipliedAlpha); physicallyBasedMaterial.BlendState = recommendedBlendState; physicallyBasedMaterial.HasTransparency = textureInfo.HasTransparency; } _texturesCache.Add(oneFileName, shaderResourceView); } } } } }
public override void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { ApplyFixedFunctionMaterial(mesh, mat, textured, shaded); }
private MonoKnight.Mesh ProcessMesh(Assimp.Mesh mesh, Assimp.Scene scene) { List <Vertex> vertices = new List <Vertex>(); List <int> indices = new List <int>(); List <Texture> textures = new List <Texture>(); // var boneDic = new Dictionary<string, Bone>(); //// //var invertGlobalTransform = AssimpMat4ToOpenTKMat4(scene.RootNode.Transform).Inverted(); // // // if(mesh.HasBones) // { // for (int i = 0; i < mesh.BoneCount; i++) // { // var assimpBone = mesh.Bones[i]; // if (!boneDic.ContainsKey(assimpBone.Name)) //{ // var bone = new Bone(); // bone.name = assimpBone.Name; // bone.offset = AssimpMat4ToOpenTKMat4(assimpBone.OffsetMatrix); // for (int j = 0; j < assimpBone.VertexWeightCount; j++) // { // VertexWeight vertexWeight; // vertexWeight.vertexId = assimpBone.VertexWeights[j].VertexID; // vertexWeight.weight = assimpBone.VertexWeights[j].Weight; // bone.weightList.Add(vertexWeight); // } // boneDic[assimpBone.Name] = bone; //} // } //} // for (int i = 0; i < mesh.VertexCount; i++) { Vertex vertex = new Vertex(); Vector3 vector = new Vector3(); vector.X = mesh.Vertices[i].X; vector.Y = mesh.Vertices[i].Y; vector.Z = mesh.Vertices[i].Z; vertex.position = vector; // if (mesh.HasNormals) { vector.X = mesh.Normals[i].X; vector.Y = mesh.Normals[i].Y; vector.Z = mesh.Normals[i].Z; vertex.normal = vector; } else { vertex.normal = Vector3.Zero; } // if (mesh.HasTextureCoords(0)) { Vector2 vec = new Vector2(); vec.X = mesh.TextureCoordinateChannels[0][i].X; vec.Y = mesh.TextureCoordinateChannels[0][i].Y; vertex.texCoord = vec; } else { vertex.texCoord = new Vector2(0.0f, 0.0f); } vertices.Add(vertex); } for (int i = 0; i < mesh.FaceCount; i++) { Face face = mesh.Faces[i]; for (int j = 0; j < face.IndexCount; j++) { indices.Add(face.Indices[j]); } } if (mesh.MaterialIndex >= 0) { Assimp.Material material = scene.Materials[mesh.MaterialIndex]; for (int i = 0; i < material.GetMaterialTextures(TextureType.Diffuse).Length; i++) { var texSlot = material.GetMaterialTextures(TextureType.Diffuse)[i]; Texture texture = new Texture(); texture.LoadFromPath(Path.Combine(modelDirPath, texSlot.FilePath)); textures.Add(texture); } //TODO other type texture } // return(new Mesh(ref vertices, ref indices, ref textures)); }
// Processa a malha lida pelo Assimp private Mesh ProcessMesh(Assimp.Mesh amesh, Assimp.Scene scene) { List <Vertex> vertices = new List <Vertex>(); List <uint> indices = new List <uint>(); List <Texture> textures = new List <Texture>(); Random r = new Random(); // Carrego pela malha do Assimp, a lista de vértice com a normal, UV (ST), tangente, bitangente for (int i = 0; i < amesh.VertexCount; i++) { Vertex vertex = new Vertex(); vertex.positionX = amesh.Vertices[i].X; vertex.positionY = amesh.Vertices[i].Y; vertex.positionZ = amesh.Vertices[i].Z; if (amesh.HasNormals) { vertex.normalX = amesh.Normals[i].X; vertex.normalY = amesh.Normals[i].Y; vertex.normalZ = amesh.Normals[i].Z; } if (amesh.HasTextureCoords(0)) { vertex.textureX = amesh.TextureCoordinateChannels[0][i].X; vertex.textureY = amesh.TextureCoordinateChannels[0][i].Y; vertex.bitangentX = amesh.BiTangents[i].X; vertex.bitangentY = amesh.BiTangents[i].Y; vertex.bitangentZ = amesh.BiTangents[i].Z; vertex.tangentX = amesh.Tangents[i].X; vertex.tangentY = amesh.Tangents[i].Y; vertex.tangentZ = amesh.Tangents[i].Z; } else { vertex.textureX = 0f; vertex.textureY = 0f; } vertex.colorA = (float)r.NextDouble(); vertex.colorR = (float)r.NextDouble(); vertex.colorB = (float)r.NextDouble(); vertex.colorG = 1f; vertices.Add(vertex); } // Carrega as informações das faces dos triâgulos, ou seja, informa quais vertices formam um triângulo da malha for (int i = 0; i < amesh.FaceCount; i++) { Assimp.Face face = amesh.Faces[i]; for (int j = 0; j < face.IndexCount; j++) { indices.Add((uint)face.Indices[j]); } } // Verifica se possui alguma textura ou arquivo mtl vinculado ao obj if (amesh.MaterialIndex >= 0) { Assimp.Material material = scene.Materials[amesh.MaterialIndex]; List <Texture> diffuseMaps = loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse"); textures.InsertRange(textures.Count, diffuseMaps); List <Texture> specularMaps = loadMaterialTextures(material, TextureType.Specular, "texture_specular"); textures.InsertRange(textures.Count, specularMaps); List <Texture> normalMaps = loadMaterialTextures(material, TextureType.Height, "texture_normal"); textures.InsertRange(textures.Count, normalMaps); } return(new Mesh(vertices, indices, textures)); }
private void LoadFromNode(Assimp.Scene _scene, Assimp.Node _node, GraphicsDevice _device, SharpDX.Toolkit.Content.ContentManager _content, Matrix _transform) { // Sum up transformations recursively _transform = FromMatrix(_node.Transform) * _transform; Matrix transformInvTr = Helpers.CreateInverseTranspose(ref _transform); // Recursive load from scene if (_node.HasChildren) { foreach (Assimp.Node node in _node.Children) { LoadFromNode(_scene, node, _device, _content, _transform); } } if (_node.HasMeshes) { foreach (int meshIndex in _node.MeshIndices) { Assimp.Mesh mesh = _scene.Meshes[meshIndex]; ModelMesh modelMesh = new ModelMesh(); // if mesh has a diffuse texture extract it Assimp.Material material = _scene.Materials[mesh.MaterialIndex]; if (material != null && material.GetTextureCount(TextureType.Diffuse) > 0) { TextureSlot texture = material.GetTexture(TextureType.Diffuse, 0); // Create new texture for mesh var dxtexture = _content.Load <Texture2D>(texture.FilePath); modelMesh.DiffuseTexture = dxtexture; } // Position is mandarory if (!mesh.HasVertices) { throw new Exception("Model::Model(): Model has no vertices."); } // Determine the elements in the vertex bool hasTexCoords = mesh.HasTextureCoords(0); bool hasColors = mesh.HasVertexColors(0); bool hasNormals = mesh.HasNormals; bool hasTangents = mesh.Tangents != null; bool hasBitangents = mesh.BiTangents != null; int numElements = 1 + (hasTexCoords ? 1 : 0) + (hasColors ? 1 : 0) + (hasNormals ? 1 : 0) + (hasTangents ? 1 : 0) + (hasBitangents ? 1 : 0); // Create vertex element list: Here starts the section of creating SharpDX stuff VertexElement[] vertexElements = new VertexElement[numElements]; uint elementIndex = 0; vertexElements[elementIndex++] = new VertexElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0); int vertexSize = Utilities.SizeOf <Vector3>(); if (hasColors) { vertexElements[elementIndex++] = new VertexElement("COLOR", 0, SharpDX.DXGI.Format.R8G8B8A8_UInt, vertexSize); vertexSize += Utilities.SizeOf <Color>(); } if (hasNormals) { vertexElements[elementIndex++] = new VertexElement("NORMAL", 0, SharpDX.DXGI.Format.R32G32B32_Float, vertexSize); vertexSize += Utilities.SizeOf <Vector3>(); } if (hasTangents) { vertexElements[elementIndex++] = new VertexElement("TANGENT", 0, SharpDX.DXGI.Format.R32G32B32_Float, vertexSize); vertexSize += Utilities.SizeOf <Vector3>(); } if (hasBitangents) { vertexElements[elementIndex++] = new VertexElement("BITANGENT", 0, SharpDX.DXGI.Format.R32G32B32_Float, vertexSize); vertexSize += Utilities.SizeOf <Vector3>(); } if (hasTexCoords) { vertexElements[elementIndex++] = new VertexElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, vertexSize); vertexSize += Utilities.SizeOf <Vector2>(); } // Set the vertex elements and size modelMesh.InputLayout = VertexInputLayout.New(VertexBufferLayout.New(0, vertexElements)); modelMesh.VertexSize = vertexSize; // Determine primitive type switch (mesh.PrimitiveType) { case Assimp.PrimitiveType.Point: modelMesh.PrimitiveTopology = SharpDX.Toolkit.Graphics.PrimitiveType.PointList; break; case Assimp.PrimitiveType.Line: modelMesh.PrimitiveTopology = SharpDX.Toolkit.Graphics.PrimitiveType.LineList; break; case Assimp.PrimitiveType.Triangle: modelMesh.PrimitiveTopology = SharpDX.Toolkit.Graphics.PrimitiveType.TriangleList; break; default: throw new Exception("Model::Model(): Unknown primitive type"); } // Create data stream for vertices //System.IO.MemoryStream vertexStream = new System.IO.MemoryStream(mesh.VertexCount * vertexSize); DataStream vertexStream = new DataStream(mesh.VertexCount * vertexSize, true, true); for (int i = 0; i < mesh.VertexCount; i++) { vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.Vertices[i]), ref _transform)); if (hasColors) { vertexStream.Write <Color>(FromColor(mesh.GetVertexColors(0)[i])); } if (hasNormals) { vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.Normals[i]), ref transformInvTr)); } if (hasTangents) { vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.Tangents[i]), ref transformInvTr)); } if (hasBitangents) { vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.BiTangents[i]), ref transformInvTr)); } if (hasTexCoords) { vertexStream.Write <Vector2>(new Vector2(mesh.GetTextureCoords(0)[i].X, mesh.GetTextureCoords(0)[i].Y)); } } vertexStream.Position = 0; // Create new vertex buffer var vertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New(_device, vertexStream); // Add it to the mesh modelMesh.VertexBuffer = vertexBuffer; modelMesh.VertexCount = mesh.VertexCount; modelMesh.PrimitiveCount = mesh.FaceCount; // Create new index buffer var indexBuffer = SharpDX.Toolkit.Graphics.Buffer.Index.New(_device, mesh.GetIndices()); // Add it to the mesh modelMesh.IndexBuffer = indexBuffer; modelMesh.IndexCount = mesh.GetIndices().GetLength(0); m_meshes.Add(modelMesh); } } }
/// <summary> /// Helper method, used to transfer information from Material to ClientMaterial /// </summary> /// <param name="mat"> the source Material </param> /// <param name="myMat"> the destination ClientMaterial </param> protected void ApplyMaterial(Material mat, ClientMaterial myMat) { if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { TextureSlot tex; if (mat.GetMaterialTexture(TextureType.Diffuse, 0, out tex)) { ShaderResourceView temp; myMat.setDiffuseTexture(temp = CreateTexture(Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileName(tex.FilePath)))); myMat.setTexCount(temp == null ? 0 : 1); } else { myMat.setDiffuseTexture(null); myMat.setTexCount(1); } } // copies over all the material properties to the struct // sets the diffuse color Color4 color = new Color4(.4f, .4f, .4f, 1.0f); // default is light grey if (mat.HasColorDiffuse) { myMat.setDiffuse(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setDiffuse(color.Red, color.Green, color.Blue, color.Alpha); } // sets the specular color color = new Color4(0.1f, 0.1f, 0.1f, 1.0f); // default is non-specular if (mat.HasColorSpecular) { myMat.setSpecular(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setSpecular(color.Red, color.Green, color.Blue, color.Alpha); } // sets the ambient color color = new Color4(.3f, .3f, .3f, 1.0f); // default is dark grey if (mat.HasColorAmbient) { myMat.setAmbient(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setAmbient(color.Red, color.Green, color.Blue, color.Alpha); } // sets the emissive color color = new Color4(0, 0, 0, 1.0f); // default is black if (mat.HasColorEmissive) { myMat.setEmissive(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setEmissive(color.Red, color.Green, color.Blue, color.Alpha); } // sets the shininess float shininess = 1; // default is 1 if (mat.HasShininess) { myMat.setShininess(mat.Shininess); } else { myMat.setShininess(shininess); } // sets the opacity float opacity = 1; // default is 1 if (mat.HasOpacity) { myMat.setOpacity(mat.Opacity); } else { myMat.setOpacity(mat.Opacity); } }
public override Node3D LoadNode(string path) { if (NormBlank == null) { NormBlank = new Texture.Texture2D("data/tex/normblank.png", Texture.LoadMethod.Single, false); DiffBlank = new Texture.Texture2D("data/tex/diffblank.png", Texture.LoadMethod.Single, false); SpecBlank = new Texture.Texture2D("data/tex/specblank.png", Texture.LoadMethod.Single, false); } string ip = path; int ic = ip.LastIndexOf("/"); if (ic < 1) { ic = ip.LastIndexOf("\\"); } if (ic > 0) { IPath = ip.Substring(0, ic); } Entity3D root = new Entity3D(); string file = path; AssimpContext e = new Assimp.AssimpContext(); Assimp.Configs.NormalSmoothingAngleConfig c1 = new Assimp.Configs.NormalSmoothingAngleConfig(75); e.SetConfig(c1); Console.WriteLine("Impporting:" + file); Assimp.Scene s = null; try { s = e.ImportFile(file, PostProcessSteps.OptimizeGraph | PostProcessSteps.FindInvalidData | PostProcessSteps.FindDegenerates | PostProcessSteps.Triangulate | PostProcessSteps.ValidateDataStructure | PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals | PostProcessSteps.FixInFacingNormals | PostProcessSteps.GenerateSmoothNormals); if (s.HasAnimations) { return(LoadAnimNode(path)); } } catch (AssimpException ae) { Console.WriteLine(ae); Console.WriteLine("Failed to import"); Environment.Exit(-1); } Console.WriteLine("Imported."); Dictionary <string, Mesh3D> ml = new Dictionary <string, Mesh3D>(); List <Mesh3D> ml2 = new List <Mesh3D>(); Console.WriteLine("animCount:" + s.AnimationCount); Matrix4x4 tf = s.RootNode.Transform; tf.Inverse(); root.GlobalInverse = ToTK(tf); Dictionary <uint, List <VertexWeight> > boneToWeight = new Dictionary <uint, List <VertexWeight> >(); //root.Animator = new Animation.Animator(); //s.Animations[0].NodeAnimationChannels[0]. //s.Animations[0].anim // root.Animator.InitAssImp(model); foreach (Mesh m in s.Meshes) { Console.WriteLine("M:" + m.Name + " Bones:" + m.BoneCount); Console.WriteLine("AA:" + m.HasMeshAnimationAttachments); Material.Material3D vm = new Material.Material3D { ColorMap = DiffBlank, NormalMap = NormBlank, SpecularMap = SpecBlank }; Mesh3D m2 = new Mesh3D(m.GetIndices().Length, m.VertexCount); ml2.Add(m2); // ml.Add(m.Name, m2); for (int b = 0; b < m.BoneCount; b++) { string name = m.Bones[b].Name; } m2.Material = vm; // root.AddMesh(m2); m2.Name = m.Name; Assimp.Material mat = s.Materials[m.MaterialIndex]; TextureSlot t1; int sc = mat.GetMaterialTextureCount(TextureType.Unknown); Console.WriteLine("SC:" + sc); if (mat.HasColorDiffuse) { vm.Diff = CTV(mat.ColorDiffuse); Console.WriteLine("Diff:" + vm.Diff); } if (mat.HasColorSpecular) { // vm.Spec = CTV ( mat.ColorSpecular ); Console.WriteLine("Spec:" + vm.Spec); } if (mat.HasShininess) { //vm.Shine = 0.3f+ mat.Shininess; Console.WriteLine("Shine:" + vm.Shine); } Console.WriteLine("Spec:" + vm.Spec); //for(int ic = 0; ic < sc; ic++) ///{ if (sc > 0) { TextureSlot tex2 = mat.GetMaterialTextures(TextureType.Unknown)[0]; // vm.SpecularMap = new Texture.Texture2D ( IPath + "/" + tex2.FilePath, Texture.LoadMethod.Single, false ); } if (mat.GetMaterialTextureCount(TextureType.Normals) > 0) { TextureSlot ntt = mat.GetMaterialTextures(TextureType.Normals)[0]; Console.WriteLine("Norm:" + ntt.FilePath); vm.NormalMap = new Texture.Texture2D(IPath + "/" + ntt.FilePath, Vivid.Texture.LoadMethod.Single, false); } if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0]; Console.WriteLine("DiffTex:" + t1.FilePath); if (t1.FilePath != null) { //Console.WriteLine ( "Tex:" + t1.FilePath ); // Console.Write("t1:" + t1.FilePath); vm.ColorMap = new Texture.Texture2D(IPath + "/" + t1.FilePath.Replace(".dds", ".png"), Texture.LoadMethod.Single, false); if (File.Exists(IPath + "/" + "norm_" + t1.FilePath)) { vm.NormalMap = new Texture.Texture2D(IPath + "/" + "norm_" + t1.FilePath, Texture.LoadMethod.Single, false); } } } for (int i = 0; i < m2.NumVertices; i++) { Vector3D v = m.Vertices[i];// * new Vector3D(15, 15, 15); Vector3D n = new Vector3D(0, 1, 0); if (m.Normals != null && m.Normals.Count > i) { n = m.Normals[i]; } List <Vector3D> t = m.TextureCoordinateChannels[0]; Vector3D tan, bi; if (m.Tangents != null && m.Tangents.Count > 0) { tan = m.Tangents[i]; bi = m.BiTangents[i]; } else { tan = new Vector3D(0, 0, 0); bi = new Vector3D(0, 0, 0); } if (t.Count() == 0) { m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(new Vector3D(0, 0, 0))); } else { Vector3D tv = t[i]; tv.Y = 1.0f - tv.Y; m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(tv)); } //var v = new PosNormalTexTanSkinned(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3(), weights.First(), boneIndices); //verts.Add(v); } int[] id = m.GetIndices(); uint[] nd = new uint[id.Length]; for (int i = 0; i < id.Length; i += 3) { //Tri t = new Tri(); //t.V0 = (int)nd[i]; // t.V1 = (int)nd[i + 1]; // t.v2 = (int)nd[i + 2]; // nd[i] = (uint)id[i]; if (i + 2 < id.Length) { m2.SetTri(i / 3, id[i], id[i + 1], id[i + 2]); } } m2.Indices = nd; //m2.Scale(AssImpImport.ScaleX, AssImpImport.ScaleY, AssImpImport.ScaleZ); //m2.GenerateTangents ( ); m2.Final(); } ProcessNode(root, s.RootNode, ml2); /* * while (true) * { * } */ return(root as Node3D); }
public override Node3D LoadAnimNode(string path) { if (NormBlank == null) { NormBlank = new Texture.Texture2D("data/tex/normblank.png", Texture.LoadMethod.Single, false); DiffBlank = new Texture.Texture2D("data/tex/diffblank.png", Texture.LoadMethod.Single, false); SpecBlank = new Texture.Texture2D("data/tex/specblank.png", Texture.LoadMethod.Single, false); } AnimEntity3D root = new AnimEntity3D(); string file = path; AssimpContext e = new Assimp.AssimpContext(); Assimp.Configs.NormalSmoothingAngleConfig c1 = new Assimp.Configs.NormalSmoothingAngleConfig(75); e.SetConfig(c1); Console.WriteLine("Impporting:" + file); Assimp.Scene s = null; try { s = e.ImportFile(file, PostProcessSteps.OptimizeMeshes | PostProcessSteps.OptimizeGraph | PostProcessSteps.FindInvalidData | PostProcessSteps.FindDegenerates | PostProcessSteps.Triangulate | PostProcessSteps.ValidateDataStructure | PostProcessSteps.CalculateTangentSpace); } catch (AssimpException ae) { Console.WriteLine(ae); Console.WriteLine("Failed to import"); Environment.Exit(-1); } Console.WriteLine("Imported."); Dictionary <string, Mesh3D> ml = new Dictionary <string, Mesh3D>(); List <Mesh3D> ml2 = new List <Mesh3D>(); Console.WriteLine("animCount:" + s.AnimationCount); Matrix4x4 tf = s.RootNode.Transform; tf.Inverse(); root.GlobalInverse = ToTK(tf); Dictionary <uint, List <VertexWeight> > boneToWeight = new Dictionary <uint, List <VertexWeight> >(); root.Animator = new Animation.Animator(); if (s.AnimationCount > 0) { Console.WriteLine("Processing animations."); root.Animator.InitAssImp(s, root); Console.WriteLine("Processed."); _ta = root.Animator; } Dictionary <uint, List <VertexWeight> > vertToBoneWeight = new Dictionary <uint, List <VertexWeight> >(); //s.Animations[0].NodeAnimationChannels[0]. //s.Animations[0].anim // root.Animator.InitAssImp(model); List <Vivid.Data.Vertex> _vertices = new List <Vertex>(); List <Vivid.Data.Tri> _tris = new List <Tri>(); List <Vertex> ExtractVertices(Mesh m, Dictionary <uint, List <VertexWeight> > vtb) { List <Vertex> rl = new List <Vertex>(); for (int i = 0; i < m.VertexCount; i++) { Vector3D pos = m.HasVertices ? m.Vertices[i] : new Assimp.Vector3D(); Vector3D norm = m.HasNormals ? m.Normals[i] : new Assimp.Vector3D(); Vector3D tan = m.HasTangentBasis ? m.Tangents[i] : new Assimp.Vector3D(); Vector3D bi = m.HasTangentBasis ? m.BiTangents[i] : new Assimp.Vector3D(); Vertex nv = new Vertex { Pos = new OpenTK.Vector3(pos.X, pos.Y, pos.Z), Norm = new OpenTK.Vector3(norm.X, norm.Y, norm.Z), Tan = new OpenTK.Vector3(tan.X, tan.Y, tan.Z), BiNorm = new OpenTK.Vector3(bi.X, bi.Y, bi.Z) }; if (m.HasTextureCoords(0)) { Vector3D coord = m.TextureCoordinateChannels[0][i]; nv.UV = new OpenTK.Vector2(coord.X, 1 - coord.Y); } float[] weights = vtb[(uint)i].Select(w => w.Weight).ToArray(); byte[] boneIndices = vtb[(uint)i].Select(w => (byte)w.VertexID).ToArray(); nv.Weight = weights.First(); nv.BoneIndices = new int[4]; nv.BoneIndices[0] = boneIndices[0]; if (boneIndices.Length > 1) { nv.BoneIndices[1] = boneIndices[1]; } if (boneIndices.Length > 2) { nv.BoneIndices[2] = boneIndices[2]; } if (boneIndices.Length > 3) { nv.BoneIndices[3] = boneIndices[3]; } rl.Add(nv); } return(rl); } root.Mesh = new Mesh3D(); foreach (Mesh m in s.Meshes) { ExtractBoneWeightsFromMesh(m, vertToBoneWeight); Mesh3D.Subset sub = new Vivid.Data.Mesh3D.Subset { VertexCount = m.VertexCount, VertexStart = _vertices.Count, FaceStart = _tris.Count, FaceCount = m.FaceCount }; root.Mesh.Subs.Add(sub); List <Vertex> verts = ExtractVertices(m, vertToBoneWeight); _vertices.AddRange(verts); List <short> indices = m.GetIndices().Select(i => (short)(i + (uint)sub.VertexStart)).ToList(); for (int i = 0; i < indices.Count; i += 3) { Tri t = new Tri { V0 = indices[i], V1 = indices[i + 2], v2 = indices[i + 1] }; _tris.Add(t); } } root.Mesh.VertexData = _vertices.ToArray(); root.Mesh.TriData = _tris.ToArray(); root.Mesh.FinalAnim(); root.Renderer = new Visuals.VRMultiPassAnim(); root.Meshes.Add(root.Mesh.Clone()); root.Meshes[0].FinalAnim(); Material.Material3D m1 = new Material.Material3D { ColorMap = DiffBlank, NormalMap = NormBlank, SpecularMap = SpecBlank }; root.Mesh.Material = m1; root.Meshes[0].Material = root.Mesh.Material; Assimp.Material mat = s.Materials[0]; TextureSlot t1; int sc = mat.GetMaterialTextureCount(TextureType.Unknown); Console.WriteLine("SC:" + sc); if (mat.HasColorDiffuse) { m1.Diff = CTV(mat.ColorDiffuse); } if (mat.HasColorSpecular) { m1.Spec = CTV(mat.ColorSpecular); // Console.WriteLine("Spec:" + vm.Spec); } if (mat.HasShininess) { //vm.Shine = 0.3f+ mat.Shininess; // Console.WriteLine("Shine:" + vm.Shine); } //Console.WriteLine("Spec:" + vm.Spec); //for(int ic = 0; ic < sc; ic++) ///{ if (sc > 0) { TextureSlot tex2 = mat.GetMaterialTextures(TextureType.Unknown)[0]; m1.SpecularMap = new Texture.Texture2D(IPath + "/" + tex2.FilePath, Texture.LoadMethod.Single, false); } if (mat.GetMaterialTextureCount(TextureType.Normals) > 0) { TextureSlot ntt = mat.GetMaterialTextures(TextureType.Normals)[0]; Console.WriteLine("Norm:" + ntt.FilePath); m1.NormalMap = new Texture.Texture2D(IPath + "/" + ntt.FilePath, Vivid.Texture.LoadMethod.Single, false); } if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0]; Console.WriteLine("DiffTex:" + t1.FilePath); if (t1.FilePath != null) { try { // Console.Write("t1:" + t1.FilePath); m1.ColorMap = new Texture.Texture2D(IPath + "/" + t1.FilePath.Replace(".dds", ".png"), Texture.LoadMethod.Single, false); if (File.Exists(IPath + "norm" + t1.FilePath)) { // vm.TNorm = new Texture.VTex2D(IPath + "norm" + // t1.FilePath,Texture.LoadMethod.Single, false); // Console.WriteLine("TexLoaded"); } } catch { } } if (true) { if (new FileInfo(t1.FilePath).Exists == true) { // var tex = App.AppSal.CreateTex2D(); // tex.Path = t1.FilePath; // tex.Load(); //m2.DiffuseMap = tex; } } } //r1.LocalTurn = new OpenTK.Matrix4(s.Transform.A1, s.Transform.A2, s.Transform.A3, s.Transform.A4, s.Transform.B1, s.Transform.B2, s.Transform.B3, s.Transform.B4, s.Transform.C1, s.Transform.C2, s.Transform.C3, s.Transform.C4, s.Transform.D1, s.Transform.D2, s.Transform.D3, s.Transform.D4); root.LocalTurn = new OpenTK.Matrix4(s.RootNode.Transform.A1, s.RootNode.Transform.B1, s.RootNode.Transform.C1, s.RootNode.Transform.D1, s.RootNode.Transform.A2, s.RootNode.Transform.B2, s.RootNode.Transform.C2, s.RootNode.Transform.D2, s.RootNode.Transform.A3, s.RootNode.Transform.B3, s.RootNode.Transform.C3, s.RootNode.Transform.D3, s.RootNode.Transform.A4, s.RootNode.Transform.B4, s.RootNode.Transform.C4, s.RootNode.Transform.D4); root.LocalTurn = ToTK(s.RootNode.Children[0].Transform); OpenTK.Matrix4 lt = root.LocalTurn; root.LocalTurn = lt.ClearTranslation(); root.LocalTurn = root.LocalTurn.ClearScale(); root.LocalPos = lt.ExtractTranslation(); root.LocalScale = lt.ExtractScale(); root.AnimName = "Run"; return(root); /* * foreach (var m in s.Meshes) * { * Console.WriteLine("M:" + m.Name + " Bones:" + m.BoneCount); * Console.WriteLine("AA:" + m.HasMeshAnimationAttachments); * * var vm = new Material.Material3D(); * vm.TCol = DiffBlank; * vm.TNorm = NormBlank; * vm.TSpec = SpecBlank; * var m2 = new VMesh(m.GetIndices().Length, m.VertexCount); * ml2.Add(m2); * // ml.Add(m.Name, m2); * for (int b = 0; b < m.BoneCount; b++) * { * uint index = 0; * string name = m.Bones[b].Name; * } * m2.Mat = vm; * // root.AddMesh(m2); * m2.Name = m.Name; * var mat = s.Materials[m.MaterialIndex]; * TextureSlot t1; * * var sc = mat.GetMaterialTextureCount(TextureType.Unknown); * Console.WriteLine("SC:" + sc); * if (mat.HasColorDiffuse) * { * vm.Diff = CTV(mat.ColorDiffuse); * } * if (mat.HasColorSpecular) * { * vm.Spec = CTV(mat.ColorSpecular); * Console.WriteLine("Spec:" + vm.Spec); * } * if (mat.HasShininess) * { * //vm.Shine = 0.3f+ mat.Shininess; * Console.WriteLine("Shine:" + vm.Shine); * } * * Console.WriteLine("Spec:" + vm.Spec); * //for(int ic = 0; ic < sc; ic++) * ///{ * if (sc > 0) * { * var tex2 = mat.GetMaterialTextures(TextureType.Unknown)[0]; * vm.TSpec = new Texture.VTex2D(IPath + "/" + tex2.FilePath, Texture.LoadMethod.Single, false); * } * * if (mat.GetMaterialTextureCount(TextureType.Normals) > 0) * { * var ntt = mat.GetMaterialTextures(TextureType.Normals)[0]; * Console.WriteLine("Norm:" + ntt.FilePath); * vm.TNorm = new Texture.VTex2D(IPath + "/" + ntt.FilePath, Fusion3D.Texture.LoadMethod.Single, false); * } * * if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) * { * t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0]; * Console.WriteLine("DiffTex:" + t1.FilePath); * * if (t1.FilePath != null) * { * try * { * // Console.Write("t1:" + t1.FilePath); * vm.TCol = new Texture.VTex2D(IPath + "/" + t1.FilePath.Replace(".dds", ".png"), Texture.LoadMethod.Single, false); * if (File.Exists(IPath + "norm" + t1.FilePath)) * { * // vm.TNorm = new Texture.VTex2D(IPath + "norm" + * // t1.FilePath,Texture.LoadMethod.Single, false); * * // Console.WriteLine("TexLoaded"); * } * } * catch * { * } * } * if (true) * { * if (new FileInfo(t1.FilePath).Exists == true) * { * // var tex = App.AppSal.CreateTex2D(); * // tex.Path = t1.FilePath; * // tex.Load(); * //m2.DiffuseMap = tex; * } * } * } * * ExtractBoneWeightsFromMesh(m, vertToBoneWeight); * * for (int i = 0; i < m2.NumVertices; i++) * { * var v = m.Vertices[i];// * new Vector3D(15, 15, 15); * var n = m.Normals[i]; * var t = m.TextureCoordinateChannels[0]; * Vector3D tan, bi; * if (m.Tangents != null && m.Tangents.Count > 0) * { * tan = m.Tangents[i]; * bi = m.BiTangents[i]; * } * else * { * tan = new Vector3D(0, 0, 0); * bi = new Vector3D(0, 0, 0); * } * if (t.Count() == 0) * { * m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(new Vector3D(0, 0, 0))); * } * else * { * var tv = t[i]; * tv.Y = 1.0f - tv.Y; * m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(tv)); * } * * var weights = vertToBoneWeight[(uint)i].Select(w => w.Weight).ToArray(); * var boneIndices = vertToBoneWeight[(uint)i].Select(w => (byte)w.VertexID).ToArray(); * * m2.SetVertexBone(i, weights.First(), boneIndices); * * //var v = new PosNormalTexTanSkinned(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3(), weights.First(), boneIndices); * //verts.Add(v); * } * int[] id = m.GetIndices(); * int fi = 0; * uint[] nd = new uint[id.Length]; * for (int i = 0; i < id.Length; i += 3) * { * //Tri t = new Tri(); * //t.V0 = (int)nd[i]; * // t.V1 = (int)nd[i + 1]; * // t.v2 = (int)nd[i + 2]; * * // nd[i] = (uint)id[i]; * m2.SetTri(i / 3, (int)id[i], (int)id[i + 1], (int)id[i + 2]); * } * * m2.Indices = nd; * //m2.Scale(AssImpImport.ScaleX, AssImpImport.ScaleY, AssImpImport.ScaleZ); * m2.Final(); * } * * ProcessNode(root, s.RootNode, ml2); * * foreach (var ac in root.Clips) * { * Console.WriteLine("Anims:" + ac); * } * root.AnimName = "Run"; * /* * while (true) * { * } */ return(root as Node3D); }
private void ApplyFixedFunctionGhostMaterial(Mesh mesh, Material mat, bool shaded) { GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.DepthMask(false); var color = new Color4(.6f, .6f, .9f, 0.15f); shaded = shaded && (mesh == null || mesh.HasNormals); if (shaded) { GL.Enable(EnableCap.Lighting); GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, color); color = new Color4(1, 1, 1, 0.4f); GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, color); color = new Color4(.2f, .2f, .2f, 0.1f); GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Ambient, color); color = new Color4(0, 0, 0, 0.0f); GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, color); GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, 16.0f); } else { GL.Disable(EnableCap.Lighting); GL.Color3(color.R, color.G, color.B); } GL.Disable(EnableCap.ColorMaterial); GL.Disable(EnableCap.Texture2D); }
public static LoadedModels <RealtimeMaterial> LoadRealtimeModelsFromFile(string baseDirectory, string localPath, PostProcessSteps flags = DefaultPostProcessSteps) { string filePath = Path.Combine(baseDirectory, localPath); string[] directoryStructure = localPath.Split('/'); string modelDir = directoryStructure[0]; AssimpContext assimpContext = new AssimpContext(); Assimp.Scene pScene = assimpContext.ImportFile(filePath, flags); //TODO: Identify meshcount for each vertex type. Have to preprocess int meshCount = pScene.MeshCount; var loadedMeshCounts = pScene.GetHenzaiMeshCounts(); int meshCountP = loadedMeshCounts.meshCountP; int meshCountPC = loadedMeshCounts.meshCountPC; int meshCountPN = loadedMeshCounts.meshCountPN; int meshCountPT = loadedMeshCounts.meshCountPT; int meshCountPNT = loadedMeshCounts.meshCountPNT; int meshCountPNTTB = loadedMeshCounts.meshCountPNTTB; Mesh <VertexPosition>[] meshesP = new Mesh <VertexPosition> [meshCountP]; Mesh <VertexPositionColor>[] meshesPC = new Mesh <VertexPositionColor> [meshCountPC]; Mesh <VertexPositionNormal>[] meshesPN = new Mesh <VertexPositionNormal> [meshCountPN]; Mesh <VertexPositionTexture>[] meshesPT = new Mesh <VertexPositionTexture> [meshCountPT]; Mesh <VertexPositionNormalTexture>[] meshesPNT = new Mesh <VertexPositionNormalTexture> [meshCountPNT]; Mesh <VertexPositionNormalTextureTangentBitangent>[] meshesPNTTB = new Mesh <VertexPositionNormalTextureTangentBitangent> [meshCountPNTTB]; RealtimeMaterial[] materialsP = new RealtimeMaterial[meshCountP]; RealtimeMaterial[] materialsPC = new RealtimeMaterial[meshCountPC]; RealtimeMaterial[] materialsPN = new RealtimeMaterial[meshCountPN]; RealtimeMaterial[] materialsPT = new RealtimeMaterial[meshCountPT]; RealtimeMaterial[] materialsPNT = new RealtimeMaterial[meshCountPNT]; RealtimeMaterial[] materialsPNTTB = new RealtimeMaterial[meshCountPNTTB]; ushort[][] meshIndiciesP = new ushort[meshCountP][]; ushort[][] meshIndiciesPC = new ushort[meshCountPC][]; ushort[][] meshIndiciesPN = new ushort[meshCountPN][]; ushort[][] meshIndiciesPT = new ushort[meshCountPT][]; ushort[][] meshIndiciesPNT = new ushort[meshCountPNT][]; ushort[][] meshIndiciesPNTTB = new ushort[meshCountPNTTB][]; int meshIndiciesP_Counter = 0; int meshIndiciesPC_Counter = 0; int meshIndiciesPN_Counter = 0; int meshIndiciesPT_Counter = 0; int meshIndiciesPNT_Counter = 0; int meshIndiciesPNTTB_Counter = 0; var loadedModels = new LoadedModels <RealtimeMaterial>(); VertexPosition[] meshDefinitionP = new VertexPosition[0]; VertexPositionColor[] meshDefinitionPC = new VertexPositionColor[0]; VertexPositionNormal[] meshDefinitionPN = new VertexPositionNormal[0]; VertexPositionTexture[] meshDefinitionPT = new VertexPositionTexture[0]; VertexPositionNormalTexture[] meshDefinitionPNT = new VertexPositionNormalTexture[0]; VertexPositionNormalTextureTangentBitangent[] meshDefinitionPNTTB = new VertexPositionNormalTextureTangentBitangent[0]; for (int i = 0; i < meshCount; i++) { var aiMesh = pScene.Meshes[i]; var vertexCount = aiMesh.VertexCount; if (vertexCount == 0) { Console.Error.WriteLine("Mesh has no verticies"); continue; } Assimp.Material aiMaterial = pScene.Materials[aiMesh.MaterialIndex]; Core.Materials.RealtimeMaterial material = aiMaterial.ToRealtimeMaterial(); VertexRuntimeTypes henzaiVertexType = aiMaterial.ToHenzaiVertexType(); switch (henzaiVertexType) { case VertexRuntimeTypes.VertexPosition: meshDefinitionP = new VertexPosition[vertexCount]; break; case VertexRuntimeTypes.VertexPositionColor: meshDefinitionPC = new VertexPositionColor[vertexCount]; break; case VertexRuntimeTypes.VertexPositionTexture: meshDefinitionPT = new VertexPositionTexture[vertexCount]; break; case VertexRuntimeTypes.VertexPositionNormalTexture: meshDefinitionPNT = new VertexPositionNormalTexture[vertexCount]; break; case VertexRuntimeTypes.VertexPositionNormal: meshDefinitionPN = new VertexPositionNormal[vertexCount]; break; case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent: meshDefinitionPNTTB = new VertexPositionNormalTextureTangentBitangent[vertexCount]; break; default: throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented"); } for (int j = 0; j < vertexCount; j++) { byte[] bytes = GenerateVertexBytesArrayFromAssimp(henzaiVertexType, aiMesh, j); switch (henzaiVertexType) { case VertexRuntimeTypes.VertexPosition: meshDefinitionP[j] = ByteMarshal.ByteArrayToStructure <VertexPosition>(bytes); break; case VertexRuntimeTypes.VertexPositionColor: meshDefinitionPC[j] = ByteMarshal.ByteArrayToStructure <VertexPositionColor>(bytes); break; case VertexRuntimeTypes.VertexPositionTexture: meshDefinitionPT[j] = ByteMarshal.ByteArrayToStructure <VertexPositionTexture>(bytes); break; case VertexRuntimeTypes.VertexPositionNormalTexture: meshDefinitionPNT[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormalTexture>(bytes); break; case VertexRuntimeTypes.VertexPositionNormal: meshDefinitionPN[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormal>(bytes); break; case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent: meshDefinitionPNTTB[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormalTextureTangentBitangent>(bytes); break; default: throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented"); } } var faceCount = aiMesh.FaceCount; switch (henzaiVertexType) { case VertexRuntimeTypes.VertexPosition: materialsP[meshIndiciesP_Counter] = material; meshIndiciesP[meshIndiciesP_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesP[meshIndiciesP_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesP[meshIndiciesP_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesP[meshIndiciesP_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesP[meshIndiciesP_Counter] = new Mesh <VertexPosition>(meshDefinitionP, meshIndiciesP[meshIndiciesP_Counter]); meshIndiciesP_Counter++; break; case VertexRuntimeTypes.VertexPositionColor: materialsPC[meshIndiciesPC_Counter] = material; meshIndiciesPC[meshIndiciesPC_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPC[meshIndiciesPC_Counter] = new Mesh <VertexPositionColor>(meshDefinitionPC, meshIndiciesPC[meshIndiciesPC_Counter]); meshIndiciesPC_Counter++; break; case VertexRuntimeTypes.VertexPositionTexture: materialsPT[meshIndiciesPT_Counter] = material; meshIndiciesPT[meshIndiciesPT_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPT[meshIndiciesPT_Counter] = new Mesh <VertexPositionTexture>(meshDefinitionPT, meshIndiciesPT[meshIndiciesPT_Counter]); meshIndiciesPT_Counter++; break; case VertexRuntimeTypes.VertexPositionNormalTexture: materialsPNT[meshIndiciesPNT_Counter] = material; meshIndiciesPNT[meshIndiciesPNT_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPNT[meshIndiciesPNT_Counter] = new Mesh <VertexPositionNormalTexture>(meshDefinitionPNT, meshIndiciesPNT[meshIndiciesPNT_Counter]); meshIndiciesPNT_Counter++; break; case VertexRuntimeTypes.VertexPositionNormal: materialsPN[meshIndiciesPN_Counter] = material; meshIndiciesPN[meshIndiciesPN_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPN[meshIndiciesPN_Counter] = new Mesh <VertexPositionNormal>(meshDefinitionPN, meshIndiciesPN[meshIndiciesPN_Counter]); meshIndiciesPN_Counter++; break; case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent: materialsPNTTB[meshIndiciesPNTTB_Counter] = material; meshIndiciesPNTTB[meshIndiciesPNTTB_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPNTTB[meshIndiciesPNTTB_Counter] = new Mesh <VertexPositionNormalTextureTangentBitangent>(meshDefinitionPNTTB, meshIndiciesPNTTB[meshIndiciesPNTTB_Counter]); meshIndiciesPNTTB_Counter++; break; default: throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented"); } } if (meshCountP > 0) { loadedModels.modelP = new Model <VertexPosition, RealtimeMaterial>(modelDir, meshesP, materialsP); } if (meshCountPC > 0) { loadedModels.modelPC = new Model <VertexPositionColor, RealtimeMaterial>(modelDir, meshesPC, materialsPC); } if (meshCountPN > 0) { loadedModels.modelPN = new Model <VertexPositionNormal, RealtimeMaterial>(modelDir, meshesPN, materialsPN); } if (meshCountPT > 0) { loadedModels.modelPT = new Model <VertexPositionTexture, RealtimeMaterial>(modelDir, meshesPT, materialsPT); } if (meshCountPNT > 0) { loadedModels.modelPNT = new Model <VertexPositionNormalTexture, RealtimeMaterial>(modelDir, meshesPNT, materialsPNT); } if (meshCountPNTTB > 0) { loadedModels.modelPNTTB = new Model <VertexPositionNormalTextureTangentBitangent, RealtimeMaterial>(modelDir, meshesPNTTB, materialsPNTTB); } return(loadedModels); }
public override void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { }
private ModelData.Material Process(Material rawMaterial) { var material = new ModelData.Material(); var properties = material.Properties; // Setup all default properties for this material if (rawMaterial.HasBlendMode) properties.SetProperty(MaterialKeysBase.BlendMode, (MaterialBlendMode)rawMaterial.BlendMode); if (rawMaterial.HasBumpScaling) properties.SetProperty(MaterialKeysBase.BumpScaling, rawMaterial.BumpScaling); if (rawMaterial.HasColorAmbient) properties.SetProperty(MaterialKeysBase.ColorAmbient, ConvertColor(rawMaterial.ColorAmbient)); if (rawMaterial.HasColorDiffuse) properties.SetProperty(MaterialKeysBase.ColorDiffuse, ConvertColor(rawMaterial.ColorDiffuse)); if (rawMaterial.HasColorEmissive) properties.SetProperty(MaterialKeysBase.ColorEmissive, (Color3)ConvertColor(rawMaterial.ColorEmissive)); if (rawMaterial.HasColorReflective) properties.SetProperty(MaterialKeysBase.ColorReflective, ConvertColor(rawMaterial.ColorReflective)); if (rawMaterial.HasColorSpecular) properties.SetProperty(MaterialKeysBase.ColorSpecular, (Color3)ConvertColor(rawMaterial.ColorSpecular)); if (rawMaterial.HasColorTransparent) properties.SetProperty(MaterialKeysBase.ColorTransparent, ConvertColor(rawMaterial.ColorTransparent)); if (rawMaterial.HasName) properties.SetProperty(MaterialKeysBase.Name, rawMaterial.Name); if (rawMaterial.HasOpacity) properties.SetProperty(MaterialKeysBase.Opacity, rawMaterial.Opacity); if (rawMaterial.HasReflectivity) properties.SetProperty(MaterialKeysBase.Reflectivity, rawMaterial.Reflectivity); if (rawMaterial.HasShininess) properties.SetProperty(MaterialKeysBase.Shininess, rawMaterial.Shininess); if (rawMaterial.HasShininessStrength) properties.SetProperty(MaterialKeysBase.ShininessStrength, rawMaterial.ShininessStrength); if (rawMaterial.HasShadingMode) properties.SetProperty(MaterialKeysBase.ShadingMode, (MaterialShadingMode)rawMaterial.ShadingMode); if (rawMaterial.HasTwoSided) properties.SetProperty(MaterialKeysBase.TwoSided, rawMaterial.IsTwoSided); if (rawMaterial.HasWireFrame) properties.SetProperty(MaterialKeysBase.Wireframe, rawMaterial.IsWireFrameEnabled); // Iterate on other properties foreach (var rawProperty in rawMaterial.GetAllProperties()) { var key = rawProperty.FullyQualifiedName; if (!properties.ContainsKey(key) && !AssimpMaterialDefaultNames.Contains(rawProperty.FullyQualifiedName)) { // Texture properties will be added after if (!rawProperty.FullyQualifiedName.StartsWith("$tex")) { // Just use our own key for this material if (key == "$mat.refracti,0,0") key = "Refraction"; const string matNamePrefix = "$mat."; if (key.StartsWith(matNamePrefix) && key.Length > matNamePrefix.Length) { var newName = key.Substring(matNamePrefix.Length); key = new StringBuilder().Append(char.ToUpperInvariant(newName[0])).Append(newName.Substring(1)).ToString(); } if (properties.ContainsKey(key)) { continue; } switch (rawProperty.PropertyType) { case PropertyType.String: properties.Add(key, rawProperty.AsString()); break; case PropertyType.Float: switch (rawProperty.ByteCount / 4) { case 1: properties.Add(key, rawProperty.AsFloat()); break; case 2: properties.Add(key, new Vector2(rawProperty.AsFloatArray())); break; case 3: properties.Add(key, new Vector3(rawProperty.AsFloatArray())); break; case 4: properties.Add(key, new Vector4(rawProperty.AsFloatArray())); break; case 16: properties.Add(key, new Matrix(rawProperty.AsFloatArray())); break; } break; case PropertyType.Integer: switch (rawProperty.ByteCount / 4) { case 1: properties.Add(key, rawProperty.AsInteger()); break; default: properties.Add(key, rawProperty.AsIntegerArray()); break; } break; case PropertyType.Buffer: properties.Add(key, rawProperty.RawData); break; } } } } // Process textures foreach (TextureType textureType in Enum.GetValues(typeof(TextureType))) { if (textureType != TextureType.None) { var textures = rawMaterial.GetTextures(textureType); if (textures != null) { var materialTextures = new List<ModelData.MaterialTexture>(); material.Textures.Add(string.Format("{0}Texture", textureType), materialTextures); foreach (var textureSlot in textures) { var textureFilePath = textureSlot.FilePath.Replace(@"/", @"\"); var textureWinFilePath = textureFilePath; // Remove any .\ while (textureFilePath.StartsWith(@".\")) { textureFilePath = textureFilePath.Substring(2); } var newTextureSlot = new ModelData.MaterialTexture() { FilePath = textureFilePath, BlendFactor = textureSlot.BlendFactor, Operation = (MaterialTextureOperator)textureSlot.Operation, Index = (int)textureSlot.TextureIndex, UVIndex = (int)textureSlot.UVIndex, WrapMode = ConvertWrapMode(textureSlot.WrapMode), Flags = (MaterialTextureFlags)textureSlot.Flags }; var pathToFullTexture = Path.Combine(modelDirectory, textureWinFilePath); if (!File.Exists(pathToFullTexture)) { logger.Warning(string.Format("Texture [{0}] not found from path [{1}] for model [{2}]. Skip it", textureSlot.FilePath, pathToFullTexture, modelFilePath)); } materialTextures.Add(newTextureSlot); } } } } return material; }
void WriteTextureStack (Material mat, TextureType type, BinaryWriter writer, Dictionary<string,string> textures) { var count = mat.GetMaterialTextureCount(type); writer.Write(count); for (var i = 0; i < count; i++) { TextureSlot slot; mat.GetMaterialTexture(type, i, out slot); if (slot.Mapping != TextureMapping.FromUV) throw new ContentException("Unsupported texture mapping type, textures must be UV-mapped."); if (!textures.ContainsKey(slot.FilePath)) { textures.Add(slot.FilePath, Path.GetFileNameWithoutExtension(slot.FilePath)); } writer.Write(textures[slot.FilePath]); writer.Write(slot.UVIndex); writer.Write(slot.BlendFactor); writer.Write((int)slot.Operation); writer.Write(slot.WrapModeU == TextureWrapMode.Wrap); writer.Write(slot.WrapModeV == TextureWrapMode.Wrap); } }
private void ApplyFixedFunctionMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { shaded = shaded && (mesh == null || mesh.HasNormals); if (shaded) { GL.Enable(EnableCap.Lighting); } else { GL.Disable(EnableCap.Lighting); } var hasColors = mesh != null && mesh.HasVertexColors(0); if (hasColors) { GL.Enable(EnableCap.ColorMaterial); GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse); } else { GL.Disable(EnableCap.ColorMaterial); } // note: keep semantics of hasAlpha consistent with IsAlphaMaterial() var hasAlpha = false; var hasTexture = false; // note: keep this up-to-date with the code in UploadTextures() if (textured && mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { hasTexture = true; TextureSlot tex; mat.GetMaterialTexture(TextureType.Diffuse, 0, out tex); var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath); hasAlpha = hasAlpha || gtex.HasAlpha == Texture.AlphaState.HasAlpha; if(gtex.State == Texture.TextureState.GlTextureCreated) { GL.ActiveTexture(TextureUnit.Texture0); gtex.BindGlTexture(); GL.Enable(EnableCap.Texture2D); } else { GL.Disable(EnableCap.Texture2D); } } else { GL.Disable(EnableCap.Texture2D); } GL.Enable(EnableCap.Normalize); var alpha = 1.0f; if (mat.HasOpacity) { alpha = mat.Opacity; if (alpha < AlphaSuppressionThreshold) // suppress zero opacity, this is likely wrong input data { alpha = 1.0f; } } var color = new Color4(.8f, .8f, .8f, 1.0f); if (mat.HasColorDiffuse) { color = AssimpToOpenTk.FromColor(mat.ColorDiffuse); if (color.A < AlphaSuppressionThreshold) // s.a. { color.A = 1.0f; } } color.A *= alpha; hasAlpha = hasAlpha || color.A < 1.0f; if (shaded) { // if the material has a texture but the diffuse color texture is all black, // then heuristically assume that this is an import/export flaw and substitute // white. if (hasTexture && color.R < 1e-3f && color.G < 1e-3f && color.B < 1e-3f) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, Color4.White); } else { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, color); } color = new Color4(0, 0, 0, 1.0f); if (mat.HasColorSpecular) { color = AssimpToOpenTk.FromColor(mat.ColorSpecular); } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, color); color = new Color4(.2f, .2f, .2f, 1.0f); if (mat.HasColorAmbient) { color = AssimpToOpenTk.FromColor(mat.ColorAmbient); } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Ambient, color); color = new Color4(0, 0, 0, 1.0f); if (mat.HasColorEmissive) { color = AssimpToOpenTk.FromColor(mat.ColorEmissive); } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, color); float shininess = 1; float strength = 1; if (mat.HasShininess) { shininess = mat.Shininess; } // todo: I don't even remember how shininess strength was supposed to be handled in assimp if (mat.HasShininessStrength) { strength = mat.ShininessStrength; } var exp = shininess*strength; if (exp >= 128.0f) // 128 is the maximum exponent as per the Gl spec { exp = 128.0f; } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, exp); } else if (!hasColors) { GL.Color3(color.R, color.G, color.B); } if (hasAlpha) { GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.DepthMask(false); } else { GL.Disable(EnableCap.Blend); GL.DepthMask(true); } }
/// <summary> /// Uploads all the textures required for a given material to VRAM (i.e. /// create the corresponding Gl objects). Textures that have been /// uploaded before are not attempted again. /// </summary> /// <param name="material"></param> /// <returns>Whether there were any new texture uploads</returns> public bool UploadTextures(Material material) { Debug.Assert(material != null); var any = false; // note: keep this up to date with the code in ApplyFixedFunctionMaterial if (material.GetMaterialTextureCount(TextureType.Diffuse) > 0) { TextureSlot tex; material.GetMaterialTexture(TextureType.Diffuse, 0, out tex); var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath); if (gtex.State == Texture.TextureState.WinFormsImageCreated) { gtex.Upload(); any = true; } else if (gtex.ReconfigureUploadedTextureRequested) { gtex.ReconfigureUploadedTexture(); } } return any; }
private static Color ConvertColor(Color4D c, AssimpMaterial aMaterial) { if (!aMaterial.HasColorTransparent) { // no transparency specified return Color.FromArgb(255, (byte)(255 * c.R), (byte)(255 * c.G), (byte)(255 * c.B)); } return Color.FromArgb((byte)(255 * c.A), (byte)(255 * c.R), (byte)(255 * c.G), (byte)(255 * c.B)); }
public Model Load(AssetManager assetManager, RenderContext renderContext, Stream stream, string sourcePath) { Scene scene = Importer.ImportFile(sourcePath, PostProcessSteps.Triangulate | PostProcessSteps.FlipUVs); if (scene == null || scene.SceneFlags.HasFlag(SceneFlags.Incomplete) || scene.RootNode == null) { throw new Exception("Assimp Error."); } var meshes = new List <Mesh>(); string directory = Path.GetDirectoryName(sourcePath); Texture2D LoadFromTextureSlot(TextureSlot textureSlot, TextureType textureType) { var texture = assetManager.Load <Texture2D>(Path.Combine(directory, textureSlot.FilePath)); texture.SetInfoFromTextureSlot(renderContext, ref textureSlot); texture.SetMinFilter(renderContext, TextureMinFilter.NearestMipmapLinear); return(texture); } List <Texture2D> LoadMaterialTextures(AssimpMaterial material, TextureType textureType) { List <Texture2D> textures = new List <Texture2D>(); for (int i = 0; i < material.GetMaterialTextureCount(textureType); i++) { material.GetMaterialTexture(textureType, i, out var textureSlot); if (textureSlot.FilePath != null) { if (textureSlot.FilePath.Contains("*")) { throw new InvalidOperationException(); } var texture = assetManager.Load <Texture2D>(Path.Combine(directory, textureSlot.FilePath)); texture.SetInfoFromTextureSlot(renderContext, ref textureSlot); textures.Add(texture); } } return(textures); } Mesh ProcessMesh(AssimpMesh mesh, System.Numerics.Matrix4x4 transformMatrix) { VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[mesh.VertexCount]; List <uint> indices = new List <uint>(); // Process vertices for (int i = 0; i < mesh.VertexCount; i++) { Vector3D position = mesh.Vertices[i]; vertices[i].Position = Unsafe.As <Vector3D, Vector3>(ref position); Vector3D normal = mesh.Normals[i]; vertices[i].Normal = Unsafe.As <Vector3D, Vector3>(ref normal); if (mesh.HasTextureCoords(0)) { Vector3D texCoord = mesh.TextureCoordinateChannels[0][i]; vertices[i].TexCoord = new Vector2(texCoord.X, 1 - texCoord.Y); } } // Process indices for (int i = 0; i < mesh.FaceCount; i++) { AssimpFace face = mesh.Faces[i]; for (int j = 0; j < face.IndexCount; j++) { indices.Add((uint)face.Indices[j]); } } Mesh.MeshTextureInfo textures = new Mesh.MeshTextureInfo(); // Process Material if (mesh.MaterialIndex >= 0) { AssimpMaterial material = scene.Materials[mesh.MaterialIndex]; var texturezzz = material.GetAllMaterialTextures(); texturezzz = texturezzz.Where(x => x.FilePath != null).ToArray(); if (material.HasTextureDiffuse) { textures.Diffuse = LoadFromTextureSlot(material.TextureDiffuse, TextureType.Diffuse); } if (material.HasTextureSpecular) { textures.Specular = LoadFromTextureSlot(material.TextureSpecular, TextureType.Specular); } if (material.HasTextureLightMap) { textures.MetallicRoughness = LoadFromTextureSlot(material.TextureLightMap, TextureType.Lightmap); } } return(new Mesh(renderContext, vertices, indices.ToArray(), textures, transformMatrix)); } void ProcessNode(Node node, System.Numerics.Matrix4x4 transform) { var t = node.Transform; var thisTransform = Unsafe.As <Matrix4x4, System.Numerics.Matrix4x4>(ref t); // Process all of the node's meshes for (int i = 0; i < node.MeshCount; i++) { AssimpMesh mesh = scene.Meshes[node.MeshIndices[i]]; meshes.Add(ProcessMesh(mesh, transform * thisTransform)); } // Recurse for (int i = 0; i < node.ChildCount; i++) { ProcessNode(node.Children[i], transform * thisTransform); } } ProcessNode(scene.RootNode, System.Numerics.Matrix4x4.Identity); return(new Model(meshes.ToArray())); }
private static SystemMaterial ConvertMaterial(AssimpMaterial aMaterial, string path) { MaterialGroup material = new MaterialGroup(); if (aMaterial.HasColorDiffuse) { material.Children.Add(new DiffuseMaterial(new SolidColorBrush( ConvertColor(aMaterial.ColorDiffuse, aMaterial)))); } if (aMaterial.HasColorEmissive) { material.Children.Add(new EmissiveMaterial(new SolidColorBrush( ConvertColor(aMaterial.ColorEmissive, aMaterial)))); } if (aMaterial.HasColorSpecular) { material.Children.Add(new SpecularMaterial(new SolidColorBrush( ConvertColor(aMaterial.ColorSpecular, aMaterial)), aMaterial.Shininess)); } // Textures TextureSlot[] textures = aMaterial.GetAllMaterialTextures(); foreach (TextureSlot texture in textures) { string imageFile = Path.Combine(path, texture.FilePath); if (File.Exists(imageFile)) { //material.Children.Clear(); ImageBrush brush = new ImageBrush(new BitmapImage(new Uri(imageFile))); brush.ViewportUnits = BrushMappingMode.Absolute; material.Children.Add(new DiffuseMaterial(brush)); } } if (material.Children.Count <= 0) { // paranoia: no material defined // -> add default-material material.Children.Add(new DiffuseMaterial(Brushes.DarkGray)); } return material; }
private static Material CreateMaterialFromAiMaterial(Ai.Material aiMaterial, TextureSet textureSet, string texturesDirectoryPath) { var material = new Material { Name = aiMaterial.Name }; foreach (string shaderName in Material.ShaderNames) { if (material.Name.IndexOf(shaderName, StringComparison.OrdinalIgnoreCase) == -1) { continue; } material.ShaderName = shaderName == "CHARA" ? "SKIN" : shaderName; break; } material.Diffuse = aiMaterial.HasColorDiffuse ? aiMaterial.ColorDiffuse.ToMML() : material.Diffuse; material.Ambient = aiMaterial.HasColorAmbient ? aiMaterial.ColorAmbient.ToMML() : material.Ambient; material.Specular = aiMaterial.HasColorSpecular ? aiMaterial.ColorSpecular.ToMML() : material.Specular; material.Emission = aiMaterial.HasColorEmissive ? aiMaterial.ColorEmissive.ToMML() : material.Emission; material.Shininess = aiMaterial.HasShininess ? aiMaterial.Shininess : material.Shininess; if (material.ShaderName == "HAIR") { material.AnisoDirection = AnisoDirection.V; } material.DoubleSided = aiMaterial.HasTwoSided ? aiMaterial.IsTwoSided : material.DoubleSided; foreach (var aiTextureSlot in aiMaterial.GetAllMaterialTextures()) { CreateMaterialTextureFromAiTextureSlot(aiTextureSlot, aiMaterial, material, textureSet, texturesDirectoryPath); } if (material.Flags.HasFlag(MaterialFlags.Normal)) { material.BumpMapType = material.Flags.HasFlag(MaterialFlags.Environment) ? BumpMapType.Env : BumpMapType.Dot; } if (material.Flags.HasFlag(MaterialFlags.Specular)) { material.LineLight = 5; } if (material.Flags.HasFlag(MaterialFlags.Environment)) { material.Flags |= MaterialFlags.ColorL1Alpha | MaterialFlags.ColorL2Alpha | MaterialFlags.OverrideIBL; } // HAIR without normal map causes the whole screen to become black. // TODO: Automatically add a flat normal map in this case. if (material.ShaderName == "HAIR" && !material.Flags.HasFlag(MaterialFlags.Normal)) { material.ShaderName = "BLINN"; } material.SortMaterialTextures(); return(material); }
private Mesh processMesh(Assimp.Mesh mesh, Assimp.Scene scene) { // Data to fill List <Vertex> vertices = new List <Vertex>(); List <uint> indices = new List <uint>(); List <Texture> textures = new List <Texture>(); // Walk through each of the mesh's vertices for (int i = 0; i < mesh.VertexCount; i++) { Vertex vertex = new Vertex(); //Vertex3 vector = new Vertex3(); // We declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first. // Positions vertex.Position.X = mesh.Vertices[i].X; vertex.Position.Y = mesh.Vertices[i].Y; vertex.Position.Z = mesh.Vertices[i].Z; //vertex.Position = vector; // Normals vertex.Normal.X = mesh.Normals[i].X; vertex.Normal.Y = mesh.Normals[i].Y; vertex.Normal.Z = mesh.Normals[i].Z; //vertex.Normal = vector; // Texture Coordinates if (mesh.HasTextureCoords(0)) // Does the mesh contain texture coordinates? { Vertex2f vec; // A vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't // use models where a vertex can have multiple texture coordinates so we always take the first set (0). vec.x = mesh.TextureCoordinateChannels[0][i].X; vec.y = mesh.TextureCoordinateChannels[0][i].Y; vertex.TexCoords.X = vec.X; vertex.TexCoords.Y = vec.Y; } else { vertex.TexCoords.X = vertex.TexCoords.Y = 0; } vertices.Add(vertex); } // Now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. for (int i = 0; i < mesh.FaceCount; i++) { Assimp.Face face = mesh.Faces[i]; // Retrieve all indices of the face and store them in the indices vector for (int j = 0; j < face.IndexCount; j++) { indices.Add((uint)face.Indices[j]); } } // Process materials if (mesh.MaterialIndex >= 0) { Assimp.Material material = scene.Materials[mesh.MaterialIndex]; // We assume a convention for sampler names in the shaders. Each diffuse texture should be named // as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER. // Same applies to other texture as the following list summarizes: // Diffuse: texture_diffuseN // Specular: texture_specularN // Normal: texture_normalN // 1. Diffuse maps List <Texture> diffuseMaps = this.loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse"); textures.InsertRange(textures.Count, diffuseMaps); // 2. Specular maps List <Texture> specularMaps = this.loadMaterialTextures(material, TextureType.Specular, "texture_specular"); textures.InsertRange(textures.Count, specularMaps); } // Return a mesh object created from the extracted mesh data return(new Mesh(vertices, indices, textures)); }
/// <summary> /// internal. /// </summary> internal static Drawing3d.Material ConvertMaterial(Assimp.Material AMAterial) { return(new Drawing3d.Material(AMAterial.Name, ConvertColor(AMAterial.ColorAmbient), ConvertColor(AMAterial.ColorDiffuse), ConvertColor(AMAterial.ColorSpecular), ConvertColor(AMAterial.ColorEmissive), AMAterial.Shininess, AMAterial.Opacity)); }
private static Material ConvertMaterialAndTextures(Ai.Material aiMaterial, ModelPackConverterOptions options, string baseDirectoryPath, TextureDictionary textureDictionary) { // Convert all textures TextureInfo diffuseTexture = null; if (aiMaterial.HasTextureDiffuse) { diffuseTexture = ConvertTexture(aiMaterial.TextureDiffuse, baseDirectoryPath); } TextureInfo lightmapTexture = null; if (aiMaterial.HasTextureLightMap) { lightmapTexture = ConvertTexture(aiMaterial.TextureLightMap, baseDirectoryPath); } TextureInfo displacementTexture = null; if (aiMaterial.HasTextureDisplacement) { displacementTexture = ConvertTexture(aiMaterial.TextureDisplacement, baseDirectoryPath); } TextureInfo opacityTexture = null; if (aiMaterial.HasTextureOpacity) { opacityTexture = ConvertTexture(aiMaterial.TextureOpacity, baseDirectoryPath); } TextureInfo normalTexture = null; if (aiMaterial.HasTextureNormal) { normalTexture = ConvertTexture(aiMaterial.TextureNormal, baseDirectoryPath); } TextureInfo heightTexture = null; if (aiMaterial.HasTextureHeight) { heightTexture = ConvertTexture(aiMaterial.TextureHeight, baseDirectoryPath); } TextureInfo emissiveTexture = null; if (aiMaterial.HasTextureEmissive) { emissiveTexture = ConvertTexture(aiMaterial.TextureEmissive, baseDirectoryPath); } TextureInfo ambientTexture = null; if (aiMaterial.HasTextureAmbient) { ambientTexture = ConvertTexture(aiMaterial.TextureAmbient, baseDirectoryPath); } TextureInfo specularTexture = null; if (aiMaterial.HasTextureSpecular) { specularTexture = ConvertTexture(aiMaterial.TextureSpecular, baseDirectoryPath); } TextureInfo reflectionTexture = null; if (aiMaterial.HasTextureReflection) { reflectionTexture = ConvertTexture(aiMaterial.TextureReflection, baseDirectoryPath); } // Convert material Material material = null; string materialName = AssimpConverterCommon.UnescapeName(aiMaterial.Name); switch (options.MaterialPreset) { case MaterialPreset.FieldTerrain: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); material = MaterialFactory.CreateFieldTerrainMaterial(materialName, diffuseTexture.Name, HasAlpha(diffuseTexture.PixelFormat)); } } break; case MaterialPreset.FieldTerrainVertexColors: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); material = MaterialFactory.CreateFieldTerrainVertexColorsMaterial(materialName, diffuseTexture.Name, HasAlpha(diffuseTexture.PixelFormat)); } } break; case MaterialPreset.FieldTerrainCastShadow: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); material = MaterialFactory.CreateFieldTerrainCastShadowMaterial(materialName, diffuseTexture.Name, HasAlpha(diffuseTexture.PixelFormat)); } } break; case MaterialPreset.CharacterSkinP5: case MaterialPreset.CharacterSkinFB: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); string shadowTextureName = diffuseTexture.Name; if (ambientTexture != null) { textureDictionary.Add(ambientTexture.Texture); shadowTextureName = ambientTexture.Name; } // TODO: transparency var hasTransparency = HasAlpha(diffuseTexture.PixelFormat); if (options.MaterialPreset == MaterialPreset.CharacterSkinP5) { material = MaterialFactory.CreateCharacterSkinP5Material(materialName, diffuseTexture.Name, shadowTextureName, hasTransparency); } else { material = MaterialFactory.CreateCharacterSkinFBMaterial(materialName, diffuseTexture.Name, shadowTextureName, hasTransparency); } } } break; case MaterialPreset.PersonaSkinP5: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); string shadowTextureName = diffuseTexture.Name; string specularTextureName = diffuseTexture.Name; if (ambientTexture != null) { textureDictionary.Add(ambientTexture.Texture); shadowTextureName = ambientTexture.Name; } if (specularTexture != null) { textureDictionary.Add(specularTexture.Texture); specularTextureName = specularTexture.Name; } material = MaterialFactory.CreatePersonaSkinP5Material(materialName, diffuseTexture.Name, specularTextureName, shadowTextureName); } } break; case MaterialPreset.CharacterClothP4D: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); material = MaterialFactory.CreateCharacterClothP4DMaterial(materialName, diffuseTexture.Name, HasAlpha(diffuseTexture.PixelFormat)); } } break; case MaterialPreset.CharacterSkinP3DP5D: { if (diffuseTexture != null) { textureDictionary.Add(diffuseTexture.Texture); material = MaterialFactory.CreateCharacterSkinP3DP5DMaterial(materialName, diffuseTexture.Name, HasAlpha(diffuseTexture.PixelFormat)); } } break; } // Create dummy material if none was created if (material == null) { material = new Material(materialName); } return(material); }
/// <summary> /// Clone a given material subject to a texture path remapping /// </summary> /// <param name="mat"></param> /// <param name="textureMapping"></param> /// <returns></returns> private static Material CloneMaterial(Material mat, Dictionary<string, string> textureMapping) { Debug.Assert(mat != null); Debug.Assert(textureMapping != null); var matOut = new Material(); foreach (var prop in mat.GetAllProperties()) { var propOut = prop; if (prop.PropertyType == PropertyType.String && textureMapping.ContainsKey(prop.GetStringValue())) { propOut = new MaterialProperty {PropertyType = PropertyType.String, Name = prop.Name}; propOut.TextureIndex = prop.TextureIndex; propOut.TextureType = prop.TextureType; propOut.SetStringValue(textureMapping[prop.GetStringValue()]); } matOut.AddProperty(propOut); } return matOut; }
protected Graphics.Material createMaterial(Assimp.Material am) { Graphics.Material mat = new Material(am.Name); mat.myFeatures |= Material.Feature.Lighting; if (am.HasColorAmbient) { mat.ambient = toColor(am.ColorAmbient); } if (am.HasColorDiffuse) { mat.diffuse = toColor(am.ColorDiffuse); } if (am.HasColorSpecular) { mat.spec = toColor(am.ColorSpecular); } if (am.HasShininess) { mat.shininess = am.Shininess; } if (am.HasOpacity) { mat.alpha = am.Opacity; } if (am.HasTextureAmbient) { Texture t = getTexture(am.TextureAmbient.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("ambientMap", t)); } } if (am.HasTextureDiffuse) { Texture t = getTexture(am.TextureDiffuse.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("diffuseMap", t)); mat.myFeatures |= Material.Feature.DiffuseMap; mat.hasTransparency = t.hasAlpha; } } if (am.HasTextureSpecular) { Texture t = getTexture(am.TextureSpecular.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("specularMap", t)); mat.myFeatures |= Material.Feature.SpecMap; } } if (am.HasTextureNormal) { Texture t = getTexture(am.TextureNormal.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("normalMap", t)); mat.myFeatures |= Material.Feature.NormalMap; } } if (am.HasTextureDisplacement) { Texture t = getTexture(am.TextureDisplacement.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("displaceMap", t)); mat.myFeatures |= Material.Feature.DisplacementMap; } } if (am.HasTextureEmissive) { Texture t = getTexture(am.TextureEmissive.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("emissiveMap", t)); mat.myFeatures |= Material.Feature.EmmissiveMap; } } if (am.HasTextureOpacity) { Texture t = getTexture(am.TextureOpacity.FilePath); if (t != null) { mat.addAttribute(new TextureAttribute("alphaMap", t)); mat.myFeatures |= Material.Feature.AlphaMap; } } return(mat); }
/// <summary> /// Constructs a new Scene. /// </summary> /// <param name="scene">Unmanaged AiScene struct.</param> internal Scene(AiScene scene) { _flags = scene.Flags; //Read materials if(scene.NumMaterials > 0 && scene.Materials != IntPtr.Zero) { AiMaterial[] materials = MemoryHelper.MarshalArray<AiMaterial>(scene.Materials, (int) scene.NumMaterials, true); _materials = new Material[materials.Length]; for(int i = 0; i < _materials.Length; i++) { _materials[i] = new Material(materials[i]); } } //Read scenegraph if(scene.RootNode != IntPtr.Zero) { _rootNode = new Node(MemoryHelper.MarshalStructure<AiNode>(scene.RootNode), null); } //Read meshes if(scene.NumMeshes > 0 && scene.Meshes != IntPtr.Zero) { AiMesh[] meshes = MemoryHelper.MarshalArray<AiMesh>(scene.Meshes, (int) scene.NumMeshes, true); _meshes = new Mesh[meshes.Length]; for(int i = 0; i < _meshes.Length; i++) { _meshes[i] = new Mesh(meshes[i]); } } //Read lights if(scene.NumLights > 0 && scene.Lights != IntPtr.Zero) { AiLight[] lights = MemoryHelper.MarshalArray<AiLight>(scene.Lights, (int) scene.NumLights, true); _lights = new Light[lights.Length]; for(int i = 0; i < _lights.Length; i++) { _lights[i] = new Light(lights[i]); } } //Read cameras if(scene.NumCameras > 0 && scene.Cameras != IntPtr.Zero) { AiCamera[] cameras = MemoryHelper.MarshalArray<AiCamera>(scene.Cameras, (int) scene.NumCameras, true); _cameras = new Camera[cameras.Length]; for(int i = 0; i < _cameras.Length; i++) { _cameras[i] = new Camera(cameras[i]); } } //Read Textures if(scene.NumTextures > 0 && scene.Textures != IntPtr.Zero) { AiTexture[] textures = MemoryHelper.MarshalArray<AiTexture>(scene.Textures, (int) scene.NumTextures, true); _textures = new Texture[textures.Length]; for(int i = 0; i < _textures.Length; i++) { _textures[i] = Texture.CreateTexture(textures[i]); } } //Read animations if(scene.NumAnimations > 0 && scene.Animations != IntPtr.Zero) { AiAnimation[] animations = MemoryHelper.MarshalArray<AiAnimation>(scene.Animations, (int) scene.NumAnimations, true); _animations = new Animation[animations.Length]; for(int i = 0; i < _animations.Length; i++) { _animations[i] = new Animation(animations[i]); } } }
public abstract void ApplyGhostMaterial(Mesh mesh, Material material, bool shaded);
private PhysicallyBasedMaterial CreatePbrMaterial(AssimpMaterial assimpMaterial, string filePath, string customTexturesFolder, bool useStrictFileNameMatch, bool supportDDSTextures) { PhysicallyBasedMaterial physicallyBasedMaterial; if (_dxMaterials.TryGetValue(assimpMaterial, out physicallyBasedMaterial)) { Log($" Material: {assimpMaterial.Name ?? ""} (already defined)"); return(physicallyBasedMaterial); } if (!assimpMaterial.HasTextureDiffuse) { Log($" Material {assimpMaterial.Name ?? ""} does not define a diffuse texture"); return(null); } Log($" Material {assimpMaterial.Name ?? ""}:"); //PhysicallyBasedMaterial physicallyBasedMaterial; string diffuseTextureFileName = assimpMaterial.TextureDiffuse.FilePath; if (!string.IsNullOrEmpty(customTexturesFolder)) { diffuseTextureFileName = System.IO.Path.Combine(customTexturesFolder, System.IO.Path.GetFileName(diffuseTextureFileName)); } else if (!System.IO.Path.IsPathRooted(diffuseTextureFileName)) { diffuseTextureFileName = System.IO.Path.Combine(filePath, diffuseTextureFileName); } string folderName = System.IO.Path.GetDirectoryName(diffuseTextureFileName); if (!System.IO.Directory.Exists(folderName)) { Log($" Folder for diffuse texture does not exist: {folderName ?? ""}:"); return(null); } if (_folderImageFiles == null) { _folderImageFiles = new Dictionary <string, string[]>(); } string[] allFilesInFolder; if (!_folderImageFiles.TryGetValue(folderName, out allFilesInFolder)) { allFilesInFolder = System.IO.Directory.GetFiles(folderName, "*.*", SearchOption.TopDirectoryOnly); _folderImageFiles.Add(folderName, allFilesInFolder); } string fileNameWithoutKnownSuffix = KnownTextureFiles.GetFileNameWithoutKnownSuffix(diffuseTextureFileName); // Get material files that start with the diffuse texture file name without a suffix List <string> materialFiles; if (useStrictFileNameMatch) { materialFiles = allFilesInFolder.Where(f => fileNameWithoutKnownSuffix == KnownTextureFiles.GetFileNameWithoutKnownSuffix(f)).ToList(); } else { materialFiles = allFilesInFolder.Where(f => f.IndexOf(fileNameWithoutKnownSuffix, 0, StringComparison.OrdinalIgnoreCase) != -1).ToList(); } _textureFiles.Clear(); if (materialFiles.Count == 0) { Log($" Folder ({folderName}) for {assimpMaterial.Name ?? ""} material does not define any texture files"); return(null); } else { bool hasDiffuseTexture = false; foreach (var materialFile in materialFiles) { if (!TextureLoader.IsSupportedFile(materialFile, supportDDSTextures)) // Skip unsupported files { continue; } var textureMapType = KnownTextureFiles.GetTextureType(materialFile); if (textureMapType == TextureMapTypes.Unknown) { if (!hasDiffuseTexture) { textureMapType = TextureMapTypes.DiffuseColor; // First unknown file type is considered to be diffuse texture file } else { continue; // Unknown file type } } bool isDiffuseTexture = (textureMapType == TextureMapTypes.DiffuseColor || textureMapType == TextureMapTypes.Albedo || textureMapType == TextureMapTypes.BaseColor); string existingTextureFileName; if (_textureFiles.TryGetValue(textureMapType, out existingTextureFileName)) { // Map for this texture type already exist var existingFileExtension = System.IO.Path.GetExtension(existingTextureFileName); if (existingFileExtension != null && existingFileExtension.Equals(".dds", StringComparison.OrdinalIgnoreCase)) { continue; // DDS texture already found for this texture type - we will use existing dds texture } } hasDiffuseTexture |= isDiffuseTexture; _textureFiles.Add(textureMapType, materialFile); Log(" " + textureMapType + ": " + System.IO.Path.GetFileName(materialFile)); } if (_textureFiles.Count > 0) { physicallyBasedMaterial = new PhysicallyBasedMaterial(); foreach (var oneTextureFile in _textureFiles) { var textureType = oneTextureFile.Key; var oneFileName = oneTextureFile.Value; ShaderResourceView shaderResourceView; if (!_texturesCache.TryGetValue(oneFileName, out shaderResourceView)) { var convertTo32bppPRGBA = (textureType == TextureMapTypes.BaseColor || textureType == TextureMapTypes.Albedo || textureType == TextureMapTypes.DiffuseColor); shaderResourceView = Ab3d.DirectX.TextureLoader.LoadShaderResourceView(MainDXViewportView.DXScene.DXDevice.Device, oneFileName, loadDdsIfPresent: false, convertTo32bppPRGBA: convertTo32bppPRGBA); physicallyBasedMaterial.TextureMaps.Add(new TextureMapInfo((Ab3d.DirectX.Materials.TextureMapTypes)textureType, shaderResourceView, null, oneFileName)); _texturesCache.Add(oneFileName, shaderResourceView); } } _dxMaterials.Add(assimpMaterial, physicallyBasedMaterial); _disposables.Add(physicallyBasedMaterial); } } return(physicallyBasedMaterial); }
public void ExportMesh(GameObject go, string path) { Vector3 lastPos = go.transform.position; go.transform.position = Vector3.zero; Scene scene = new Scene(); List <string> sameNames = new List <string>(); List <Transform> children = new List <Transform>(); Dictionary <Transform, Node> nodesByTransform = new Dictionary <Transform, Node>(); GetAllChildren(children, go.transform); foreach (Transform child in children) { string nname = child.name; if (sameNames.Contains(nname)) { nname += "_"; } else { sameNames.Add(nname); } Node node = new Node(nname); UnityEngine.Matrix4x4 m = child.localToWorldMatrix.inverse; node.Transform = new Assimp.Matrix4x4( m.m00, m.m01, m.m02, m.m03, m.m10, m.m11, m.m12, m.m13, m.m20, m.m21, m.m22, m.m23, m.m30, m.m31, m.m32, m.m33 ); nodesByTransform.Add(child, node); if (child == go.transform) { Node rootNode = new Node(Path.GetFileNameWithoutExtension(path)); rootNode.Children.Add(node); scene.RootNode = rootNode; } } foreach (Transform child in children) { foreach (Transform c in child) { if (child == go.transform) { scene.RootNode.Children.Add(nodesByTransform[c]); } else { nodesByTransform[child].Children.Add(nodesByTransform[c]); } } } sameNames.Clear(); MeshFilter[] mfs = go.GetComponentsInChildren <MeshFilter>(); SkinnedMeshRenderer[] smrs = go.GetComponentsInChildren <SkinnedMeshRenderer>(); int meshIndex = 0; foreach (var mf in mfs) { PdxShape shape = mf.GetComponent <PdxShape>(); Assimp.Material mat = new Assimp.Material(); mat.Name = shape.shader; TextureSlot diff = new TextureSlot(); diff.FilePath = shape.diffuse; diff.TextureType = TextureType.Diffuse; diff.UVIndex = 0; //mat.TextureDiffuse = diff; mat.AddMaterialTexture(ref diff); TextureSlot norm = new TextureSlot(); norm.FilePath = shape.normal; norm.TextureType = TextureType.Normals; norm.UVIndex = 0; //mat.TextureNormal = norm; mat.AddMaterialTexture(ref norm); TextureSlot spec = new TextureSlot(); spec.FilePath = shape.specular; spec.TextureType = TextureType.Specular; spec.UVIndex = 0; //mat.TextureSpecular = spec; mat.AddMaterialTexture(ref spec); scene.Materials.Add(mat); Assimp.Mesh am = null; am = FromUnityMesh(mf.mesh, "pShape" + meshIndex, go.transform); if (sameNames.Contains(am.Name)) { am.Name += "_"; } else { sameNames.Add(am.Name); } am.MaterialIndex = meshIndex; scene.Meshes.Add(am); nodesByTransform[mf.transform].MeshIndices.Add(meshIndex); meshIndex++; } foreach (var smr in smrs) { PdxShape shape = smr.GetComponent <PdxShape>(); Assimp.Material mat = new Assimp.Material(); mat.Name = shape.shader; TextureSlot diff = new TextureSlot(); diff.FilePath = shape.diffuse; diff.TextureType = TextureType.Diffuse; diff.UVIndex = 0; //mat.TextureDiffuse = diff; mat.AddMaterialTexture(ref diff); TextureSlot norm = new TextureSlot(); norm.FilePath = shape.normal; norm.TextureType = TextureType.Normals; norm.UVIndex = 0; //mat.TextureNormal = norm; mat.AddMaterialTexture(ref norm); TextureSlot spec = new TextureSlot(); spec.FilePath = shape.specular; spec.TextureType = TextureType.Specular; spec.UVIndex = 0; //mat.TextureSpecular = spec; mat.AddMaterialTexture(ref spec); scene.Materials.Add(mat); Assimp.Mesh am = null; UnityEngine.Mesh baked = new UnityEngine.Mesh(); smr.BakeMesh(baked); am = FromUnityMesh(baked /*smr.sharedMesh*/, "pShape" + meshIndex, go.transform); if (sameNames.Contains(am.Name)) { am.Name += "_"; } else { sameNames.Add(am.Name); } am.MaterialIndex = meshIndex; scene.Meshes.Add(am); nodesByTransform[smr.transform].MeshIndices.Add(meshIndex); meshIndex++; } AssimpContext context = new AssimpContext(); bool result = context.ExportFile(scene, path, "obj", PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder); context.Dispose(); go.transform.position = lastPos; if (result) { EditorController.instance.Status("Object saved as " + path); } else { EditorController.instance.Status("Export failed :(", 2); } }
public override void ApplyGhostMaterial(Mesh mesh, Material material, bool shaded) { }
public override void ApplyGhostMaterial(Mesh mesh, Material material, bool shaded) { ApplyFixedFunctionGhostMaterial(mesh, material, shaded); }
private void _initMaterials(Scene scene) { // Initialize the matrials for (int i = 0; i < scene.MeshCount; i++) { Assimp.Material material = scene.Materials[scene.Meshes[i].MaterialIndex]; _materials[i] = new Material(); if (material.HasBlendMode) { _materials[i].HasBlendMode = true; _materials[i].BlendMode = (Material.MaterialBlendMode)material.BlendMode; } if (material.HasBumpScaling) { _materials[i].HasBumpScaling = true; _materials[i].BumpScaling = material.BumpScaling; } if (material.HasColorAmbient) { _materials[i].HasColorAmbient = true; _materials[i].ColorAmbient = new Color4(material.ColorAmbient.R, material.ColorAmbient.G, material.ColorAmbient.B, material.ColorAmbient.A); } if (material.HasColorDiffuse) { _materials[i].HasColorDiffuse = true; _materials[i].ColorDiffuse = new Color4(material.ColorDiffuse.R, material.ColorDiffuse.G, material.ColorDiffuse.B, material.ColorDiffuse.A); } if (material.HasColorEmissive) { _materials[i].HasColorEmissive = true; _materials[i].ColorEmissive = new Color4(material.ColorEmissive.R, material.ColorEmissive.G, material.ColorEmissive.B, material.ColorEmissive.A); } if (material.HasColorReflective) { _materials[i].HasColorReflective = true; _materials[i].ColorReflective = new Color4(material.ColorReflective.R, material.ColorReflective.G, material.ColorReflective.B, material.ColorReflective.A); } if (material.HasColorSpecular) { _materials[i].HasColorSpecular = true; _materials[i].ColorSpecular = new Color4(material.ColorSpecular.R, material.ColorSpecular.G, material.ColorSpecular.B, material.ColorSpecular.A); } if (material.HasColorTransparent) { _materials[i].HasColorTransparent = true; _materials[i].ColorTransparent = new Color4(material.ColorTransparent.R, material.ColorTransparent.G, material.ColorTransparent.B, material.ColorTransparent.A); } if (material.HasTextureAmbient) { _materials[i].HasTextureAmbient = true; _materials[i].TextureAmbient = new Texture(_getTextureFullPath(material.TextureAmbient), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureDiffuse) { _materials[i].HasTextureDiffuse = true; _materials[i].TextureDiffuse = new Texture(_getTextureFullPath(material.TextureDiffuse), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureDisplacement) { _materials[i].HasTextureDisplacement = true; _materials[i].TextureDisplacement = new Texture(_getTextureFullPath(material.TextureDisplacement), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureEmissive) { _materials[i].HasTextureEmissive = true; _materials[i].TextureEmissive = new Texture(_getTextureFullPath(material.TextureEmissive), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureHeight) { _materials[i].HasTextureHeight = true; _materials[i].TextureHeight = new Texture(_getTextureFullPath(material.TextureHeight), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureLightMap) { _materials[i].HasTextureLightMap = true; _materials[i].TextureLightMap = new Texture(_getTextureFullPath(material.TextureLightMap), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureNormal) { _materials[i].HasTextureNormal = true; _materials[i].TextureNormal = new Texture(_getTextureFullPath(material.TextureNormal), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureOpacity) { _materials[i].HasTextureOpacity = true; _materials[i].TextureOpacity = new Texture(_getTextureFullPath(material.TextureOpacity), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureReflection) { _materials[i].HasTextureReflection = true; _materials[i].TextureReflection = new Texture(_getTextureFullPath(material.TextureReflection), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasTextureSpecular) { _materials[i].HasTextureSpecular = true; _materials[i].TextureSpecular = new Texture(_getTextureFullPath(material.TextureSpecular), Core.Graphics.OpenGL.TextureTarget.Texture2D); } if (material.HasName) { _materials[i].HasName = true; _materials[i].Name = material.Name; } if (material.HasOpacity) { _materials[i].HasOpacity = true; _materials[i].Opacity = material.Opacity; } if (material.HasReflectivity) { _materials[i].HasReflectivity = true; _materials[i].Reflectivity = material.Reflectivity; } if (material.HasShadingMode) { _materials[i].HasShadingMode = true; _materials[i].ShadingMode = (Material.MaterialShadingMode)material.ShadingMode; } if (material.HasShininess) { _materials[i].HasShininess = true; _materials[i].Shininess = material.Shininess; } if (material.HasShininessStrength) { _materials[i].HasShininessStrength = true; _materials[i].ShininessStrength = material.ShininessStrength; } if (material.HasTwoSided) { _materials[i].HasTwoSided = true; _materials[i].IsTwoSided = material.IsTwoSided; } if (material.HasWireFrame) { _materials[i].HasWireFrame = true; _materials[i].IsWireFrameEnabled = material.IsWireFrameEnabled; } _materials[i].PropertyCount = material.PropertyCount; _materials[i].ShaderProgram = new AlienEngine.Shaders.DiffuseShaderProgram(); } }
public GameObject LoadMesh(string path) { AssimpContext context = new AssimpContext(); Scene scene = context.ImportFile(path, PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder); if (!scene.HasMeshes) { return(null); } List <UnityEngine.Material> snow = new List <UnityEngine.Material>(); List <UnityEngine.Material> color = new List <UnityEngine.Material>(); List <UnityEngine.Material> atlas = new List <UnityEngine.Material>(); Dictionary <string, Transform> bonesByName = new Dictionary <string, Transform>(); GameObject goRoot = new GameObject(Path.GetFileName(path)); float min = 0; int idx = 0; foreach (Assimp.Mesh sceneMesh in scene.Meshes) { GameObject go = new GameObject("pShape" + idx); go.tag = "Shape"; bool skinned = false; UnityEngine.Mesh mesh = new UnityEngine.Mesh(); mesh.name = "pMeshShape" + idx; idx++; List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uv = new List <Vector2>(); List <Vector2> uv2 = null; List <BoneWeight> boneWeights = new List <BoneWeight>(); Transform[] bones = null; foreach (var sceneVertex in sceneMesh.Vertices) { vertices.Add(new Vector3(sceneVertex.X, sceneVertex.Y, sceneVertex.Z)); } foreach (var sceneNormal in sceneMesh.Normals) { normals.Add(new Vector3(sceneNormal.X, sceneNormal.Y, sceneNormal.Z)); } foreach (var sceneUV in sceneMesh.TextureCoordinateChannels[0]) { uv.Add(new Vector2(sceneUV.X, 1f - sceneUV.Y)); } if (sceneMesh.TextureCoordinateChannelCount > 1) { uv2 = new List <Vector2>(); foreach (var sceneUV2 in sceneMesh.TextureCoordinateChannels[1]) { uv2.Add(new Vector2(sceneUV2.X, 1f - sceneUV2.Y)); } } Transform rootBone = null; if (sceneMesh.HasBones) { for (int j = 0; j < sceneMesh.VertexCount; j++) { boneWeights.Add(new BoneWeight()); } skinned = true; bones = new Transform[sceneMesh.BoneCount]; int boneIndex = 0; foreach (var sceneBone in sceneMesh.Bones) { GameObject bone = new GameObject(sceneBone.Name); bone.tag = "Bone"; UnityEngine.Matrix4x4 matrix = new UnityEngine.Matrix4x4(); matrix.SetRow(0, new Vector4(sceneBone.OffsetMatrix.A1, sceneBone.OffsetMatrix.A2, sceneBone.OffsetMatrix.A3, sceneBone.OffsetMatrix.A4)); matrix.SetRow(1, new Vector4(sceneBone.OffsetMatrix.B1, sceneBone.OffsetMatrix.B2, sceneBone.OffsetMatrix.B3, sceneBone.OffsetMatrix.B4)); matrix.SetRow(2, new Vector4(sceneBone.OffsetMatrix.C1, sceneBone.OffsetMatrix.C2, sceneBone.OffsetMatrix.C3, sceneBone.OffsetMatrix.C4)); matrix.SetRow(3, new Vector4(sceneBone.OffsetMatrix.D1, sceneBone.OffsetMatrix.D2, sceneBone.OffsetMatrix.D3, sceneBone.OffsetMatrix.D4)); bone.transform.FromMatrix(matrix.inverse); bonesByName[bone.name] = bone.transform; bones[boneIndex] = bone.transform; if (sceneBone.HasVertexWeights) { for (int i = 0; i < sceneBone.VertexWeights.Count; i++) { BoneWeight bw = boneWeights[sceneBone.VertexWeights[i].VertexID]; if (bw.boneIndex0 == 0 && bw.weight0 == 0) { bw.boneIndex0 = boneIndex; bw.weight0 = sceneBone.VertexWeights[i].Weight; } else if (bw.boneIndex1 == 0 && bw.weight1 == 0) { bw.boneIndex1 = boneIndex; bw.weight1 = sceneBone.VertexWeights[i].Weight; } else if (bw.boneIndex2 == 0 && bw.weight2 == 0) { bw.boneIndex2 = boneIndex; bw.weight2 = sceneBone.VertexWeights[i].Weight; } else if (bw.boneIndex3 == 0 && bw.weight3 == 0) { bw.boneIndex3 = boneIndex; bw.weight3 = sceneBone.VertexWeights[i].Weight; } /*if (bw.weight0 < 0.0011f) bw.weight0 = 0f; * if (bw.weight1 < 0.0011f) bw.weight1 = 0f; * if (bw.weight2 < 0.0011f) bw.weight2 = 0f; * if (bw.weight3 < 0.0011f) bw.weight3 = 0f;*/ boneWeights[sceneBone.VertexWeights[i].VertexID] = bw; } } boneIndex++; } foreach (var bone in bonesByName) { if (bone.Key.ToLower().Equals("root")) { rootBone = bone.Value; } string parent = ""; FindParentInHierarchy(bone.Key, scene.RootNode, out parent); if (parent.Length > 0 && bonesByName.ContainsKey(parent)) { bone.Value.SetParent(bonesByName[parent]); } else { bone.Value.SetParent(goRoot.transform); } } } UnityEngine.Matrix4x4[] bindposes = null; if (bones != null) { bindposes = new UnityEngine.Matrix4x4[bones.Length]; for (int b = 0; b < bones.Length; b++) { bindposes[b] = bones[b].worldToLocalMatrix * go.transform.localToWorldMatrix; } } mesh.vertices = vertices.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = sceneMesh.GetIndices(); mesh.uv = uv.ToArray(); mesh.RecalculateBounds(); mesh.RecalculateTangents(); if (min < mesh.bounds.max.z) { min = mesh.bounds.max.z; } //print(mesh.bounds.min.ToString()); //print(mesh.bounds.max.ToString()); PdxShape shape = go.AddComponent <PdxShape>(); Assimp.Material _mat = scene.Materials[sceneMesh.MaterialIndex]; //print(_mat.Name); Shader shader = Shader.Find("PDX/" + _mat.Name); shape.shader = _mat.Name; if (shader == null) { shader = Shader.Find("PDX/PdxMeshStandard"); shape.shader = "PdxMeshStandard"; } UnityEngine.Material mat = new UnityEngine.Material(shader); bool collision = false; switch (shape.shader) { case "Collision": collision = true; break; case "PdxMeshSnow": snow.Add(mat); break; case "PdxMeshColor": color.Add(mat); break; case "PdxMeshTextureAtlas": atlas.Add(mat); mat.SetTexture("_Atlas", atlasExample); break; } if (_mat.HasTextureDiffuse) { if (_mat.TextureDiffuse.FilePath.EndsWith(".dds")) { string texPath = _mat.TextureDiffuse.FilePath; if (texPath[1] != ':') { texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureDiffuse.FilePath; } if (File.Exists(texPath)) { shape.diffuse = texPath; Texture2D tex = PdxLoader.LoadDDS(texPath); tex.name = Path.GetFileName(texPath); mat.SetTexture("_Diffuse", tex); } } } if (_mat.HasTextureHeight) { if (_mat.TextureHeight.FilePath.EndsWith(".dds")) { string texPath = _mat.TextureHeight.FilePath; if (texPath[1] != ':') { texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureHeight.FilePath; } if (File.Exists(texPath)) { shape.normal = texPath; Texture2D tex = PdxLoader.LoadDDS(texPath); tex.name = Path.GetFileName(texPath); mat.SetTexture("_Normal", tex); } } } if (_mat.HasTextureSpecular) { if (_mat.TextureSpecular.FilePath.EndsWith(".dds")) { string texPath = _mat.TextureSpecular.FilePath; if (texPath[1] != ':') { texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureSpecular.FilePath; } if (File.Exists(texPath)) { shape.specular = texPath; Texture2D tex = PdxLoader.LoadDDS(texPath); tex.name = Path.GetFileName(texPath); mat.SetTexture("_Specular", tex); } } } if (skinned) { SkinnedMeshRenderer smr = go.AddComponent <SkinnedMeshRenderer>(); smr.bones = bones; smr.rootBone = rootBone; mesh.bindposes = bindposes; mesh.boneWeights = boneWeights.ToArray(); smr.sharedMesh = mesh; if (collision) { smr.sharedMaterial = mat; } else { smr.sharedMaterials = new UnityEngine.Material[] { mat, highlightMaterial } }; shape.smr = smr; } else { MeshFilter mf = go.AddComponent <MeshFilter>(); mf.mesh = mesh; MeshRenderer mr = go.AddComponent <MeshRenderer>(); if (collision) { mr.sharedMaterial = mat; } else { mr.sharedMaterials = new UnityEngine.Material[] { mat, highlightMaterial } }; shape.mr = mr; } go.transform.SetParent(goRoot.transform); } #region import animation foreach (var a in scene.Animations) { if ((int)a.TicksPerSecond == 1) { EditorController.instance.Status("Can't load animation with custom frame rate", 1); break; } bool resampled = false; if (a.HasNodeAnimations) { PdxDataService.AnimationData adata = new PdxDataService.AnimationData(); #if UNITY_EDITOR print("fps: " + a.TicksPerSecond + ", duration: " + a.DurationInTicks); #endif adata.fps = 15;// (float)a.TicksPerSecond; adata.sampleCount = (int)a.DurationInTicks; adata.length = adata.sampleCount / adata.fps; foreach (var nac in a.NodeAnimationChannels) { resampled = nac.PositionKeyCount == adata.sampleCount + 1 || nac.RotationKeyCount == adata.sampleCount + 1 || nac.ScalingKeyCount == adata.sampleCount + 1; if (resampled) { break; } } #if UNITY_EDITOR print("resampled " + resampled); #endif foreach (var nac in a.NodeAnimationChannels) { if (!bonesByName.ContainsKey(nac.NodeName)) { continue; } var animation = new PdxDataService.AnimationData.Animation(); animation.name = nac.NodeName; animation.parent = bonesByName[nac.NodeName]; animation.keys = new List <PdxDataService.AnimationData.Key>(); for (int i = 0; i < adata.sampleCount + 1; i++) { animation.keys.Add(new PdxDataService.AnimationData.Key()); } animation.keys[0].pos = animation.parent.transform.localPosition; animation.keys[0].rot = animation.parent.transform.localRotation; animation.keys[0].scl = animation.parent.transform.localScale; //animation.sampleT = true; // or joint mistmatch error if (nac.HasPositionKeys) { if (resampled) { foreach (var pk in nac.PositionKeys) { int i = (int)pk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].pos = new Vector3(pk.Value.X, pk.Value.Y, pk.Value.Z); animation.keys[i].time = (float)pk.Time / (float)adata.fps; } } else { List <VectorKey> posKeys = nac.PositionKeys; if (ListVectorKey(ref posKeys, adata.sampleCount)) { animation.sampleT = true; foreach (var pk in posKeys) { int i = (int)pk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].pos = new Vector3(pk.Value.X, pk.Value.Y, pk.Value.Z); animation.keys[i].time = (float)pk.Time / (float)adata.fps; } } } } if (nac.HasRotationKeys) { if (resampled) { foreach (var rk in nac.RotationKeys) { int i = (int)rk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].rot = new UnityEngine.Quaternion(rk.Value.X, rk.Value.Y, rk.Value.Z, rk.Value.W); animation.keys[i].time = (float)rk.Time / (float)adata.fps; } } else { List <QuaternionKey> rotKeys = nac.RotationKeys; if (ListQuaternionKey(ref rotKeys, adata.sampleCount)) { animation.sampleQ = true; foreach (var rk in rotKeys) { int i = (int)rk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].rot = new UnityEngine.Quaternion(rk.Value.X, rk.Value.Y, rk.Value.Z, rk.Value.W); animation.keys[i].time = (float)rk.Time / (float)adata.fps; } } } } if (nac.HasScalingKeys) { if (resampled) { foreach (var sk in nac.ScalingKeys) { int i = (int)sk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].scl = new Vector3(sk.Value.X, sk.Value.Y, sk.Value.Z); animation.keys[i].time = (float)sk.Time / (float)adata.fps; } } else { List <VectorKey> sclKeys = nac.ScalingKeys; if (ListVectorKey(ref sclKeys, adata.sampleCount)) { animation.sampleS = true; foreach (var sk in sclKeys) { int i = (int)sk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].scl = new Vector3(sk.Value.X, sk.Value.Y, sk.Value.Z); animation.keys[i].time = (float)sk.Time / (float)adata.fps; } } } } adata.hierarchy.Add(animation); } var player = goRoot.AddComponent <PdxAnimationPlayer>(); adata.Fix(); player.animationData = adata; } } #endregion EditorController.instance.SceneHasSnowMaterial(snow.Count > 0 ? snow.ToArray() : null); EditorController.instance.SceneHasColorMaterial(color.Count > 0 ? color.ToArray() : null); EditorController.instance.SceneHasAtlasMaterial(atlas.Count > 0 ? atlas.ToArray() : null); if (!path.ToLower().EndsWith(".obj")) { goRoot.transform.Translate(0, min, 0, Space.World); goRoot.transform.rotation = UnityEngine.Quaternion.Euler(90, 0, 0); } context.Dispose(); return(goRoot); }
private SEAMaterial AppendMaterial(Scene scene, Material material) { int sIndex = GetIndexByTag(material); if (sIndex != -1) return (SEAMaterial)Writer.Objects[sIndex]; SEAMaterial mat = new SEAMaterial(GetValidString(materials, material.Name)); mat.doubleSided = material.IsTwoSided; mat.receiveLights = true; mat.receiveShadows = true; mat.receiveFog = true; mat.repeat = true; mat.alpha = material.Opacity; // // DEFAULT // PhongTech defaultTech = new PhongTech(); defaultTech.diffuseColor = ToInteger( material.ColorDiffuse ); defaultTech.specularColor = ToInteger( material.ColorSpecular ); defaultTech.specular = material.ShininessStrength; defaultTech.gloss = material.Shininess; mat.techniques.Add(defaultTech); // // DIFFUSE_MAP // if (material.HasTextureDiffuse) { SEAObject tex = AppendTextureFromSlot(scene, material.TextureDiffuse); if (tex != null) { DiffuseMapTech tech = new DiffuseMapTech(); tech.texture = GetIndex(tex); mat.techniques.Add(tech); } } // // SPECULAR_MAP // if (material.HasTextureSpecular) { SEAObject tex = AppendTextureFromSlot(scene, material.TextureSpecular); if (tex != null) { SpecularMapTech tech = new SpecularMapTech(); tech.texture = GetIndex(tex); mat.techniques.Add(tech); } } // // EMISSIVE_MAP // if (material.HasTextureAmbient || material.HasTextureEmissive) { SEAObject tex = AppendTextureFromSlot(scene, material.HasTextureAmbient ? material.TextureAmbient : material.TextureEmissive); if (tex != null) { EmissiveMapTech tech = new EmissiveMapTech(); tech.texture = GetIndex(tex); mat.techniques.Add(tech); } } // // NORMAL_MAP // if (material.HasTextureNormal) { SEAObject tex = AppendTextureFromSlot(scene, material.TextureNormal); if (tex != null) { NormalMapTech tech = new NormalMapTech(); tech.texture = GetIndex(tex); mat.techniques.Add(tech); } } // // OPACITY_MAP // if (material.HasTextureOpacity) { SEAObject tex = AppendTextureFromSlot(scene, material.TextureOpacity); if (tex != null) { OpacityMapTech tech = new OpacityMapTech(); tech.texture = GetIndex(tex); mat.techniques.Add(tech); } } // // REFLECTION_MAP // if (material.HasTextureReflection) { SEAObject tex = AppendTextureFromSlot(scene, material.TextureReflection); if (tex != null) { ReflectionTech tech = new ReflectionTech(); tech.texture = GetIndex(tex); tech.alpha = material.Reflectivity; mat.techniques.Add(tech); } } // -- mat.tag = material; materials.Add(mat); Writer.AddObject(mat); return mat; }
/// <summary> /// Applies a material to the Gl state machine. Depending on the renderer, /// this either sets GLSL shaders (GL3) or it configures the fixed function pipeline /// (legacy/classic). /// </summary> /// <param name="mesh">Mesh to be drawn. This parameter may be left null /// to use a material with geometry other than assimp meshes (i.e. /// for the material preview tab). In this case, it is assumed that /// the geometry to be used with the materials specifies normals, /// one set of UV coordinates but no vertex colors. /// TODO tangents, bitangents? /// </param> /// <param name="mat">Material to be applied, must be non-null</param> public abstract void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded);
/// <summary> /// Primena razlicitih komponenti datog materijala (ambijentalna, difuzna, spekularna, emisiona, sjaj). /// </summary> /// <param name="material">Materijal cije ce karakteristike biti primenjene.</param> private void ApplyMaterial(Material material) { // Primena ambijentalne komponente datog materijala. U slucaju da ista nije definisana, koristi se podrazumevana vrednost. float[] ambientColor = material.HasColorAmbient ? new float[] { material.ColorAmbient.R, material.ColorAmbient.G, material.ColorAmbient.B, material.ColorAmbient.A } : new float[] { 0.2f, 0.2f, 0.2f, 1.0f }; Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT, ambientColor); // Primena difuzne komponente datog materijala. U slucaju da ista nije definisana, koristi se podrazumevana vrednost. float[] diffuseColor = material.HasColorDiffuse ? new float[] { material.ColorDiffuse.R, material.ColorDiffuse.G, material.ColorDiffuse.B, material.ColorDiffuse.A } : new float[] { 0.8f, 0.8f, 0.8f, 1.0f }; Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE, diffuseColor); // Primena spekularne komponente datog materijala. U slucaju da ista nije definisana, koristi se podrazumevana vrednost. float[] specularColor = material.HasColorSpecular ? new float[] { material.ColorSpecular.R, material.ColorSpecular.G, material.ColorSpecular.B, material.ColorSpecular.A } : new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, specularColor); // Primena emisione komponente datog materijala. U slucaju da ista nije definisana, koristi se podrazumevana vrednost. float[] emissiveColor = material.HasColorEmissive ? new float[] { material.ColorEmissive.R, material.ColorEmissive.G, material.ColorEmissive.B, material.ColorEmissive.A } : new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, emissiveColor); // Primena sjaja materijala. U slucaju da ista nije definisana, koristi se podrazumevana vrednost. float shininess = material.HasShininess ? material.Shininess : 1.0f; float strength = material.HasShininessStrength ? material.ShininessStrength : 1.0f; Gl.glMaterialf(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, shininess * strength); }
private Mesh <Vertex> proccessMesh(ai.Mesh mesh, ai.Scene scene) { //Vertex[] vertices = new Vertex[mesh.VertexCount]; //uint[] indices = new uint[mesh.FaceCount * 3]; List <Vertex> vertices = new List <Vertex>(); List <uint> indices = new List <uint>(); ImageTexture[] textures; for (int i = 0; i < mesh.VertexCount; i++) { Vertex v = new Vertex(); ai.Vector3D mvp = mesh.Vertices[i]; v.Position = new vec3(mvp.X, mvp.Y, mvp.Z); ai.Vector3D mvn = mesh.Normals[i]; v.Normal = new vec3(mvn.X, mvn.Y, mvn.Z); ai.Vector3D mvt = mesh.Tangents[i]; v.Tangent = new vec3(mvt.X, mvt.Y, mvt.Z); ai.Vector3D mvb = mesh.BiTangents[i]; v.Bitangent = new vec3(mvb.X, mvb.Y, mvb.Z); if (mesh.TextureCoordinateChannelCount > 0) { ai.Vector3D mvc = mesh.TextureCoordinateChannels[0][i]; v.TexCoords = new vec2(mvc.X, mvc.Y); } else { v.TexCoords = new vec2(0, 0); } vertices.Add(v); } for (int i = 0; i < mesh.FaceCount; i++) { for (int j = 0; j < mesh.Faces[i].IndexCount; j++) { indices.Add((uint)mesh.Faces[i].Indices[j]); } } if (mesh.MaterialIndex >= 0) { ai.Material material = scene.Materials[mesh.MaterialIndex]; List <ImageTexture> tempTextures = new List <ImageTexture>(); ImageTexture[] diffuse = loadMaterialTextures(material, ai.TextureType.Diffuse, TextureType.Diffuse); tempTextures.AddRange(diffuse); ImageTexture[] specular = loadMaterialTextures(material, ai.TextureType.Specular, TextureType.Specular); tempTextures.AddRange(specular); ImageTexture[] normal = loadMaterialTextures(material, ai.TextureType.Height, TextureType.Normal); tempTextures.AddRange(normal); textures = tempTextures.ToArray(); } else { textures = new ImageTexture[0]; } return(new ModelMesh(vertices.ToArray(), indices.ToArray(), textures)); }