Hi sinkingsugar!
As far as I know, yes I am setting my frames properly since my constraint’s center gets set exactly where I do intend it to be, relatively to the child.
This is my setup:
EDIT: it says -2.5 for the RelativeContraintLocation. But ignore it, the proper value is 2.5 and it works fine to have the constraint place where the cube is.
–
The cube at the bottom, 2.5 units away from the selected cube, is where my constraint is meant to be (relative to the cube). The cube on the right of the screenshot is the parent, which is a kinematic rigid body (0 mass).
You can also see the current parameters of my component on the far right.
Here is the code that’s meant to do the thing, As you will see, I’m pretty sure that my parent frame is correct. I’m very confused about the child’s frame though…
RigidbodyComponent parentBody = null; //The Rigid body this entity will attach to.
RigidbodyComponent childBody = Entity.Get<RigidbodyComponent>(); //This entity's rigid body.
Generic6DoFConstraint newConstraint = null;
if (childBody.ColliderShapes.Count <= 0)
{
Console.WriteLine("Entity's rigid body has no collider shape. No constraint will be created.");
return;
}
Matrix childFrame = Matrix.Translation(RelativeConstraintLocation);
Quaternion childWorldRotation = Quaternion.RotationMatrix(Entity.Transform.WorldMatrix);
if (ParentEntity?.GetAll<RigidbodyComponent>().Count(component => true) == 1)
{
parentBody = ParentEntity.Get<RigidbodyComponent>(); //The Rigid body this entity will attach to.
if (parentBody.ColliderShapes.Count <= 0)
{
Console.WriteLine("Parent entity's rigid body has no collider shape. No constraint will be created.");
return;
}
// Copy of the RelativeConstraintLocation vector, just to make sure and manipulate it.
Vector3 parentOffset = RelativeConstraintLocation;
// Rotates the offset using world rotation so that it lines up with the local space to compute the parent's frame constraint point.
parentOffset = Vector3.Transform(parentOffset, childWorldRotation);
// Calculates the position of the constraint center taking into account the rotation of the child (since the center is in its relative space)
Vector3 parentFrameVector = (Entity.Transform.WorldMatrix.TranslationVector - ParentEntity.Transform.WorldMatrix.TranslationVector) + parentOffset;
// Definition of the parent frame translation, basically the local offset to the constraint center put in a matrix.
Matrix parentFrame = Matrix.Identity * Matrix.Translation(parentFrameVector);
// Multiplying the matrix to counter-rotate the constraint so that it does not line up with the parent, but keeps world space regardless of the parent's rotation (otherwise it will just re-align with it and the whole system will rotate)
parentFrame *= Matrix.RotationQuaternion(QuaternionInverse(Quaternion.RotationMatrix(ParentEntity.Transform.WorldMatrix)));
// Defining the child's frame which is basically the relative offset for the translation. I'm not sure I need to counter-rotate it in this case of rotate it.. those frames usage is a bit opaque and hard to grasp...
childFrame = Matrix.Identity * Matrix.Translation(RelativeConstraintLocation);
Console.WriteLine("Parent anchor point = {0} \nChild anchor point = {1}", parentFrame.TranslationVector, childFrame.TranslationVector);
// Make sure that those bodies cannot sleep.
parentBody.CanSleep = childBody.CanSleep = false;
// Create the constraint and returns it as a Generic6DoFConstraint
newConstraint = Simulation.CreateConstraint(ConstraintTypes.Generic6DoF, parentBody, childBody, parentFrame, childFrame, true) as Generic6DoFConstraint;
}
else if (ParentEntity == null || ParentEntity?.GetAll<RigidbodyComponent>().Count(component => true) != 1)
{
newConstraint = Simulation.CreateConstraint(ConstraintTypes.Generic6DoF, childBody, childFrame, true) as Generic6DoFConstraint;
}
if (newConstraint != null)
{
// Sets limits... In world space? :'(
newConstraint.AngularLowerLimit = Vector3DegreesToRadians(AngularLowerLimit);
newConstraint.AngularUpperLimit = Vector3DegreesToRadians(AngularUpperLimit);
newConstraint.LinearLowerLimit = LinearLowerLimit;
newConstraint.LinearUpperLimit = LinearUpperLimit;
// Adds constraint to simulation.
this.GetSimulation().AddConstraint(newConstraint, DisableCollisionBetweenBodies);
if (parentBody != null)
{
parentBody.ClearForces();
parentBody.AngularVelocity = parentBody.LinearVelocity = Vector3.Zero;
}
childBody.ClearForces();
childBody.AngularVelocity = childBody.LinearVelocity = Vector3.Zero;
}
I did put some comments to help read and understand what I’m doing that’s important in there. (also, yes I’m pre-setting the childFrame, but I did re-set it later, it’s not optimal yet, things that will get cleaned up afterward
)
There is also the function “QuaternionInverse” which is defined in the following way since matrix.invert does not return a new matrix but only modified the one existing. 
private Quaternion QuaternionInverse(Quaternion quat)
{
quat.Invert();
return quat;
}
To be honest, I hope that I just messed up my frames. But if that’s not the case… uhhh. That will be a huge problem.
There seems to be a couple of bugs with the limits as well yes, since setting up the Y axis as free axis and having my DynamicCube revolve around it resulted in 180 rotations only… When it reached either side… It got brutally sent back the other way.
EDIT 2: This issue only happens on Y axis, X and Z rotate just fine. :o –
Thanks for taking the time to help me with this. 