TJR TJR - 1 month ago 4x
C++ Question

Scaling and moving 3d object with openGL

I'm trying to load a 3D object from an .obj file, to scale it to a certain size to to move it to a certain coordinate (I prefer changing its matrix than scaling and moving each vector).
From the .obj parsing function, I know the width, height, depth and center of the object's bounding box.

To make it clear, I have a map of tiles from (-1.0, 0, 1.0) to (1.0, 0, -1.0) and for modeling the all thing I use an obj file of a cube (with length of 40.0). Clearly, I had to scale the cube before printing it.

My problem is that I keep failing on moving the cube correctly on the z axis.
Scaling was done this way:

model.Scale(xn * x_unit / model.GetWidth(), yn * y_unit / model.GetHeight(), zn * z_unit / model.GetDepth());

Where xn, yn and zn are the amount of tiles the cube will stretch on in each axis and x_unit, y_unit and z_unit are the length of each tile in that axis (this function works perfectly)

In order to move the cube to the desired place I calculated the translation amount in each axis (assuming the cube's center is at 0, 0, 0):

x_trans = (((xn - (2.0f / x_unit)) / 2.0f) * model.GetOriginalWidth()) / xn;
y_trans = (0.5f * model.GetOriginalHeight());
z_trans = ((zn - (2.0f / z_unit)) / 2.0f) * model.GetOriginalDepth() / zn;

And transalting the all model:

model.Move(x_trans - model.GetX(), y_trans - model.GetY(), z_trans - model.GetZ());

The Move function and the Scale function moves and scales the model matrix, not the real array of coordinates:

void Graphic3dModelPart::Move(float dx, float dy, float dz)
model_ = glm::translate(model_, glm::vec3(dx, dy, dz));
mvp_ = projection_ * view_ * model_;

void Graphic3dModelPart::Scale(float sx, float sy, float sz)
model_ *= glm::scale(glm::mat4(), glm::vec3(sx, sy, sz));
mvp_ = projection_ * view_ * model_;

Yet the problem is that in the Z axis something goes wrong (when the cube's depth is more than one tile's length (on the x axis and y axis it works perfectly).

If pictures will help understanding the situation tell me and I will upload.


So I finally solved the issue. Since the scaling method just changed the matrix, moving the object must be relative to how much you scaled the object.

float x_trans, y_trans, z_trans;

model.Scale(xn * x_unit / model.GetWidth(), yn * y_unit / model.GetHeight(), zn * z_unit / model.GetDepth());
model.Move(0.0f - model.GetX() / (xn * x_unit / model.GetOriginalWidth()), 0.0f - model.GetY() / (yn * y_unit / model.GetOriginalHeight()), 0.0f - model.GetZ() / (zn * z_unit / model.GetOriginalDepth()));

x_trans = (((xn - (2.0f / x_unit)) / 2.0f + x_offset) * model.GetOriginalWidth()) / xn;
y_trans = ((yn / 2.0f + y_offset) * model.GetOriginalHeight()) / yn;
z_trans = (((zn - (2.0f / z_unit)) / 2.0f + z_offset) * model.GetOriginalDepth()) / zn;

model.Move(x_trans, y_trans, z_trans);

This code just works perfectly for me.