| 2016 | } |
| 2017 | |
| 2018 | bool TSShape::setSequenceBlend(const String& seqName, bool blend, const String& blendRefSeqName, S32 blendRefFrame) |
| 2019 | { |
| 2020 | // Find the target sequence |
| 2021 | S32 seqIndex = findSequence(seqName); |
| 2022 | if (seqIndex < 0) |
| 2023 | { |
| 2024 | Con::errorf("TSShape::setSequenceBlend: Could not find sequence named '%s'", seqName.c_str()); |
| 2025 | return false; |
| 2026 | } |
| 2027 | TSShape::Sequence& seq = sequences[seqIndex]; |
| 2028 | |
| 2029 | // Ignore if blend flag is already correct |
| 2030 | if (seq.isBlend() == blend) |
| 2031 | return true; |
| 2032 | |
| 2033 | // Find the sequence containing the reference frame |
| 2034 | S32 blendRefSeqIndex = findSequence(blendRefSeqName); |
| 2035 | if (blendRefSeqIndex < 0) |
| 2036 | { |
| 2037 | Con::errorf("TSShape::setSequenceBlend: Could not find reference sequence named '%s'", blendRefSeqName.c_str()); |
| 2038 | return false; |
| 2039 | } |
| 2040 | TSShape::Sequence& blendRefSeq = sequences[blendRefSeqIndex]; |
| 2041 | |
| 2042 | if ((blendRefFrame < 0) || (blendRefFrame >= blendRefSeq.numKeyframes)) |
| 2043 | { |
| 2044 | Con::errorf("TSShape::setSequenceBlend: Reference frame out of range (0-%d)", blendRefSeq.numKeyframes-1); |
| 2045 | return false; |
| 2046 | } |
| 2047 | |
| 2048 | // Set the new flag |
| 2049 | if (blend) |
| 2050 | seq.flags |= TSShape::Blend; |
| 2051 | else |
| 2052 | seq.flags &= (~TSShape::Blend); |
| 2053 | |
| 2054 | // For each animated node in the target sequence, need to add or subtract the |
| 2055 | // reference keyframe from each frame |
| 2056 | TSIntegerSet nodeMatters(seq.rotationMatters); |
| 2057 | nodeMatters.overlap(seq.translationMatters); |
| 2058 | |
| 2059 | S32 end = nodeMatters.end(); |
| 2060 | for (S32 nodeIndex = nodeMatters.start(); nodeIndex < end; nodeMatters.next(nodeIndex)) |
| 2061 | { |
| 2062 | MatrixF refMat; |
| 2063 | getNodeKeyframe(nodeIndex, blendRefSeq, blendRefFrame, &refMat); |
| 2064 | |
| 2065 | // Add or subtract the reference? |
| 2066 | if (blend) |
| 2067 | refMat.inverse(); |
| 2068 | |
| 2069 | bool updateRot(false), updateTrans(false); |
| 2070 | S32 rotOffset(0), transOffset(0); |
| 2071 | if (seq.rotationMatters.test(nodeIndex)) |
| 2072 | { |
| 2073 | updateRot = true; |
| 2074 | rotOffset = seq.baseRotation + seq.rotationMatters.count(nodeIndex) * seq.numKeyframes; |
| 2075 | } |