Kanzi  3.9.6
Kanzi Engine API
kanzi::Mesh::CreateInfo Struct Reference

Use Mesh::CreateInfo to describe and create meshes. More...

#include <kanzi/core.ui/graphics3d/mesh_create_info.hpp>

Classes

struct  Cluster
 Parameters for Mesh::Cluster creation. More...
 

Public Types

typedef vector< PropertyEntryPropertyContainer
 
typedef pair< AbstractPropertyType, VariantPropertyEntry
 

Public Member Functions

 CreateInfo ()
 Default constructor for mesh create info. More...
 

Public Attributes

Box boundingBox
 The bounding box for the mesh in the local coordinates of the mesh. More...
 
vector< Mesh::CreateInfo::Clusterclusters
 Clusters. More...
 
GPUBuffer::NativeHandle instanceBufferHandle
 Native handle to the instance buffer. More...
 
size_t instanceCount
 Number of instances in the mesh. More...
 
vector< byteinstanceData
 Instance buffer data. More...
 
size_t instanceSize
 Size of one instance data in bytes. More...
 
MemoryType memoryType
 Memory type for the texture. More...
 
PropertyContainer properties
 Properties to copy to the mesh. More...
 
Skeleton skeleton
 Mesh skeleton for bone animations. More...
 
bool takeOwnership
 Indicates whether Kanzi destroys the native handles with the Mesh. More...
 
bool uploadDataAtCreation
 Indicates whether to upload vertex and index data when creating the buffer. More...
 
GPUBuffer::NativeHandle vertexBufferHandle
 Native handle to the vertex buffer. More...
 
size_t vertexCount
 Number of vertices in the mesh. More...
 
vector< bytevertexData
 Vertex buffer data. More...
 
MeshAttributeCollection vertexFormat
 Mesh vertex attributes. More...
 
size_t vertexSize
 Size of one vertex in bytes. This is the sum of the sizes of all mesh vertex attributes. More...
 

Detailed Description

Use Mesh::CreateInfo to describe and create meshes.

Vertex and index listings define meshes. Indices refer to vertices which define the faces of a mesh.

To define a mesh, you need:

  • Vertex format definition. This definition describes the components that define a vertex. This includes information about the vertex position, texture coordinates, normal, and tangent.
  • List of vertices. Each vertex contains components that the format definition describes.
  • List of indices. Indices describe polygons by referring to each vertex by index. When triangles describe a polygon, three indices describe a triangle. You can use several index listings, each of which uses a material.

To enable the Kanzi Studio Preview to visualize the bounding volume of a mesh, set the bounding box for that mesh.

Examples

To create a cube mesh:

