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






  • 相关阅读:
    Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (初级)
    Microsoft Enterprise Library 5.0 系列(五) Data Access Application Block
    Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
    Microsoft Enterprise Library 5.0 系列(九) Policy Injection Application Block
    Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
    软件研发打油诗祝大家节日快乐
    从挖井的故事中想到开发管理中最容易忽视的几个简单道理
    ITIL管理思想的执行工具发布
    管理类软件设计“渔”之演化
    20070926日下午工作流与ITILQQ群 事件管理 讨论聊天记录
  • 原文地址:https://www.cnblogs.com/username/p/6477722.html
Copyright © 2011-2022 走看看