示例#1
0
        public override void WriteToStream(BinaryWriter bw, MMDExportSettings exportSettings)
        {
            if (exportSettings.Format == MMDExportSettings.ModelFormat.PMX)
            {
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameJP);
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameEN);

                bw.Write((byte)(int)this.Type);

                PMXParser.WriteIndex(bw, exportSettings.BitSettings.RigidBodyIndexLength, PMXRigidBody.CheckIndexInModel(this.RigidBodyA, exportSettings));
                PMXParser.WriteIndex(bw, exportSettings.BitSettings.RigidBodyIndexLength, PMXRigidBody.CheckIndexInModel(this.RigidBodyB, exportSettings));
            }
            else
            {
                PMDParser.WriteString(bw, 20, exportSettings.TextEncoding, this.NameJP);

                PMXParser.WriteIndex(bw, 4, PMXRigidBody.CheckIndexInModel(this.RigidBodyA, exportSettings));
                PMXParser.WriteIndex(bw, 4, PMXRigidBody.CheckIndexInModel(this.RigidBodyB, exportSettings));
            }


            this.Position.WriteToStream(bw);
            this.Rotation.WriteToStream(bw);
            this.TranslationLimitMin.WriteToStream(bw);
            this.TranslationLimitMax.WriteToStream(bw);
            this.RotationLimitMin.WriteToStream(bw);
            this.RotationLimitMax.WriteToStream(bw);
            this.SpringConstantTranslation.WriteToStream(bw);
            this.SpringConstantRotation.WriteToStream(bw);
        }
示例#2
0
        public override void WriteToStream(BinaryWriter bw, MMDExportSettings exportSettings)
        {
            PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameJP);
            PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameEN);

            bool isImportant = (this.Model.DisplaySlots.IndexOf(this) <= 1); //Root and EXP Displays

            if (isImportant)
            {
                bw.Write((byte)1);
            }
            else
            {
                bw.Write((byte)0);
            }

            bw.Write((Int32)this.References.Count);
            foreach (PMXBasePart rfr in this.References)
            {
                if (rfr is PMXBone)
                {
                    bw.Write((byte)PMXDisplaySlot.REF_IDENTIFY_BONE);
                    PMXParser.WriteIndex(bw, exportSettings.BitSettings.BoneIndexLength, PMXBone.CheckIndexInModel((PMXBone)rfr, exportSettings, false));
                }
                else if (rfr is PMXMorph)
                {
                    bw.Write((byte)PMXDisplaySlot.REF_IDENTIFY_MORPH);
                    PMXParser.WriteIndex(bw, exportSettings.BitSettings.MorphIndexLength, PMXMorph.CheckIndexInModel((PMXMorph)rfr, exportSettings, false));
                }
                else
                {
                    throw new InvalidDataException("Invalid reference in display slots. Only bones and morphs are supported!");
                }
            }
        }
示例#3
0
        public override void WriteToStream(BinaryWriter bw, MMDExportSettings exportSettings)
        {
            if (exportSettings.Format == MMDExportSettings.ModelFormat.PMX)
            { //PMX format
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameJP);
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameEN);

                bw.Write((byte)(int)this.Panel);

                if (this.Offsets.Count == 0)
                {
                    bw.Write((byte)PMXMorph.MORPH_IDENTIFY_VERTEX);
                    bw.Write((Int32)0);
                }
                else
                {
                    byte morphTypeId = this.Offsets[0].MorphTargetType;
                    bw.Write((byte)morphTypeId);
                    bw.Write((Int32)this.Offsets.Count);

                    foreach (PMXMorphOffsetBase offset in this.Offsets)
                    {
                        if (offset.MorphTargetType != morphTypeId)
                        {
                            throw new InvalidDataException("Morph offset types mustn't be mixed types");
                        }
                        offset.WriteToStream(bw, exportSettings);
                    }
                }
            } //PMD format
            else
            {
                PMDParser.WriteString(bw, 20, exportSettings.TextEncoding, this.NameJP);
                bw.Write((Int32)this.Offsets.Count);
                bw.Write((byte)(int)this.Panel);
                foreach (PMXMorphOffsetBase offset in this.Offsets)
                {
                    if (!(offset is PMXMorphOffsetVertex))
                    {
                        throw new InvalidDataException("PMD only supports vertex morphs.");
                    }
                    offset.WriteToStream(bw, exportSettings);
                }
            }
        }