// Define a CreateInfo structure and set it to keep the data after uploading it to the GPU.
Mesh::CreateInfo createInfo;
createInfo.memoryType = GPUResource::GpuAndRam;
// Describe the format for each vertex. In this example, every vertex has a position in 3D space,
// texture coordinates pointing to 2D texture space, and normal and tangent data in 3D space.
// Add a three-component position to the vertex format description.
// Use the standard Kanzi name kzPosition.
MeshVertexAttribute position("kzPosition", VertexAttribute::SemanticPosition, 0, GraphicsDataTypeSFLOAT32, 3, ~0u);
createInfo.vertexFormat.push_back(position);
// Add a two-component texture coordinate to the vertex format description.
// Texture coordinates enable you to use textures on a mesh.
// Use the standard Kanzi name kzTextureCoordinate0.
MeshVertexAttribute textureCoordinate("kzTextureCoordinate0", VertexAttribute::SemanticTextureCoordinate, 0, GraphicsDataTypeSFLOAT32, 2, ~0u);
createInfo.vertexFormat.push_back(textureCoordinate);
// Add three-component normals to the vertex format description.
// Normals enable you to use lighting on a mesh.
// Use the standard Kanzi name kzNormal.
MeshVertexAttribute normal("kzNormal", VertexAttribute::SemanticNormal, 0, GraphicsDataTypeSFLOAT32, 3, ~0u);
createInfo.vertexFormat.push_back(normal);
// Add three-component tangents to the vertex format description.
// Tangents enable you to use normal maps on a mesh.
// Use the standard Kanzi name kzTangent.
MeshVertexAttribute tangent("kzTangent", VertexAttribute::SemanticTangent, 0, GraphicsDataTypeSFLOAT32, 3, ~0u);
createInfo.vertexFormat.push_back(tangent);
// Now that you added all components to the vertex format description, update the offsets, strides, and vertex size.
// Create a cluster. Two triangles define a face. Since a cube has six faces, you must create 36 indices
// (2 * 3 * 6 = 36). In this example, the entire mesh uses a single material, which is why you need only
// one cluster.
Mesh::CreateInfo::Cluster cluster(GraphicsPrimitiveTypeTriangles, 36, IndexBufferTypeUInt16, material, materialUrl);
createInfo.clusters.push_back(cluster);
// Create the vertices. Four vertices define one face of a cube. Since a cube has six faces, you must
// create 24 vertices (4 * 6 = 24). Here you create vertex faces with normals that point to the same
// direction. This makes the faces of a cube appear flat. You cannot reuse vertex positions because the
// normals for each face are separate.
{
createInfo.vertexCount = 24;
size_t dataSize = createInfo.vertexCount * createInfo.vertexSize;
createInfo.vertexData.resize(dataSize);
// Define the positions of the cube corners.
// This example first defines the back face, then the front face.
const Vector3 cornerPositions[] =
{
Vector3(1.0f, 1.0f, 1.0f),
Vector3(-1.0f, 1.0f, 1.0f),
Vector3(-1.0f, -1.0f, 1.0f),
Vector3(1.0f, -1.0f, 1.0f),
Vector3(1.0f, -1.0f, -1.0f),
Vector3(1.0f, 1.0f, -1.0f),
Vector3(-1.0f, 1.0f, -1.0f),
Vector3(-1.0f, -1.0f, -1.0f)
};
// Define vertex indices for all faces.
const Vector2 UVs[] =
{
Vector2(1.0f, 1.0f),
Vector2(0.0f, 1.0f),
Vector2(0.0f, 0.0f),
Vector2(1.0f, 0.0f)
};
// Define vertex indices for all faces.
const unsigned int faceIndices[][4] =
{
// Front.
{ 0, 1, 2, 3 },
// Right.
{ 5, 0, 3, 4 },
// Back.
{ 6, 5, 4, 7 },
// Left.
{ 1, 6, 7, 2 },
// Top.
{ 5, 6, 1, 0 },
// Bottom.
{ 3, 2, 7, 4 }
};
// Define the normals for each face.
const Vector3 faceNormals[] =
{
Vector3(0.0f, 0.0f, 1.0f),
Vector3(1.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, -1.0f),
Vector3(-1.0f, 0.0f, 0.0f),
Vector3(0.0f, 1.0f, 0.0f),
Vector3(0.0f, -1.0f, 0.0f)
};
// Define tangents for each face.
const Vector3 faceTangent[] =
{
Vector3(1.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, -1.0f),
Vector3(-1.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 1.0f),
Vector3(1.0f, 0.0f, 0.0f),
Vector3(1.0f, 0.0f, 0.0f)
};
uint16_t vertexIndex = 0;
// To generate the vertex data, loop the data arrays that you defined above.
for (unsigned int face = 0; face < 6; ++face)
{
// Add two triangles.
uint16_t* indexData = reinterpret_cast<uint16_t*>(&createInfo.clusters[0].indexData[0]);
unsigned int faceBaseIndex = face * 6;
// The first three vertices of a face define the first triangle...
indexData[faceBaseIndex + 0] = vertexIndex + 0;
indexData[faceBaseIndex + 1] = vertexIndex + 1;
indexData[faceBaseIndex + 2] = vertexIndex + 2;
// ...and the second triangle uses the two last vertices of the face with the first vertex.
// These two triangles create a quad.
indexData[faceBaseIndex + 3] = vertexIndex + 2;
indexData[faceBaseIndex + 4] = vertexIndex + 3;
indexData[faceBaseIndex + 5] = vertexIndex + 0;
// Write vertices for the face.
for (unsigned int faceCorner = 0; faceCorner < 4; ++faceCorner, ++vertexIndex)
{
unsigned int boxCorner = faceIndices[face][faceCorner];
// Write the correct vertex for this corner of each face.
writeVertexAttribute(createInfo, vertexIndex, 0, cornerPositions[boxCorner]);
// UVs for each face are the same.
writeVertexAttribute(createInfo, vertexIndex, 1, UVs[faceCorner]);
// Normal is constant throughout the face.
writeVertexAttribute(createInfo, vertexIndex, 2, faceNormals[face]);
// Tangent is constant throughout the face.
writeVertexAttribute(createInfo, vertexIndex, 3, faceTangent[face]);
}
}
}
// Create a Box and set it as the bounding volume of the mesh.
// Position the box in the center of the mesh. Set the dimensions of the box along each axis
// to 2.0f, that is, from point (-1, -1, -1) to point (1, 1, 1) in the local coordinate space
// of the mesh.
createInfo.boundingBox = Box::fromCenterAndSize(Vector3(0.0f, 0.0f, 0.0f), Vector3(2.0f, 2.0f, 2.0f));
// Create a mesh from the data that you defined in the CreateInfo.
MeshSharedPtr mesh = Mesh::create(domain, createInfo, "box");

