예제 #1
0
        private void UpdateDerivedValues()
        {
            // Validate chain. Compute bone lengths, bone indices and total chain length.
            if (_isDirty)
            {
                return;
            }

            _boneLengths.Clear();
            _boneIndices.Clear();
            _totalChainLength = -1;

            try
            {
                // Check if chain is valid.
                if (!SkeletonPose.IsAncestorOrSelf(RootBoneIndex, TipBoneIndex))
                {
                    throw new ArgumentException("The RootBoneIndex and the TipBoneIndex do not form a valid bone chain.");
                }

                // Get bone indices.
                SkeletonPose.GetChain(RootBoneIndex, TipBoneIndex, _boneIndices);

                var numberOfBones = _boneIndices.Count;

                // Get bone lengths. We compute the bone lengths from an actual bone pose because
                // our archer test model had a scale in the bone transforms. Therefore we cannot
                // compute the length from only the bind poses.
                _boneLengths.Capacity = numberOfBones;
                _totalChainLength     = 0;
                for (int i = 0; i < numberOfBones - 1; i++)
                {
                    int   boneIndex  = _boneIndices[i];
                    int   childIndex = _boneIndices[i + 1];
                    var   boneVector = SkeletonPose.GetBonePoseAbsolute(childIndex).Translation - SkeletonPose.GetBonePoseAbsolute(boneIndex).Translation;
                    float boneLength = boneVector.Length;
                    _boneLengths.Add(boneLength);
                    _totalChainLength += boneLength;
                }

                // Tip bone.
                _boneLengths.Add((SkeletonPose.GetBonePoseAbsolute(TipBoneIndex).Scale *TipOffset).Length);
                _totalChainLength += _boneLengths[numberOfBones - 1];

                // Initialize _bones list with dummy values.
                _bones.Clear();
                for (int i = 0; i < numberOfBones; i++)
                {
                    _bones.Add(SrtTransform.Identity);
                }

                _isDirty = true;
            }
            catch
            {
                _boneLengths.Clear();
                _boneIndices.Clear();
                _totalChainLength = 0;

                throw;
            }
        }