Example #1
0
        public void Read(BinaryReader reader, PmxHeaderData header)
        {
            BoneName  = reader.ReadText(header.Encoding);
            BoneNameE = reader.ReadText(header.Encoding);

            Pos      = reader.ReadVector3();
            ParentId = reader.ReadPmxId(header.BoneIndexSize);

            Depth = reader.ReadInt32();
            Flag  = (BoneFlags)reader.ReadInt16();

            if (Flag.HasFlag(BoneFlags.OFFSET))
            {
                ArrowId = reader.ReadPmxId(header.BoneIndexSize);
            }
            else
            {
                PosOffset = reader.ReadVector3();
            }

            if (Flag.HasFlag(BoneFlags.ROTATE_LINK) || Flag.HasFlag(BoneFlags.MOVE_LINK))
            {
                LinkParentId = reader.ReadPmxId(header.BoneIndexSize);
                LinkWeight   = reader.ReadSingle();
            }

            if (Flag.HasFlag(BoneFlags.AXIS_ROTATE))
            {
                AxisVec = reader.ReadVector3();
            }

            if (Flag.HasFlag(BoneFlags.LOCAL_AXIS))
            {
                LocalAxisVecX = reader.ReadVector3();
                LocalAxisVecZ = reader.ReadVector3();
            }

            if (Flag.HasFlag(BoneFlags.EXTRA))
            {
                ExtraParentId = reader.ReadInt32();
            }

            if (Flag.HasFlag(BoneFlags.IK))
            {
                IkTargetId = reader.ReadPmxId(header.BoneIndexSize);

                IkDepth    = reader.ReadInt32();
                AngleLimit = reader.ReadSingle();

                int boneNum = reader.ReadInt32();
                IkChilds = new PmxIkData[boneNum];

                for (int i = 0; i < boneNum; i++)
                {
                    IkChilds[i] = new PmxIkData();
                    IkChilds[i].Read(reader, header);
                }
            }
        }
Example #2
0
        public void Write(BinaryWriter writer, PmxHeaderData header)
        {
            writer.WriteText(header.Encoding, BoneName);
            writer.WriteText(header.Encoding, BoneNameE);

            writer.Write(Pos);
            writer.WritePmxId(header.BoneIndexSize, ParentId);

            writer.Write(Depth);
            writer.Write((short)Flag);

            if (Flag.HasFlag(BoneFlags.OFFSET))
            {
                writer.WritePmxId(header.BoneIndexSize, ArrowId);
            }
            else
            {
                writer.Write(PosOffset);
            }

            if (Flag.HasFlag(BoneFlags.ROTATE_LINK) || Flag.HasFlag(BoneFlags.MOVE_LINK))
            {
                writer.WritePmxId(header.BoneIndexSize, LinkParentId);
                writer.Write(LinkWeight);
            }

            if (Flag.HasFlag(BoneFlags.AXIS_ROTATE))
            {
                writer.Write(AxisVec);
            }

            if (Flag.HasFlag(BoneFlags.LOCAL_AXIS))
            {
                writer.Write(LocalAxisVecX);
                writer.Write(LocalAxisVecZ);
            }

            if (Flag.HasFlag(BoneFlags.EXTRA))
            {
                writer.Write(ExtraParentId);
            }

            if (Flag.HasFlag(BoneFlags.IK))
            {
                writer.WritePmxId(header.BoneIndexSize, IkTargetId);

                writer.Write(IkDepth);
                writer.Write(AngleLimit);

                int boneNum = IkChilds.Length;

                writer.Write(boneNum);
                for (int i = 0; i < boneNum; i++)
                {
                    IkChilds[i].Write(writer, header);
                }
            }
        }
Example #3
0
        //Initialize should only be called from parent group during parse.
        //Bones need not be imported/exported anyways
        public override bool OnInitialize()
        {
            MDL0Bone *header = Header;

            SetSizeInternal(header->_headerLen);

            //Conditional name assignment
            if (_name == null && header->_stringOffset != 0)
            {
                _name = header->ResourceString;
            }

            //Assign fields
            _boneFlags      = (BoneFlags)(uint)header->_flags;
            _billboardFlags = (BillboardFlags)(uint)header->_bbFlags;
            _nodeIndex      = header->_nodeId;
            _entryIndex     = header->_index;

            _bbRefNode = !_replaced && _boneFlags.HasFlag(BoneFlags.HasBillboardParent) ?
                         Model._linker.NodeCache[header->_bbNodeId] as MDL0BoneNode : null;

            if (_billboardFlags != BillboardFlags.Off)
            {
                Model._billboardBones.Add(this); //Update mesh in T-Pose
            }
            _bindState         = _frameState = new FrameState(header->_scale, (Vector3)header->_rotation, header->_translation);
            _bindMatrix        = _frameMatrix = header->_transform;
            _inverseBindMatrix = _inverseFrameMatrix = header->_transformInv;

            _extents = header->_extents;

            (_userEntries = new UserDataCollection()).Read(header->UserDataAddress);

            //We don't want to process children because not all have been parsed yet.
            //Child assignments will be handled by the parent group.
            return(false);
        }