To create a mesh from native handles:

// Define a CreateInfo structure.
Mesh::CreateInfo createInfo;
// Create native handles for vertex and index buffers.
// Use buffer 0 for vertices and 1 for indices.
GPUBuffer::NativeHandle bufferHandles[2];
kzsGlGenBuffers(2, bufferHandles);
kzsGlBindBuffer(KZS_GL_ARRAY_BUFFER, bufferHandles[0]);
kzsGlBindBuffer(KZS_GL_ELEMENT_ARRAY_BUFFER, bufferHandles[1]);
createInfo.vertexBufferHandle = bufferHandles[0];
// Let the Mesh manage the handles from now on.
createInfo.takeOwnership = true;
// Describe the format for each vertex. In this example, every vertex has a position in 3D space,
// texture coordinates pointing to 2D texture space, and normal and tangent data in 3D space.
// Add a three-component position to the vertex format description.
// Use the standard Kanzi name kzPosition.
MeshVertexAttribute position("kzPosition", VertexAttribute::SemanticPosition, 0, GraphicsDataTypeSFLOAT32, 3, ~0u);
createInfo.vertexFormat.push_back(position);
// Add a two-component texture coordinate to the vertex format description.
// Texture coordinates enable you to use textures on a mesh.
// Use the standard Kanzi name kzTextureCoordinate0.
MeshVertexAttribute textureCoordinate("kzTextureCoordinate0", VertexAttribute::SemanticTextureCoordinate, 0, GraphicsDataTypeSFLOAT32, 2, ~0u);
createInfo.vertexFormat.push_back(textureCoordinate);
// Add three-component normals to the vertex format description.
// Normals enable you to use lighting on a mesh.
// Use the standard Kanzi name kzNormal.
MeshVertexAttribute normal("kzNormal", VertexAttribute::SemanticNormal, 0, GraphicsDataTypeSFLOAT32, 3, ~0u);
createInfo.vertexFormat.push_back(normal);
// Add three-component tangents to the vertex format description.
// Tangents enable you to use normal maps on a mesh.
// Use the standard Kanzi name kzTangent.
MeshVertexAttribute tangent("kzTangent", VertexAttribute::SemanticTangent, 0, GraphicsDataTypeSFLOAT32, 3, ~0u);
createInfo.vertexFormat.push_back(tangent);
// Now that you added all components to the vertex format description, update the offsets, strides, and vertex size.
// Create a cluster. Two triangles define a face. Since a cube has six faces, you must create 36 indices
// (2 * 3 * 6 = 36). In this example, the entire mesh uses a single material, which is why you need only
// one cluster.
Mesh::CreateInfo::Cluster cluster(GraphicsPrimitiveTypeTriangles, 36, IndexBufferTypeUInt16, bufferHandles[1], material, materialUrl);
createInfo.clusters.push_back(cluster);
// Create the vertices. Four vertices define one face of a cube. Since cube has six faces, you must
// create 24 vertices (4 * 6 = 24). Here you create vertex faces with normals that point to the same
// direction. This makes the faces of a cube appear flat. You cannot reuse vertex positions because the
// normals for each face are separate.
{
createInfo.vertexCount = 24;
size_t dataSize = createInfo.vertexCount * createInfo.vertexSize;
// Define the positions of the cube corners.
// This example first defines the back face, then the front face.
const Vector3 cornerPositions[] = {
Vector3(1.0f, 1.0f, 1.0f),
Vector3(-1.0f, 1.0f, 1.0f),
Vector3(-1.0f, -1.0f, 1.0f),
Vector3(1.0f, -1.0f, 1.0f),
Vector3(1.0f, -1.0f, -1.0f),
Vector3(1.0f, 1.0f, -1.0f),
Vector3(-1.0f, 1.0f, -1.0f),
Vector3(-1.0f, -1.0f, -1.0f)
};
// Define vertex indices for all faces.
const Vector2 UVs[] = {
Vector2(1.0f, 1.0f),
Vector2(0.0f, 1.0f),
Vector2(0.0f, 0.0f),
Vector2(1.0f, 0.0f)
};
// Define vertex indices for all faces.
const unsigned int faceIndices[][4] = {
// Front.
{ 0, 1, 2, 3 },
// Right.
{ 5, 0, 3, 4 },
// Back.
{ 6, 5, 4, 7 },
// Left.
{ 1, 6, 7, 2 },
// Top.
{ 5, 6, 1, 0 },
// Bottom.
{ 3, 2, 7, 4 }
};
// Define the normals for each face.
const Vector3 faceNormals[] = {
Vector3(0.0f, 0.0f, 1.0f),
Vector3(1.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, -1.0f),
Vector3(-1.0f, 0.0f, 0.0f),
Vector3(0.0f, 1.0f, 0.0f),
Vector3(0.0f, -1.0f, 0.0f)
};
// Define tangents for each face.
const Vector3 faceTangent[] = {
Vector3(1.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, -1.0f),
Vector3(-1.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 1.0f),
Vector3(1.0f, 0.0f, 0.0f),
Vector3(1.0f, 0.0f, 0.0f)
};
uint16_t vertexIndex = 0;
vector<uint16_t> indexBuffer;
indexBuffer.resize(createInfo.clusters[0].indexCount);
vector<uint8_t> vertexBuffer;
vertexBuffer.resize(dataSize);
uint8_t* vertexPtr = vertexBuffer.data();
// To generate the vertex data, loop the data arrays that you defined above.
for (unsigned int face = 0; face < 6; ++face)
{
// Add two triangles.
uint16_t* indexData = indexBuffer.data();
unsigned int faceBaseIndex = face * 6;
// The first three vertices of a face define the first triangle...
indexData[faceBaseIndex + 0] = vertexIndex + 0;
indexData[faceBaseIndex + 1] = vertexIndex + 1;
indexData[faceBaseIndex + 2] = vertexIndex + 2;
// ...and the second triangle uses the two last vertices of the face with the first vertex.
// These two triangles create a quad.
indexData[faceBaseIndex + 3] = vertexIndex + 2;
indexData[faceBaseIndex + 4] = vertexIndex + 3;
indexData[faceBaseIndex + 5] = vertexIndex + 0;
// Write vertices for the face.
for (unsigned int faceCorner = 0; faceCorner < 4; ++faceCorner, ++vertexIndex)
{
unsigned int boxCorner = faceIndices[face][faceCorner];
// Write the correct vertex for this corner of each face.
float* floatPtr = reinterpret_cast<float*>(vertexPtr);
*floatPtr++ = cornerPositions[boxCorner].getX();
*floatPtr++ = cornerPositions[boxCorner].getY();
*floatPtr++ = cornerPositions[boxCorner].getZ();
// UVs for each face are the same.
*floatPtr++ = UVs[faceCorner].getX();
*floatPtr++ = UVs[faceCorner].getY();
// Normal is constant throughout the face.
*floatPtr++ = faceNormals[face].getX();
*floatPtr++ = faceNormals[face].getY();
*floatPtr++ = faceNormals[face].getZ();
// Tangent is constant throughout the face.
*floatPtr++ = faceTangent[face].getX();
*floatPtr++ = faceTangent[face].getY();
*floatPtr++ = faceTangent[face].getZ();
vertexPtr += createInfo.vertexSize;
}
}
kzsGlBufferData(KZS_GL_ARRAY_BUFFER, static_cast<int>(vertexBuffer.size()), vertexBuffer.data(), KZS_GL_STATIC_DRAW);
kzsGlBufferData(KZS_GL_ELEMENT_ARRAY_BUFFER, static_cast<int>(indexBuffer.size() * sizeof(uint16_t)), indexBuffer.data(), KZS_GL_STATIC_DRAW);
}
// Create a Box and set it as the bounding volume of the mesh.
// Position the box in the center of the mesh. Set the dimensions of the box along each axis
// to 2.0f, that is, from point (-1, -1, -1) to point (1, 1, 1) in the local coordinate space
// of the mesh.
createInfo.boundingBox = Box::fromCenterAndSize(Vector3(0.0f, 0.0f, 0.0f), Vector3(2.0f, 2.0f, 2.0f));
// Create a mesh from the data that you defined in the CreateInfo.
MeshSharedPtr mesh = Mesh::create(domain, createInfo, "box");
See also
Mesh

