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); } } }
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); } } }
//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); }
//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; }