public override void OnRebuild(VoidPtr address, int length, bool force) { MDL0Bone *header = (MDL0Bone *)address; if (Users.Count > 0 || SingleBindObjects.Length > 0) { _boneFlags |= BoneFlags.HasGeometry; } else { _boneFlags &= ~BoneFlags.HasGeometry; } header->_headerLen = length; header->_index = _entryIndex; header->_nodeId = _nodeIndex; header->_flags = (uint)_boneFlags; header->_bbFlags = (uint)_billboardFlags; header->_bbNodeId = _bbRefNode == null ? 0 : (uint)_bbRefNode.NodeIndex; header->_scale = _bindState._scale; header->_rotation = _bindState._rotate; header->_translation = _bindState._translate; header->_extents = _extents; header->_transform = (bMatrix43)_bindMatrix; header->_transformInv = (bMatrix43)_inverseBindMatrix; if (_userEntries.Count > 0) { header->_userDataOffset = 0xD0; _userEntries.Write(address + 0xD0); } else { header->_userDataOffset = 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; //Bone cache isn't done parsing yet, so set billboard ref node later 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); }
public bool GetFlag(BoneFlags f) { return((f & Flags) == f); }
public void ClearFlags() { Flags = (BoneFlags.Rotation | BoneFlags.Visible | BoneFlags.Enable); }
public static bool HasFlag([NotNull] this PmxBone bone, BoneFlags flags) { return((bone.Flags & flags) != 0); }
public static void ClearFlag([NotNull] this PmxBone bone, BoneFlags flags) { bone.Flags &= ~flags; }
public static void SetFlag([NotNull] this PmxBone bone, BoneFlags flags) { bone.Flags |= flags; }
public static bool HasFlag(this BoneFlags src, BoneFlags check) { return((src & check) == check); }
//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); }
public Single[] WorldMatrix; //4x3 #endregion Fields #region Constructors public Bone(EndianBinaryReader er) { NameOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32(); Flags = (BoneFlags)er.ReadUInt32(); JointID = er.ReadUInt32(); ParentID = er.ReadInt32(); if (ParentID == -1) ParentOffset = er.ReadUInt32(); else ParentOffset = (UInt32)(er.BaseStream.Position + er.ReadInt32()); ChildOffset = er.ReadUInt32(); if (ChildOffset != 0) ChildOffset += (UInt32)(er.BaseStream.Position - 4); PreviousSiblingOffset = er.ReadUInt32(); if (PreviousSiblingOffset != 0) PreviousSiblingOffset += (UInt32)(er.BaseStream.Position - 4); NextSiblingOffset = er.ReadUInt32(); if (NextSiblingOffset != 0) NextSiblingOffset += (UInt32)(er.BaseStream.Position - 4); Scale = new Vector3(er.ReadSingle(), er.ReadSingle(), er.ReadSingle()); Rotation = new Vector3(er.ReadSingle(), er.ReadSingle(), er.ReadSingle()); Translation = new Vector3(er.ReadSingle(), er.ReadSingle(), er.ReadSingle()); LocalMatrix = er.ReadSingles(4 * 3); WorldMatrix = er.ReadSingles(4 * 3); InverseBaseMatrix = er.ReadSingles(4 * 3); BillboardMode = (BBMode)er.ReadUInt32(); Unknown6 = er.ReadUInt32(); Unknown7 = er.ReadUInt32(); long curpos = er.BaseStream.Position; er.BaseStream.Position = NameOffset; Name = er.ReadStringNT(Encoding.ASCII); er.BaseStream.Position = curpos; }
public override void OnRebuild(VoidPtr address, int length, bool force) { MDL0Bone* header = (MDL0Bone*)address; RecalcOffsets(header, address, length); if (_refCount > 0 || _weightCount > 0 || InfluencedObjects.Length > 0) _flags1 |= BoneFlags.HasGeometry; else _flags1 &= ~BoneFlags.HasGeometry; header->_headerLen = length; header->_index = _boneIndex = _entryIndex; header->_nodeId = _nodeIndex; header->_flags = (uint)_flags1; header->_bbFlags = (uint)_flags2; header->_bbNodeId = _bbNodeId; header->_scale = _bindState._scale; header->_rotation = _bindState._rotate; header->_translation = _bindState._translate; header->_boxMin = _bMin; header->_boxMax = _bMax; header->_transform = (bMatrix43)_bindMatrix; header->_transformInv = (bMatrix43)_inverseBindMatrix; _moved = 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; }
public void CalcFlags() { _flags1 = BoneFlags.Visible; if ((Scale._x == Scale._y) && (Scale._y == Scale._z)) _flags1 += (int)BoneFlags.ScaleEqual; if (_refCount > 0) _flags1 += (int)BoneFlags.HasGeometry; if (Scale == new Vector3(1)) _flags1 += (int)BoneFlags.FixedScale; if (Rotation == new Vector3(0)) _flags1 += (int)BoneFlags.FixedRotation; if (Translation == new Vector3(0)) _flags1 += (int)BoneFlags.FixedTranslation; if (Parent is MDL0BoneNode) { if ((BindMatrix == ((MDL0BoneNode)Parent).BindMatrix) && (InverseBindMatrix == ((MDL0BoneNode)Parent).InverseBindMatrix)) _flags1 += (int)BoneFlags.NoTransform; } else if (BindMatrix == Matrix.Identity && InverseBindMatrix == Matrix.Identity) _flags1 += (int)BoneFlags.NoTransform; }
public bool HasFlag(BoneFlags flags) { return((Flags & flags) != 0); }