Member Typedef Documentation

◆ PropertyEntry

◆ PropertyContainer

Constructor & Destructor Documentation

◆ CreateInfo()

kanzi::Mesh::CreateInfo::CreateInfo ( )
explicit

Default constructor for mesh create info.

Member Data Documentation

◆ memoryType

MemoryType kanzi::Mesh::CreateInfo::memoryType

Memory type for the texture.

If Gpu is not included, texture will not be deployed when created. If Ram is not included, texture will not contain images after it has been deployed. Default value is GpuOnly.

See also
MemoryType

◆ clusters

vector<Mesh::CreateInfo::Cluster> kanzi::Mesh::CreateInfo::clusters

Clusters.

◆ boundingBox

Box kanzi::Mesh::CreateInfo::boundingBox

The bounding box for the mesh in the local coordinates of the mesh.

When you do not set the size of a node with the Node::WidthProperty, Node::HeightProperty, and Node::DepthProperty properties, layout control nodes use the bounding box to determine the size of the node.

The Kanzi Studio Preview uses the bounding box to visualize the bounding volume of the mesh.

◆ skeleton

Skeleton kanzi::Mesh::CreateInfo::skeleton

Mesh skeleton for bone animations.

◆ vertexFormat

MeshAttributeCollection kanzi::Mesh::CreateInfo::vertexFormat

