FBX SDK Programmer's Guide > Meshes, Materials and Textures >

# Meshes

Creating a Mesh

Meshes in the FBX SDK are abstracted by the FbxMesh class. A mesh is defined by a set of vertices, or "control points", and by a group of layers to define the mesh's normals, textures, and materials. The following code sample illustrates how to instantiate a FbxMesh.

    // Create a node for our mesh in the scene.
    FbxNode* lMeshNode = FbxNode::Create(pScene, "meshNode");

    // Create a mesh.
    FbxMesh* lMesh = FbxMesh::Create(pScene, "mesh");

    // Set the node attribute of the mesh node.
    lMeshNode->SetNodeAttribute(lMesh);

    // Add the mesh node to the root node in the scene.
    FbxNode *lRootNode = pScene->GetRootNode();
    lRootNode->AddChild(lMeshNode);

Defining Control Points

The vertices of a FbxMesh are known as control points. Since objects in the FBX SDK are created by default in the right handed, Y-Up axis system, the vertices of a mesh should be defined accordingly. An instance of FbxMesh contains an array of control points which can be initiated to a specific size. For example, a cube's mesh requires 24 control points: there are 4 control points per face, and a cube has 6 faces. The following code sample initializes the array of control points for a 100x100x100 cube.

    // Define the eight corners of the cube.
    // The cube spans from
    //    -50 to  50 along the X axis
    //      0 to 100 along the Y axis
    //    -50 to  50 along the Z axis
    FbxVector4 lControlPoint0(-50, 0, 50);
    FbxVector4 lControlPoint1(50, 0, 50);
    FbxVector4 lControlPoint2(50, 100, 50);
    FbxVector4 lControlPoint3(-50, 100, 50);
    FbxVector4 lControlPoint4(-50, 0, -50);
    FbxVector4 lControlPoint5(50, 0, -50);
    FbxVector4 lControlPoint6(50, 100, -50);
    FbxVector4 lControlPoint7(-50, 100, -50);

    // Initialize the control point array of the mesh.
    lMesh->InitControlPoints(24);
    FbxVector4* lControlPoints = lMesh->GetControlPoints();

    // Define each face of the cube.
    // Face 1
    lControlPoints[0] = lControlPoint0;
    lControlPoints[1] = lControlPoint1;
    lControlPoints[2] = lControlPoint2;
    lControlPoints[3] = lControlPoint3;
    // Face 2
    lControlPoints[4] = lControlPoint1;
    lControlPoints[5] = lControlPoint5;
    lControlPoints[6] = lControlPoint6;
    lControlPoints[7] = lControlPoint2;
    // Face 3
    lControlPoints[8] = lControlPoint5;
    lControlPoints[9] = lControlPoint4;
    lControlPoints[10] = lControlPoint7;
    lControlPoints[11] = lControlPoint6;
    // Face 4
    lControlPoints[12] = lControlPoint4;
    lControlPoints[13] = lControlPoint0;
    lControlPoints[14] = lControlPoint3;
    lControlPoints[15] = lControlPoint7;
    // Face 5
    lControlPoints[16] = lControlPoint3;
    lControlPoints[17] = lControlPoint2;
    lControlPoints[18] = lControlPoint6;
    lControlPoints[19] = lControlPoint7;
    // Face 6
    lControlPoints[20] = lControlPoint1;
    lControlPoints[21] = lControlPoint0;
    lControlPoints[22] = lControlPoint4;
    lControlPoints[23] = lControlPoint5;

For more information on control point management, consult the FbxGeometry class documentation. FbxGeometry is the parent class of FbxMesh, FbxLine, FbxNurb and other classes used to define scene geometry.

NoteNote that a scene axis conversion does not affect the vertex values of a mesh. For more information, see Scene Axis and Unit Conversion.

Assigning Normals

The normal vectors of a mesh are defined in an instance of FbxLayerElementNormal. Layer elements such as normals can be mapped to the surface of a mesh in a variety of ways, such as by control point (FbxLayerElement::eBY_CONTROL_POINT), by polygon vertex (FbxLayerElement::eBY_POLYGON_VERTEX), by polygon (FbxLayerElement::eBY_POLYGON), by edge (FbxLayerElement::eBY_EDGE), or one mapping coordinate for the whole surface (FbxLayerElement::eALL_SAME). For more information, see FbxLayerElement::EMappingMode.

Given an array of normal vectors and an array of control points, we can specify how the array of normal vectors is referenced by the array of control points. This is defined by the FbxLayerElement::EReferenceMode assigned in FbxLayerElement::SetReferenceMode(). The EReferenceMode::eDIRECT mode maps the n'th element in the normal vector array to the n'th element in the control point array.

Reference Mode (FbxLayerElement::EReferenceMode) | Description
--- | ---
FbxLayerElement::eDIRECT | This indicates that the mapping information for the n'th element is found in the n'th place of FbxLayerElementTemplate::mDirectArray.
FbxLayerElement::eINDEX | This symbol is kept for backward compatibility with FBX v5.0 files. In FBX v6.0 and higher, this symbol is replaced with FbxLayerElement::eINDEX_TO_DIRECT.
FbxLayerElement::eINDEX_TO_DIRECT | This indicates that each element of FbxLayerElementTemplate::mIndexArray contains an index referring to an element in FbxLayerElementTemplate::mDirectArray.

In the following code sample, we will examine how to apply a per-control point mapping (FbxLayerElement::eBY_CONTROL_POINT) of normals onto a mesh using a EReferenceMode::eDIRECT reference mode. Observe that the order in which FbxLayerElementArrayTemplate::Add() is invoked corresponds to the order of the control points which have been defined above.

    // Define normal vectors along each axis.
    FbxVector4 lNormalXPos( 1,  0,  0);
    FbxVector4 lNormalXNeg(-1,  0,  0);
    FbxVector4 lNormalYPos( 0,  1,  0);
    FbxVector4 lNormalYNeg( 0, -1,  0);
    FbxVector4 lNormalZPos( 0,  0,  1);
    FbxVector4 lNormalZNeg( 0,  0, -1);

    // Create layer 0 for the mesh if it does not already exist.
    // This is where we will define our normals.
    FbxLayer lLayer = lMesh->GetLayer(0);
    if(lLayer == NULL) {
        lMesh->CreateLayer();
        lLayer = lMesh->GetLayer(0);
    }

    // Create a normal layer.
    FbxLayerElementNormal* lLayerElementNormal= FbxLayerElementNormal::Create(lMesh, "");

    // Set its mapping mode to map each normal vector to each control point.
    lLayerElementNormal->SetMappingMode(FbxLayerElement::eBY_CONTROL_POINT);

    // Set the reference mode of so that the n'th element of the normal array maps to the n'th
    // element of the control point array.
    lLayerElementNormal->SetReferenceMode(FbxLayerElement::eDIRECT);

    // Assign the normal vectors in the same order the control points were defined for the mesh.
    // Face 1
    lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
    // Face 2
    lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
    // Face 3
    lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
    // Face 4
    lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
    // Face 5
    lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
    lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
    // Face 6
    lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
    lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);

    // Finally, we set layer 0 of the mesh to the normal layer element.
    lLayer->SetNormals(lLayerElementNormal);

#### Topics in this section

- Instancing - Sharing a Mesh