zoukankan      html  css  js  c++  java
  • 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






  • 相关阅读:
    C# 时间+三位随机数
    dataGridView加行标识方法与制作
    MySql多列查询
    php 去掉字符串的最后一个字符
    DataTable 排序
    汇编第一个程序 Hello World (初学者与入门)
    C# 获取前一天,明天,本周,上周,本季度等!
    php 字符串中任意添加
    天涯论坛的经典回帖!!!
    系统时间同步
  • 原文地址:https://www.cnblogs.com/username/p/6477722.html
Copyright © 2011-2022 走看看