I have two Quaternion transforms, and a viewmatrix. These are custom transforms made by Dice, and I'm working on some custom modding for an older version of Battlefield.
Now, I don't have the entire context of these, as I've reversed engineered these, however I'm lost on how to calculate the Child's world location with the parent.
One is the parent transform, and here's what it looks like
Parent/Root
translation: Vector4(-497.010f, 116.293f, -393.720f, 0.0f)
rotation: Quaternion(0.000f, 0.0707f, 0.000f, 0.707f)
Child
translation: Vector4(0.018f, 1.547f, 0.030f, 0) // note how translation is simply an offset of the parent
rotation: Quaternion(0.000f, 0.0707f, 0.000f, 0.707f) // I made this value up, I can't remember what a good example was
How do I factor in the parents rotation? I've tried the following:
relativeRotation = inverse(parent.Rotation) * child.Rotation
var transformed = Vector4.Transform(childTranslation, relativeRotation) + parent.Translation
However it doesn't seem to be accurate. What am I missing here? Speficically I'm looking to calculate the 3d coordinate (with rotation applied) of the child, i.e. the world location.
There's also a scale for both, but its the same value for all parent and child:
var scale = Vector4(1, 1, 1, 0)
Current code:
parent
child
childWorldLocation = Vector4.Multiply(Vector4.Transform(child.Translation, parent.Rotation), parent.Scale) + parent.Translation;
screenCoordinate = Util.WorldToScreen(new Vector3(childWorldPosition.X, childWorldPosition.Y, childWorldPosition.Z), viewProjection); // this works fine for any vec3 origin, not the issue
Result is most of the child transforms are near the bottom where the parent translation is.
W2S:
public static Vector2 WorldToScreen(Vector3 position, Matrix viewProjection) {
float w = viewProjection.M14 * position.X + viewProjection.M24 * position.Y + viewProjection.M34 * position.Z + viewProjection.M44;
if (w < 0.01) {
return Vector2.Zero;
}
var screenPositionX = viewProjection.M11 * position.X + viewProjection.M21 * position.Y + viewProjection.M31 * position.Z + viewProjection.M41;
var screenPositionY = viewProjection.M12 * position.X + viewProjection.M22 * position.Y + viewProjection.M32 * position.Z + viewProjection.M42;
float invw = 1.0f / w;
screenPositionX *= invw;
screenPositionY *= invw;
float x = (float)H.ViewPortX / 2; //viewport is the resolution x,y
float y = (float)H.ViewPortY / 2;
x += 0.5f * screenPositionX * (float)H.ViewPortX + 0.5f;
y -= 0.5f * screenPositionY * (float)H.ViewPortY + 0.5f;
return new Vector2(x, y);
}
x += 0.5f * screenPositionX * (float)H.ViewPortX + 0.5f;
, haven't you messed up the symbols? Shouldn't it bex += 0.5f * screenPositionX + (float)H.ViewPortX * 0.5f;
or am I missing something? \$\endgroup\$