• Unreal Engine 4 —— 可交互绳索的构建


    在隐龙传:影踪中的钩爪玩法中,绳索是使用UE4中的Cable Component构建的。在当初还看了一下这方面的源代码和文档,可以在Unreal Engine 4的博客专栏搜到对应信息:传送门

    UE4的这个Cable Component是与世界场景没有交互的,因此这篇博客将讲解如何基于该Cable Component来实现绳索与世界的交互。

    Verlet Integration

    在查看UCableComponent的源代码时,看到在Tick函数中有这么一段代码:

    // Perform simulation substeps
    TimeRemainder += DeltaTime;
    while(TimeRemainder > UseSubstep)
    {
        PerformSubstep(UseSubstep, Gravity);
        TimeRemainder -= UseSubstep;
    }

    PerformSubstep函数的实现如下:

    void UCableComponent::PerformSubstep(float InSubstepTime, const FVector& Gravity)
    {
        VerletIntegrate(InSubstepTime, Gravity);
        SolveConstraints();
    }

    看到VerletIntegrate函数我就笑了,因为当初专门研究过它,对应的论文如下:传送门

    Cable Particle

    在UE4的UCableComponent中,使用Cable Particle来模拟绳索,使用Verlet Integration与松弛法进行绳索粒子的模拟,然后在对应的SceneProxy中进行Mesh的构建。

    UE4中的代码如下:

    void UCableComponent::SolveConstraints()
    {
        const float SegmentLength = CableLength/(float)NumSegments;
    
        // For each iteration..
        for(int32 IterationIdx=0; IterationIdx<SolverIterations; IterationIdx++)
        {
            // For each segment..
            for(int32 SegIdx=0; SegIdx<NumSegments; SegIdx++)
            {
                FCableParticle& ParticleA = Particles[SegIdx];
                FCableParticle& ParticleB = Particles[SegIdx+1];
                // Solve for this pair of particles
                SolveDistanceConstraint(ParticleA, ParticleB, SegmentLength);
            }
        }
    }

    与球形物体的交互

    该如何实现绳索与球形物体的交互?相对来讲还是比较简单,只需要在松弛法里面加上一个检测——如果有Cable Particle陷到对应的球形里面去了,那么直接将其推到球面上即可。

    因此我们将SolveConstraints函数改为:

    void UCableComponent::SolveConstraints()
    {
        const float SegmentLength = CableLength/(float)NumSegments;
    
        // For each iteration..
        for(int32 IterationIdx=0; IterationIdx<SolverIterations; IterationIdx++)
        {
            SolveCollides();
            // For each segment..
            for(int32 SegIdx=0; SegIdx<NumSegments; SegIdx++)
            {
                FCableParticle& ParticleA = Particles[SegIdx];
                FCableParticle& ParticleB = Particles[SegIdx+1];
                // Solve for this pair of particles
                SolveDistanceConstraint(ParticleA, ParticleB, SegmentLength);
            }
        }
    }

    只添加了一个SolveCollides函数,用于约束Particle与物体的碰撞:

    void UCableComponent::SolveCollides()
    {
        for (int32 SegIdx = 0; SegIdx < NumSegments SegIdx++)
        {
            for (int SphereIdx = 0; SphereIdx < CollideSphere.Num(); SphereIdx++)
            {
                SolveSphereCollide(Particles[SegIdx + 1], CollideSphere[SphereIdx]);
            }
        }
    }
    
    
    void UCableComponent::SolveSphereCollide(FStripParticle& Particle, FComponentReference Comp)
    {
        auto Component = Comp.GetComponent(GetOwner());
    
        if (IsValid(Component))
        {
            if (Particle.bFree)
            {
                const float dist = FVector::Dist(Component->GetComponentLocation(), Particle.Position);
                auto sphere = Cast<USphereComponent>(Component);
                if (sphere && dist < (sphere->GetScaledSphereRadius()))
                {
                    auto tmp1 = Particle.Position;
                    auto tmp2 = sphere->GetComponentLocation();
                    auto tmp3 = sphere->GetScaledSphereRadius();
                    auto delta = tmp3 * ((tmp1 - tmp2).GetSafeNormal());
                    Particle.Position = Component->GetComponentLocation() + delta;
                }
            }
        }
    
    }

    这样一来就可以实现绳索与球形的碰撞交互了。

    与胶囊体的碰撞

    绳索与胶囊体的碰撞约束也很简单,只要将对应的点推到胶囊体表面即可。这里不方便将代码放出,读者可以自己实现。

    思考

    UE4中的Cable Component使用的是Verlet Integration,而Mesh在SceneProxy里面进行构建。在这里实现了与球形&胶囊体的碰撞,这样一来就可以很方便地实现布料&发丝&水面的模拟啊……

  • 相关阅读:
    套件测试
    注解实战aftersuite和beforesuite
    注解实战Beforeclass和Afterclass
    Centos7下安装Mongodb
    java的算法实现冒泡
    注解实战BeforeMethed和afterMethed
    前端 HTML的规范
    前端 HTML标签介绍
    前端 HTML文档 详解
    前端 HTML 简介
  • 原文地址:https://www.cnblogs.com/arrowinmyknee/p/5470382.html
Copyright © 2020-2023  润新知