Mesh Related Assets

Just like the materials, in order to manipulate Meshes, you'll need to acknowledge two main classes: Vertex and Mesh. We highly recommend that you have a basic knowledge on how Meshes works before attempting to work with the Mesh Manipulation APIs provided below. This is a good start if you don't have experience with it.

Before jumping to the class Documentation, I'll explain how Cave Engine handles meshes, so you can have a better knowledge of it in order to manipulate them.

The Cave meshes consists in two lists: a list with all the vertex information (for each vertice, its position, normal, uv and so on) and a list of indices to build the faces with. The indices are basically integer numbers that corresponds to a vertice in the vertex list. Every 3 consecutive indexes in the indices list corresponds to a Triangle. So if you want to create a triangle mesh, the vertex list will probably have 3 Vertex elements, one for each corner of the triangle, and the indices will likely to be: [0, 1, 2].

You'll see below that the cave.Mesh class does have python lists for both of those elements, called vertices and indices, respectively. They behave as normal python lists, supporting all the operators that you expect to it, such as append and remove.

IMPORTANT: Be aware that after any modification to a mesh, you need to update it in the GPU. That can be done by calling the Mesh's reload() method. Keep in mind that this operation is expensive and may cause performance issues if you call it every frame (for example).


How to get a Mesh Instance?

The way you'll tipically get a Mesh class instance is by retrieving them from a MeshComponent, do NOT try to create your own instance from scratch, it will not work. Here is an example of how it's done:

# Getting the mesh component:
meshComponent = self.entity.get("Mesh")

# Getting the mesh:
mesh = meshComponent.getMesh()

# If you want to change the mesh of a specific Entity, 
# you can duplicate it and reassign to the Component:
meshCopy = mesh.getCopy()
meshComponent.setMesh(meshCopy)

# Now you'll be able to do local changes to the *meshCopy*:
print(meshCopy.indices)

Documentation

Here is the full documentation:

cave.Vertex

This class describes a Vertex. You can instantiate it in your code and when you do it, all the variables will be initialized with zeros and the jointIDs will all be -1 (meaning that there is no bone influencing the vertex). Sample code:

v = cave.Vertex()
v.position = cave.Vector3(0,1,0)
# And so on...
Variables

API reference:

position:   Vector3
normal:     Vector3
tangent:    Vector3
uv:         Vector2
jointWeights: Vector4
jointIDs:     Vector4

Here is the description of every variable in the Vertex class:

Variable Description
position The local position of the Vertex. Keep in mind that the Entity's transform will be taken into account automatically by the GPU code, so you don't need to consider it here.
normal The local normal of the Vertex, that represents the direction that it is looking at. Mainly used for shading and also takes the Entity's transform into account. Read this for more details.
tangent The local tangent of the Vertex. Same details as the normal, read this for more details.
uv The UV mapped coordinates of the Vertex (in 2D space). This is used to texture the Mesh and does not take (or need to) the Entity's transform into account. Read this for more details.

If the mesh was intended to be used with an Armature, it will contain bone influence data. In cave, a vertex can only be influenced by up to 4 bones. The total weight of all the influenced bones must be equal to 1.0 (otherwise you'll see some animation artefacts). For each bone, its weight needs to be set into the joinWeights variable and its bone ID in the jointIDs. If there is no bone influencing the vertex, the ID should be -1. Notice that both variables have the type Vector4. Meaning that each bone that influences the vertex (again, up to 4), will correspond to an ID of the vector (0 to 3, or .x to .z).

Variable Description
jointWeights For each dimension of the vector (up to 4), the bone weight (if any). The bone's ID is set in the variable below, if -1, the number here will be ignored.
jointIDs For each dimension of the vector (up to 4), the corresponding bone ID to map in the armature. If there is no bone, it should be set to -1.

cave.Mesh

This is the main mesh class. As explained above, here is where you can add or remove vertices and use the indices to connect them as triangles. Polygons (a face with more than 3 vertices) are not directly supported and you should convert triangulate them before adding to the indices list.

Variables

Both lists below are treated as python lists, supporting all its operations.

vertices    : list of Vertex
indices     : list of ints
Methods

Aftet doing any change to the Mesh (such as adding or removing elements from the vertices and indices or modifying them, like changing a vertex's position), you need to reload the Mesh in order to update the GPU with the new values. It can be done by calling this function below. NOTE: it may be expensive, depending on the amount of polygons you have!

reload()

If you need to duplicate a mesh (in order to do local changes to a specific Entity, for example), this is what you're looking for. It will duplicate the mesh and add it to the game data!

GetCopy() -> Mesh