UE4 CableMesh

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容