示例#4
0
        public override void WriteToStream(BinaryWriter bw, MMDExportSettings exportSettings)
        {
            if (exportSettings.Format == MMDExportSettings.ModelFormat.PMX)
            {
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameJP);
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameEN);

                PMXParser.WriteIndex(bw, exportSettings.BitSettings.BoneIndexLength, PMXBone.CheckIndexInModel(this.Bone, exportSettings, true));
            }
            else
            {
                PMDParser.WriteString(bw, 20, exportSettings.TextEncoding, this.NameEN);

                PMXParser.WriteIndex(bw, 2, PMXBone.CheckIndexInModel(this.Bone, exportSettings, true));
            }

            bw.Write((byte)this.CollissionGroup);
            this.NoCollissionGroups.WriteToStream(bw, exportSettings);

            bw.Write((byte)(int)this.Shape);
            this._shapeSize.WriteToStream(bw);

            if (exportSettings.Format == MMDExportSettings.ModelFormat.PMD && this.Bone != null)
            { //PMD location fix
                PMXVector3 pos = new PMXVector3(this.Position.X, this.Position.Y, this.Position.Z);
                pos -= this.Bone.Position;
                pos.WriteToStream(bw);
            }
            else
            {
                this.Position.WriteToStream(bw);
            }

            this.Rotation.WriteToStream(bw);

            bw.Write(this.Mass);
            bw.Write(this.LinearDamping);
            bw.Write(this.AngularDamping);
            bw.Write(this.Repulsion);
            bw.Write(this.Friction);

            bw.Write((byte)(int)this.Type);
        }
