FBX scaling cannot use negative numbers.
image.png (62.5 KB)
When I use a negative number, it will automatically be converted to a positive number.
FBX scaling cannot use negative numbers.
image.png (62.5 KB)
When I use a negative number, it will automatically be converted to a positive number.
Hi
Пользователь сообщает о проблеме с использованием отрицательных значений масштабирования в FBX, которые автоматически преобразуются в положительные, что приводит к несоответствию ожидаемого и полученного результата. Упоминается ручное кодирование и попытка зеркального отображения модели, что указывает на необходимость помощи в устранении ошибки в коде или поведении API.
Yes plz help
@LuoHui
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.
Issue ID(s): THREEDNET-1749
@LuoHui
Thank you for bringing this to our attention.
Different 3D formats handle node transformations in various ways—some use matrices, others rely on Euler angles with scaling and translation, some use quaternions with scaling and translation, and a few employ custom formulas. To support all of these cases, our library automatically converts the incoming data to a common internal representation. That conversion is what you observed in your situation.
We’re working on a solution that preserves the original transformation definitions while maintaining full compatibility across formats. Your feedback helps us improve this process, and we appreciate your patience. If you have any further questions or need additional assistance, please let us know.
I’d like to know when this issue will be fixed, and I look forward to your product becoming even better!
@LuoHui
The current implementation uses quaternion, scaling, and translation by default. I noticed you assigned the transformation matrix manually in your code; skipping this might resolve the issue. We’ll investigate exposing the internal transform carefully today, as doing so could introduce potential issues with other file formats.
You’re right. When I don’t use Matrix4 rotationMatrix, negative values for the scale are normal.
I need to clarify that this is the original code. The example in the image is just my test code with negative numbers added. I want to know how I should modify it to use the matrix’s scale and multiply it with my external negative scale to achieve the correct scale and successfully output fbx’s P: “Lcl Scaling”, “Lcl Scaling”.
Node node = parentNode.CreateChildNode(partObj.Name);
Matrix4 rotationMatrix = new Matrix4
(
partObj.ScaleBase[0].X, partObj.ScaleBase[1].X, partObj.ScaleBase[2].X, 0,
partObj.ScaleBase[0].Y, partObj.ScaleBase[1].Y, partObj.ScaleBase[2].Y, 0,
partObj.ScaleBase[0].Z, partObj.ScaleBase[1].Z, partObj.ScaleBase[2].Z, 0,
0, 0, 0, 1
);
node.Transform.TransformMatrix = rotationMatrix;
node.Transform.SetScale(partObj.Scale[0], partObj.Scale[1], partObj.Scale[2]);
node.Transform.SetTranslation(partObj.Coord[0], partObj.Coord[1], partObj.Coord[2]);
data:
ScaleBase: 0.9997265,0.09965264,6.375911E-08 / 0.02338834,-0.9950223,-7.487667E-07 / -1.305191E-08,-4.372432E-07,1
Scale: 0.4911708,0.7093347,0.4804392
The scale of ScaleBase is already negative.
@LuoHui
A potential workaround is to use Matrix4.Decompose to decompose your transformation matrix into translation, scaling, and rotation. You can then multiply the scaling component with your negative values and assign these results to the Rotation, Scaling, and Translation properties of the node’s Transform.
I implemented it using this code following your tutorial.
This code can solve the current problem.
rotationMatrix.Decompose(out Vector3 translation, out Vector3 scaling, out Quaternion rotation);
if (!true)
{
node.Transform.TransformMatrix = rotationMatrix;//這個方案scale負數會自動變正 已反餽
}
else
{
Vector3 eulerAnglesInRadians = rotation.EulerAngles(); // Returns (pitch, yaw, roll) in radians
double rx_deg = eulerAnglesInRadians.X * 180.0 / Math.PI; // Convert to degrees if necessary
double ry_deg = eulerAnglesInRadians.Y * 180.0 / Math.PI;
double rz_deg = eulerAnglesInRadians.Z * 180.0 / Math.PI;
//node.Transform.SetEulerAngles(rx_deg, ry_deg, rz_deg);//歐拉角計算不一定準確 還要處理一下
void QuaternionToEulerZYX(Quaternion q, out double yaw_deg, out double pitch_deg, out double roll_deg)
{
double w = q.W;
double x = q.X;
double y = q.Y;
double z = q.Z;
double sinr_cosp = 2 * (w * x + y * z);
double cosr_cosp = 1 - 2 * (x * x + y * y);
roll_deg = Math.Atan2(sinr_cosp, cosr_cosp);
double sinp = 2 * (w * y - z * x);
if (Math.Abs(sinp) >= 1)
pitch_deg = Math.Sign(sinp) * Math.PI / 2;
else
pitch_deg = Math.Asin(sinp);
double siny_cosp = 2 * (w * z + x * y);
double cosy_cosp = 1 - 2 * (y * y + z * z);
yaw_deg = Math.Atan2(siny_cosp, cosy_cosp);
yaw_deg *= 180.0 / Math.PI;
pitch_deg *= 180.0 / Math.PI;
roll_deg *= 180.0 / Math.PI;
}
QuaternionToEulerZYX(rotation, out double rz_deg_custom, out double ry_deg_custom, out double rx_deg_custom);
node.Transform.SetEulerAngles(rx_deg_custom, ry_deg_custom, rz_deg_custom);
}
var finalScaling = new Vector3(
scaling.X * partObj.Scale[0],
scaling.Y * partObj.Scale[1],
scaling.Z * partObj.Scale[2]
);
node.Transform.SetScale(finalScaling.X, finalScaling.Y, finalScaling.Z);
node.Transform.SetTranslation(partObj.Coord[0], partObj.Coord[1], partObj.Coord[2]);
However, I found that the result obtained by your EulerAngles() method doesn’t seem to be what I’m looking for. For example,
0 / 0 / -0.999999999999997 Using EulerAngles(), the result is
180 / 0 / -179.999991990893
But after writing this result to FBX and importing it into 3ds Max, the rotation result is 0,180,0. When I manually change it to 0,0,-180, the model’s position is correct.
But I think your result should be 0 / 0 / -179.999991990893 to meet expectations. You can refer to the algorithm in my code; my algorithm works correctly.
@LuoHui
Thank you for providing the code snippet; our implementation was reverse-engineered from an existing 3D SDK. We will evaluate your approach.