美文网首页
UE4 CableMesh

UE4 CableMesh

作者: wblong | 来源:发表于2021-03-30 21:32 被阅读0次

    UE4 CableMesh

    UE4 CableComponent 生成绳索效果的Mesh。

    绳索网格

    基本思路

    给定起始点内插一系列点,然后物理模拟调整点的位置,最后在点周围生成一系列三角网。

    生成三角网的代码如下:

    /** The vertex type used for dynamic meshes. */
    struct FDynamicMeshVertex
    {
        FDynamicMeshVertex() {}
        FDynamicMeshVertex( const FVector& InPosition ):
            Position(InPosition),
            TangentX(FVector(1,0,0)),
            TangentZ(FVector(0,0,1)),
            Color(FColor(255,255,255)) 
        {
            //..............................
        }
    
        FDynamicMeshVertex(const FVector& InPosition, const FVector2D& InTexCoord, const FColor& InColor) :
            Position(InPosition),
            TangentX(FVector(1, 0, 0)),
            TangentZ(FVector(0, 0, 1)),
            Color(InColor)
        {
            //...................................
        }
    
        FDynamicMeshVertex(const FVector& InPosition,const FVector& InTangentX,const FVector& InTangentZ,const FVector2D& InTexCoord, const FColor& InColor):
            Position(InPosition),
            TangentX(InTangentX),
            TangentZ(InTangentZ),
            Color(InColor)
        {
            //.......................
        }
    
        FDynamicMeshVertex(const FVector& InPosition, const FVector& LayerTexcoords, const FVector2D& WeightmapTexcoords)
            : Position(InPosition)
            , TangentX(FVector(1, 0, 0))
            , TangentZ(FVector(0, 0, 1))
            , Color(FColor::White)
        {
            //...............
        }
       //顶点位置
        FVector Position;
       //纹理坐标
        FVector2D TextureCoordinate[MAX_STATIC_TEXCOORDS];
       //切线
        FPackedNormal TangentX;
       //法线
        FPackedNormal TangentZ;
        FColor Color;
    };
    
    void BuildCableMesh(const TArray<FVector>& InPoints, TArray<FDynamicMeshVertex>& OutVertices, TArray<int32>& OutIndices)
        {
            const FColor VertexColor(255,255,255);
            const int32 NumPoints = InPoints.Num();
            const int32 SegmentCount = NumPoints-1;
    
            // Build vertices
    
            // We double up the first and last vert of the ring, because the UVs are different
            int32 NumRingVerts = NumSides+1;
    
            // For each point along spline..
            for(int32 PointIdx=0; PointIdx<NumPoints; PointIdx++)
            {
                const float AlongFrac = (float)PointIdx/(float)SegmentCount; // Distance along cable
    
                // Find direction of cable at this point, by averaging previous and next points
                const int32 PrevIndex = FMath::Max(0, PointIdx-1);
                const int32 NextIndex = FMath::Min(PointIdx+1, NumPoints-1);
                const FVector ForwardDir = (InPoints[NextIndex] - InPoints[PrevIndex]).GetSafeNormal();
    
                // Find quat from up (Z) vector to forward
                const FQuat DeltaQuat = FQuat::FindBetween(FVector(0, 0, -1), ForwardDir);
    
                // Apply quat orth vectors
                const FVector RightDir = DeltaQuat.RotateVector(FVector(0, 1, 0));
                const FVector UpDir = DeltaQuat.RotateVector(FVector(1, 0, 0));
    
                // Generate a ring of verts
                for(int32 VertIdx = 0; VertIdx<NumRingVerts; VertIdx++)
                {
                    const float AroundFrac = float(VertIdx)/float(NumSides);
                    // Find angle around the ring
                    const float RadAngle = 2.f * PI * AroundFrac;
                    // Find direction from center of cable to this vertex
                    const FVector OutDir = (FMath::Cos(RadAngle) * UpDir) + (FMath::Sin(RadAngle) * RightDir);
    
                    FDynamicMeshVertex Vert;
                    Vert.Position = InPoints[PointIdx] + (OutDir * 0.5f * CableWidth);
                    Vert.TextureCoordinate[0] = FVector2D(AlongFrac * TileMaterial, AroundFrac);
                    Vert.Color = VertexColor;
                    Vert.SetTangents(ForwardDir, OutDir ^ ForwardDir, OutDir);
                    OutVertices.Add(Vert);
                }
            }
    
            // Build triangles
            for(int32 SegIdx=0; SegIdx<SegmentCount; SegIdx++)
            {
                for(int32 SideIdx=0; SideIdx<NumSides; SideIdx++)
                {
                    int32 TL = GetVertIndex(SegIdx, SideIdx);
                    int32 BL = GetVertIndex(SegIdx, SideIdx+1);
                    int32 TR = GetVertIndex(SegIdx+1, SideIdx);
                    int32 BR = GetVertIndex(SegIdx+1, SideIdx+1);
    
                    OutIndices.Add(TL);
                    OutIndices.Add(BL);
                    OutIndices.Add(TR);
    
                    OutIndices.Add(TR);
                    OutIndices.Add(BL);
                    OutIndices.Add(BR);
                }
            }
        }
    

    参考链接

    UE4 CableMesh

    相关文章

      网友评论

          本文标题:UE4 CableMesh

          本文链接:https://www.haomeiwen.com/subject/rccnhltx.html