示例#5
0
        /// <summary>
        /// Saves a model to a stream.
        /// </summary>
        /// <param name="stream"></param>
        public void SaveToStream(Stream stream)
        {
            List <string> requiredTextureList = new List <string>(); //List of textures to export
            int           triangleCount       = 0;

            foreach (PMXMaterial mat in this.Materials)
            {
                this.AddToListIfRequired(requiredTextureList, mat.DiffuseTexture);
                this.AddToListIfRequired(requiredTextureList, mat.SphereTexture);

                if (!mat.StandardToon)
                {
                    this.AddToListIfRequired(requiredTextureList, mat.NonStandardToonTexture);
                }

                triangleCount += mat.Triangles.Count;
            }

            int maxAddUV = 0;

            foreach (PMXVertex v in this.Vertices)
            {
                maxAddUV = Math.Max(v.AddedUVs.Count, maxAddUV);
            }
            if (maxAddUV > 4)
            {
                throw new InvalidDataException("Maximum Add UV data is 4");
            }

            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            byte[] magic = Encoding.ASCII.GetBytes("PMX ");
            stream.Write(magic, 0, 4);

            Random rnd          = new Random();
            int    randomNumber = rnd.Next();

            MMDExportSettings settings = new MMDExportSettings(MMDExportSettings.ModelFormat.PMX);

            settings.Model      = this;
            settings.ExportHash = randomNumber;
            settings.ExtendedUV = (byte)maxAddUV;

            float version = 2.0f;

            foreach (PMXJoint j in this.Joints)
            {
                if (j.Type != PMXJoint.JointType.SpringSixDOF)
                {
                    version = 2.1f;
                    break;
                }
            }

            bw.Write(version);

            //Flag length
            bw.Write((byte)8);

            //Encoding (UTF-16 LE only)
            settings.TextEncoding = Encoding.Unicode;
            bw.Write((byte)0);
            bw.Write((byte)settings.ExtendedUV);

            settings.BitSettings.VertexIndexLength    = this.DetermineRequiredBitLength(this.Vertices.Count);
            settings.BitSettings.TextureIndexLength   = this.DetermineRequiredBitLength(requiredTextureList.Count);
            settings.BitSettings.MaterialIndexLength  = this.DetermineRequiredBitLength(this.Materials.Count);
            settings.BitSettings.BoneIndexLength      = this.DetermineRequiredBitLength(this.Bones.Count);
            settings.BitSettings.MorphIndexLength     = this.DetermineRequiredBitLength(this.Morphs.Count);
            settings.BitSettings.RigidBodyIndexLength = this.DetermineRequiredBitLength(this.RigidBodies.Count);

            bw.Write(settings.BitSettings.VertexIndexLength);
            bw.Write(settings.BitSettings.TextureIndexLength);
            bw.Write(settings.BitSettings.MaterialIndexLength);
            bw.Write(settings.BitSettings.BoneIndexLength);
            bw.Write(settings.BitSettings.MorphIndexLength);
            bw.Write(settings.BitSettings.RigidBodyIndexLength);

            PMXParser.WriteString(bw, settings.TextEncoding, this.NameJP);
            PMXParser.WriteString(bw, settings.TextEncoding, this.NameEN);
            PMXParser.WriteString(bw, settings.TextEncoding, this.DescriptionJP);
            PMXParser.WriteString(bw, settings.TextEncoding, this.DescriptionEN);

            //Vertices
            bw.Write((Int32)this.Vertices.Count);
            int vtxIndex = 0;

            foreach (PMXVertex v in this.Vertices)
            {
                v.AddIndexForExport(settings, vtxIndex);
                v.WriteToStream(bw, settings);
                vtxIndex++;
            }

            //Triangles
            bw.Write((Int32)(triangleCount * 3));

            foreach (PMXMaterial mat in this.Materials)
            {
                foreach (PMXTriangle t in mat.Triangles)
                {
                    t.WriteToStream(bw, settings);
                }
            }

            //Textures
            string[] textures = requiredTextureList.ToArray();
            bw.Write((Int32)textures.Length);

            foreach (string textureFile in textures)
            {
                PMXParser.WriteString(bw, settings.TextEncoding, textureFile);
            }

            //Materials
            bw.Write((Int32)this.Materials.Count);

            foreach (PMXMaterial mat in this.Materials)
            {
                mat.WriteToStream(bw, settings, textures);
            }

            //Bones
            bw.Write((Int32)this.Bones.Count);

            foreach (PMXBone bn in this.Bones)
            {
                bn.WriteToStream(bw, settings);
            }

            //Morphs
            bw.Write((Int32)this.Morphs.Count);

            foreach (PMXMorph mrph in this.Morphs)
            {
                mrph.WriteToStream(bw, settings);
            }

            //Displays
            bw.Write((Int32)this.DisplaySlots.Count);

            foreach (PMXDisplaySlot dsp in this.DisplaySlots)
            {
                dsp.WriteToStream(bw, settings);
            }

            //Rigid bodies
            bw.Write((Int32)this.RigidBodies.Count);

            foreach (PMXRigidBody bdy in this.RigidBodies)
            {
                bdy.WriteToStream(bw, settings);
            }

            //Joints
            bw.Write((Int32)this.Joints.Count);
            foreach (PMXJoint jt in this.Joints)
            {
                jt.WriteToStream(bw, settings);
            }

            //Reset triangles
            foreach (PMXVertex v in this.Vertices)
            {
                v.RemoveIndexForExport(settings);
            }


            long length = ms.Position;

            ms.Seek(0, SeekOrigin.Begin);

            ms.CopyTo(stream);

            ms.Close();
            ms = null;
        }
