Example #1
0
                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;
                }
        //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 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;
        }
        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;
        }