ObjectMeshDynamic Class
This class is used to procedurally create dynamic meshes (i.e. triangles), lines or points and modify them in run-time. You can also load an existing mesh as a dynamic one in order to modify it.
- Intersections and collisions with dynamic meshes are slow (just like intersections and collisions with skinned meshes). Intersection and collision detection for points and lines is not available.
- Geometry instancing is not supported for meshes created via new operator, so if you want to render the same mesh several times, several copies of it will be stored on the GPU. Hardware instancing is supported only for meshes cloned via clone() function.
The following samples demonstrate the ObjectMeshDynamic class usage:
Creating a Mesh
Adding Triangles
You can create a dynamic mesh from a scratch, by adding one triangle after another. This variant is suitable to create meshes with a moderate number of triangles.
- First of all, reserve a necessary space in a vertex buffer for triangle vertices and add indices for them to the index buffer. This is done by calling one of the following methods:
- Add the corresponding number of vertices via addVertex() method.
- After each addVertex() call, you can set up properties of the newly added vertex manually via calling:
- addTexCoord() (optional for solid colored triangles)
- addNormal() (optional)
- addTangent() (optional)
- Automatically calculate all normals for all vertices at once via updateNormals().
- Calculate tangent vectors for all vertices via updateTangents(). Make sure that you call this method after normals are calculated.
- Calculate a bounding box and a bounding sphere for the created mesh by calling updateBounds().
- If necessary, you can remove duplicated vertices of the created mesh and optimize it for faster rendering. Use updateIndices() function, for example, if a quad polygon is created via addTriangles(2) (6 vertices are created) instead of an optimized addQuads(1) (4 vertices are created).
Here is an example of creating a quad polygon.
int init() {
mesh = new ObjectMeshDynamic(); // Create a dynamic mesh and add it into the editor.
engine.editor.addNode(node_remove(mesh));
mesh.setWorldTransform(translate(Vec3(0.0f,0.0f,2.0f)));
mesh.setMaterial("mesh_base","*");
mesh.setProperty("surface_base","*");
mesh.addQuads(1); // Allocate space in a vertex buffer and create vertex indices.
mesh.addVertex(vec3(-1.0f,-1.0f,0.0f)); // Add vertices and assign texture coordinates, if necessary.
mesh.addTexCoord(vec4(0,0,0,0));
mesh.addVertex(vec3(1.0f,-1.0f,0.0f));
mesh.addTexCoord(vec4(1,0,0,0));
mesh.addVertex(vec3(1.0f,1.0f,0.0f));
mesh.addTexCoord(vec4(1,1,0,0));
mesh.addVertex(vec3(-1.0f,1.0f,0.0f));
mesh.addTexCoord(vec4(0,1,0,0));
mesh.updateNormals(); // Calculate normal vectors.
mesh.updateTangents(); // Calculate tangent vectors.
//mesh.updateIndices(); // Optimize vertex and index buffers, if necessary.
mesh.updateBounds(); // Calculate a mesh bounding box.
return 1;
}
Adding a Big Number of Vertices
To create dynamic meshes with a huge number of vertices, it is better to use a more optimized approach: instead of allocating memory in small chunks (which can be costly), all necessary memory is preallocated first and filled with data after that.
- Allocate space for triangle vertices in an index buffer using allocateIndices().
- Allocate space for vertices in a vertex buffer using allocateVertex().
- Add the corresponding number of vertices via addVertex() method.
- Add the corresponding number of indices via addIndex() method.
- Follow steps 3-7 described above.
Here is an example of creating dynamic meshes with high vertex count.
int init() {
mesh = new ObjectMeshDynamic(); // Create a dynamic mesh and add it into the editor.
engine.editor.addNode(node_remove(mesh));
mesh.setWorldTransform(translate(Vec3(0.0f,0.0f,2.0f)));
mesh.setMaterial("mesh_base","*");
mesh.setProperty("surface_base","*");
mesh.allocateIndices(6); // Allocate space in index and vertex buffers.
mesh.allocateVertex(4);
mesh.addVertex(vec3(-1.0f,-1.0f,0.0f)); // Add vertices.
mesh.addVertex(vec3(1.0f,-1.0f,0.0f));
mesh.addVertex(vec3(1.0f,1.0f,0.0f));
mesh.addVertex(vec3(-1.0f,1.0f,0.0f));
mesh.addIndex(0); // Add indices for created vertices.
mesh.addIndex(1);
mesh.addIndex(2);
mesh.addIndex(0);
mesh.addIndex(2);
mesh.addIndex(3);
mesh.updateNormals(); // Calculate normal vectors.
mesh.updateTangents(); // Calculate tangent vectors.
//mesh.updateIndices(); // Optimize vertex and index buffers, if necessary.
mesh.updateBounds(); // Calculate a mesh bounding box.
return 1;
}
Creating Points and Lines
To create dynamic meshes from points or lines, you simply need to follow these steps:
- Set a corresponding rendering mode (OBJECT_MESH_DYNAMIC_MODE_LINES or OBJECT_MESH_DYNAMIC_MODE_POINTS) for a surface via setSurfaceMode() method.
- Add the corresponding number of vertices via addVertex() method.
- Add the corresponding number of indices via addIndex() method.
- Calculate a bounding box and a bounding sphere for the created mesh by calling updateBounds().
Here is an example of creating lines using ObjectMeshDynamic.
int init() {
mesh = new ObjectMeshDynamic(); // Create a dynamic mesh and add it into the editor.
engine.editor.addNode(node_remove(mesh));
mesh.setMaterial("objects_mesh_emission","*"); // Assign an emissive material.
mesh.setProperty("surface_base","*");
mesh.setSurfaceMode(OBJECT_MESH_DYNAMIC_MODE_LINES,0); // Set a rendering mode for lines.
mesh.addVertex(vec3(-1.0f,-1.0f,1.0f)); // Add vertices.
mesh.addVertex(vec3(0.0f,0.0f,1.0f));
mesh.addIndex(0); // Add indices for created vertices.
mesh.addIndex(1);
mesh.updateBounds(); // Calculate a mesh bounding box.
return 1;
}
Rewriting Mesh Data
ObjectMeshDynamic Class
This class inherits from ObjectMembers
ObjectMeshDynamic (variable arg)
Constructor. Creates a new dynamic mesh object. By default, it will be rendered using triangles.Arguments
- variable arg - Constructor argument of two possible types:
- int dynamic - set this flag to 1 if a mesh is going to be changed every frame. This flag optimizes internal render buffer usage and, for example, can be used to create custom particle systems.
- string name - mesh file name. This argument creates a dynamic mesh from a given mesh file.
void addIndex (int vertex)
Adds an index pointing to a given vertex.Arguments
- int vertex - Vertex number.
void addLineStrip (int num_vertex)
Adds a line strip to the mesh. This method does not add vertices, rather it allocates indices, for which vertices should be then created with addVertex(). Indices will point to vertices starting from the current last vertex in the vertex buffer.Arguments
- int num_vertex - Number of vertices comprising the strip.
void addMeshSurface (ObjectMeshDynamic mesh, int surface)
Appends a new mesh surface to the current mesh.Arguments
- ObjectMeshDynamic mesh - Mesh, from which the surface is copied.
- int surface - Number of the mesh surface to copy.
void addNormal (vec3 normal)
Adds a normal vector to the last added vertex.Arguments
- vec3 normal - Coordinates of the normal vector.
void addPoints (int num_points)
Adds points to the mesh. This method does not add vertices, rather it allocates indices, for which vertices should be then created with addVertex(). Indices will point to vertices starting from the current last vertex in the vertex buffer.Arguments
- int num_points - Number of points.
void addQuads (int quads)
Adds a given number of quads to the mesh. This method does not add vertices, rather it allocates indices, for which vertices should be then created with addVertex() .Indices will point to vertices starting from the current last vertex in the vertex buffer.Arguments
- int quads - Number of quads.
void addSurface (string name)
Adds all of the last listed and unsigned vertices and triangles to a new mesh surface with a specified name.Arguments
- string name - Name of the new surface.
void addTangent (vec4 tangent)
Adds a tangent vector to the last added vertex.Arguments
- vec4 tangent - Coordinates of the tangent vector. The vector's w component is set to 0.
void addTexCoord (vec4 texcoord)
Adds texture coordinates to the last added vertex.Arguments
- vec4 texcoord - Coordinate pairs for both texture channels.
void addTriangleFan (int num_vertex)
Adds a triangle fan to the mesh. This method does not add vertices, rather it allocates indices, for which vertices should be then created with addVertex(). Indices will point to vertices starting from the current last vertex in the vertex buffer.Arguments
- int num_vertex - Number of vertices comprising the fan.
void addTriangleStrip (int num_vertex)
Adds a triangle strip to the mesh. This method does not add vertices, rather it allocates indices, for which vertices should be then created with addVertex(). Indices will point to vertices starting from the current last vertex in the vertex buffer.Arguments
- int num_vertex - Number of vertices comprising the strip.
void addTriangles (int triangles)
Adds a given number of triangles to the mesh. This method does not add vertices, rather it allocates indices, for which vertices should be then created with addVertex() .Indices will point to vertices starting from the current last vertex in the vertex buffer.Arguments
- int triangles - Number of triangles.
void addVertex (vec3 coordinates)
Adds a vertex with given coordinates to the mesh.Arguments
- vec3 coordinates - Vertex coordinates in the mesh system of coordinates.
void allocateIndices (int num)
Allocate an index buffer for a given number of indices that will be used for a mesh. With this function, memory can be allocated once rather than in chunks, making the creation faster.Arguments
- int num - The number of indices that will be stored in a buffer.
void allocateVertex (int num)
Allocate a vertex buffer for a given number of vertices that will be used for a mesh. With this function, memory can be allocated once rather than in chunks, making the creation faster.Arguments
- int num - The number of vertices that will be stored in a buffer.
void clearIndices ()
Clears all vertex indices used by the mesh.void clearSurfaces ()
Clears all the surface settings.void clearVertex ()
Clears all vertices comprising the mesh.void flush ()
Sends all data to the GPU. This method is called automatically, if the length of either vertex or index buffer changes. If you change the contents of either of the buffers, you should call this method.int getIndex (int index)
Returns a vertex number pointed by a given index.Arguments
- int index - Index number in the index buffer.
Return value
Vertex number.int getMesh (ObjectMesh mesh)
Copies the current dynamic mesh node into the received mesh node.Arguments
- ObjectMesh mesh - Mesh node.
Return value
1 if the dynamic mesh is copied successfully, otherwise - 0.Examples
For example, you can copy a dynamic mesh into a static mesh as follows:
// create a static mesh
ObjectMesh mesh = new ObjectMesh(NULL,1);
// copy the dynamic mesh into the static one
dynamic.getMesh(mesh);
vec3 getNormal (int vertex)
Returns a normal vector of a given vertex.Arguments
- int vertex - ID number of the vertex.
Return value
The vertex normal vector.int getNumIndices ()
Returns the number of vertex indices used by the mesh.Return value
Number of indices.int getNumVertex ()
Returns the number of vertices comprising the mesh.Return value
Number of vertices.int getSurfaceBegin (int surface)
Returns the begin index of the specified mesh surface.Arguments
- int surface - Surface number.
Return value
Begin index of the surface.int getSurfaceEnd (int surface)
Returns the end index of the specified mesh surface.Arguments
- int surface - Surface number.
Return value
Returns the end index of the surface.vec4 getTangent (int vertex)
Returns a tangent vector of a given vertex.Arguments
- int vertex - ID number of the vertex.
Return value
The tangent vector.vec4 getTexCoord (int vertex)
Returns texture coordinates of a given vertex.Arguments
- int vertex - ID number of the vertex.
Return value
Coordinate pairs for both texture channels.vec3 getVertex (int vertex)
Returns coordinates of a given vertex.Arguments
- int vertex - ID number of the vertex.
Return value
Coordinates in the mesh system of coordinates.int load (string name)
Loads a mesh file and re-generate the dynamic mesh.Arguments
- string name - Name of a mesh file.
Return value
1 if success; 0 otherwise.int save (string name)
Saves the dynamic mesh into a file.Arguments
- string name - Name of a mesh file.
Return value
1 if success; 0 otherwise.void setBoundBox (vec3 min, vec3 max, int surface)
Sets a bounding box of the specified size for the given dynamic mesh surface.Arguments
- vec3 min - Bound box minimum.
- vec3 max - Bound box maximum.
- int surface - ID number of the target surface of the object.
void setBoundBox (vec3 min, vec3 max)
Sets a bounding box of the specified size for the dynamic object mesh.Arguments
- vec3 min - Bounding box minimum.
- vec3 max - Bounding box maximum.
void setIndex (int index, int vertex)
Updates a given index in the index buffer.Arguments
- int index - Index number in the index buffer.
- int vertex - Number of the vertex.
int setMesh (ObjectMesh mesh)
Allows reinitializing the ObjectMeshDynamic: it copies a given mesh node into the current dynamic mesh node.Arguments
- ObjectMesh mesh - Mesh node.
Return value
1 if the mesh node is copied successfully, otherwise - 0.Examples
For example, you can load a static mesh and copy all the vertices and indices of this mesh into a dynamic one as follows:
// load the static mesh
ObjectMesh static = new ObjectMesh("sample.mesh");
// the dynamic mesh
ObjectMeshDynamic dynamic = new ObjectMeshDynamic();
dynamic.setMesh(static);
void setNormal (int vertex, vec3 normal)
Updates a normal vector in a given vertex.Arguments
- int vertex - ID number of the vertex.
- vec3 normal - New coordinates of the normal vector.
void setSurfaceBegin (int begin, int surface)
Sets the begin index to the specified surface of the dynamic object mesh. It means that the surface will be rendered the first.Arguments
- int begin - Begin index.
- int surface - ID number of the target surface.
void setSurfaceEnd (int begin, int surface)
Sets the end index to the specified surface of the dynamic object mesh. It means that the surface will be rendered the last.Arguments
- int begin - End index.
- int surface - ID number of the target surface.
void setTangent (int vertex, vec4 tangent)
Updates a tangent vector in a given vertex.Arguments
- int vertex - ID number of the vertex.
- vec4 tangent - New coordinates of the tangent vector. The vector's w component is set to 0.
void setTexCoord (int vertex, vec4 texcoord)
Updates texture coordinates of a given vertex.Arguments
- int vertex - ID number of the vertex.
- vec4 texcoord - New coordinate pairs for both texture channels.
void setVertex (int vertex, vec3 coordinates)
Updates coordinates of a given vertex.Arguments
- int vertex - ID number of the vertex.
- vec3 coordinates - New coordinates in the mesh system of coordinates.
void updateBounds ()
Calculates a bounding box and a bounding sphere for the current mesh.void updateIndices ()
Optimizes vertex indices by removing duplicated vertices. Vertices are merged only if all the following conditions are met:- Coordinates of vertices match
- Normals of vertices match
- Texture coordinates of vertices match
- Tangents of vertices match
void updateNormals (float angle)
Calculates smooth normal vectors in vertices of the current mesh.Arguments
- float angle - Face threshold angle in degrees (set zero for flat normals).
void updateNormals ()
Updates normal vectors in mesh vertices.void updateSurfaceBegin (int surface)
Synchronizes surface begin index.Arguments
- int surface - ID of a target surface.
void updateSurfaceEnd (int surface)
Synchronizes surface end index.Arguments
- int surface - ID of a target surface.