Page 1 of 2

Making a door hinge

Posted: Sat Jun 09, 2018 3:07 am
by thehankinator
I am working making a door, I have it so that if I walk up to the door and click, it opens(yay!). The problem now is that if I push the door without opening it, the door can fall over. How can I "pin" the door such that it's position is locked and the axis which the door can rotate is restricted to the Z axis? I've played with the Constraint components (Line, Point and Plane) and I cannot figure out how to configure them to create the hinge on the door. Anyone dealt with this before? Thanks!

Re: Making a door hinge

Posted: Sat Jun 09, 2018 8:03 am
by mknmknmknjk
unity has hinge joint . cryengine have similar, but have to use c++ code .

in rigidentity.cpp line 854,
https://github.com/CRYTEK/CRYENGINE/blo ... entity.cpp

there is comment saying:
// 3. if only X limits are valid then we need a hinge joint to prevent YZ rotations and a constraint to limit the X twist

but there is no use cast.

there are already constrains
https://github.com/CRYTEK/CRYENGINE/tre ... onstraints

Re: Making a door hinge

Posted: Sun Jun 10, 2018 2:50 am
by thehankinator
This is the code I have come up with so far:

Code: Select all

Matrix34 entityTM = m_pEntity->GetWorldTM();
IPhysicalEntity *pPE = m_pEntity->GetPhysics();
pe_action_add_constraint ac;

ac.flags = world_frames | constraint_no_tears;
ac.pBuddy = WORLD_ENTITY;
ac.xlimits[0] = 1.0f;
ac.xlimits[1] = 0.0f;
ac.pt[0] = ac.pt[1] = entityTM.GetTranslation();

pPE->Action(&ac);
The door position is locked however if I push on the door from the side, it will rotate over the y axis. It seems like I need to find a way to lock the rotation on the y axis. I've tried setting pt[1] above pt[0] and adding the constraint_line flag but I haven't been able to find the right formula. Any ideas?

Thanks for your help.

Re: Making a door hinge

Posted: Sun Jun 10, 2018 9:44 am
by mknmknmknjk

Re: Making a door hinge

Posted: Mon Jun 11, 2018 2:04 am
by thehankinator
I've been referencing that file but I am still struggling to get it to work properly. I have two cases that work but both have flaws. I don't know where I am going wrong.

First
The problem with this is that if I push on the door from the side, the "hinge" at the top moves and the door is no longer square.
Image

Code: Select all

Matrix34 entityTM = m_pEntity->GetWorldTM();
IPhysicalEntity *pPE = m_pEntity->GetPhysics();
pe_action_add_constraint ac;

ac.flags = world_frames | constraint_no_tears;
ac.pBuddy = WORLD_ENTITY;
ac.xlimits[0] = 1.0f;
ac.xlimits[1] = 0.0f;
ac.pt[0] = ac.pt[1] = entityTM.GetTranslation();
ac.damping = 10;

pPE->Action(&ac);

Second
The problem with this is that if I push the door open then push it closed, the position if the door moves away from the hinge leaving a gap.
Image

Code: Select all

Matrix34 entityTM = m_pEntity->GetWorldTM();
IPhysicalEntity *pPE = m_pEntity->GetPhysics();
pe_action_add_constraint ac;

ac.flags = world_frames | constraint_no_tears | constraint_line;
ac.pBuddy = WORLD_ENTITY;
ac.xlimits[0] = 1.0f;
ac.xlimits[1] = 0.0f;
ac.pt[0] = ac.pt[1] = entityTM.GetTranslation();
ac.damping = 10;

pPE->Action(&ac);

Re: Making a door hinge

Posted: Mon Jun 11, 2018 11:58 am
by mknmknmknjk
constraint.flags = world_frames | constraint_no_tears | constraint_line;
world_frames indicte world pivot and world point.

constraint.pt[0] = constraint.pt[1] = slotTransform.GetTranslation();
slotTransform.GetTranslation(); indicate world point.

m_axis is your local rotation axis.
constraint.qframe[0] = constraint.qframe[1] = Quat(slotTransform) * Quat::CreateRotationV0V1(Vec3(1, 0, 0), m_axis);

Quat(slotTransform) * Quat::CreateRotationV0V1(Vec3(1, 0, 0), m_axis) indicate world frame.

world point must be your hinge point.

Re: Making a door hinge

Posted: Sat Jun 16, 2018 7:27 pm
by thehankinator
Sorry for the delay, I had to travel for work.

I tried initializing qframe[0] and qframe[1] as LineConstraint did but I still must have something messed up. My code looks like this now:

Code: Select all

Matrix34 entityTM = m_pEntity->GetWorldTM();
IPhysicalEntity *pPE = m_pEntity->GetPhysics();
pe_action_add_constraint ac;
Vec3 axis = Vec3(0, 0, 1);

ac.flags = world_frames | constraint_no_tears | constraint_line;
ac.pBuddy = WORLD_ENTITY;
ac.xlimits[0] = 1.0f;
ac.xlimits[1] = 0.0f;
ac.pt[0] = ac.pt[1] = entityTM.GetTranslation();
ac.qframe[0] = ac.qframe[1] = Quat(entityTM) * Quat::CreateRotationV0V1(Vec3(1, 0, 0), axis);
ac.damping = 10;
In this configuration I can push the door over, it's like it's pinned over the X axis rather than Z. By setting axis to 0,0,1 the entity rotation is constrained to only rotating on the Z axis? I tried 1,0,0 and 0,1,0 also but the door rotation was not constrained to the Z axis. Is the problem the first term in Quat::CreateRotationV0V1? Should it be Vec3(0,0,1)? I tried playing with that but couldn't get it to work right.

I've got to be close, any ideas what else I can check? Thanks again for your help.

Re: Making a door hinge

Posted: Sat Jun 16, 2018 11:15 pm
by mknmknmknjk
set rotation so that your x axis is aligned to your rotation axis.
q*(1,0,0) = world rotation axis.

Re: Making a door hinge

Posted: Sat Jun 16, 2018 11:21 pm
by mknmknmknjk
CreateRotationV0V1 means rotate vector3 from v0 to v1. because rotation around x axis. so v0 should be vector 1,0,0 v1 should be your local rotation axis.

Re: Making a door hinge

Posted: Sun Jun 17, 2018 2:45 am
by thehankinator
So if I want a swinging door that has a hinge along the (world) Z axis, Then using the code previously posted on my component, I would rotate my entity in the editor by 90 degrees on the Y axis then rotate the mesh component on the Y axis (to make the door stand up right) by -90 degrees? Is that what you meant? I tried this and the door swings correctly but the door's position isn't pinned.