Dynamic Meshes
This article describes usage examples of dynamic meshes by using the ObjectMeshDynamic class. This class is used to procedurally create dynamic meshes and modify them in run-time. You can also load an existing mesh as a dynamic one in order to modify it.
See Also
- An ObjectMeshDynamic class to edit dynamic meshes via UnigineScript
- A set of samples located in the data/samples/objects/ directory:
Creating a Dynamic Mesh
There are three methods to add a new dynamic mesh:
- Add a new dynamic mesh via UnigineEditor.
- Create a new dynamic mesh by adding vertices.
- Create a new dynamic mesh from the existing mesh.
Creating a New Dynamic Mesh
This chapter describes how to create a new dynamic mesh by allocating memory and adding vertices for a new mesh. You can allocate memory for a moderate number of triangles or for a big number of vertices.
Adding trianlges
You can create a dynamic mesh from scratch, by adding one triangle after another. This variant is suitable to create meshes with a moderate number of triangles. To create a new dynamic mesh you should do the following:
- 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: All of these functions allocate memory for polygons of the corresponding form.
- Add the corresponding number of vertices via addVertex() method.
- After each call of the addVertex() function, you can set up properties of the last added vertex manually via calling: All these functions a optional, you can call them as needed.
- Calculate tangent vectors for all vertices via updateTangents().
- 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).
Usage Example
The following example shows how to create of a quad polygon by using the addTriangleQuads() function.
int init() {
ObjectMeshDynamic 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.addTriangleQuads(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.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-6 described above.
Usage Example
The following example shows how to create a plane by adding vertex by vertex.
int init() {
ObjectMeshDynamic 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.updateTangents(); // Calculate tangent vectors.
//mesh.updateIndices(); // Optimize vertex and index buffers, if necessary.
mesh.updateBounds(); // Calculate a mesh bounding box.
}
Creating a Dynamic Mesh Based on the Existing Mesh
There are some ways to create a dynamic mesh from the existing mesh:
- Create a new instance of the ObjectMeshDynamic class instance by passing the Mesh class instance as an argument to the constructor.
- Create a new instance of the ObjectMeshDynamic class instance by passing the name of the saved mesh as an argument to the constructor.
- Copy the mesh class instance to the existing ObjectMeshDynamic instance by passing the Mesh class instance as an argument to the setMesh() function.
Passing a Mesh to a New Dynamic Mesh
To create a new ObjectMeshDynamic instance from this existing mesh, you should pass the existing Mesh class instance to the ObjectMeshDynamic class constructor.
Usage Example
The following example shows how to create a new dynamic mesh from the existing Mesh class instance. It is supposed that you already have the Mesh instance, but in this example we create a new instance of the Mesh class with the box surface.
int init() {
/* ... */
// create the mesh with the box surface
Mesh mesh = new Mesh();
mesh.addBoxSurface("box", vec3(0.2));
// create a new ObjectMeshDynamic instance by passing mesh as an argument
ObjectMeshDynamic dynamic_mesh = new ObjectMeshDynamic(mesh);
// Assign a material and a property.
dynamic_mesh.setMaterial("mesh_base","*");
dynamic_mesh.setProperty("surface_base","*");
/* ... */
}
Passing a Mesh Name to a New Dynamic Mesh
To create a new dynamic mesh from the existing .mesh file, you should pass to the constructor of the ObjectMeshDynamic class the path to the file. The path is relative to the data/ folder of your project.
Usage Example
The following example shows how to create a new dynamic mesh from existing .mesh file. It is supposed that you have a file with a mesh and you pass the path to the file as an argument to the ObjectMeshDynamic constructor. In this example a statue mesh from the Unigine samples is used.
int init() {
/* ... */
// create a new ObjectMeshDynamic instance
// by passing the path of the existing mesh as an argument
ObjectMeshDynamic dynamic_mesh = new ObjectMeshDynamic("/samples/common/meshes/statue.mesh");
engine.editor.addNode(node_remove(dynamic_mesh));
// Assign a material and a property.
dynamic_mesh.setMaterial("mesh_base","*");
dynamic_mesh.setProperty("surface_base","*");
/* ... */
}
Copy a Mesh to the Existing Dynamic Mesh
To copy the mesh from the Mesh instance to an existing dynamic mesh, you should use the setMesh() function and pass the Mesh instance as an argument to it. This function copies a given mesh into the current dynamic mesh.
Usage Example
In the following example described how to copy the mesh from the Mesh instance to the ObjectMeshDynamic instance. It is supposed that you already have the Mesh instance, but in this example we create a new instance of the Mesh class with the box surface.
int init() {
/* ... */
// existing mesh with a box surface
Mesh mesh = new Mesh();
mesh.addBoxSurface("box", vec3(0.2));
// create a new ObjectMeshDynamic
ObjectMeshDynamic dynamic_mesh = new ObjectMeshDynamic();
engine.editor.addNode(node_remove(dynamic_mesh));
// copy the existing mesh to the ObjectMeshDynamic
dynamic_mesh.setMesh(mesh);
// Assign a material and a property.
dynamic_mesh.setMaterial("mesh_base","*");
dynamic_mesh.setProperty("surface_base","*");
/* ... */
}
Adding Physics to Dynamic Meshes
To add some physical properties to the dynamic mesh so that it could participate in interactions between objects or external physical forces, it should have a body. You can easily assign it from UnigineScript or in the UnigineEditor.
Usage Example
The following example shows how to add the rigid body with a shape to the dynamic mesh. In the example the dynamic mesh is created from the existing mesh with the box surface.
/* ... */
// create a mesh instance with a box surface
Mesh mesh = new Mesh();
mesh.addBoxSurface("box", vec3(0.2));
// create a new dynamic mesh from the Mesh instance and add it to editor
ObjectMeshDynamic dynamic_mesh = new ObjectMeshDynamic(mesh);
engine.editor.addNode(node_remove(dynamic_mesh));
// Assign a material and a property to the dynamic mesh
dynamic_mesh.setMaterial("mesh_base","*");
dynamic_mesh.setProperty("surface_base","*");
// Assign a body and a shape to the dynamic mesh
BodyRigid body = class_remove(new BodyRigid(dynamic_mesh));
ShapeBox shape = class_remove(new ShapeBox(body, vec3(0.2f)));
/* ... */
See Also
- The article about Physical bodies in Unigine.
- The article about Shapes in Unigine.
Intersections with Dynamic Meshes
To detect if the dynamic mesh intersects a line or bounds of the specified volume, you should use one of these functions;
- Object.getIntersection() - this function detects the intersection of the specified object with a tracing line. See the usage example of object intersections here.
- engine.world.getIntersection() - world functions detect all the objects and nodes in the specific bounding volume or the first object intersection with the invisible tracing line. See examples of the world intersections.
- engine.physics.getIntersection() - physics functions detect the intersection with a shape of bodies. If the object has no body, this function detects intersection with surfaces (polygons) of the object with intersection flag. See usage example of thephysics intersections here.
- Shape.getIntersection() - this function detects the intersection of the specified shape with a tracing line. See the example of shape intersection here.
Saving a Dynamic Mesh to a File
To save the dynamic mesh into a file, you should copy it to the Mesh class instance. By using the save() function of the Mesh class, you can save the mesh with the specified name.
Usage Example
The following example shows how to save the dynamic mesh to the file. It is supposed that you have a dynamic mesh to save. You should pass a path as an argument to the save() function of the Mesh class. The path is relative to the data/ folder of your project.
/* ... */
// create a mesh instance
Mesh mesh = new Mesh();
// copy the dynamic mesh to the Mesh class instance
dynamic_mesh.getMesh(mesh);
// save the mesh to the data/samples/dynamic_mesh.mesh file
mesh.save("samples/dynamic_mesh.mesh");
/* ... */