Example #4
0
        //Initialize should only be called from parent group during parse.
        //Bones need not be imported/exported anyways
        public override bool OnInitialize()
        {
            MDL0Bone *header = Header;

            SetSizeInternal(header->_headerLen);

            //Assign true parent using parent header offset
            int offset = header->_parentOffset;

            //Offsets are always < 0, because parent entries are listed before children
            if (offset < 0)
            {
                //Get address of parent header
                MDL0Bone *pHeader = (MDL0Bone *)((byte *)header + offset);
                //Search bone list for matching header
                foreach (MDL0BoneNode bone in Parent._children)
                {
                    if (pHeader == bone.Header)
                    {
                        _parent = bone;
                        break;
                    }
                }
            }

            //Conditional name assignment
            if ((_name == null) && (header->_stringOffset != 0))
            {
                _name = header->ResourceString;
            }

            //Assign fields
            _flags1           = (BoneFlags)(uint)header->_flags;
            _flags2           = (BillboardFlags)(uint)header->_bbFlags;
            _bbNodeId         = header->_bbNodeId;
            _nodeIndex        = header->_nodeId;
            _boneIndex        = header->_index;
            _headerLen        = header->_headerLen;
            _mdl0Offset       = header->_mdl0Offset;
            _stringOffset     = header->_stringOffset;
            _parentOffset     = header->_parentOffset;
            _firstChildOffset = header->_firstChildOffset;
            _nextOffset       = header->_nextOffset;
            _prevOffset       = header->_prevOffset;
            _userDataOffset   = header->_userDataOffset;

            if (_flags2 != 0 && _flags1.HasFlag(BoneFlags.HasGeometry))
            {
                Model._billboardBones.Add(this); //Update mesh in T-Pose
            }
            _bindState         = _frameState = new FrameState(header->_scale, (Vector3)header->_rotation, header->_translation);
            _bindMatrix        = _frameMatrix = header->_transform;
            _inverseBindMatrix = _inverseFrameMatrix = header->_transformInv;

            _bMin = header->_boxMin;
            _bMax = header->_boxMax;

            (_userEntries = new UserDataCollection()).Read(header->UserDataAddress);

            //We don't want to process children because not all have been parsed yet.
            //Child assigning will be handled by the parent group.
            return(false);
        }
        //Initialize should only be called from parent group during parse.
        //Bones need not be imported/exported anyways
        public override bool OnInitialize()
        {
            MDL0Bone* header = Header;

            SetSizeInternal(header->_headerLen);

            //Assign true parent using parent header offset
            int offset = header->_parentOffset;
            //Offsets are always < 0, because parent entries are listed before children
            if (offset < 0)
            {
                //Get address of parent header
                MDL0Bone* pHeader = (MDL0Bone*)((byte*)header + offset);
                //Search bone list for matching header
                foreach (MDL0BoneNode bone in Parent._children)
                    if (pHeader == bone.Header)
                    {
                        _parent = bone;
                        break;
                    }
            }

            //Conditional name assignment
            if ((_name == null) && (header->_stringOffset != 0))
                _name = header->ResourceString;

            //Assign fields
            _flags1 = (BoneFlags)(uint)header->_flags;
            _flags2 = (BillboardFlags)(uint)header->_bbFlags;
            _bbNodeId = header->_bbNodeId;
            _nodeIndex = header->_nodeId;
            _boneIndex = header->_index;
            _headerLen = header->_headerLen;
            _mdl0Offset = header->_mdl0Offset;
            _stringOffset = header->_stringOffset;
            _parentOffset = header->_parentOffset;
            _firstChildOffset = header->_firstChildOffset;
            _nextOffset = header->_nextOffset;
            _prevOffset = header->_prevOffset;
            _userDataOffset = header->_userDataOffset;

            if (_flags2 != 0 && _flags1.HasFlag(BoneFlags.HasGeometry))
                Model._billboardBones.Add(this); //Update mesh in T-Pose

            _bindState = _frameState = new FrameState(header->_scale, (Vector3)header->_rotation, header->_translation);
            _bindMatrix = _frameMatrix = header->_transform;
            _inverseBindMatrix = _inverseFrameMatrix = header->_transformInv;

            _bMin = header->_boxMin;
            _bMax = header->_boxMax;

            (_userEntries = new UserDataCollection()).Read(header->UserDataAddress);

            //We don't want to process children because not all have been parsed yet.
            //Child assigning will be handled by the parent group.
            return false;
        }