private static IReadOnlyList <PmxMaterial> AddMaterials([NotNull] Mesh combinedMesh, [NotNull] string texturePrefix) { var materialCount = combinedMesh.SubMeshes.Count; var materials = new PmxMaterial[materialCount]; for (var i = 0; i < materialCount; ++i) { var material = new PmxMaterial(); material.NameEnglish = material.Name = $"Mat #{i:00}"; material.AppliedFaceVertexCount = (int)combinedMesh.SubMeshes[i].IndexCount; material.Ambient = new Vector3(0.5f, 0.5f, 0.5f); material.Diffuse = Vector4.One; material.Specular = Vector3.Zero; material.EdgeColor = new Vector4(0.3f, 0.3f, 0.3f, 0.8f); material.EdgeSize = 1.0f; // TODO: The right way: reading textures' path ID and do the mapping. material.TextureFileName = $"{texturePrefix}{i:00}.png"; material.Flags = MaterialFlags.Shadow | MaterialFlags.SelfShadow | MaterialFlags.SelfShadowMap | MaterialFlags.CullNone | MaterialFlags.Edge; materials[i] = material; } return(materials); }
private void WritePmxMaterial([NotNull] PmxMaterial material) { WriteString(material.Name); WriteString(material.NameEnglish); _writer.Write(material.Diffuse); _writer.Write(material.Specular); _writer.Write(material.SpecularPower); _writer.Write(material.Ambient); _writer.Write((byte)material.Flags); _writer.Write(material.EdgeColor); _writer.Write(material.EdgeSize); var texNameIndex = GetTextureIndex(material.TextureFileName); _writer.WriteInt32AsVarLenInt(texNameIndex, TexElementSize); var sphereTexNameIndex = GetTextureIndex(material.SphereTextureFileName); _writer.WriteInt32AsVarLenInt(sphereTexNameIndex, TexElementSize); _writer.Write((byte)material.SphereMode); var mappedToonTexture = !IsNormalToonTexture(material.ToonTextureFileName, out var toon); _writer.Write(!mappedToonTexture); if (mappedToonTexture) { var toonTexNameIndex = GetTextureIndex(material.ToonTextureFileName); _writer.WriteInt32AsVarLenInt(toonTexNameIndex, TexElementSize); } else { _writer.Write((byte)toon); } WriteString(material.MemoTextureFileName); _writer.Write(material.AppliedFaceVertexCount); bool IsNormalToonTexture(string name, out int toonIndex) { if (string.IsNullOrEmpty(name)) { toonIndex = 0; return(true); } var match = ToonNameRegex.Match(name); if (!match.Success) { toonIndex = -1; return(false); } toonIndex = Convert.ToInt32(match.Groups["toonIndex"].Value); return(toonIndex >= 0); } }
private PmxMaterial ReadPmxMaterial() { var material = new PmxMaterial(); material.Name = ReadString() ?? string.Empty; material.NameEnglish = ReadString() ?? string.Empty; material.Diffuse = _reader.ReadVector4(); material.Specular = _reader.ReadVector3(); material.SpecularPower = _reader.ReadSingle(); material.Ambient = _reader.ReadVector3(); material.Flags = (MaterialFlags)_reader.ReadByte(); material.EdgeColor = _reader.ReadVector4(); material.EdgeSize = _reader.ReadSingle(); var texNameIndex = _reader.ReadVarLenIntAsInt32(TexElementSize); material.TextureFileName = TextureNameMap[texNameIndex]; var sphereTexNameIndex = _reader.ReadVarLenIntAsInt32(TexElementSize); material.SphereTextureFileName = TextureNameMap[sphereTexNameIndex]; material.SphereMode = (SphereMode)_reader.ReadByte(); var mappedToonTexture = _reader.ReadByte() == 0; if (mappedToonTexture) { var toonTexNameIndex = _reader.ReadVarLenIntAsInt32(TexElementSize); material.ToonTextureFileName = TextureNameMap[toonTexNameIndex]; } else { var toonTexIndex = (int)_reader.ReadByte(); if (toonTexIndex < 0) { toonTexIndex = -1; } toonTexIndex += 1; if (toonTexIndex > 0) { // PMX Editor // What about other editors' defaults? var toonStr = toonTexIndex.ToString("00"); material.ToonTextureFileName = $"toon{toonStr}.bmp"; } } material.MemoTextureFileName = ReadString() ?? string.Empty; material.AppliedFaceVertexCount = _reader.ReadInt32(); return(material); }
private void CreateMaterial(Material material, int count) { PmxMaterial pmxMaterial = new PmxMaterial(); pmxMaterial.Name = material.name; pmxMaterial.NameE = material.name; pmxMaterial.Flags = (PmxMaterial.MaterialFlags.DrawBoth | PmxMaterial.MaterialFlags.Shadow | PmxMaterial.MaterialFlags.SelfShadowMap | PmxMaterial.MaterialFlags.SelfShadow); if (material.HasProperty("_MainTex")) { string textureName = material.name; if (textureName.Contains("Instance")) { textureName = material.name + "_(" + material.GetInstanceID() + ")"; } pmxMaterial.Tex = textureName + ".png"; Texture mainTexture = material.GetTexture("_MainTex"); if (mainTexture == null) { mainTexture = material.mainTexture; } if (mainTexture != null && this.SaveTexture) { Debug.Log($"Generate Material: {material.name} {mainTexture.name}"); TextureBuilder.WriteTextureToFile(Path.Combine(this.ExportFolder, pmxMaterial.Tex), mainTexture); } } if (material.HasProperty("_AmbColor")) { pmxMaterial.Ambient = new PmxLib.Vector3(material.GetColor("_AmbColor")); } if (material.HasProperty("_Color")) { pmxMaterial.Diffuse = new PmxLib.Vector4(material.GetColor("_Color")); } if (material.HasProperty("_Opacity")) { pmxMaterial.Diffuse.Alpha = material.GetFloat("_Opacity"); } if (material.HasProperty("_SpecularColor")) { pmxMaterial.Specular = new PmxLib.Vector3(material.GetColor("_SpecularColor")); } if (material.HasProperty("_Shininess")) { pmxMaterial.Power = material.GetFloat("_Shininess"); } if (material.HasProperty("_OutlineColor")) { pmxMaterial.EdgeSize = material.GetFloat("_OutlineWidth"); pmxMaterial.EdgeColor = new PmxLib.Vector4(material.GetColor("_OutlineColor")); } pmxMaterial.FaceCount = count; this.pmxFile.MaterialList.Add(pmxMaterial); }
private void WritePmxMaterial([NotNull] PmxMaterial material, [NotNull, ItemNotNull] string[] textureNames) { WriteString(material.Name); WriteString(material.NameEnglish); _writer.Write(material.Diffuse); _writer.Write(material.Specular); _writer.Write(material.SpecularPower); _writer.Write(material.Ambient); _writer.Write((byte)material.Flags); _writer.Write(material.EdgeColor); _writer.Write(material.EdgeSize); var texNameIndex = GetTextureIndex(textureNames, material.TextureFileName); _writer.WriteInt32AsVarLenInt(texNameIndex, TexElementSize); var sphereTexNameIndex = GetTextureIndex(textureNames, material.SphereTextureFileName); _writer.WriteInt32AsVarLenInt(sphereTexNameIndex, TexElementSize); _writer.Write((byte)material.SphereTextureMode); var mappedToonTexture = !IsNormalToonTexture(material.ToonTextureFileName, out var toon); _writer.Write(!mappedToonTexture); if (mappedToonTexture) { var toonTexNameIndex = GetTextureIndex(textureNames, material.ToonTextureFileName); _writer.WriteInt32AsVarLenInt(toonTexNameIndex, TexElementSize); } else { _writer.Write((byte)toon); } WriteString(material.MemoTextureFileName); _writer.Write(material.AppliedFaceVertexCount); }
private void CreateMaterial(Material material, int count) { PmxMaterial pmxMaterial = new PmxMaterial(); pmxMaterial.Name = material.name; pmxMaterial.NameE = material.name; pmxMaterial.Flags = (PmxMaterial.MaterialFlags.DrawBoth | PmxMaterial.MaterialFlags.Shadow | PmxMaterial.MaterialFlags.SelfShadowMap | PmxMaterial.MaterialFlags.SelfShadow); MaterialInfo info = new MaterialInfo(); materialInfo[material.name] = info; info.shader = material.shader.name; /* * _Color [color] * _MainTex * _MultiColTex "Multi Color Table (RGBA)" * _UseMulticolTex * * _ShadowColor [color] * _ShadowTex * _ShadowRateToon [tex] * _RimColor * _RimPower * _RimShift * _HiTex "Hilight (RGB)" * _HiRate "Hilight rate" * _HiPow * * _Ramp "Toon Ramp (RGB)" * * _OutlineColor [color] * _OutlineTex * _OutlineToonRamp * * _OutlineWidth [float] * * _EdgeLength "Edge length" * _Phong "Phong Strengh" * * * */ /* Uncomment to dump list of material textures * if (true)//material.name.StartsWith("Face011_GP_Skin")) * { * Debug.Log($"Material {material.name} uses shader {material.shader.name} ({material.shader.GetInstanceID()}) and textures:"); * for (int i = 0; i < 99999; i++) * { * Texture t = material.GetTexture(i); * if (t == null) * { * continue; * } * Debug.Log($" ({i,5}) {t.name} [{t.GetType().Name}]"); * } * } * // */ if (material.HasProperty("_MainTex")) { Texture mainTexture = material.GetTexture("_MainTex"); if (mainTexture == null) { mainTexture = material.mainTexture; } if (mainTexture != null && SaveTexture) { Debug.Log($"Generate Material: {material.name} {mainTexture.name}"); pmxMaterial.Tex = textureBuilder.Export(ExportFolder, material, "_MainTex", mainTexture); } info.mainTex = pmxMaterial.Tex; } SetMaterialInfoProperty(out info.color, material, "_Color"); info.shadowTex = textureBuilder.Export(ExportFolder, material, "_ShadowTex"); SetMaterialInfoProperty(out info.shadowColor, material, "_ShadowColor"); info.shadowRateToon = textureBuilder.Export(ExportFolder, material, "_ShadowRateToon"); info.toonRamp = textureBuilder.Export(ExportFolder, material, "_ToonRamp"); pmxMaterial.Toon = info.toonRamp ?? ""; SetMaterialInfoProperty(out info.rimColor, material, "_RimColor"); SetMaterialInfoProperty(out info.rimPower, material, "_RimPower"); SetMaterialInfoProperty(out info.rimShift, material, "_RimShift"); info.hiTex = textureBuilder.Export(ExportFolder, material, "_HiTex"); SetMaterialInfoProperty(out info.hiRate, material, "_HiRate"); SetMaterialInfoProperty(out info.hiPow, material, "_HiPow"); SetMaterialInfoProperty(out info.outlineColor, material, "_OutlineColor"); SetMaterialInfoProperty(out info.outlineWidth, material, "_OutlineWidth"); if (material.HasProperty("_AmbColor")) { pmxMaterial.Ambient = new PmxLib.Vector3(material.GetColor("_AmbColor")); } if (material.HasProperty("_Color")) { pmxMaterial.Diffuse = new PmxLib.Vector4(material.GetColor("_Color")); } if (material.HasProperty("_Opacity")) { pmxMaterial.Diffuse.Alpha = material.GetFloat("_Opacity"); } if (material.HasProperty("_SpecularColor")) { pmxMaterial.Specular = new PmxLib.Vector3(material.GetColor("_SpecularColor")); } if (material.HasProperty("_Shininess")) { pmxMaterial.Power = material.GetFloat("_Shininess"); } if (material.HasProperty("_OutlineColor")) { pmxMaterial.EdgeSize = material.GetFloat("_OutlineWidth"); pmxMaterial.EdgeColor = new PmxLib.Vector4(material.GetColor("_OutlineColor")); } pmxMaterial.FaceCount = count; pmxFile.MaterialList.Add(pmxMaterial); }
private PmxModel ReadPmxModel() { var model = new PmxModel(); model.Name = ReadString() ?? string.Empty; model.NameEnglish = ReadString() ?? string.Empty; model.Comment = ReadString() ?? string.Empty; model.CommentEnglish = ReadString() ?? string.Empty; ReadVertexInfo(); ReadFaceInfo(); ReadTextureInfo(); ReadMaterialInfo(); ReadBoneInfo(); ReadMorphInfo(); ReadNodeInfo(); ReadRigidBodyInfo(); ReadJointInfo(); ReadSoftBodyInfo(); return(model); void ReadVertexInfo() { var vertexCount = _reader.ReadInt32(); var vertices = new PmxVertex[vertexCount]; for (var i = 0; i < vertexCount; ++i) { vertices[i] = ReadPmxVertex(); } model.Vertices = vertices; } void ReadFaceInfo() { var faceCount = _reader.ReadInt32(); var faceIndices = new int[faceCount]; for (var i = 0; i < faceCount; ++i) { faceIndices[i] = _reader.ReadVarLenIntAsInt32(VertexElementSize, true); } model.FaceTriangles = faceIndices; } void ReadTextureInfo() { var textureCount = _reader.ReadInt32(); var textureNameMap = new Dictionary <int, string>(); var textureIndexLookup = new Dictionary <string, int>(); for (var i = 0; i < textureCount; ++i) { var textureName = ReadString() ?? string.Empty; textureNameMap[i] = textureName; textureIndexLookup[textureName] = i; } textureNameMap[-1] = string.Empty; TextureNameMap = textureNameMap; TextureIndexLookup = textureIndexLookup; } void ReadMaterialInfo() { var materialCount = _reader.ReadInt32(); var materials = new PmxMaterial[materialCount]; for (var i = 0; i < materialCount; ++i) { materials[i] = ReadPmxMaterial(); } model.Materials = materials; } void ReadBoneInfo() { var boneCount = _reader.ReadInt32(); var bones = new PmxBone[boneCount]; for (var i = 0; i < boneCount; ++i) { bones[i] = ReadPmxBone(); bones[i].BoneIndex = i; } model.Bones = bones; model.BonesDictionary = bones.ToDictionary(bone => bone.Name); var rootBoneIndexList = new List <int>(); for (var i = 0; i < bones.Length; ++i) { var bone = bones[i]; if (bone.ParentIndex < 0) { rootBoneIndexList.Add(i); } else { bone.Parent = bones[bone.ParentIndex]; } if (bone.AppendParentIndex >= 0) { bone.AppendParent = bones[bone.AppendParentIndex]; } if (bone.ExternalParentIndex >= 0) { bone.ExternalParent = bones[bone.ExternalParentIndex]; } if (bone.HasFlag(BoneFlags.IK)) { var ik = bone.IK; Debug.Assert(ik != null, nameof(ik) + " != null"); ik.TargetBone = bones[ik.TargetBoneIndex]; foreach (var link in ik.Links) { if (link.BoneIndex >= 0) { link.Bone = bones[link.BoneIndex]; } } } } model.RootBoneIndices = rootBoneIndexList.ToArray(); foreach (var bone in bones) { bone.SetToBindingPose(); } } void ReadMorphInfo() { var morphCount = _reader.ReadInt32(); var morphs = new PmxMorph[morphCount]; for (var i = 0; i < morphCount; ++i) { morphs[i] = ReadPmxMorph(); } model.Morphs = morphs; } void ReadNodeInfo() { var nodeCount = _reader.ReadInt32(); var nodes = new PmxNode[nodeCount]; for (var i = 0; i < nodeCount; ++i) { var node = ReadPmxNode(); nodes[i] = node; if (node.IsSystemNode) { if (node.Name == "Root") { model.RootNodeIndex = i; } else if (node.Name == "表情") { model.FacialExpressionNodeIndex = i; } } } model.Nodes = nodes; } void ReadRigidBodyInfo() { var bodyCount = _reader.ReadInt32(); var bodies = new PmxRigidBody[bodyCount]; for (var i = 0; i < bodyCount; ++i) { bodies[i] = ReadPmxRigidBody(); } model.RigidBodies = bodies; } void ReadJointInfo() { var jointCount = _reader.ReadInt32(); var joints = new PmxJoint[jointCount]; for (var i = 0; i < jointCount; ++i) { joints[i] = ReadPmxJoint(); } model.Joints = joints; } void ReadSoftBodyInfo() { if (DetailedVersion < 2.1f) { return; } var bodyCount = _reader.ReadInt32(); var bodies = new PmxSoftBody[bodyCount]; for (var i = 0; i < bodyCount; ++i) { bodies[i] = ReadPmxSoftBody(); } model.SoftBodies = bodies; } }
private void CreateMaterial(Material material, int count) { PmxMaterial pmxMaterial = new PmxMaterial(); pmxMaterial.Name = material.name; pmxMaterial.NameE = material.name; pmxMaterial.Flags = (PmxMaterial.MaterialFlags.DrawBoth | PmxMaterial.MaterialFlags.Shadow | PmxMaterial.MaterialFlags.SelfShadowMap | PmxMaterial.MaterialFlags.SelfShadow); MaterialInfo info = new MaterialInfo(); materialInfo[material.name] = info; info.shader = material.shader.name; /* Uncomment to dump list of material textures (put one / at the start of this line) * if (true)//material.name.StartsWith("Face011_GP_Skin")) * { * Debug.Log($"Material {material.name} uses shader {material.shader.name} ({material.shader.GetInstanceID()}) and textures:"); * for (int i = 0; i < 99999; i++) * { * Texture t = material.GetTexture(i); * if (t == null) * { * continue; * } * Debug.Log($" ({i,5}) {t.name} [{t.GetType().Name}]"); * } * } * // */ if (material.HasProperty("_MainTex")) { Texture mainTexture = material.GetTexture("_MainTex"); if (mainTexture == null) { mainTexture = material.mainTexture; } if (mainTexture != null && SaveTexture) { Debug.Log($"Generate Material: {material.name} {mainTexture.name}"); pmxMaterial.Tex = textureBuilder.Export(ExportFolder, material, "_MainTex", mainTexture); } info.mainTex = pmxMaterial.Tex; } SetMaterialInfoProperty(out info.color, material, "_Color"); info.shadowTex = textureBuilder.Export(ExportFolder, material, "_ShadowTex"); SetMaterialInfoProperty(out info.shadowColor, material, "_ShadowColor"); info.shadowRateToon = textureBuilder.Export(ExportFolder, material, "_ShadowRateToon"); pmxMaterial.Toon = textureBuilder.Export(ExportFolder, material, "_ToonRamp"); info.toonRamp = pmxMaterial.Toon; SetMaterialInfoProperty(out info.shininess, material, "_Shininess"); SetMaterialInfoProperty(out info.rimColor, material, "_RimColor"); SetMaterialInfoProperty(out info.rimPower, material, "_RimPower"); SetMaterialInfoProperty(out info.rimShift, material, "_RimShift"); info.hiTex = textureBuilder.Export(ExportFolder, material, "_HiTex"); SetMaterialInfoProperty(out info.hiRate, material, "_HiRate"); SetMaterialInfoProperty(out info.hiPow, material, "_HiPow"); SetMaterialInfoProperty(out info.outlineColor, material, "_OutlineColor"); info.outlineTex = textureBuilder.Export(ExportFolder, material, "_OutlineTex"); info.outlineToonRamp = textureBuilder.Export(ExportFolder, material, "_OutlineToonRamp"); SetMaterialInfoProperty(out info.outlineWidth, material, "_OutlineWidth"); info.outlineWidthTex = textureBuilder.Export(ExportFolder, material, "_OutlineWidthTex"); SetMaterialInfoProperty(out info.zTest, material, "_ZTest"); SetMaterialInfoProperty(out info.zTest2, material, "_ZTest2"); SetMaterialInfoProperty(out info.zTest2Alpha, material, "_ZTest2Alpha"); if (material.HasProperty("_Color")) { pmxMaterial.Diffuse = new PmxLib.Vector4(material.GetColor("_Color")); } if (material.HasProperty("_Opacity")) { pmxMaterial.Diffuse.Alpha = material.GetFloat("_Opacity"); } pmxMaterial.FaceCount = count; pmxFile.MaterialList.Add(pmxMaterial); }
// PMDEditor.Pmx internal static Pmx FromStream(Stream s, PmxElementFormat f = null) { var Ret = new Pmx(); var pmxHeader = new PmxHeader(2f); pmxHeader.FromStreamEx(s, null); Ret.Header = pmxHeader; if (pmxHeader.Ver <= 1f) { var mMD_Pmd = new MMD_Pmd(); s.Seek(0L, SeekOrigin.Begin); mMD_Pmd.FromStreamEx(s, null); Ret.FromPmx(PmxConvert.PmdToPmx(mMD_Pmd)); return(Ret); } Ret.ModelInfo = new PmxModelInfo(); Ret.ModelInfo.FromStreamEx(s, pmxHeader.ElementFormat); var num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.VertexList = new List <PmxVertex>(); Ret.VertexList.Clear(); Ret.VertexList.Capacity = num; for (var i = 0; i < num; i++) { var pmxVertex = new PmxVertex(); pmxVertex.FromStreamEx(s, pmxHeader.ElementFormat); Ret.VertexList.Add(pmxVertex); } num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.FaceList = new List <int>(); Ret.FaceList.Clear(); Ret.FaceList.Capacity = num; for (var j = 0; j < num; j++) { var item = PmxStreamHelper.ReadElement_Int32(s, pmxHeader.ElementFormat.VertexSize, false); Ret.FaceList.Add(item); } var pmxTextureTable = new PmxTextureTable(); pmxTextureTable.FromStreamEx(s, pmxHeader.ElementFormat); num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.MaterialList = new List <PmxMaterial>(); Ret.MaterialList.Clear(); Ret.MaterialList.Capacity = num; for (var k = 0; k < num; k++) { var pmxMaterial = new PmxMaterial(); pmxMaterial.FromStreamEx_TexTable(s, pmxTextureTable, pmxHeader.ElementFormat); Ret.MaterialList.Add(pmxMaterial); } num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.BoneList = new List <PmxBone>(); Ret.BoneList.Clear(); Ret.BoneList.Capacity = num; for (var l = 0; l < num; l++) { var pmxBone = new PmxBone(); pmxBone.FromStreamEx(s, pmxHeader.ElementFormat); Ret.BoneList.Add(pmxBone); } num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.MorphList = new List <PmxMorph>(); Ret.MorphList.Clear(); Ret.MorphList.Capacity = num; for (var m = 0; m < num; m++) { var pmxMorph = new PmxMorph(); pmxMorph.FromStreamEx(s, pmxHeader.ElementFormat); Ret.MorphList.Add(pmxMorph); } num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.NodeList = new List <PmxNode>(); Ret.NodeList.Clear(); Ret.NodeList.Capacity = num; for (var n = 0; n < num; n++) { var pmxNode = new PmxNode(); pmxNode.FromStreamEx(s, pmxHeader.ElementFormat); Ret.NodeList.Add(pmxNode); if (Ret.NodeList[n].SystemNode) { if (Ret.NodeList[n].Name == "Root") { Ret.RootNode = Ret.NodeList[n]; } else if (Ret.NodeList[n].Name == "表情") { Ret.ExpNode = Ret.NodeList[n]; } } } num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.BodyList = new List <PmxBody>(); Ret.BodyList.Clear(); Ret.BodyList.Capacity = num; for (var num2 = 0; num2 < num; num2++) { var pmxBody = new PmxBody(); pmxBody.FromStreamEx(s, pmxHeader.ElementFormat); Ret.BodyList.Add(pmxBody); } num = PmxStreamHelper.ReadElement_Int32(s, 4, true); Ret.JointList = new List <PmxJoint>(); Ret.JointList.Clear(); Ret.JointList.Capacity = num; for (var num3 = 0; num3 < num; num3++) { var pmxJoint = new PmxJoint(); pmxJoint.FromStreamEx(s, pmxHeader.ElementFormat); Ret.JointList.Add(pmxJoint); } return(Ret); }