private void meshesCB_SelectedIndexChanged(object sender, EventArgs e) { if (meshesCB.SelectedIndex >= 0) { ActiveMaterial = Materials[meshesCB.SelectedIndex]; ChannelTextures.Clear(); Textures.Clear(); textureCB.Items.Clear(); foreach (var texMap in ActiveMaterial.TextureMaps) { var texture = texMap.GetTexture(); if (texture != null && !Textures.Contains(texture)) { textureCB.Items.Add(texture.Text); Textures.Add(texture); ActiveTexture tex = new ActiveTexture(); tex.TextureIndex = Textures.IndexOf(texture); tex.Width = texture.Width; tex.Height = texture.Height; tex.MagFilter = texMap.MagFilter; tex.MinFilter = texMap.MinFilter; tex.UvChannelIndex = 0; ChannelTextures.Add(tex); } } if (textureCB.Items.Count > 0) { textureCB.SelectedIndex = 0; } } }
public static STGenericMaterial LoadMaterial(material daeMat) { STGenericMaterial mat = new STGenericMaterial(); mat.Name = daeMat.id; return(mat); }
public void LoadMaterial(STGenericMaterial mat) { TextureMapEditor.LoadMaterial(mat, new List <STGenericMesh>() { ActiveMesh }); }
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) { var cmbMaterial = ((CMB.CMBMaterialWrapper)mat).CMBMaterial; var cmbMesh = ((CMB.CmbMeshWrapper)m); bool HasNoNormals = cmbMesh.Mesh.HasNormal == false; shader.SetBoolToInt("HasNoNormals", HasNoNormals); shader.SetBoolToInt("isTransparent", cmbMaterial.BlendEnabled); SetGLCullMode(cmbMaterial.CullMode); if (cmbMaterial.BlendEnabled) { GL.Enable(EnableCap.Blend); GL.BlendColor(cmbMaterial.BlendColor.R / 255, cmbMaterial.BlendColor.G / 255, cmbMaterial.BlendColor.B / 255, cmbMaterial.BlendColor.A / 255); GL.BlendFunc(ConvertBlendFunc(cmbMaterial.BlendFunction.AlphaSrcFunc), ConvertBlendFunc(cmbMaterial.BlendFunction.AlphaDstFunc)); } else { GL.Disable(EnableCap.Blend); } if (cmbMaterial.AlphaTest.Enabled) { GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(ConvertTestFunction(cmbMaterial.AlphaTest.Function), cmbMaterial.AlphaTest.Reference / 255f); } else { GL.Disable(EnableCap.AlphaTest); } }
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) { var cmbMaterial = ((CMB.CMBMaterialWrapper)mat).Material; var cmbMesh = ((CMB.CmbMeshWrapper)m); bool HasNoNormals = cmbMesh.Shape.Normal.VertexData == null || cmbMesh.Shape.Normal.VertexData.Length == 0; shader.SetBoolToInt("HasNoNormals", HasNoNormals); shader.SetBoolToInt("isTransparent", cmbMaterial.BlendEnaled); SetGLCullMode(cmbMaterial.CullMode); GL.Enable(EnableCap.Blend); GL.BlendFunc(cmbMaterial.BlendingFactorSrcAlpha, cmbMaterial.BlendingFactorDestAlpha); GL.BlendColor(1.0f, 1.0f, 1.0f, cmbMaterial.BlendColorA); if (cmbMaterial.AlphaTestEnable) { GL.Enable(EnableCap.AlphaTest); } else { GL.Disable(EnableCap.AlphaTest); } GL.AlphaFunc(cmbMaterial.AlphaTestFunction, cmbMaterial.AlphaTestReference); }
public void DrawModel(GLControl control, STSkeleton Skeleton, STGenericMaterial Material, STGenericObject m, ShaderProgram shader) { if (m.PolygonGroups.Count > 0) { foreach (var group in m.PolygonGroups) { if (group.faces.Count <= 3) { return; } SetRenderData(Material, shader, m); SetUniforms(Material, shader, m); SetUniformBlocks(Material, shader, m); SetBoneUniforms(control, shader, Skeleton, m); SetVertexAttributes(m, shader); SetTextureUniforms(Material, m, shader); if (m.IsSelected || m.GetMaterial().IsSelected) { DrawModelSelection(group, shader); } else { if (Runtime.RenderModels) { GL.DrawElements(PrimitiveType.Triangles, group.displayFaceSize, DrawElementsType.UnsignedInt, group.Offset); } } } } else { if (m.lodMeshes.Count <= 0 || m.lodMeshes[m.DisplayLODIndex].faces.Count <= 3) { return; } SetUniforms(Material, shader, m); SetUniformBlocks(Material, shader, m); SetBoneUniforms(control, shader, Skeleton, m); SetVertexAttributes(m, shader); SetTextureUniforms(Material, m, shader); if (m.IsSelected) { DrawModelSelection(m, shader); } else { if (Runtime.RenderModels) { GL.DrawElements(PrimitiveType.Triangles, m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset); } } } }
private static void SetUniforms(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) { //UV Scale shader.SetFloat("ColorUVScaleU", 1); shader.SetFloat("ColorUVScaleV", 1); //UV Translate shader.SetFloat("ColorUVTranslateU", 0); shader.SetFloat("ColorUVTranslateV", 0); }
public virtual void SetMaterialUniforms(ShaderProgram shader, STGenericMaterial material, STGenericMesh mesh) { shader.SetColor("diffuseColor", STColor8.White.Color); if (material == null) { return; } shader.SetColor("diffuseColor", material.DiffuseColor.Color); }
public static STGenericMaterial LoadMaterial(ColladaScene scene, material daeMat) { STGenericMaterial mat = new STGenericMaterial(); mat.Name = daeMat.id; if (daeMat.instance_effect != null) { var effectid = daeMat.instance_effect.url.Remove(0, 1); if (scene.effectLookup.ContainsKey(effectid)) { var effect = scene.effectLookup[effectid]; if (effect.Items == null) { return(mat); } foreach (var item in effect.Items) { if (item.Items == null) { continue; } foreach (var param in item.Items) { if (param is common_newparam_type) { var newparam = (common_newparam_type)param; if (newparam.ItemElementName == ItemChoiceType.surface) { var surface = newparam.Item as fx_surface_common; var name = surface.init_from[0].Value; mat.TextureMaps.Add(new STGenericTextureMap() { Name = name, Type = STTextureType.Diffuse, }); } } if (param is technique) { var technique = (technique)param; } } } } else { Console.WriteLine($"cannot find id! {effectid}"); } } return(mat); }
public override void RenderMaterials(ShaderProgram shader, STGenericMesh mesh, STPolygonGroup group, STGenericMaterial material, Vector4 highlight_color) { var msh = (HSFMesh)mesh; shader.SetVector4("highlight_color", highlight_color); //Note we render picking pass here for backface culling shader.SetFloat("brightness", 1.0f); SetRenderData(group.Material, shader, msh); SetTextureUniforms(shader, (HSFMaterialWrapper)group.Material); }
public override void SetMaterialUniforms(ShaderProgram shader, STGenericMaterial material, STGenericMesh mesh) { shader.SetVector4("tint_color", Vector4.One); var mat = (BIN.BIN_Material)material; shader.SetVector4("tint_color", new Vector4( mat.TintColor.R / 255F, mat.TintColor.G / 255F, mat.TintColor.B / 255F, mat.TintColor.A / 255F)); }
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) { var bmdMaterial = (BMDMaterialWrapper)mat; //This is only for translucency //Todo figure out how bmd determines transparent materials shader.SetBoolToInt("isTransparent", bmdMaterial.isTransparent); GXToOpenGL.SetBlendState(bmdMaterial.Material.BMode); GXToOpenGL.SetCullState(bmdMaterial.Material.CullMode); // GXToOpenGL.SetDepthState(bmdMaterial.Material.ZMode, false); // GXToOpenGL.SetDitherEnabled(bmdMaterial.Material.Dither); }
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) { shader.SetBoolToInt("NoSkinning", Skeleton.bones.Count == 0); if (mat.Text == "driver_cloth") { GL.Disable(EnableCap.CullFace); } else { GL.Enable(EnableCap.CullFace); } }
private void TextureUniform(ShaderProgram shader, STGenericMaterial mat, bool hasTex, string name, STGenericMatTexture mattex) { if (mattex.textureState == STGenericMatTexture.TextureState.Binded) { return; } // Bind the texture and create the uniform if the material has the right textures. if (hasTex) { GL.Uniform1(shader[name], BindTexture(mattex, shader)); } }
public override void SetMaterialUniforms(ShaderProgram shader, STGenericMaterial material, STGenericMesh mesh) { var mat = (LMMaterial)material; if (mat == null) { return; } shader.SetBool("isAmbientMap", mat.IsAmbientMap); base.SetMaterialUniforms(shader, material, mesh); }
private void SetupMaterial(STGenericMaterial importedMaterial, Material newMaterial, List <string> textures) { return; //Here all we want is the diffuse texture and swap them foreach (var texMap in importedMaterial.TextureMaps) { var diffuseTex = newMaterial.TextureMaps.FirstOrDefault(x => x.Sampler == "Col0Tex" || x.Sampler == "BaseColor0"); if (diffuseTex != null) { diffuseTex.Index = (uint)textures.IndexOf(texMap.Name); } } }
public void LoadMaterial(STGenericMaterial material, List <STGenericMesh> meshes) { Reset(); ActiveMaterial = material; ActiveMeshes = meshes; listViewCustom1.LargeImageList = imgListBig; listViewCustom1.SmallImageList = imgListSmall; listViewCustom1.View = View.LargeIcon; foreach (var texture in material.TextureMaps) { ListViewItem item = new ListViewItem(); item.Text = texture.Name; item.ImageIndex = 0; listViewCustom1.Items.Add(item); } if (Thread != null && Thread.IsAlive) { Thread.Abort(); } Thread = new Thread((ThreadStart)(() => { int index = 0; foreach (var texture in material.TextureMaps) { var tex = texture.GetTexture(); if (tex != null) { LoadTextureIcon(index, tex); } index++; } })); Thread.Start(); isLoaded = true; if (listViewCustom1.Items.Count > 0) { listViewCustom1.Items[0].Selected = true; listViewCustom1.Select(); } }
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) { var h3dMaterialWrapper = (H3DMaterialWrapper)mat; var h3dMaterial = h3dMaterialWrapper.Material; if (h3dMaterial.MaterialParams.AlphaTest.Enabled) { GL.Enable(EnableCap.AlphaTest); } else { GL.Disable(EnableCap.AlphaTest); } float alphaRef = h3dMaterial.MaterialParams.AlphaTest.Reference / 255f; GL.AlphaFunc(ConvertAlphaFunction(h3dMaterial.MaterialParams.AlphaTest.Function), alphaRef); }
public STGenericModel ToGeneric() { if (CachedModel != null) { return(CachedModel); } STGenericModel model = new STGenericModel("Model"); foreach (var shape in Meshes) { foreach (var meshGroup in shape.Groups) { var genericMesh = new STGenericMesh(); genericMesh.Name = $"Mesh{model.Meshes.Count}"; genericMesh.Vertices.AddRange(meshGroup.Vertices); var group = new STPolygonGroup(); genericMesh.PolygonGroups.Add(group); var mat = new STGenericMaterial(); mat.DiffuseColor = meshGroup.Color; group.Material = mat; if (meshGroup.TextureIndex != -1) { var texMap = new STGenericTextureMap() { Name = $"Texture{meshGroup.TextureIndex}", Type = STTextureType.Diffuse, }; mat.TextureMaps.Add(texMap); } genericMesh.Optmize(group); model.Meshes.Add(genericMesh); } } CachedModel = model; return(model); }
private void SetTextureUniforms(STGenericMaterial mat, STGenericObject m, ShaderProgram shader) { SetDefaultTextureAttributes(mat, shader); LoadDebugTextureMaps(shader); shader.SetInt("RedChannel", 0); shader.SetInt("GreenChannel", 1); shader.SetInt("BlueChannel", 2); shader.SetInt("AlphaChannel", 3); LoadPBRMaps(shader); foreach (STGenericMatTexture matex in mat.TextureMaps) { if (matex.Type == STGenericMatTexture.TextureType.Diffuse) { shader.SetBoolToInt("HasDiffuse", true); TextureUniform(shader, mat, true, "DiffuseMap", matex); } } }
public STGenericModel ToGeneric() { if (CachedModel != null) return CachedModel; STGenericModel model = new STGenericModel(FileName); foreach (var shape in Meshes) { foreach (var meshGroup in shape.Groups) { var genericMesh = new STGenericMesh(); genericMesh.Name = $"Mesh{model.Meshes.Count}"; genericMesh.Vertices.AddRange(meshGroup.Vertices); var group = new STPolygonGroup(); genericMesh.PolygonGroups.Add(group); genericMesh.Optmize(group); model.Meshes.Add(genericMesh); var mat = new STGenericMaterial(); group.Material = mat; // group.IsTransparentPass = true; if (TextureContainer.Textures.Count > 0) { var texMap = new STGenericTextureMap() { Name = $"Texture{meshGroup.TextureIndex}", Type = STTextureType.Diffuse, }; mat.TextureMaps.Add(texMap); } } } foreach (var tex in TextureContainer.Textures) model.Textures.Add(tex); CachedModel = model; return model; }
public void SetMaterial(STGenericMaterial mat) { material = mat; }
public BMDShapeWrapper(Shape shape, SuperBMDLib.Model model, BMDMaterialWrapper mat) { BMDShape = shape; ParentModel = model; material = mat; }
public override void SetTextureUniforms(GLContext control, ShaderProgram shader, STGenericMaterial mat) { var bfresMaterial = (FMAT)mat; GL.ActiveTexture(TextureUnit.Texture0 + 1); GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.ID); List <string> shaderSamplers = new List <string>(); foreach (var sampler in ShaderModel.Samplers.GetKeys()) { if (!string.IsNullOrEmpty(sampler)) { shaderSamplers.Add(sampler); } } int id = 1; foreach (var sampler in bfresMaterial.Material.ShaderAssign.SamplerAssigns) { var fragOutput = sampler.Key; var bfresInput = sampler.Value; var textureIndex = bfresMaterial.TextureMaps.FindIndex(x => x.Sampler == bfresInput); if (textureIndex == -1) { continue; } var texMap = mat.TextureMaps[textureIndex]; var name = texMap.Name; //Lookup samplers targeted via animations and use that texture instead if possible if (bfresMaterial.AnimatedSamplers.ContainsKey(bfresInput)) { name = bfresMaterial.AnimatedSamplers[bfresInput]; } int index = shaderSamplers.IndexOf(fragOutput); var uniformName = $"{ConvertSamplerID(index)}"; var binded = BindTexture(shader, GetTextures(), texMap, name, id); shader.SetInt(uniformName, id++); } LoadEngineTextures(shader, id); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); }
public virtual void RenderMaterials(ShaderProgram shader, STGenericMesh mesh, STPolygonGroup group, STGenericMaterial material, Vector4 highlight_color) { if (material == null && group.MaterialIndex != -1 && Model.Materials.Count > group.MaterialIndex) { material = Model.Materials[group.MaterialIndex]; } shader.SetVector4("highlight_color", highlight_color); SetTextureUniforms(shader); SetMaterialUniforms(shader, material, mesh); if (material == null) { return; } int textureUintID = 1; foreach (var textureMap in material.TextureMaps) { var tex = textureMap.GetTexture(); if (textureMap.Type == STTextureType.Diffuse) { shader.SetBoolToInt("hasDiffuse", true); BindTexture(shader, Model.Textures, textureMap, textureUintID); shader.SetInt($"tex_Diffuse", textureUintID); } textureUintID++; } }
public STGenericModel ToGeneric() { if (Model != null) { return(Model); } STGenericModel model = new STGenericModel(FileInfo.FileName); model.Skeleton = new STSkeleton(); foreach (var bone in Header.Bones) { var matrix = bone.InverseTransform.Inverted(); model.Skeleton.Bones.Add(new STBone(model.Skeleton) { Name = bone.Name, Position = bone.Position, Rotation = matrix.ExtractRotation(), Scale = matrix.ExtractScale(), ParentIndex = bone.ParentIndex, }); } model.Skeleton.Reset(); model.Skeleton.Update(); List <STGenericMaterial> materials = new List <STGenericMaterial>(); foreach (var mat in Header.Materials) { STGenericMaterial genericMaterial = new STGenericMaterial(); genericMaterial.Name = mat.Name; materials.Add(genericMaterial); for (int i = 0; i < mat.TextureSlots.Length; i++) { if (mat.TextureSlots[i] == null) { continue; } genericMaterial.TextureMaps.Add(new STGenericTextureMap() { Name = mat.TextureSlots[i].Name, Type = STTextureType.Diffuse, WrapU = STTextureWrapMode.Mirror, WrapV = STTextureWrapMode.Mirror, }); break; } } foreach (var mesh in Header.Meshes) { if (mesh.Vertices.Count == 0) { continue; } STGenericMesh genericMesh = new STGenericMesh(); genericMesh.Name = mesh.Name; model.Meshes.Add(genericMesh); foreach (var vert in mesh.Vertices) { if (mesh.BoneIndices.Length == 1) { var bone = model.Skeleton.Bones[(int)mesh.BoneIndices[0]]; vert.Position = Vector3.TransformPosition(vert.Position, bone.Transform); } genericMesh.Vertices.Add(new STVertex() { Position = vert.Position, Normal = vert.Normal, TexCoords = new Vector2[] { vert.TexCoord0, vert.TexCoord1 }, Colors = new Vector4[] { vert.Color }, }); } Console.WriteLine($"Vertices {mesh.Vertices.Count}"); genericMesh.FlipUvsVertical(); var poly = new STPolygonGroup(); poly.Material = materials[(int)mesh.MaterialIndex]; foreach (var face in mesh.Faces) { poly.Faces.Add(face); } genericMesh.PolygonGroups.Add(poly); } Model = model; return(model); }
public virtual void SetTextureUniforms(GLContext control, ShaderProgram shader, STGenericMaterial mat) { var bfresMaterial = (FMAT)mat; GL.ActiveTexture(TextureUnit.Texture0 + 1); GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.ID); shader.SetBoolToInt("hasDiffuseMap", false); shader.SetBoolToInt("hasAlphaMap", false); int id = 1; for (int i = 0; i < bfresMaterial.TextureMaps?.Count; i++) { var name = mat.TextureMaps[i].Name; var sampler = mat.TextureMaps[i].Sampler; //Lookup samplers targeted via animations and use that texture instead if possible if (bfresMaterial.AnimatedSamplers.ContainsKey(sampler)) { name = bfresMaterial.AnimatedSamplers[sampler]; } string uniformName = GetSamplerUniform(sampler); if (uniformName == string.Empty) { continue; } var binded = BindTexture(shader, GetTextures(), mat.TextureMaps[i], name, id); bool hasTexture = binded != null; switch (sampler) { //Always load diffuse map with a placeholder texture case "_a0": shader.SetBoolToInt("hasDiffuseMap", true); break; case "_ms0": shader.SetBoolToInt("hasAlphaMap", hasTexture); break; } if (hasTexture || sampler == "_a0") { shader.SetInt(uniformName, id++); } } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); }
public override void RenderMaterials(ShaderProgram shader, STGenericMesh mesh, STPolygonGroup group, STGenericMaterial material, Vector4 highlight_color) { shader.SetVector4("highlight_color", highlight_color); shader.SetBoolToInt("hasShadowMap", false); SetTextureUniforms(shader); SetMaterialUniforms(shader, material, mesh); if (material == null) { return; } int textureUintID = 1; foreach (var textureMap in material.TextureMaps) { var tex = textureMap.GetTexture(); if (textureMap.Type == STTextureType.Diffuse) { shader.SetBoolToInt("hasDiffuse", true); BindTexture(shader, Runtime.TextureCache, textureMap, textureUintID); shader.SetInt($"tex_Diffuse", textureUintID); } if (textureMap.Type == STTextureType.Shadow) { shader.SetBoolToInt("hasShadowMap", true); BindTexture(shader, Runtime.TextureCache, textureMap, textureUintID); shader.SetInt($"tex_ShadowMap", textureUintID); } textureUintID++; } }
public static void Export(string FileName, ExportSettings settings, List <STGenericMesh> Meshes, List <STGenericMaterial> Materials, List <STGenericTexture> Textures, STSkeleton skeleton = null, List <int> NodeArray = null) { if (Materials == null) { Materials = new List <STGenericMaterial>(); } if (settings.RemoveDuplicateVertices) { foreach (var mesh in Meshes) { mesh.RemoveDuplicateVertices(); } } Console.WriteLine($"DAE Materials {Materials.Count}"); List <string> failedTextureExport = new List <string>(); Dictionary <string, STGenericMaterial> MaterialRemapper = new Dictionary <string, STGenericMaterial>(); using (ColladaWriter writer = new ColladaWriter(FileName, settings)) { writer.WriteAsset(); if (Materials.Count > 0) { List <string> textureNames = new List <string>(); for (int i = 0; i < Textures?.Count; i++) { if (!textureNames.Contains(Textures[i].Name)) { textureNames.Add(Textures[i].Name); } if (settings.ExportTextures) { try { var bitmap = Textures[i].GetBitmap(); if (bitmap != null) { string textureName = Textures[i].Name; if (textureName.RemoveIllegaleFileNameCharacters() != textureName) { string properName = textureName.RemoveIllegaleFileNameCharacters(); for (int m = 0; m < Materials?.Count; m++) { foreach (var tex in Materials[m].TextureMaps) { if (tex.Name == textureName) { tex.Name = properName; } } } textureName = properName; } if (settings.ImageFolder != "") { bitmap.Save($"{settings.ImageFolder}/{textureName}.png"); } else { bitmap.Save($"{textureName}.png"); } bitmap.Dispose(); GC.Collect(); } } catch (Exception ex) { failedTextureExport.Add(Textures[i].Name); } } } for (int i = 0; i < Materials.Count; i++) { if (Materials[i].Name == null) { Materials[i].Name = $"Material{i}"; } } List <Material> materials = new List <Material>(); foreach (var mat in Materials) { Material material = new Material(); material.Name = mat.Name; if (!MaterialRemapper.ContainsKey(mat.Name)) { MaterialRemapper.Add(mat.Name, mat); } else { string name = Utils.RenameDuplicateString(mat.Name, MaterialRemapper.Keys.ToList()); MaterialRemapper.Add(name, mat); material.Name = name; } if (mat.DiffuseColor != null) { material.DiffuseColor = new float[4] { mat.DiffuseColor.R / 255.0F, mat.DiffuseColor.G / 255.0F, mat.DiffuseColor.B / 255.0F, mat.DiffuseColor.A / 255.0F } } ; materials.Add(material); foreach (var tex in mat.TextureMaps) { TextureMap texMap = new TextureMap(); texMap.Name = tex.Name; if (tex.Type == STTextureType.Diffuse) { texMap.Type = PhongTextureType.diffuse; } else if (tex.Type == STTextureType.Normal) { texMap.Type = PhongTextureType.bump; } else if (tex.Type == STTextureType.Specular) { texMap.Type = PhongTextureType.specular; } else if (tex.Type == STTextureType.Emission) { texMap.Type = PhongTextureType.emission; } else { continue; //Skip adding unknown types } if (tex.WrapU == STTextureWrapMode.Repeat) { texMap.WrapModeS = SamplerWrapMode.WRAP; } else if (tex.WrapU == STTextureWrapMode.Mirror) { texMap.WrapModeS = SamplerWrapMode.MIRROR; } else if (tex.WrapU == STTextureWrapMode.Clamp) { texMap.WrapModeS = SamplerWrapMode.CLAMP; } if (tex.WrapV == STTextureWrapMode.Repeat) { texMap.WrapModeT = SamplerWrapMode.WRAP; } else if (tex.WrapV == STTextureWrapMode.Mirror) { texMap.WrapModeT = SamplerWrapMode.MIRROR; } else if (tex.WrapV == STTextureWrapMode.Clamp) { texMap.WrapModeT = SamplerWrapMode.CLAMP; } //If no textures are saved, still keep images references //So the user can still dump textures after if (Textures?.Count == 0 && !textureNames.Contains(texMap.Name)) { textureNames.Add($"{texMap.Name}"); } material.Textures.Add(texMap); } } writer.WriteLibraryImages(textureNames.ToArray()); writer.WriteLibraryMaterials(materials); writer.WriteLibraryEffects(materials); } else { writer.WriteLibraryImages(); } if (skeleton != null) { for (int i = 0; i < skeleton.Bones.Count; i++) { if (skeleton.Bones[i].Name == null) { skeleton.Bones[i].Name = $"Bones{i}"; } } //Search for bones with rigging first List <string> riggedBones = new List <string>(); if (settings.OnlyExportRiggedBones) { for (int i = 0; i < Meshes.Count; i++) { for (int v = 0; v < Meshes[i].Vertices.Count; v++) { var vertex = Meshes[i].Vertices[v]; for (int j = 0; j < vertex.BoneIndices.Count; j++) { int id = -1; if (NodeArray != null && NodeArray.Count > vertex.BoneIndices[j]) { id = NodeArray[vertex.BoneIndices[j]]; } else { id = vertex.BoneIndices[j]; } if (id < skeleton.Bones.Count && id != -1) { riggedBones.Add(skeleton.Bones[id].Name); } } } } } foreach (var bone in skeleton.Bones) { if (settings.OnlyExportRiggedBones && !riggedBones.Contains(bone.Name)) { Console.WriteLine("Skipping " + bone.Name); continue; } //Set the inverse matrix var inverse = skeleton.GetBoneTransform(bone).Inverted(); var transform = bone.GetTransform(); float[] Transform = new float[] { transform.M11, transform.M21, transform.M31, transform.M41, transform.M12, transform.M22, transform.M32, transform.M42, transform.M13, transform.M23, transform.M33, transform.M43, transform.M14, transform.M24, transform.M34, transform.M44 }; float[] InvTransform = new float[] { inverse.M11, inverse.M21, inverse.M31, inverse.M41, inverse.M12, inverse.M22, inverse.M32, inverse.M42, inverse.M13, inverse.M23, inverse.M33, inverse.M43, inverse.M14, inverse.M24, inverse.M34, inverse.M44 }; writer.AddJoint(bone.Name, bone.ParentIndex == -1 ? "" : skeleton.Bones[bone.ParentIndex].Name, Transform, InvTransform, new float[3] { bone.Position.X, bone.Position.Y, bone.Position.Z }, new float[3] { bone.EulerRotation.X, bone.EulerRotation.Y, bone.EulerRotation.Z }, new float[3] { bone.Scale.X, bone.Scale.Y, bone.Scale.Z }); } } for (int i = 0; i < Meshes.Count; i++) { if (Meshes[i].Name == null) { Meshes[i].Name = $"Mesh{i}"; } } int meshIndex = 0; writer.StartLibraryGeometries(); foreach (var mesh in Meshes) { int[] IndexTable = null; if (NodeArray != null) { IndexTable = NodeArray.ToArray(); } writer.StartGeometry(mesh.Name); /* if (mesh.MaterialIndex != -1 && Materials.Count > mesh.MaterialIndex) * { * writer.CurrentMaterial = Materials[mesh.MaterialIndex].Text; * Console.WriteLine($"MaterialIndex {mesh.MaterialIndex } {Materials[mesh.MaterialIndex].Text}"); * }*/ if (settings.TransformColorUVs) { List <STVertex> transformedVertices = new List <STVertex>(); foreach (var poly in mesh.PolygonGroups) { var mat = poly.Material; if (mat == null) { continue; } var faces = poly.Faces; for (int v = 0; v < poly.Faces.Count; v += 3) { if (faces.Count < v + 2) { break; } var diffuse = mat.TextureMaps.FirstOrDefault(x => x.Type == STTextureType.Diffuse); STTextureTransform transform = new STTextureTransform(); if (diffuse != null) { transform = diffuse.Transform; } var vertexA = mesh.Vertices[(int)faces[v]]; var vertexB = mesh.Vertices[(int)faces[v + 1]]; var vertexC = mesh.Vertices[(int)faces[v + 2]]; if (!transformedVertices.Contains(vertexA)) { vertexA.TexCoords[0] = (vertexA.TexCoords[0] * transform.Scale) + transform.Translate; transformedVertices.Add(vertexA); } if (!transformedVertices.Contains(vertexB)) { vertexB.TexCoords[0] = (vertexB.TexCoords[0] * transform.Scale) + transform.Translate; transformedVertices.Add(vertexB); } if (!transformedVertices.Contains(vertexC)) { vertexC.TexCoords[0] = (vertexC.TexCoords[0] * transform.Scale) + transform.Translate; transformedVertices.Add(vertexC); } } } } // collect sources List <float> Position = new List <float>(); List <float> Normal = new List <float>(); List <float> UV1 = new List <float>(); List <float> UV2 = new List <float>(); List <float> UV3 = new List <float>(); List <float> Color = new List <float>(); List <float> Color2 = new List <float>(); List <int[]> BoneIndices = new List <int[]>(); List <float[]> BoneWeights = new List <float[]>(); bool HasNormals = false; bool HasColors = false; bool HasColors2 = false; bool HasUV0 = false; bool HasUV1 = false; bool HasUV2 = false; bool HasBoneIds = false; mesh.OptimizeVertices(); foreach (var vertex in mesh.Vertices) { //Remove zero weights if (settings.OptmizeZeroWeights) { float MaxWeight = 1; for (int i = 0; i < 4; i++) { if (vertex.BoneWeights.Count <= i) { continue; } if (vertex.BoneIndices.Count < i + 1) { vertex.BoneWeights[i] = 0; MaxWeight = 0; } else { float weight = vertex.BoneWeights[i]; if (vertex.BoneWeights.Count == i + 1) { weight = MaxWeight; } if (weight >= MaxWeight) { weight = MaxWeight; MaxWeight = 0; } else { MaxWeight -= weight; } vertex.BoneWeights[i] = weight; } } } if (vertex.Normal != Vector3.Zero) { HasNormals = true; } if (vertex.Colors.Length > 0 && settings.UseVertexColors) { HasColors = true; } if (vertex.Colors.Length > 1 && settings.UseVertexColors) { HasColors2 = true; } if (vertex.TexCoords.Length > 0) { HasUV0 = true; } if (vertex.TexCoords.Length > 1) { HasUV1 = true; } if (vertex.TexCoords.Length > 2) { HasUV2 = true; } if (vertex.BoneIndices.Count > 0) { HasBoneIds = true; } Position.Add(vertex.Position.X); Position.Add(vertex.Position.Y); Position.Add(vertex.Position.Z); Normal.Add(vertex.Normal.X); Normal.Add(vertex.Normal.Y); Normal.Add(vertex.Normal.Z); for (int i = 0; i < vertex.TexCoords.Length; i++) { var texCoord = vertex.TexCoords[i]; if (settings.FlipTexCoordsVertical) { texCoord = new Vector2(texCoord.X, 1 - texCoord.Y); } if (i == 0) { UV1.Add(texCoord.X); UV1.Add(texCoord.Y); } if (i == 1) { UV2.Add(texCoord.X); UV2.Add(texCoord.Y); } if (i == 2) { UV3.Add(texCoord.X); UV3.Add(texCoord.Y); } } if (vertex.Colors.Length > 0) { Color.AddRange(new float[] { vertex.Colors[0].X, vertex.Colors[0].Y, vertex.Colors[0].Z, vertex.Colors[0].W }); } if (vertex.Colors.Length > 1) { Color2.AddRange(new float[] { vertex.Colors[1].X, vertex.Colors[1].Y, vertex.Colors[1].Z, vertex.Colors[1].W }); } List <int> bIndices = new List <int>(); List <float> bWeights = new List <float>(); for (int b = 0; b < vertex.BoneIndices.Count; b++) { if (b > mesh.VertexSkinCount - 1) { continue; } if (vertex.BoneWeights.Count > b) { if (vertex.BoneWeights[b] == 0) { continue; } } int index = -1; if (IndexTable != null) { index = (int)IndexTable[vertex.BoneIndices[b]]; } else { index = (int)vertex.BoneIndices[b]; } if (index != -1 && index < skeleton?.Bones.Count) { bIndices.Add(index); } //Some models may only use indices (single bind, rigid skin) if (vertex.BoneWeights.Count > b) { bWeights.Add(vertex.BoneWeights[b]); } else { bWeights.Add(1); } } if (bIndices.Count == 0 && mesh.BoneIndex != -1) { HasBoneIds = true; bIndices.Add(mesh.BoneIndex); bWeights.Add(1); } BoneIndices.Add(bIndices.ToArray()); BoneWeights.Add(bWeights.ToArray()); } List <TriangleList> triangleLists = new List <TriangleList>(); if (mesh.PolygonGroups.Count > 0) { foreach (var group in mesh.PolygonGroups) { TriangleList triangleList = new TriangleList(); triangleLists.Add(triangleList); STGenericMaterial material = new STGenericMaterial(); if (group.MaterialIndex != -1 && Materials.Count > group.MaterialIndex) { material = Materials[group.MaterialIndex]; } if (group.Material != null) { material = group.Material; } if (MaterialRemapper.Values.Any(x => x == material)) { var key = MaterialRemapper.FirstOrDefault(x => x.Value == material).Key; triangleList.Material = key; } else if (material.Name != string.Empty) { triangleList.Material = material.Name; } List <uint> faces = new List <uint>(); if (group.PrimitiveType == STPrimitiveType.TriangleStrips) { faces = TriangleConverter.ConvertTriangleStripsToTriangles(group.Faces); } else { faces = group.Faces; } for (int i = 0; i < faces.Count; i++) { triangleList.Indices.Add(faces[i]); } } } // write sources writer.WriteGeometrySource(mesh.Name, SemanticType.POSITION, Position.ToArray(), triangleLists.ToArray()); if (HasNormals) { writer.WriteGeometrySource(mesh.Name, SemanticType.NORMAL, Normal.ToArray(), triangleLists.ToArray()); } if (HasColors) { writer.WriteGeometrySource(mesh.Name, SemanticType.COLOR, Color.ToArray(), triangleLists.ToArray(), 0); } if (HasColors2) { writer.WriteGeometrySource(mesh.Name, SemanticType.COLOR, Color2.ToArray(), triangleLists.ToArray(), 1); } Console.WriteLine($"HasUV0 {HasUV0} {UV1.Count}"); if (HasUV0) { writer.WriteGeometrySource(mesh.Name, SemanticType.TEXCOORD, UV1.ToArray(), triangleLists.ToArray(), 0); } if (HasUV1) { writer.WriteGeometrySource(mesh.Name, SemanticType.TEXCOORD, UV2.ToArray(), triangleLists.ToArray(), 1); } if (HasUV2) { writer.WriteGeometrySource(mesh.Name, SemanticType.TEXCOORD, UV3.ToArray(), triangleLists.ToArray(), 2); } if (HasBoneIds) { writer.AttachGeometryController(BoneIndices, BoneWeights); } writer.EndGeometryMesh(); } writer.EndGeometrySection(); } }
private static void SetDefaultTextureAttributes(STGenericMaterial mat, ShaderProgram shader) { }