vault backup: 2023-11-08 13:11:35

This commit is contained in:
BlueRose 2023-11-08 13:11:35 +08:00
parent 2570e51d65
commit 47f3f64625
3 changed files with 70 additions and 4 deletions

View File

@ -102,6 +102,14 @@
"lastUpdated": 1699350988289 "lastUpdated": 1699350988289
} }
} }
},
"c++17带来的代码变化": {
"c++17带来的代码变化": {
"internalLink": {
"count": 1,
"lastUpdated": 1699369392809
}
}
} }
} }
} }

View File

@ -103,5 +103,61 @@ FChainDecoderFK::DecodePose()
2. 从根骨骼开始重定向以保证最后结果不会发生偏差。计算了Source/Target InitialDelta、Target 根骨骼 Transform后将两者相乘最后应用给所有Source骨骼链。 2. 从根骨骼开始重定向以保证最后结果不会发生偏差。计算了Source/Target InitialDelta、Target 根骨骼 Transform后将两者相乘最后应用给所有Source骨骼链。
3. 如果禁用FK重定向则返回当前WorldSpace Transform并且return。 3. 如果禁用FK重定向则返回当前WorldSpace Transform并且return。
4. 计算Source & Target 骨骼链开始Index。 4. 计算Source & Target 骨骼链开始Index。
5. 开始遍历 5. 开始遍历所有骨骼。
1. 取得Target骨骼Index以及InitialTransform。
2. 根据设置的FK的旋转模式执行对应逻辑默认为插值模式也就是他实现了骨骼链的不同数量骨骼间的重定向匹配。计算SourceCurrentTransform与SourceInitialTransform。
1. 使用Target的Params骨骼长度百分比来插值计算出Source的Transform。参考[[#插值计算]]。
2. Params的计算在FChainFK::CalculateBoneParameters(),可以看得出就是根据**当前骨骼长度/总长度**计算百分比最后加入Params。该函数的调用堆栈为UIKRetargetProcessor::Initialize() => UIKRetargetProcessor::InitializeBoneChainPairs() => FRetargetChainPairFK::Initialize() => FChainFK::Initialize()
3. 计算旋转值SourceCurrentRotation、SourceInitialRotation => RotationDelta TargetInitialRotation => **OutRotation**
4. 计算当前TargetBone的父骨骼 ParentGlobalTransform。
5. 根绝设置的FK TranslationMode计算出 **OutPosition**
6. 计算OutScale = SourceCurrentScale + (TargetInitialScale - SourceInitialScale),计算出**OutScale**。
7. 对应index的`CurrentGlobalTransforms[ChainIndex]`/`InOutGlobalPose[BoneIndex]`赋值。
6. 进行一些后处理计算,默认状态下跳过。
## 插值计算
```c++
FTransform FChainDecoderFK::GetTransformAtParam(
const TArray<FTransform>& Transforms,
const TArray<float>& InParams,
const float& Param) const
{
if (InParams.Num() == 1)
{
return Transforms[0];
}
if (Param < KINDA_SMALL_NUMBER)
{
return Transforms[0];
}
if (Param > 1.0f - KINDA_SMALL_NUMBER)
{
return Transforms.Last();
}
for (int32 ChainIndex=1; ChainIndex<InParams.Num(); ++ChainIndex)
{
const float CurrentParam = InParams[ChainIndex];
if (CurrentParam <= Param)
{
continue;
}
//关键在这
const float PrevParam = InParams[ChainIndex-1];
const float PercentBetweenParams = (Param - PrevParam) / (CurrentParam - PrevParam);
const FTransform& Prev = Transforms[ChainIndex-1];
const FTransform& Next = Transforms[ChainIndex];
const FVector Position = FMath::Lerp(Prev.GetTranslation(), Next.GetTranslation(), PercentBetweenParams);
const FQuat Rotation = FQuat::FastLerp(Prev.GetRotation(), Next.GetRotation(), PercentBetweenParams).GetNormalized();
const FVector Scale = FMath::Lerp(Prev.GetScale3D(), Next.GetScale3D(), PercentBetweenParams);
return FTransform(Rotation,Position, Scale);
}
checkNoEntry();
return FTransform::Identity;
}
```

View File

@ -62,16 +62,18 @@ $$p \rightarrow q\cdot p \cdot q^-1$$
$$x^2 + y^2 + z^2 =1$$ $$x^2 + y^2 + z^2 =1$$
# FBX # FBX
四元数旋转顺序 xyz 四元数旋转顺序 xyz
旋转xyz分别为
可以使用 可以使用
`FbxNode::RotationOrder` `FbxNode::RotationOrder`
了解其顺序。 了解其顺序。
旋转xyz分别为
the "roll" about the x-axis along the plane, the "roll" about the x-axis along the plane,
the "pitch" about the y-axis which extends along the wings of the plane, the "pitch" about the y-axis which extends along the wings of the plane,
and the "yaw" or "heading" about the z-axis and the "yaw" or "heading" about the z-axis
# Qt # Qt
四元数旋转顺序zyx 或 yxz Qt中四元数旋转顺序zyx 或 yxz
旋转xyz分别为pitch yaw roll 旋转xyz分别为pitch yaw roll
# UE
UE中四元数的旋转顺序为**zyx**。其中旋转X轴为Roll旋转Y轴为Pitch旋转Z轴为Yaw