/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="filePath"></param> /// <returns></returns> private string AddImage(IOTexture tex) { var name = tex.Name; var filePath = tex.FilePath; // create image node Image img = new Image() { ID = GetUniqueID(name + "-image"), Name = name, Init_From = new Init_From() { Value = filePath } }; // add image element to image library if (_collada.Library_Images == null) { _collada.Library_Images = new Library_Images(); } if (_collada.Library_Images.Image == null) { _collada.Library_Images.Image = new Image[0]; } Array.Resize(ref _collada.Library_Images.Image, _collada.Library_Images.Image.Length + 1); _collada.Library_Images.Image[_collada.Library_Images.Image.Length - 1] = img; // return id return(img.ID); }
/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="color"></param> /// <param name="texture"></param> private bool ReadEffectColorType(Profile_COMMON prof, FX_Common_Color_Or_Texture_Type type, out Vector4 color, out IOTexture texture) { color = Vector4.One; texture = null; if (type.Color != null) { var c = type.Color.GetValues(); color = new Vector4(c[0], c[1], c[2], c[3]); } if (type.Texture != null) { // create diffuse texture texture = new IOTexture(); var texid = type.Texture.Textures; // blender image lookup if (prof.New_Param != null) { var samp = prof.New_Param.FirstOrDefault(e => e.sID == type.Texture.Textures); if (samp != null && samp.Data != null) { var samp2d = samp.Data.FirstOrDefault(e => e.Name == "sampler2D"); if (samp2d != null) { var src = FindChild(samp2d, "source"); if (src != null) { var surf = prof.New_Param.FirstOrDefault(e => e.sID == src.InnerText); if (surf != null && surf.Data != null) { var sur2d = surf.Data.FirstOrDefault(e => e.Name == "surface"); if (sur2d != null) { var init = FindChild(sur2d, "init_from"); texid = init.InnerText; } } } } } } // lookup image from image library var image = _collada.Library_Images.Image.FirstOrDefault(e => e.ID == texid); if (image != null) { texture.Name = image.Name; texture.FilePath = string.IsNullOrEmpty(image.Init_From.Ref) ? image.Init_From.Value : image.Init_From.Ref; } } return(type.Color != null); }
public IOModel GetIOModel() { IOModel outModel = new IOModel(); Mesh meshFile = null; Matl materialFile = null; foreach (FileNode n in Parent.Nodes) { if (n.Text.Equals(model.MeshString)) { meshFile = ((NumsbhNode)n).mesh; } if (n.Text.Equals(model.SkeletonFileName)) { outModel.Skeleton = (RSkeleton)((SkelNode)n).GetRenderableNode(); } if (n.Text.Equals(model.MaterialFileNames[0].MaterialFileName)) { materialFile = ((MatlNode)n).Material; } } Dictionary <string, int> indexByBoneName = new Dictionary <string, int>(); if (outModel.Skeleton != null) { for (int i = 0; i < outModel.Skeleton.Bones.Count; i++) { indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i); } } Dictionary <string, int> materialNameToIndex = new Dictionary <string, int>(); if (materialFile != null) { int materialIndex = 0; foreach (var entry in materialFile.Entries) { materialNameToIndex.Add(entry.ShaderLabel, materialIndex++); IOMaterial material = new IOMaterial { Name = entry.ShaderLabel }; outModel.Materials.Add(material); foreach (var attr in entry.Attributes) { if (attr.ParamId == MatlEnums.ParamId.Texture0) { IOTexture dif = new IOTexture { Name = attr.DataObject.ToString() }; material.DiffuseTexture = dif; } } } } if (meshFile != null) { SsbhVertexAccessor vertexAccessor = new SsbhVertexAccessor(meshFile); { SsbhRiggingAccessor riggingAccessor = new SsbhRiggingAccessor(meshFile); foreach (MeshObject obj in meshFile.Objects) { IOMesh outMesh = new IOMesh() { Name = obj.Name, }; outModel.Meshes.Add(outMesh); // get material if (materialFile != null) { foreach (var entry in model.ModelEntries) { if (entry.MeshName.Equals(obj.Name) && entry.SubIndex == obj.SubMeshIndex) { outMesh.MaterialIndex = materialNameToIndex[entry.MaterialLabel]; break; } } } IOVertex[] vertices = new IOVertex[obj.VertexCount]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new IOVertex(); } foreach (MeshAttribute attr in obj.Attributes) { SsbhVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj); if (attr.AttributeStrings[0].Name.Equals("Position0")) { outMesh.HasPositions = true; for (int i = 0; i < values.Length; i++) { vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z); } } if (attr.AttributeStrings[0].Name.Equals("Normal0")) { outMesh.HasNormals = true; for (int i = 0; i < values.Length; i++) { vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z); } } // Flip UVs vertically for export. if (attr.AttributeStrings[0].Name.Equals("map1")) { outMesh.HasUV0 = true; for (int i = 0; i < values.Length; i++) { vertices[i].UV0 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y); } } if (attr.AttributeStrings[0].Name.Equals("uvSet")) { outMesh.HasUV1 = true; for (int i = 0; i < values.Length; i++) { vertices[i].UV1 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y); } } if (attr.AttributeStrings[0].Name.Equals("uvSet1")) { outMesh.HasUV2 = true; for (int i = 0; i < values.Length; i++) { vertices[i].UV2 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y); } } if (attr.AttributeStrings[0].Name.Equals("uvSet2")) { outMesh.HasUV3 = true; for (int i = 0; i < values.Length; i++) { vertices[i].UV3 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y); } } if (attr.AttributeStrings[0].Name.Equals("colorSet1")) { outMesh.HasColor = true; for (int i = 0; i < values.Length; i++) { vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W) / 127f; } } } // Fix SingleBinds if (outModel.Skeleton != null && !obj.ParentBoneName.Equals("")) { int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName); if (parentIndex != -1) { for (int i = 0; i < vertices.Length; i++) { vertices[i].Position = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform); vertices[i].Normal = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform); vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName]; vertices[i].BoneWeights.X = 1; outMesh.HasBoneWeights = true; } } } // Apply Rigging SsbhVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex); foreach (SsbhVertexInfluence influence in influences) { outMesh.HasBoneWeights = true; // Some influences refer to bones that don't exist in the skeleton. // _eff bones? if (!indexByBoneName.ContainsKey(influence.BoneName)) { continue; } if (vertices[influence.VertexIndex].BoneWeights.X == 0) { vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName]; vertices[influence.VertexIndex].BoneWeights.X = influence.Weight; } else if (vertices[influence.VertexIndex].BoneWeights.Y == 0) { vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName]; vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight; } else if (vertices[influence.VertexIndex].BoneWeights.Z == 0) { vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName]; vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight; } else if (vertices[influence.VertexIndex].BoneWeights.W == 0) { vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName]; vertices[influence.VertexIndex].BoneWeights.W = influence.Weight; } } outMesh.Vertices.AddRange(vertices); outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj)); } } } return(outModel); }
/// <summary> /// /// </summary> /// <param name="color"></param> /// <param name="tex"></param> /// <returns></returns> private FX_Common_Color_Or_Texture_Type GenerateTextureInfo(string sid, Vector4 color, IOTexture tex) { return(new FX_Common_Color_Or_Texture_Type() { Color = new IONET.Collada.Core.Lighting.Color() { sID = sid, Value_As_String = $"{color.X} {color.Y} {color.Z} {color.W}" }, Texture = tex != null && _settings.ExportTextureInfo ? new IONET.Collada.FX.Custom_Types.Texture() { Textures = AddImage(tex), TexCoord = "CHANNEL0", } : null }); }
/// <summary> /// /// </summary> /// <param name="color"></param> /// <param name="tex"></param> /// <returns></returns> private FX_Common_Color_Or_Texture_Type GenerateTextureInfo(string sid, Vector4 color, IOTexture tex, List <New_Param> textureParams) { FX.Custom_Types.Texture texData = null; if (tex != null) { var surfaceString = AddImage(tex); var doc = new XmlDocument(); var surfacenode = doc.CreateElement("surface", "http://www.collada.org/2005/11/COLLADASchema"); surfacenode.SetAttribute("type", "2D"); var init_node = doc.CreateElement("init_from", "http://www.collada.org/2005/11/COLLADASchema"); init_node.InnerText = surfaceString; surfacenode.AppendChild(init_node); textureParams.Add(new New_Param() { sID = surfaceString + "_surface", Data = new XmlElement[] { surfacenode } }); var samplernode = doc.CreateElement("sampler2D", "http://www.collada.org/2005/11/COLLADASchema"); var sourceNode = doc.CreateElement("source", "http://www.collada.org/2005/11/COLLADASchema"); sourceNode.InnerText = surfaceString + "_surface"; samplernode.AppendChild(sourceNode); textureParams.Add(new New_Param() { sID = surfaceString + "_sampler", Data = new XmlElement[] { samplernode } }); texData = new IONET.Collada.FX.Custom_Types.Texture() { Textures = surfaceString + "_sampler", TexCoord = "CHANNEL0", }; } return(new FX_Common_Color_Or_Texture_Type() { Color = new IONET.Collada.Core.Lighting.Color() { sID = sid, Value_As_String = $"{color.X} {color.Y} {color.Z} {color.W}" }, Texture = _settings.ExportTextureInfo ? texData : null }); }