示例#6
0
        public void WriteToStream(BinaryWriter bw, MMDExportSettings exportSettings, PMXBone[] ikBones)
        {
            if (exportSettings.Format == MMDExportSettings.ModelFormat.PMX)
            { //PMX export
                short flags = 0x0000;

                flags |= (short)(this.HasChildBone ? PMXBone.BONE_TAILPOS_IS_BONE : 0x0000);

                flags |= (short)(this.Rotatable ? PMXBone.BONE_CAN_ROTATE : 0x0000);
                flags |= (short)(this.Translatable ? PMXBone.BONE_CAN_TRANSLATE : 0x0000);
                flags |= (short)(this.Visible ? PMXBone.BONE_IS_VISIBLE : 0x0000);
                flags |= (short)(this.Operating ? PMXBone.BONE_CAN_MANIPULATE : 0x0000);

                flags |= (short)((this.ExternalModificationType == BoneExternalModificationType.Both || this.ExternalModificationType == BoneExternalModificationType.Rotation) ? PMXBone.BONE_IS_EXTERNAL_ROTATION : 0x0000);
                flags |= (short)((this.ExternalModificationType == BoneExternalModificationType.Both || this.ExternalModificationType == BoneExternalModificationType.Translation) ? PMXBone.BONE_IS_EXTERNAL_TRANSLATION : 0x0000);

                flags |= (short)(this.FixedAxis ? PMXBone.BONE_HAS_FIXED_AXIS : 0x0000);
                flags |= (short)(this.LocalCoordinates ? PMXBone.BONE_HAS_LOCAL_COORDINATE : 0x0000);
                flags |= (short)(this.HasExternalParent ? PMXBone.BONE_IS_EXTERNAL_PARENT_DEFORM : 0x0000);

                flags |= (short)(this.TransformPhysicsFirst ? PMXBone.BONE_IS_AFTER_PHYSICS_DEFORM : 0x0000);

                flags |= (short)((this.IK != null) ? PMXBone.BONE_IS_IK : 0x0000);

                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameJP);
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameEN);

                this.Position.WriteToStream(bw);

                PMXParser.WriteIndex(bw, exportSettings.BitSettings.BoneIndexLength, PMXBone.CheckIndexInModel(this.Parent, exportSettings, true));

                bw.Write((Int32)this.Layer);
                bw.Write((Int16)flags);

                if (this.HasChildBone)
                {
                    PMXParser.WriteIndex(bw, exportSettings.BitSettings.BoneIndexLength, PMXBone.CheckIndexInModel(this.ChildBone, exportSettings, true));
                }
                else
                {
                    this.ChildVector.WriteToStream(bw);
                }

                if (this.ExternalModificationType != BoneExternalModificationType.None)
                {
                    PMXParser.WriteIndex(bw, exportSettings.BitSettings.BoneIndexLength, PMXBone.CheckIndexInModel(this.ExternalBone, exportSettings, true));
                    bw.Write(this.ExternalBoneEffect);
                }

                if (this.FixedAxis)
                {
                    this.AxisLimit.WriteToStream(bw);
                }

                if (this.LocalCoordinates)
                {
                    this.LocalCoordinatesX.WriteToStream(bw);
                    this.LocalCoordinatesZ.WriteToStream(bw);
                }

                if (this.HasExternalParent)
                {
                    bw.Write((Int32)this.ExternalParentKey);
                }

                if (this.IK != null)
                {
                    this.IK.WriteToStream(bw, exportSettings);
                }
            }
            else
            { //PMD format
                PMDParser.WriteString(bw, 20, exportSettings.TextEncoding, this.NameJP);
                bw.Write((Int16)PMXBone.CheckIndexInModel(this.Parent, exportSettings, true));

                if (this.HasChildBone)
                {
                    bw.Write((Int16)PMXBone.CheckIndexInModel(this.ChildBone, exportSettings, true));
                }
                else
                {
                    bw.Write((Int16)(-1));
                }

                byte  type    = PMD_BONE_TYPE_ROTATE;
                short ikIndex = 0;

                if (this.Translatable)
                {
                    type = PMD_BONE_TYPE_ROTATE_MOVE;
                }

                if (this.IK != null)
                {
                    type = PMD_BONE_TYPE_IK;
                }

                if (this.IK != null)
                {
                    bool isIkTarget = false;
                    foreach (PMXBone ikBone in ikBones)
                    {
                        foreach (PMXIKLink link in ikBone.IK.IKLinks)
                        {
                            if (link.Bone == this)
                            {
                                ikIndex    = (Int16)PMXBone.CheckIndexInModel(ikBone, exportSettings, true);
                                isIkTarget = true;
                                break;
                            }
                        }
                        if (isIkTarget)
                        {
                            break;
                        }
                    }

                    if (isIkTarget)
                    {
                        type = (this.Visible ? PMD_BONE_TYPE_IK_CHILD:PMD_BONE_TYPE_IK_TARGET);
                    }
                    else if (!this.Visible)
                    {
                        type = PMD_BONE_TYPE_INVISIBLE;
                    }
                    else if (this.FixedAxis)
                    {
                        type = (this.Visible ? PMD_BONE_TYPE_TWIST : PMD_BONE_TYPE_TWIST_INVISIBLE);
                    }
                    else if (this.ExternalModificationType != BoneExternalModificationType.Both)
                    {
                        type    = PMD_BONE_TYPE_EXTERNAL_ROTATOR;
                        ikIndex = (Int16)PMXBone.CheckIndexInModel(this.ExternalBone, exportSettings, true);
                    }
                }

                bw.Write(type);
                bw.Write(ikIndex);

                this.Position.WriteToStream(bw);
            }
        }
