public static PMXVertexDeformBDEF1 DeformFromPMDFile(PMXModel model, PMXVertex vertex, ushort boneId) { PMXVertexDeformBDEF1 res = new PMXVertexDeformBDEF1(model, vertex); res.bone1Index = (int)boneId; return(res); }
public PMXRigidBody(PMXModel model) : base(model) { this._shapeSize = new PMXVector3(); this.Position = new PMXVector3(); this.Rotation = new PMXVector3(); this.NoCollissionGroups = new PMXNoCollissionGroup(this.Model, this); }
public PMXMaterial(PMXModel model) : base(model) { this.Triangles = new List <PMXTriangle>(); this.Diffuse = new PMXColorRGB(); this.Alpha = 1.0f; this.Specular = new PMXColorRGB(); this.Ambient = new PMXColorRGB(); this.EdgeColor = new PMXColorRGBA(0.0f, 0.0f, 0.0f, 1.0f); this.DoubleSided = false; this.GroundShadow = true; this.SelfShadow = true; this.SelfShadowPlus = true; this.EdgeEnabled = true; this.EdgeSize = 1.0f; this.VertexColor = false; this.DiffuseTexture = null; this.SphereTexture = null; this.NonStandardToonTexture = null; this.StandardToon = true; this.StandardToonIndex = 0; }
public PMXMorphOffsetUV(PMXModel model, PMXMorph morph, UVAddIndexType index = UVAddIndexType.UV) : base(model, morph) { switch (index) { case UVAddIndexType.UV: this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_UV; break; case UVAddIndexType.AddUV1: this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_UV_EXTENDED1; break; case UVAddIndexType.AddUV2: this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_UV_EXTENDED2; break; case UVAddIndexType.AddUV3: this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_UV_EXTENDED3; break; case UVAddIndexType.AddUV4: this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_UV_EXTENDED4; break; default: this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_UV; break; } this.UVTranslation = new PMXVector2(); this.UVTranslation2 = new PMXVector2(); }
public PMXJoint(PMXModel model) : base(model) { this.Position = new PMXVector3(); this.Rotation = new PMXVector3(); this.TranslationLimitMin = new PMXVector3(); this.TranslationLimitMax = new PMXVector3(); this.RotationLimitMin = new PMXVector3(); this.RotationLimitMax = new PMXVector3(); this.SpringConstantTranslation = new PMXVector3(); this.SpringConstantRotation = new PMXVector3(); }
public PMXMorphOffsetMaterial(PMXModel model, PMXMorph morph) : base(model, morph) { this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_MATERIAL; this.Diffuse = new PMXColorRGBA(); this.Specular = new PMXColorRGBA(); this.Ambient = new PMXColorRGB(); this.EdgeColor = new PMXColorRGBA(); this.TextureFactor = new PMXColorRGBA(); this.SphereTextureFactor = new PMXColorRGBA(); this.ToonTextureFactor = new PMXColorRGBA(); }
public PMXBone(PMXModel model) : base(model) { this.Rotatable = true; this.Translatable = false; this.HasChildBone = true; this.Operating = true; this.Visible = true; this.Position = new PMXVector3(); this.ChildVector = new PMXVector3(); this.AxisLimit = new PMXVector3(); this.LocalCoordinatesX = new PMXVector3(); this.LocalCoordinatesZ = new PMXVector3(); }
/// <summary> /// Checks if the rigid body is part of a given model. /// </summary> /// <param name="bdy"></param> /// <param name="exportSettings"></param> /// <param name="nullAcceptable"></param> /// <returns></returns> public static int CheckIndexInModel(PMXRigidBody bdy, MMDExportSettings exportSettings) { if (bdy == null) { throw new InvalidDataException("Rigid body mustn't be null!"); } PMXModel model = exportSettings.Model; int index = model.RigidBodies.IndexOf(bdy); if (index < 0) { throw new InvalidDataException("Rigid body is not a member of model!"); } return(index); }
private Dictionary <int, int> _exportHashNumbers; //Export only public PMXVertex(PMXModel model) : base(model) { this.AddedUVs = new List <PMXQuaternion>(); this.Position = new PMXVector3(); this.Normals = new PMXVector3(); this.UV = new PMXVector2(); PMXVertexDeformBDEF1 df = new PMXVertexDeformBDEF1(this.Model, this); this.Deform = df; if (this.Model.Bones.Count > 0) { df.Bone1 = this.Model.Bones[0]; } this._exportHashNumbers = new Dictionary <int, int>(); }
/// <summary> /// Checks if the bone is part of a given model. /// </summary> /// <param name="model"></param> /// <returns></returns> public static int CheckIndexInModel(PMXVertex vtx, MMDExportSettings settings) { if (vtx == null) { throw new InvalidDataException("Vertex mustn't be null!"); } if (vtx._exportHashNumbers.ContainsKey(settings.ExportHash)) { return(vtx._exportHashNumbers[settings.ExportHash]); } PMXModel model = settings.Model; int index = model.Vertices.IndexOf(vtx); if (index < 0) { throw new InvalidDataException("Vertex not a member of model!"); } return(index); }
public static PMXBaseDeform DeformFromPMDFile(PMXModel model, PMXVertex vertex, BinaryReader br) { ushort boneId1 = br.ReadUInt16(); ushort boneId2 = br.ReadUInt16(); byte weight = br.ReadByte(); if (weight >= 100) { //BDEF1 return(PMXVertexDeformBDEF1.DeformFromPMDFile(model, vertex, boneId1)); } else if (weight <= 0) { //BDEF 1 as well return(PMXVertexDeformBDEF1.DeformFromPMDFile(model, vertex, boneId2)); } else { //BDEF2 PMXVertexDeformBDEF2 res = new PMXVertexDeformBDEF2(model, vertex); res.bone1Index = (int)boneId1; res.bone2Index = (int)boneId2; res.Bone1Weight = (float)weight / 100.0f; return(res); } }
/// <summary> /// Checks if the material is part of a given model. /// </summary> /// <param name="bn"></param> /// <param name="exportSettings"></param> /// <param name="nullAcceptable"></param> /// <returns></returns> public static int CheckIndexInModel(PMXMaterial mat, MMDExportSettings exportSettings, bool nullAcceptable = true) { if (mat == null) { if (nullAcceptable) { return(-1); } else { throw new InvalidDataException("Material mustn't be null!"); } } PMXModel model = exportSettings.Model; int index = model.Materials.IndexOf(mat); if (index < 0) { throw new InvalidDataException("Material not a member of model!"); } return(index); }
/// <summary> /// Checks if the bone is part of a given model. /// </summary> /// <param name="bn"></param> /// <param name="exportSettings"></param> /// <param name="nullAcceptable"></param> /// <returns></returns> public static int CheckIndexInModel(PMXBone bn, MMDExportSettings exportSettings, bool nullAcceptable = true) { if (bn == null) { if (nullAcceptable) { return(-1); } else { throw new InvalidDataException("Bone mustn't be null!"); } } PMXModel model = exportSettings.Model; int index = model.Bones.IndexOf(bn); if (index < 0) { throw new InvalidDataException("Bone not a member of model!"); } return(index); }
public PMXMorphOffsetGroup(PMXModel model, PMXMorph morph) : base(model, morph) { this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_GROUP; }
public PMXIK(PMXModel model, PMXBone bone) : base(model) { this.IKLinks = new List <PMXIKLink>(); this.Bone = bone; }
public static PMXModel LoadFromPMXFile(string pmxFile, PMXModelDescriptor modelDescriptor) { FileStream fs = new FileStream(pmxFile, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] buffer = new byte[3]; fs.Read(buffer, 0, 3); string head = Encoding.ASCII.GetString(buffer); fs.Seek(1, SeekOrigin.Current); if (head != "PMX") { throw new Exception("Not a PMX file!"); } BinaryReader br = new BinaryReader(fs); float PMXVersion = br.ReadSingle(); if (PMXVersion != 2.0f && PMXVersion != 2.1f) { throw new Exception("Unsupported PMX Version!"); } byte flags = br.ReadByte(); if (flags != 8) { throw new Exception("Invalid PMX bytes version!"); } MMDImportSettings settings = new MMDImportSettings(MMDImportSettings.ModelFormat.PMX); List <PMXBasePart> allParts = new List <PMXBasePart>(); byte text_encoding = br.ReadByte(); settings.TextEncoding = (text_encoding == 1 ? Encoding.UTF8 : (text_encoding == 0 ? Encoding.Unicode : Encoding.GetEncoding(932))); settings.ExtendedUV = br.ReadByte(); settings.ClassDescriptor = modelDescriptor; PMXModel md = new PMXModel(); settings.BitSettings.VertexIndexLength = br.ReadByte(); settings.BitSettings.TextureIndexLength = br.ReadByte(); settings.BitSettings.MaterialIndexLength = br.ReadByte(); settings.BitSettings.BoneIndexLength = br.ReadByte(); settings.BitSettings.MorphIndexLength = br.ReadByte(); settings.BitSettings.RigidBodyIndexLength = br.ReadByte(); md.NameJP = PMXParser.ReadString(br, settings.TextEncoding); md.NameEN = PMXParser.ReadString(br, settings.TextEncoding); md.DescriptionJP = PMXParser.ReadString(br, settings.TextEncoding); md.DescriptionEN = PMXParser.ReadString(br, settings.TextEncoding); //Vertices uint vertexCount = br.ReadUInt32(); for (int i = 0; i < vertexCount; i++) { PMXVertex v = (PMXVertex)Activator.CreateInstance(modelDescriptor.VertexType.StoredType, new object[] { md }); v.LoadFromStream(br, settings); md.Vertices.Add(v); allParts.Add(v); } //Triangles uint vertexRefCount = br.ReadUInt32(); if (vertexRefCount % 3 != 0) { throw new Exception("Invalid triangle count!"); } uint triangleCount = vertexRefCount / 3; List <PMXTriangle> importTriangles = new List <PMXTriangle>(); for (int i = 0; i < triangleCount; i++) { PMXTriangle t = (PMXTriangle)Activator.CreateInstance(modelDescriptor.TriangleType.StoredType, new object[] { md }); t.LoadFromStream(br, settings); importTriangles.Add(t); allParts.Add(t); } //Textures uint textureCount = br.ReadUInt32(); List <string> importTextures = new List <string>(); for (int i = 0; i < textureCount; i++) { string tex = PMXParser.ReadString(br, settings.TextEncoding); importTextures.Add(tex); } string[] textures = importTextures.ToArray(); //Materials uint materialCount = br.ReadUInt32(); for (int i = 0; i < materialCount; i++) { PMXMaterial mt = (PMXMaterial)Activator.CreateInstance(modelDescriptor.MaterialType.StoredType, new object[] { md }); mt.LoadFromStream(br, settings, textures, importTriangles); md.Materials.Add(mt); allParts.Add(mt); } if (importTriangles.Count > 0) { throw new InvalidDataException("Model materials don't cover all triangles!"); } //Bones uint boneCount = br.ReadUInt32(); for (int i = 0; i < boneCount; i++) { PMXBone bn = (PMXBone)Activator.CreateInstance(modelDescriptor.BoneType.StoredType, new object[] { md }); bn.LoadFromStream(br, settings); md.Bones.Add(bn); allParts.Add(bn); } //Morphs uint morphCount = br.ReadUInt32(); for (int i = 0; i < morphCount; i++) { PMXMorph mrph = (PMXMorph)Activator.CreateInstance(modelDescriptor.MorphType.StoredType, new object[] { md }); mrph.LoadFromStream(br, settings); md.Morphs.Add(mrph); allParts.Add(mrph); } //Display frames md.DisplaySlots.Clear(); uint displayCount = br.ReadUInt32(); for (int i = 0; i < displayCount; i++) { PMXDisplaySlot ds = new PMXDisplaySlot(md); ds.LoadFromStream(br, settings); md.DisplaySlots.Add(ds); allParts.Add(ds); } //Rigid bodies uint rigidBodyCount = br.ReadUInt32(); for (int i = 0; i < rigidBodyCount; i++) { PMXRigidBody rb = (PMXRigidBody)Activator.CreateInstance(modelDescriptor.RigidBodyType.StoredType, new object[] { md }); rb.LoadFromStream(br, settings); md.RigidBodies.Add(rb); allParts.Add(rb); } //Joints uint jointsCount = br.ReadUInt32(); for (int i = 0; i < jointsCount; i++) { PMXJoint jt = (PMXJoint)Activator.CreateInstance(modelDescriptor.JointType.StoredType, new object[] { md }); jt.LoadFromStream(br, settings); md.Joints.Add(jt); allParts.Add(jt); } br.BaseStream.Close(); br = null; fs = null; foreach (PMXBasePart part in allParts) { part.FinaliseAfterImport(); } return(md); }
/// <summary> /// Loads a model from a PMD file and converts it to PMX internally. /// </summary> /// <param name="pmdFile">PMD file name</param> /// <param name="modelDescriptor">Classes to use during import</param> /// <returns></returns> public static PMXModel LoadFromPMDFile(string pmdFile, PMXModelDescriptor modelDescriptor) { FileStream fs = new FileStream(pmdFile, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] buffer = new byte[3]; fs.Read(buffer, 0, 3); string head = Encoding.ASCII.GetString(buffer); if (head != "Pmd") { throw new Exception("Not a PMD file!"); } BinaryReader br = new BinaryReader(fs); float PMDVersion = br.ReadSingle(); if (PMDVersion != 1.0f) { throw new Exception("Unsupported PMD Version!"); } MMDImportSettings settings = new MMDImportSettings(MMDImportSettings.ModelFormat.PMD); List <PMXBasePart> allParts = new List <PMXBasePart>(); settings.ClassDescriptor = modelDescriptor; settings.TextEncoding = Encoding.GetEncoding(932); settings.ExtendedUV = 0; PMXModel md = new PMXModel(); md.NameJP = PMDParser.ReadString(br, 20, settings.TextEncoding); md.DescriptionJP = PMDParser.ReadString(br, 256, settings.TextEncoding); //Vertices uint vertexCount = br.ReadUInt32(); for (int i = 0; i < vertexCount; i++) { PMXVertex v = (PMXVertex)Activator.CreateInstance(modelDescriptor.VertexType.StoredType, new object[] { md }); v.LoadFromStream(br, settings); md.Vertices.Add(v); allParts.Add(v); } //Triangles uint vertexRefCount = br.ReadUInt32(); if (vertexRefCount % 3 != 0) { throw new Exception("Invalid triangle count!"); } uint triangleCount = vertexRefCount / 3; List <PMXTriangle> importTriangles = new List <PMXTriangle>(); for (int i = 0; i < triangleCount; i++) { PMXTriangle t = (PMXTriangle)Activator.CreateInstance(modelDescriptor.TriangleType.StoredType, new object[] { md }); t.LoadFromStream(br, settings); importTriangles.Add(t); allParts.Add(t); } //Materials uint materialCount = br.ReadUInt32(); for (int i = 0; i < materialCount; i++) { PMXMaterial mt = (PMXMaterial)Activator.CreateInstance(modelDescriptor.MaterialType.StoredType, new object[] { md }); mt.LoadFromStream(br, settings, null, importTriangles); md.Materials.Add(mt); mt.NameJP = "Material" + (i + 1).ToString(); //Initialise default names mt.NameEN = "Material" + (i + 1).ToString(); //Initialise default names allParts.Add(mt); } //Bones uint boneCount = (uint)br.ReadUInt16(); for (int i = 0; i < boneCount; i++) { PMXBone bn = (PMXBone)Activator.CreateInstance(modelDescriptor.BoneType.StoredType, new object[] { md }); bn.LoadFromStream(br, settings); md.Bones.Add(bn); allParts.Add(bn); } //PMD IKs - will be handled internally uint ikCount = (uint)br.ReadUInt16(); for (int i = 0; i < ikCount; i++) { int boneId = br.ReadUInt16(); PMXBone bn = md.Bones[boneId]; bn.IK = new PMXIK(md, bn); bn.IK.LoadFromStream(br, settings); } //Morphs uint mCount = (uint)br.ReadUInt16(); for (int i = 0; i < mCount; i++) { PMXMorph mrph = (PMXMorph)Activator.CreateInstance(modelDescriptor.MorphType.StoredType, new object[] { md }); mrph.LoadFromStream(br, settings); if (mrph.NameJP == "base") { settings.BaseMorph = mrph; } md.Morphs.Add(mrph); allParts.Add(mrph); } //Display groups - kinda insanely set up for PMD //Initialising root slot manually md.DisplaySlots[0].References.Add(md.Bones[0]); allParts.Add(md.DisplaySlots[0]); //Exp slot is initialised differently (cause why not?) uint miCount = (uint)br.ReadByte(); for (int i = 0; i < miCount; i++) { int morphId = br.ReadUInt16(); md.DisplaySlots[1].References.Add(md.Morphs[morphId]); } allParts.Add(md.DisplaySlots[1]); //Display slots.. guess.. work completely different as well - first of all: Let's gather the names! uint nameCount = (uint)br.ReadByte(); for (int i = 0; i < nameCount; i++) { PMXDisplaySlot ds = new PMXDisplaySlot(md); ds.NameJP = PMDParser.ReadString(br, 50, settings.TextEncoding); md.DisplaySlots.Add(ds); allParts.Add(ds); } //We've got the names - now let's put the bones in uint boneIndexCount = (uint)br.ReadUInt32(); for (int i = 0; i < boneIndexCount; i++) { ushort bI = br.ReadUInt16(); byte slot = br.ReadByte(); md.DisplaySlots[slot + 1].References.Add(md.Bones[bI]); } //Those were the display slots! //Does the model have English names? bool hasEnglishNames = false; if (br.BaseStream.Position < br.BaseStream.Length) //Not EOF yet { hasEnglishNames = (br.ReadByte() == 1); } if (hasEnglishNames) //Read English names { md.NameEN = PMDParser.ReadString(br, 20, settings.TextEncoding); md.DescriptionEN = PMDParser.ReadString(br, 256, settings.TextEncoding); foreach (PMXBone bn in md.Bones) { bn.NameEN = PMDParser.ReadString(br, 20, settings.TextEncoding); } bool firstMorph = true; foreach (PMXMorph mrph in md.Morphs) { if (firstMorph && mrph.NameJP == "base") { continue; } mrph.NameEN = PMDParser.ReadString(br, 20, settings.TextEncoding); firstMorph = false; } for (int i = 2; i < md.DisplaySlots.Count; i++) { md.DisplaySlots[i].NameEN = PMDParser.ReadString(br, 50, settings.TextEncoding); } } else //At least initialise them by using JP names { md.NameEN = md.NameJP; md.DescriptionEN = md.DescriptionJP; foreach (PMXBone bn in md.Bones) { bn.NameEN = bn.NameJP; } foreach (PMXMorph mrph in md.Morphs) { mrph.NameEN = mrph.NameJP; } for (int i = 2; i < md.DisplaySlots.Count; i++) { md.DisplaySlots[i].NameEN = md.DisplaySlots[i].NameJP; } } //Are there special toon textures? string[] defaultToons = new string[] { "toon01.bmp", "toon02.bmp", "toon03.bmp", "toon04.bmp", "toon05.bmp", "toon06.bmp", "toon07.bmp", "toon08.bmp", "toon09.bmp", "toon10.bmp" }; string[] thisModelToons = new string[10]; if (br.BaseStream.Position < br.BaseStream.Length) //Not EOF yet { for (int i = 0; i < 10; i++) { thisModelToons[i] = PMDParser.ReadString(br, 100, settings.TextEncoding); } } else { Array.Copy(defaultToons, thisModelToons, 10); } //Does the PMD file have physics? if (br.BaseStream.Position < br.BaseStream.Length) //Not EOF yet { //Rigid bodies uint rigidBodyCount = br.ReadUInt32(); for (int i = 0; i < rigidBodyCount; i++) { PMXRigidBody rb = (PMXRigidBody)Activator.CreateInstance(modelDescriptor.RigidBodyType.StoredType, new object[] { md }); rb.LoadFromStream(br, settings); md.RigidBodies.Add(rb); allParts.Add(rb); } //Joints uint jointsCount = br.ReadUInt32(); for (int i = 0; i < jointsCount; i++) { PMXJoint jt = (PMXJoint)Activator.CreateInstance(modelDescriptor.JointType.StoredType, new object[] { md }); jt.LoadFromStream(br, settings); md.Joints.Add(jt); allParts.Add(jt); } } foreach (PMXBasePart part in allParts) { part.FinaliseAfterImport(); } foreach (PMXMaterial mt in md.Materials) { mt.AssignToonForPMD(defaultToons, thisModelToons); } foreach (PMXBone bn in md.Bones) { bn.ParsePMDTwist(); bn.CreateLocalCoodinateAxisForPMD(); bn.UpdatePMDIKs(); } if (md.Morphs[0].NameJP == "base") { md.Morphs.RemoveAt(0); } br = null; fs.Close(); fs = null; return(md); }
public PMXIKLink(PMXModel model, PMXIK ik) : base(model) { this.IK = ik; this.Minimum = new PMXVector3(); this.Maximum = new PMXVector3(); }
public PMXMorphOffsetBone(PMXModel model, PMXMorph morph) : base(model, morph) { this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_BONE; this.Translation = new PMXVector3(); this.Rotation = new PMXQuaternion(); }
public PMXDisplaySlot(PMXModel model) : base(model) { this.References = new List <PMXBasePart>(); }
public PMXMorph(PMXModel model) : base(model) { this.Offsets = new List <PMXMorphOffsetBase>(); }
/// <summary> /// Base constructor for a model part. /// </summary> /// <param name="model">Model this part belongs to.</param> public PMXBasePart(PMXModel model) { this._model = model; }
public PMXTriangle(PMXModel model, PMXVertex vertex1, PMXVertex vertex2, PMXVertex vertex3) : this(model) { this.Vertex1 = vertex1; this.Vertex2 = vertex2; this.Vertex3 = vertex3; }
public PMXTriangle(PMXModel model) : base(model) { }
public PMXNoCollissionGroup(PMXModel model, PMXRigidBody body) : base(model) { this.RigidBody = body; this._noCollissionGroup = new BitArray(16, false); }
public PMXMorphOffsetVertex(PMXModel model, PMXMorph morph) : base(model, morph) { this.MorphTargetType = PMXMorph.MORPH_IDENTIFY_VERTEX; this.Translation = new PMXVector3(); }
public PMXBaseDeform(PMXModel model, PMXVertex vertex) : base(model) { this.deformIdentifier = 0; this.Vertex = vertex; }
public PMXVertexDeformQDEF(PMXModel model, PMXVertex vertex) : base(model, vertex) { this.deformIdentifier = PMXBaseDeform.DEFORM_IDENTIFY_QDEF; }
public PMXMorphOffsetBase(PMXModel model, PMXMorph morph) : base(model) { this.MorphTargetType = 0; this.Morph = morph; }