Mesh vertex attributes.

◆ vertexSize

size_t kanzi::Mesh::CreateInfo::vertexSize

Size of one vertex in bytes. This is the sum of the sizes of all mesh vertex attributes.

◆ vertexCount

size_t kanzi::Mesh::CreateInfo::vertexCount

Number of vertices in the mesh.

◆ vertexData

vector<byte> kanzi::Mesh::CreateInfo::vertexData

Vertex buffer data.

◆ vertexBufferHandle

GPUBuffer::NativeHandle kanzi::Mesh::CreateInfo::vertexBufferHandle

Native handle to the vertex buffer.

Since
Kanzi 3.9.6

◆ instanceSize

size_t kanzi::Mesh::CreateInfo::instanceSize

Size of one instance data in bytes.

This is the sum of the sizes of all mesh instance attributes.

Since
Kanzi 3.9.6

◆ instanceCount

size_t kanzi::Mesh::CreateInfo::instanceCount

Number of instances in the mesh.

Since
Kanzi 3.9.6

◆ instanceData

vector<byte> kanzi::Mesh::CreateInfo::instanceData

Instance buffer data.

Since
Kanzi 3.9.6

◆ instanceBufferHandle

GPUBuffer::NativeHandle kanzi::Mesh::CreateInfo::instanceBufferHandle

Native handle to the instance buffer.

Since
Kanzi 3.9.6

◆ takeOwnership

bool kanzi::Mesh::CreateInfo::takeOwnership

Indicates whether Kanzi destroys the native handles with the Mesh.

If set to false, you must manage the lifecycle of the native handles.

Since
Kanzi 3.9.6

◆ uploadDataAtCreation

bool kanzi::Mesh::CreateInfo::uploadDataAtCreation

Indicates whether to upload vertex and index data when creating the buffer.

◆ properties

PropertyContainer kanzi::Mesh::CreateInfo::properties

Properties to copy to the mesh.

Currently they are not used.


The documentation for this struct was generated from the following file: