Download

Can't assign material to a Procedural Mesh

Dear community,

Question from a newbie here. I have made my first C++ Actor and added a Procedural Mesh to it (code dropped in below). If not the right forum, feel free to move.

I cannot drag a material onto the Material Element box, it looks a little dimmed compared to how it looks for the Cube Static Mesh. When I start dragging the area lights up with green dashed border, but when dropping the material on the box, or hovering over it, it doesn’t allow me to drop it. See video in link below. Can’t assign the material. What’s going on?

I notice a fine-grained checker-board pattern on top of the “normal” checker-board pattern, that I made 10x10, but I also see a 100x100 pattern, which I don’t see on the normal Cube Static Mesh. Is that any indication?

Screen Shot 2016-12-15 at 08.13.19.png

The cube to the left is made with a Procedural Mesh.

Here’s a video showing what happens when I try assigning a material.

[video]https://youtu.be/-HeW9vdhCiY[/video]

First code section, defining corners of each cube face, normals and tangents.


// Since we need unique normals and colors for each face,
// this is how we do it, repeating the vertices
static const FVector scUnitVerts[4*6] = {
    // Front face
    FVector(-1, -1, -1),   // 0: Lower front left corner
    FVector(-1, -1,  1),   // 2: Upper front left corner
    FVector(-1,  1,  1),   // 3: Upper front right corner
    FVector(-1,  1, -1),   // 1: Lower front right corner
    // Right face
    FVector(-1,  1, -1),   // 4: Lower front right corner
    FVector(-1,  1,  1),   // 6: Upper front right corner
    FVector( 1,  1,  1),   // 7: Upper back right corner
    FVector( 1,  1, -1),   // 5: Lower back right corner
    // Back face
    FVector( 1,  1, -1),   // 8: Lower back right corner
    FVector( 1,  1,  1),   // 10: Upper back right corner
    FVector( 1, -1,  1),   // 11: Upper back left corner
    FVector( 1, -1, -1),   // 9: Lower back left corner
    // Left face
    FVector( 1, -1, -1),   // 12: Lower back left corner
    FVector( 1, -1,  1),   // 14: Upper back left corner
    FVector(-1, -1,  1),   // 15: Upper front left corner
    FVector(-1, -1, -1),   // 13: Lower front left corner
    // Top face
    FVector(-1, -1,  1),   // 16: Upper front left corner
    FVector( 1, -1,  1),   // 18: Upper back left corner
    FVector( 1,  1,  1),   // 19: Upper back right corner
    FVector(-1,  1,  1),   // 17: Upper front right corner
    // Bottom face
    FVector( 1, -1, -1),   // 20: Lower back left corner
    FVector(-1, -1, -1),   // 22: Lower front left corner
    FVector(-1,  1, -1),   // 23: Lower front right corner
    FVector( 1,  1, -1)    // 21: Lower back right corner
};

static const FVector scFaceNormals[6] = {
    FVector(-1,  0,  0),  // Front face
    FVector( 0,  1,  0),  // Right face
    FVector( 1,  0,  0),  // Back face
    FVector( 0, -1,  0),  // Left face
    FVector( 0,  0,  1),  // Top face
    FVector( 0,  0, -1)   // Bottom face
};

static const FProcMeshTangent scFaceTangents[6] = {
    FProcMeshTangent( 0,  1,  0),  // Front face
    FProcMeshTangent( 1,  0,  0),  // Right face
    FProcMeshTangent( 0, -1,  0),  // Back face
    FProcMeshTangent(-1,  0,  0),  // Left face
    FProcMeshTangent( 0,  1,  0),  // Top face
    FProcMeshTangent( 0,  1,  0)   // Bottom face
};


Constructor code section


AMyDVRActor::AMyDVRActor()
{
    PrimaryActorTick.bCanEverTick = true;

    USphereComponent * SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
    RootComponent = SphereComponent;
    
    UProceduralMeshComponent * mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("BoundingBoxMesh"));

    BuildBoundingBox(mesh, 0);
    
    (void)mesh->SetupAttachment(RootComponent);
}


Actual code creating the mesh


void BuildBoundingBox(UProceduralMeshComponent * mesh, int meshSection)
{
    // These should become input parameters in BP
    FVector volSize(100.0, 100.0, 100.0);
    FVector volOffset(0.0, 0.0, 0.0);

    TArray<FVector> vertices;
    TArray<int32> triangles;
    TArray<FVector> normals;
    TArray<FVector2D> uv;
    TArray<FColor> colors;
    TArray<FProcMeshTangent> tangents;
    
    FVector halfSize = 0.5 * volSize;
    FVector grey(0.5, 0.5, 0.5);

    for (int face = 0; face < 6; face++)
    {
        const int idx = 4*face;

        vertices.Add(scUnitVerts[idx + 0] * halfSize + volOffset);
        vertices.Add(scUnitVerts[idx + 1] * halfSize + volOffset);
        vertices.Add(scUnitVerts[idx + 2] * halfSize + volOffset);
        vertices.Add(scUnitVerts[idx + 3] * halfSize + volOffset);

        const FVector & faceNormal(scFaceNormals[face]);
        const FProcMeshTangent & faceTangent(scFaceTangents[face]);

        normals.Add(faceNormal);
        normals.Add(faceNormal);
        normals.Add(faceNormal);
        normals.Add(faceNormal);
        uv.Add(FVector2D(0, 0));
        uv.Add(FVector2D(0, 10));
        uv.Add(FVector2D(10, 10));
        uv.Add(FVector2D(10, 0));

        FColor faceColor(faceNormal[0] * 128 + 127,
                         faceNormal[1] * 128 + 127,
                         faceNormal[2] * 128 + 127);

        colors.Add(faceColor);
        colors.Add(faceColor);
        colors.Add(faceColor);
        colors.Add(faceColor);
        tangents.Add(faceTangent);
        tangents.Add(faceTangent);
        tangents.Add(faceTangent);
        tangents.Add(faceTangent);
        // Configure the face with triangles.
        triangles.Add(idx + 0);
        triangles.Add(idx + 3);
        triangles.Add(idx + 2);
        triangles.Add(idx + 2);
        triangles.Add(idx + 1);
        triangles.Add(idx + 0);
    }
    
    mesh->CreateMeshSection(meshSection, vertices, triangles, normals, uv,
                            colors, tangents, false);
}


Thankful for any comment or idea that could help. Seems I am missing something.

cheers / Patric