gpt4 book ai didi

c++ - 翻译 Assimp 3D 模型也旋转

转载 作者:行者123 更新时间:2023-11-28 04:06:33 26 4
gpt4 key购买 nike

This is the view before translate, which is correct. This is the view after translate, which is incorrect.

我在使用 Assimp 加载的 OpenGL (C++) 中有一个 3D 模型。我需要在屏幕上移动这个模型(平移),就像它始终在 X 轴和 Y 轴(无 Z 轴)上面向相机一样。这就像移动这个模型,就像它只是 2D 一样(当然,如果我旋转它,它也会显示 Z 轴)。

我的渲染函数是:

    camX = CamY = 0;  
camZ = 5;
lookatX = lookatY = lookatZ = 0;

void C3DModel::render(void)
{

static float step = 0.0f;
setCamera(camX, camY, camZ, lookatX, lookatY, lookatZ);
translate(-3, 1, 0); // here is the issue .
scale(scaleFactor, scaleFactor, scaleFactor);
rotate(step, 0.0f, 1.0f, 0.0f);
}

void C3DModel::translate(float x, float y, float z)
{

float aux[16];

setTranslationMatrix(aux, x, y, z);
multMatrix(modelMatrix, aux);
setModelMatrix();
}

void C3DModel::setTranslationMatrix(float *mat, float x, float y, float z)
{

setIdentityMatrix(mat, 4);
mat[12] = x;
mat[13] = y;
mat[14] = z;
}

void C3DModel::setScaleMatrix(float *mat, float sx, float sy, float sz)
{

setIdentityMatrix(mat, 4);
mat[0] = sx;
mat[5] = sy;
mat[10] = sz;
}

void C3DModel::setRotationMatrix(float *mat, float angle, float x, float y, float z)
{
float radAngle = DegToRad(angle);
float co = cos(radAngle);
float si = sin(radAngle);
float x2 = x * x;
float y2 = y * y;
float z2 = z * z;

mat[0] = x2 + (y2 + z2) * co;
mat[4] = x * y * (1 - co) - z * si;
mat[8] = x * z * (1 - co) + y * si;
mat[12] = 0.0f;

mat[1] = x * y * (1 - co) + z * si;
mat[5] = y2 + (x2 + z2) * co;
mat[9] = y * z * (1 - co) - x * si;
mat[13] = 0.0f;

mat[2] = x * z * (1 - co) - y * si;
mat[6] = y * z * (1 - co) + x * si;
mat[10] = z2 + (x2 + y2) * co;
mat[14] = 0.0f;

mat[3] = 0.0f;
mat[7] = 0.0f;
mat[11] = 0.0f;
mat[15] = 1.0f;
}


void C3DModel::rotate(float angle, float x, float y, float z)
{

float aux[16];

setRotationMatrix(aux, angle, x, y, z);
multMatrix(modelMatrix, aux);
setModelMatrix();
}

void C3DModel::scale(float x, float y, float z)
{
float aux[16];

setScaleMatrix(aux, x, y, z);
multMatrix(modelMatrix, aux);
setModelMatrix();
}

void C3DModel::setIdentityMatrix(float *mat, int size)
{
// fill matrix with 0s
for (int i = 0; i < size * size; ++i)
mat[i] = 0.0f;
// fill diagonal with 1s
for (int i = 0; i < size; ++i)
mat[i + i * size] = 1.0f;
}

void C3DModel::multMatrix(float *a, float *b)
{

float res[16];

for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
res[j * 4 + i] = 0.0f;
for (int k = 0; k < 4; ++k)
{
res[j * 4 + i] += a[k * 4 + i] * b[j * 4 + k];
}
}
}
memcpy(a, res, 16 * sizeof(float));
}

void C3DModel::setModelMatrix()
{
glBindBuffer(GL_UNIFORM_BUFFER, matricesUniBuffer);
glBufferSubData(GL_UNIFORM_BUFFER, ModelMatrixOffset, MatrixSize, modelMatrix);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

void C3DModel::crossProduct(float *a, float *b, float *res)
{
res[0] = a[1] * b[2] - b[1] * a[2];
res[1] = a[2] * b[0] - b[2] * a[0];
res[2] = a[0] * b[1] - b[0] * a[1];
}

// Normalize a vec3
void C3DModel::normalize(float *a)
{

float mag = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
a[0] /= mag;
a[1] /= mag;
a[2] /= mag;
}

void C3DModel::setCamera(float posX, float posY, float posZ, float lookAtX, float lookAtY, float lookAtZ)
{

float dir[3], right[3], up[3];
up[0] = 0.0f; up[1] = 1.0f; up[2] = 0.0f;
dir[0] = (lookAtX - posX);
dir[1] = (lookAtY - posY);
dir[2] = (lookAtZ - posZ);
normalize(dir);
crossProduct(dir, up, right);
normalize(right);
crossProduct(right, dir, up);
normalize(up);
float viewMatrix[16], aux[16];
viewMatrix[0] = right[0];
viewMatrix[4] = right[1];
viewMatrix[8] = right[2];
viewMatrix[12] = 0.0f;
viewMatrix[1] = up[0];
viewMatrix[5] = up[1];
viewMatrix[9] = up[2];
viewMatrix[13] = 0.0f;
viewMatrix[2] = -dir[0];
viewMatrix[6] = -dir[1];
viewMatrix[10] = -dir[2];
viewMatrix[14] = 0.0f;
viewMatrix[3] = 0.0f;
viewMatrix[7] = 0.0f;
viewMatrix[11] = 0.0f;
viewMatrix[15] = 1.0f;
setTranslationMatrix(aux, -posX, -posY, -posZ);
multMatrix(viewMatrix, aux);
glBindBuffer(GL_UNIFORM_BUFFER, matricesUniBuffer);
glBufferSubData(GL_UNIFORM_BUFFER, ViewMatrixOffset, MatrixSize, viewMatrix);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

最佳答案

我将尝试在 2 个不同的矩阵中分离对象的旋转和平移请求的屏幕位置。

在每一帧,我会用 C3DModel::setRotationMatrix 中的代码计算旋转矩阵,用 C3DModel::setTranslationMatrix 计算平移,将它们组合成一个新的新模型矩阵并将其应用于您的对象。请记住,顺序很重要,如果您先旋转,对象将围绕您的 obj 文件中的原点旋转,如果您在平移之后旋转,它将围绕世界原点旋转(就像行星围绕太阳,太阳就是原点)。

最后,它看起来像:

void C3DModel::render(void){

float* rotation = createRotation(angle, x, y, z);
float* translation = createTranslation(x, y, z);
float* updatedModel = mul(rotation, translation) //order matters
setModel(updatedModel);
}

关于c++ - 翻译 Assimp 3D 模型也旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58618370/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com