Kanzi Engine APIを使用してメッシュを作成する¶
Mesh は、Model3D ノードをレンダリングするためのジオメトリデータを格納します。メッシュは1つ以上のクラスターを持ちます。各クラスターはマテリアルとプリミティブを持ちます。プリミティブは通常、頂点データとインデックスデータとして格納される三角形です。
メッシュリソースをkzbファイルからロードするか、Mesh::create 関数を使用してメッシュを作成できます。コンストラクタで Mesh を作成した後、Kanzi はすべてのプリミティブデータを Mesh のCPUメモリに保存する代わりにGPUメモリにアップロードします。
メッシュを定義するには、以下が必要です:
頂点フォーマット定義。
この定義は、頂点を定義するコンポーネントについて説明しています。これには、頂点の位置、テクスチャ座標、法線、および接線に関する情報が含まれます。
頂点のリスト。
各頂点には、フォーマット定義が記述するコンポーネントが含まれています。
インデックスのリスト。
インデックスは、各頂点をインデックスで参照することによってポリゴンを記述します。三角形がポリゴンを記述する場合、3つのインデックスが三角形を記述します。複数のインデックスリストを使用することができ、それぞれがマテリアルを使用します。
Kanzi Studio Preview がメッシュのバウンディングボリュームを視覚化できるようにするには、そのメッシュのバウンディングボックスを設定します。プレビューでアプリケーションを分析する を参照してください。
メッシュを作成する¶
Kanzi Engine APIを使用してキューブメッシュを作成するには:
// Define a CreateInfo structure and set it to not keep the data after uploading it to the GPU.
Mesh::CreateInfo createInfo;
createInfo.memoryType = GPUResource::GpuOnly;
// 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.
updateVertexAttributeOffsetsAndVertexSize(createInfo);
updateVertexAttributeStrides(createInfo);
// 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 texture UV coordinates 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 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");
ネイティブハンドルからメッシュを作成する¶
Kanzi Engine APIを使用して、既存のOpenGLバッファハンドルからメッシュを作成し、既存のメッシュからそれらのハンドルをクエリすることができます。
Kanzi Engine APIを使用してネイティブハンドルからキューブメッシュを作成するには:
// 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.
updateVertexAttributeOffsetsAndVertexSize(createInfo);
updateVertexAttributeStrides(createInfo);
// 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 texture UV coordinates 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 normals for all faces.
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 all faces.
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");
詳細については、Mesh クラスを参照してください。
インスタンシングを使用したメッシュの作成¶
同じメッシュの多数のコピーをレンダリングする場合、各コピーに対してドローコールを行うとGPU時間を消費し、アプリケーションのパフォーマンスが低下します。インスタンシングを使用すると、位置、サイズ、色などの異なる属性を持つメッシュの複数のコピーを単一のレンダーコールで描画することが可能になります。
この例では、キューブメッシュの4つのインスタンスを異なる場所で異なる色でレンダリングします。
Kanzi Engine APIを使用してインスタンシングを伴うキューブメッシュを作成するには、
// Create a custom shader to use instanced attributes.
const char* vertexSource =
"#version 100\n"
"attribute vec3 kzPosition;\n"
"attribute vec3 InstancePosition;\n"
"attribute vec4 InstanceColor;\n"
"uniform highp mat4 kzProjectionCameraWorldMatrix;\n"
"varying vec4 outColor;\n"
"void main() {\n"
"precision mediump float;\n"
"vec3 position = kzPosition + InstancePosition;\n"
"gl_Position = kzProjectionCameraWorldMatrix * vec4(position, 1.0);\n"
"outColor = InstanceColor;\n"
"}\n";
const char* fragmentSource =
"#version 100\n"
"varying vec4 outColor;\n"
"void main() {\n"
"precision lowp float;\n"
"gl_FragColor = outColor;\n"
"}\n";
ShaderProgram::CreateInfoShaderSources shaderCreateInfo(vertexSource, fragmentSource);
static const ShaderVertexAttribute kzPosition = ShaderVertexAttribute("kzPosition", VertexAttribute::SemanticPosition,
0, GraphicsElementTypeFLOAT, 0, 3, 0, 0);
static const ShaderVertexAttribute InstancePosition = ShaderVertexAttribute("InstancePosition", VertexAttribute::SemanticPosition,
1, GraphicsElementTypeFLOAT, 0, 3, 1, 0);
static const ShaderVertexAttribute InstanceColor = ShaderVertexAttribute("InstanceColor", VertexAttribute::SemanticColor,
0, GraphicsElementTypeFLOAT, 0, 4, 2, 0);
shaderCreateInfo.vertexFormat.push_back(kzPosition);
shaderCreateInfo.vertexFormat.push_back(InstancePosition);
shaderCreateInfo.vertexFormat.push_back(InstanceColor);
shaderCreateInfo.addFixedUniform("kzProjectionCameraWorldMatrix");
auto shader = ShaderProgram::create(domain, shaderCreateInfo, "CustomShader");
auto material = Material::create(domain, "CustomMaterial", shader);
// Define a CreateInfo structure and set it to not keep the data after uploading it to the GPU.
Mesh::CreateInfo createInfo;
createInfo.memoryType = GPUResource::GpuOnly;
// Describe the format for each vertex. In this example, every vertex has a position in 3D space,
// and every instance has a position in 3D space and a color.
// 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 instance position.
MeshVertexAttribute instancePosition("InstancePosition", VertexAttribute::SemanticPosition, 1, GraphicsDataTypeSFLOAT32, 3, 0);
instancePosition.divisor = 1;
createInfo.vertexFormat.push_back(instancePosition);
// Add instance color.
MeshVertexAttribute instanceColor("InstanceColor", VertexAttribute::SemanticColor, 0, GraphicsDataTypeUNORM8, 4, 3 * sizeof(float));
instanceColor.divisor = 1;
createInfo.vertexFormat.push_back(instanceColor);
// Now that you added all components to the vertex format description, update the offsets,
// strides, and sizes.
updateVertexAttributeOffsetsAndVertexSize(createInfo);
updateVertexAttributeStrides(createInfo);
// 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, "");
createInfo.clusters.push_back(cluster);
// Create the vertices. In this example, faces share vertices, so you need only eight vertices.
{
createInfo.vertexCount = 8;
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 uint16_t 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 }
};
// 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] = faceIndices[face][0];
indexData[faceBaseIndex + 1] = faceIndices[face][1];
indexData[faceBaseIndex + 2] = faceIndices[face][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] = faceIndices[face][2];
indexData[faceBaseIndex + 4] = faceIndices[face][3];
indexData[faceBaseIndex + 5] = faceIndices[face][0];
}
// Write vertices.
for (unsigned int vertexIndex = 0; vertexIndex < 8; ++vertexIndex)
{
// Write the correct vertex for this corner of each face.
writeVertexAttribute(createInfo, vertexIndex, 0, cornerPositions[vertexIndex]);
}
}
// Create the instance data: float position vector with three components and packed
// 32-bit color per instance.
{
// Create four instances of the cube.
createInfo.instanceCount = 4;
createInfo.instanceData.resize(createInfo.instanceCount * createInfo.instanceSize);
// Define the positions.
const Vector3 instancePositions[] = {
Vector3(-1.0f, -1.0f, 0.0f),
Vector3(-1.0f, 1.0f, 0.0f),
Vector3(1.0f, 1.0f, 0.0f),
Vector3(1.0f, -1.0f, 0.0f)
};
// Define the colors: white, red, green, blue.
const uint32_t instanceColors[] = {
0xffffffff,
0xffff0000,
0xff00ff00,
0xff0000ff
};
byte* instanceBuffer = createInfo.instanceData.data();
for (unsigned instance = 0; instance < createInfo.instanceCount; ++instance)
{
// Copy the positions and colors to the instance data buffer.
auto pos = reinterpret_cast<float*>(instanceBuffer + instance * createInfo.instanceSize);
*pos++ = instancePositions[instance].getX();
*pos++ = instancePositions[instance].getY();
*pos++ = instancePositions[instance].getZ();
auto color = reinterpret_cast<uint32_t*>(pos);
*color = instanceColors[instance];
}
}
// 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 4.0f, that is, from point (-2, -2, -1) to point (2, 2, 1) in the local coordinate space
// of the mesh. This includes all the instances.
createInfo.boundingBox = Box::fromCenterAndSize(Vector3(0.0f, 0.0f, 0.0f), Vector3(4.0f, 4.0f, 2.0f));
// Create a mesh from the data that you defined in the CreateInfo.
MeshSharedPtr mesh = Mesh::create(domain, createInfo, "instancedBox");