示例#7
0
        public void WriteToStream(BinaryWriter bw, MMDExportSettings exportSettings, string[] textures, string[] defaultToons = null)
        {
            if (exportSettings.Format == MMDExportSettings.ModelFormat.PMX)
            { //PMX Export
                if (textures == null)
                {
                    textures = new string[0];
                }

                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameJP);
                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.NameEN);

                this.Diffuse.WriteToStream(bw);
                bw.Write(this.Alpha);
                this.Specular.WriteToStream(bw);
                bw.Write(this.SpecularFactor);
                this.Ambient.WriteToStream(bw);

                byte flags = (byte)(((int)this.GroundShadowType) << 6);
                flags |= (byte)(this.DoubleSided ? PMXMaterial.MATERIAL_DOUBLE_SIDED : 0);
                flags |= (byte)(this.GroundShadow ? PMXMaterial.MATERIAL_GROUND_SHADOW : 0);
                flags |= (byte)(this.SelfShadow ? PMXMaterial.MATERIAL_SELF_SHADOW : 0);
                flags |= (byte)(this.SelfShadowPlus ? PMXMaterial.MATERIAL_SELF_SHADOW_PLUS : 0);
                flags |= (byte)(this.EdgeEnabled ? PMXMaterial.MATERIAL_EDGE_ENABLED : 0);
                flags |= (byte)(this.VertexColor ? PMXMaterial.MATERIAL_VERTEX_COLOR : 0);
                bw.Write(flags);

                this.EdgeColor.WriteToStream(bw);
                bw.Write(this.EdgeSize);

                PMXParser.WriteIndex(bw, exportSettings.BitSettings.TextureIndexLength, this.GetTextureIndex(this.DiffuseTexture, textures));
                PMXParser.WriteIndex(bw, exportSettings.BitSettings.TextureIndexLength, this.GetTextureIndex(this.SphereTexture, textures));

                bw.Write((byte)this.SphereMode);

                if (this.StandardToon)
                {
                    bw.Write((byte)1);
                    bw.Write(this.StandardToonIndex);
                }
                else
                {
                    bw.Write((byte)0);
                    PMXParser.WriteIndex(bw, exportSettings.BitSettings.TextureIndexLength, this.GetTextureIndex(this.NonStandardToonTexture, textures));
                }

                PMXParser.WriteString(bw, exportSettings.TextEncoding, this.Comment);

                int triangleVerticesCount = (this.Triangles.Count * 3);
                bw.Write((Int32)triangleVerticesCount);
            }
            else
            {
                if (defaultToons == null || textures == null)
                {
                    throw new InvalidDataException("Toon data required for PMD.");
                }

                //PMD format
                this.Diffuse.WriteToStream(bw);
                bw.Write(this.Alpha);
                bw.Write(this.SpecularFactor);
                this.Specular.WriteToStream(bw);
                this.Ambient.WriteToStream(bw);

                int    toonIndex = -1;
                string toonFile  = null;
                if (this.StandardToon && this.StandardToonIndex >= 0)
                {
                    if (this.StandardToonIndex < 10)
                    {
                        toonFile = defaultToons[this.StandardToonIndex];
                    }
                }
                else if (!this.StandardToon)
                {
                    toonFile = this.NonStandardToonTexture;
                }

                if (toonFile != null)
                {
                    int index = Array.IndexOf <string>(textures, toonFile);
                    if (index >= 0 && index < 10)
                    {
                        toonIndex = index;
                    }
                }

                bw.Write((sbyte)toonIndex);
                bw.Write((byte)(this.EdgeEnabled ? 1 : 0));

                bw.Write((Int32)(this.Triangles.Count * 3));

                string textureFile = "";
                if (this.DiffuseTexture != null)
                {
                    textureFile += this.DiffuseTexture;
                }
                if (this.SphereTexture != null)
                {
                    textureFile += "*" + this.DiffuseTexture;
                }

                PMDParser.WriteString(bw, 20, exportSettings.TextEncoding, textureFile);
            }
        }