围绕点/线翻转3D对象

问题描述 投票:0回答:1

我正在制作3D怪物制作器。我最近添加了一个功能,可以沿x和y轴翻转零件,它本身可以很好地工作,但是,我还有一个功能,它允许用户组合零件(设置标志,不组合网格),这意味着简单地翻转单个对象就不会翻转组合对象的“形状”。我对如何执行此操作有两个想法,但没有用,我将在下面列出。我可以访问对象的原点和所有组合实例的重心-理论数字平面上的0、0、0点

在这些示例中,我们在y轴上翻转,轴平面为X =宽度,Y =高度,Z =深度

尝试#1-只需翻转单个对象的X比例,获取与centerMass的X距离,并从centerMass取得X距离作为位置,则当对象的方向为(0,0,1)且右边为( 1,0,0)或(-1,0,0),在任何其他方向X都不是对象的确切“左/右”。这是一个要澄清的视频:https://youtu.be/QXdEF4ScP10

代码:

modelInstance[i].scale.x *= -1;
modelInstance[i].basePosition.set(centre.x - modelInstance[i].distFromCentre.x, modelInstance[I].basePosition.y, modelInstance[I].basePosition.z);
modelInstance[i].transform.set(modelInstance[i].basePosition, modelInstance[i].baseRotation, modelInstance[i].scale);

尝试#2-将对象绕中心质量旋转Y180°,然后翻转其z值。据我了解,这是一个解决方案,但我认为我无法做到这一点。围绕点AFAIK旋转对象的方法包括将矩阵转换为该点,旋转它,然后将其平移回我无法使用的位置。由于具有旋转,连接,翻转和缩放对象的能力,我将旋转,位置和缩放完全分开,因为会发生缩放/旋转和移动问题。每当我更改其中的任何一个时,我都有一个用于位置的Vector3,一个用于旋转的矩阵以及一个用于比例尺的Vector3;使用object.transform.set(position,matrix.getRotation(),scale);因此,当我尝试执行此方法(将旋转矩阵转换为点等)时,对象会单独翻转但保留在同一位置,转换对象转换矩阵会产生奇怪的结果,并且不起作用。两种版本的视频:https://youtu.be/5xzTAHA1vCU

代码:

modelInstance[i].scale.z *= -1;
modelInstance[i].baseRotationMatrix.translate(modelInstance[i].distFromCentre).rotate(Vector3.Y, 180).translate( modelInstance[i].distFromCentre.scl(-1));
modelInstance[i].transform.set(modelInstance[i].basePosition, modelInstance[i].baseRotation, modelInstance[i].scale);
matrix 3d libgdx
1个回答
0
投票

[好吧,因为没有其他人帮助我,所以我会给您一些代码,您可以直接使用它们,也可以用来帮助您更改代码,以便以类似的方式完成。

首先,我倾向于只处理矩阵并将它们作为投影矩阵传递给着色器,即。我真的不知道是什么modelInstance [i],是演员(我从不使用过)还是其他libgdx类?无论是什么,如果您确实使用此代码生成矩阵,则应该能够在其末尾覆盖modelInstance [i]矩阵。如果没有,也许它将为您提供有关如何更改代码的指导。

[首先,旋转或翻转对象时不带任何平移。不要先翻译或缩放,因为旋转时也会旋转已执行的翻译。我使用此函数生成旋转矩阵,它首先绕y轴旋转,我认为这比其他旋转顺序要好得多。或者,您可以创建一个单位矩阵,并在其上使用libgdx旋转函数创建一个相似的矩阵。

  public static void setYxzRotationMatrix(double xRotation, double yRotation, double zRotation, Matrix4 matrix)
  {
    // yxz - y rotation performed first
    float c1=(float)Math.cos(yRotation);
    float c2=(float)Math.cos(xRotation);
    float c3=(float)Math.cos(zRotation);
    float s1=(float)Math.sin(yRotation);
    float s2=(float)Math.sin(xRotation);
    float s3=(float)Math.sin(zRotation);

    matrix.val[0]=  -c1*c3 - s1*s2*s3;  matrix.val[1]=c2*s3;    matrix.val[2]=c1*s2*s3-c3*s1;               matrix.val[3]=0;
    matrix.val[4]=  -c3*s1*s2 + c1*s3;  matrix.val[5]=c2*c3;    matrix.val[6]=c1*c3*s2+s1*s3;    matrix.val[7]=0;
    matrix.val[8]=  -c2*s1;             matrix.val[9]=-s2;      matrix.val[10]=c1*c2;            matrix.val[11]=0;
    matrix.val[12]=0;                   matrix.val[13]=0;       matrix.val[14]=0;                   matrix.val[15]=1.0f;
  }

我使用上述功能将对象旋转到正确的方向,然后将其平移到正确的位置,然后将其乘以相机矩阵并缩放为最终操作。如果您可以这样做,那肯定会起作用,但是我只是将最终矩阵传递给着色器。我不确定您如何使用矩阵。如果要使用比例翻转模型,则应在创建旋转矩阵后立即尝试。我建议您先使用它,而不必先用scale翻转,这样您可以在最后一步中测试matrix.scl()和matrix.scale()。暂时,我不确定您需要哪种缩放功能。

Matrix4 matrix1;
setYxzRotationMatrix(xRotationInRadians, yRotationInRadians, zRotationInRadians,matrix1);
//matrix1 will rotate your model to the correct orientation, around the origin.

//here is where you may wish to use matrix1.scl(-1,1,1) or matrix1.scale(-1,1,1).

//get anchor position here if required - see notes later

//now translate to the correct location, I alter the matrix directly so I know exactly
what is going on. I think matrix1.trn(x, y, z) would do the same.
matrix1.val[12]=x;
matrix1.val[13]=y;
matrix1.val[14]=z;

//Combine with your camera, this may be part of your stage or scene, but I don't use
//these, so can't help.
Matrix4 matrix2;
//set matrix2 to an identity matrix, multiply it by the cameras projection matrix, then
//finally with your rotation/flip/transform matrix1 you've created. 
matrix2.idt().mul(yourCamera.combined).mul(matrix1); 

matrix2.scale(-1,1,1); //flipping like this will work, but may screw up any anchor
                       //position if you calculated one earlier.

//matrix2 is the final projection matrix for your model. ie. you just pass that matrix
to a shader and it should be used to multiply with each vertex position vector to create
the fragment positions.

希望您能够将以上内容适应您的需求。我建议一次尝试一个操作,并确保您的下一个操作不会破坏您已经完成的操作。

上面的代码假设您知道要将模型转换到的位置,也就是知道中心将在哪里。如果您有一个锚点,可以说在x方向上为-3个单位,则需要找出该锚点在旋转后可能会移动到的位置。您可以通过将向量乘以matrix1来做到这一点,我建议在进行任何转换之前将其转换到正确的位置。

Vector3 anchor=new vector3(-3,0,0);
anchor.mul(matrix1); //after this operation anchor is now set to the correct location
                     //for the new rotation and flipping of the model. This offset should
                     //be applied to your translation if your anchor point is not at 0,0,0
                     //of the model.

这可能会有些痛苦,特别是如果您不喜欢矩阵。所做的一切都与您到目前为止尝试的方式不同,这无济于事,但这是我用来显示游戏中所有3D模型的方法,如果您可以将其适应您的代码,它将起作用。希望它无论如何都会对某人有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.