首页 > 代码库 > 17020701(AnimDynamic继续)
17020701(AnimDynamic继续)
【目标】
AnimDynamic继续
【思路】
1 之前运行效果
2 FAnimPhys.CalculateNextPose 会去更新每块骨骼位置
s2 = s1+ vt
3
4 计算流程
5 实验
FAnimPhys.CalculateNextPose
不更新NextPosition
效果如下:
因为FAnimPhys.CalculateNextPose没屏蔽旋转计算,所以有一部分变化
6
【步骤】
1 添加相关绘制盒子函数USkelControlAnimDynamic
INT USkelControlAnimDynamic::GetNumBodies() const{ return Bodies.Num();}const FAnimPhysRigidBody& USkelControlAnimDynamic::GetPhysBody(INT BodyIndex) const{ return Bodies(BodyIndex).RigidBody.PhysBody;}void USkelControlAnimDynamic::DrawSkelControl3D(const FSceneView* View, FPrimitiveDrawInterface* PDI, USkeletalMeshComponent* SkelComp, INT BoneIndex){ // If we want to preview the live node, process it here if(bPreviewLive) { for(INT BodyIndex = 0 ; BodyIndex < GetNumBodies() ; ++BodyIndex) { const FAnimPhysRigidBody& Body = GetPhysBody(BodyIndex); FBoneAtom BodyTransform(Body.Pose.Orientation, Body.Pose.Position); //for(const FAnimPhysShape& Shape : Body.Shapes) for (INT BodyIdx = 0; BodyIdx < Body.Shapes.Num(); BodyIdx++) { const FAnimPhysShape& Shape = Body.Shapes(BodyIdx); //for(const FIntVector& Triangle : Shape.Triangles) for (INT TriangleIdx = 0; TriangleIdx < Shape.Triangles.Num(); TriangleIdx++) { const FIntVector& Triangle = Shape.Triangles(TriangleIdx); for(INT Idx = 0 ; Idx < 3 ; ++Idx) { INT Next = (Idx + 1) % 3; FVector FirstVertPosition = BodyTransform.TransformPosition(Shape.Vertices(Triangle(Idx))); FVector SecondVertPosition = BodyTransform.TransformPosition(Shape.Vertices(Triangle(Next))); PDI->DrawLine(FirstVertPosition, SecondVertPosition, FLinearColor::Yellow, SDPG_Foreground, ShapeLineWidth); } } const INT BoneIndex = SkelComp->MatchRefBone(BoundBone); if(BoneIndex != INDEX_NONE) { FBoneAtom BodyJointTransform = SkelComp->SpaceBases(BoneIndex); FBoneAtom ShapeOriginalTransform = BodyJointTransform; // Draw pin location FVector LocalPinOffset = BodyTransform.Rotator().RotateVector(GetBodyLocalJointOffset(BodyIndex)); PDI->DrawLine(Body.Pose.Position, Body.Pose.Position + LocalPinOffset, FLinearColor::Green, SDPG_Foreground, ShapeLineWidth); // Draw basis at body location FVector Origin = BodyTransform.GetTranslation(); FVector XAxis(1.0f, 0.0f, 0.0f); FVector YAxis(0.0f, 1.0f, 0.0f); FVector ZAxis(0.0f, 0.0f, 1.0f); XAxis = BodyTransform.TransformVector(XAxis); YAxis = BodyTransform.TransformVector(YAxis); ZAxis = BodyTransform.TransformVector(ZAxis); PDI->DrawLine(Origin, Origin + XAxis * TransformBasisScale, FLinearColor::Red, SDPG_Foreground, TransformLineWidth); PDI->DrawLine(Origin, Origin + YAxis * TransformBasisScale, FLinearColor::Green, SDPG_Foreground, TransformLineWidth); PDI->DrawLine(Origin, Origin + ZAxis * TransformBasisScale, FLinearColor::Blue, SDPG_Foreground, TransformLineWidth); if(bShowLinearLimits) { DrawLinearLimits(PDI, BodyJointTransform); } if(bShowAngularLimits) { FBoneAtom AngularLimitsTM(BodyJointTransform.GetRotation(), BodyTransform.GetTranslation() + LocalPinOffset); DrawAngularLimits(PDI, AngularLimitsTM); } if(bShowCollisionSpheres && Body.CollisionType != AnimPhysCollisionType::CoM) { // Draw collision sphere DrawWireSphere(PDI, BodyTransform, FLinearColor(FColor::Cyan), Body.SphereCollisionRadius, 24, SDPG_Foreground); } } } } }}void USkelControlAnimDynamic::DrawAngularLimits(FPrimitiveDrawInterface* PDI, const FBoneAtom& JointTransform) const{ FVector XAxis = JointTransform.GetUnitAxis(0); FVector YAxis = JointTransform.GetUnitAxis(1); FVector ZAxis = JointTransform.GetUnitAxis(2); const FVector& MinAngles = ConstraintSetup.AngularLimitsMin; const FVector& MaxAngles = ConstraintSetup.AngularLimitsMax; FVector AngleRange = MaxAngles - MinAngles; FVector Middle = MinAngles + AngleRange * 0.5f; UMaterialInterface* LimitMaterial = LoadObject<UMaterialInterface>(NULL, TEXT("EditorMaterials.PhAT_JointLimitMaterial"), NULL, LOAD_None, NULL); if (AngleRange.X > 0.0f && AngleRange.X < 180.0f) { FBoneAtom XAxisConeTM(YAxis, XAxis ^ YAxis, XAxis, JointTransform.GetTranslation()); XAxisConeTM.SetRotation(FQuat(XAxis, DegreesToRadians(-Middle.X)) * XAxisConeTM.GetRotation()); DrawCone(PDI, FScaleMatrix(30.0f) * XAxisConeTM.ToMatrix(), DegreesToRadians(AngleRange.X / 2.0f), 0.0f, 24, false, FLinearColor::White, LimitMaterial->GetRenderProxy(false), SDPG_World); } if (AngleRange.Y > 0.0f && AngleRange.Y < 180.0f) { FBoneAtom YAxisConeTM(ZAxis, YAxis ^ ZAxis, YAxis, JointTransform.GetTranslation()); YAxisConeTM.SetRotation(FQuat(YAxis, DegreesToRadians(Middle.Y)) * YAxisConeTM.GetRotation()); DrawCone(PDI, FScaleMatrix(30.0f) * YAxisConeTM.ToMatrix(), DegreesToRadians(AngleRange.Y / 2.0f), 0.0f, 24, false, FLinearColor::White, LimitMaterial->GetRenderProxy(false), SDPG_World); } if (AngleRange.Z > 0.0f && AngleRange.Z < 180.0f) { FBoneAtom ZAxisConeTM(XAxis, ZAxis ^ XAxis, ZAxis, JointTransform.GetTranslation()); ZAxisConeTM.SetRotation(FQuat(ZAxis, DegreesToRadians(Middle.Z)) * ZAxisConeTM.GetRotation()); DrawCone(PDI, FScaleMatrix(30.0f) * ZAxisConeTM.ToMatrix(), DegreesToRadians(AngleRange.Z / 2.0f), 0.0f, 24, false, FLinearColor::White, LimitMaterial->GetRenderProxy(false), SDPG_World); }}void USkelControlAnimDynamic::DrawLinearLimits(FPrimitiveDrawInterface* PDI, const FBoneAtom& ShapeTransform) const{ // Draw linear limits FVector LinearLimitHalfExtents(ConstraintSetup.LinearAxesMax - ConstraintSetup.LinearAxesMin); // Add a tiny bit so we can see collapsed axes LinearLimitHalfExtents += FVector(0.1f); LinearLimitHalfExtents /= 2.0f; FVector LinearLimitsCenter = ConstraintSetup.LinearAxesMin + LinearLimitHalfExtents; FBoneAtom LinearLimitsTransform = ShapeTransform; LinearLimitsTransform.SetTranslation(LinearLimitsTransform.GetTranslation() + LinearLimitsTransform.TransformVector(LinearLimitsCenter)); UMaterialInterface* LimitMaterial = LoadObject<UMaterialInterface>(NULL, TEXT("EditorMaterials.PhAT_JointLimitMaterial"), NULL, LOAD_None, NULL); DrawBox(PDI, LinearLimitsTransform.ToMatrix(), LinearLimitHalfExtents, LimitMaterial->GetRenderProxy(false), SDPG_Foreground);}FVector USkelControlAnimDynamic::GetBodyLocalJointOffset(INT BodyIndex) const{ if (JointOffsets.IsValidIndex(BodyIndex)) { return JointOffsets(BodyIndex); } return FVector::ZeroVector;}
使用兽人模型前飘带测试
目测骨骼位置反了?
旋转计算的问题
FAnimPhysAngularLimit.Iter
实验:去掉FAnimPhysAngularLimit.Iter 计算
qun02 和qun09 骨骼位置弄反了
应该qun02固定 qun09飘动的
会不会是 计算结果列表顺序 和应用上去的列表顺序 不一致
USkelControlAnimDynamic.CalculateNewBoneTransforms
USkelControlAnimDynamic.GetAffectedBones
2 修改USkelControlAnimDynamic.GetAffectedBones
//INT BoneIndex = Component->MatchRefBone(ChainEnd); //OutBoneIndices.AddItem(ChainEndBoneIdx); OutBoneIndices.InsertItem(ChainEndBoneIdx,0);... while(ParentBoneIndex != 0) { FName ParentBoneName = SkelComp->GetBoneName(ParentBoneIndex); //OutBoneIndices.AddItem(ParentBoneIndex); OutBoneIndices.InsertItem(ParentBoneIndex,0);....... } } else { //OutBoneIndices.AddItem(BoneIndex); OutBoneIndices.InsertItem(BoneIndex,0); }
【运行】
顺序对了
效果有待调整
【运行】
3
来自为知笔记(Wiz)
17020701(AnimDynamic继续)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。