Short answer:

- Code: Select all
`Vector3 position = modelInstance.transform.getTranslation(new Vector3());`

Long answer:

The location of a ModelInstance obviously depends on what you define as the center or origin of the model. Or in other words, what you define as the location when it hasn't been moved or rotated. This might seem obvious to you as viewer, e.g. you might say that the location of the feet of a character is the location of the whole character. But as far as the data goes your model is just a bunch of vertices (points of triangles) all with their own location. What this origin (point zero, so to speak) actually is depends on how you exported the model in your modeling application. You typically want to use the center of the model as origin (because of center of mass e.g.).

Most commonly you don't need the actual location, but the movement relative to the original location instead. E.g. if you create a ModelInstance, then it is not moved yet. Now if you move the ModelInstance around and want to know its location, you actually want to know how much it is moved relative to when it was created. This is called the translation. Likewise, you could need to know its rotation (instead of orientation, because the modelinstance doesn't know which side of it is front or back etc.).

It is possible that you apply a combination of multiple translations (movement) and rotations (and even scale), which can (and will) influence each other. To understand this, imagine that you're standing at the center of a football field, facing north. Now imagine taking 5 steps forward. Next imagine rotating 90 degrees to your right, so your facing east. Next image taking another 2 steps forward. You are now located 5 steps north and 2 steps east of where you started and yet you've only taking steps forward.

The order in which the transformation (translation, rotation and scaling) are performed is very important. E.g. in the previous thought example if you would change the order (e.g. 2 steps forward, then rotate 90 degrees, then 5 steps forward), you might end up at a different location. Luckily there's a nice mathematical method to keep track of these transformations, including the order in which they are performed, with just 16 floating point values (regardless the amount of transformations): the matrix.

A matrix (in this case a 4x4 matrix) can be used to store the result of multiple transformation. (If you want to know more about them, I'm sure google will help you with that). A matrix is great for chaining transformations (which can be matrix each as well) and is also great to transform vectors. It is therefore used by the vertex shader to transform the vertices of the model on the GPU. You could say that it is the endpoint (the lowest level, if you prefer) of the transformation.

Unfortunately it isn't very suitable to work with in game logic where you need to e.g. limit the position. It is possible to fetch most information about the transformation (the resulting individual translation, rotation and scale transformations). But some of the information about the transformation might get lost in a matrix (e.g. the result of scaling by -1 on X or rotating 180 degrees on Y is the same). Also, because of the relatively many floating point operations, floating point errors might accumulate.

So while you can fetch the information from the transform matrix of a ModelInstance for basic operations, it might be easier (in quite some cases better as well) to keep track of the transformations yourself. (untested code):

- Code: Select all
`public class GameObject extends ModelInstance {`

public final Vector3 position = new Vector3();

public final Quaternion rotation = new Quaternion();

public final Vector3 scale = new Vector3();

// this is just an example constructor, make sure to implement the constructor you need

public GameObject (Model model, String nodeName) {

super(model, nodeName, true);

}

// Call this method everytime you've updated the position, rotation and/or scale values and don't use the transform member directly

public void updateTransform () {

this.transform.set(position, rotation, scale);

}

}

Note that in this example a quaternion is used, which is a bit like a matrix but only for rotations. If you needm you could simplify that as well by using euler angles (yaw, pitch and roll).