Hi again,
I want to implement some exercises in my Unity project where I have to grasp some rigid objects to put them in some nets. We have, for not deformable objects, a useful system to grab native Unity objects (Colliders+RigidBodies).
In this point, I have 3 options:
-
Implement RigidGrasping.cs in Unity. Grasping.cs doesn’t work with iMSTK-Unity rigids →
"Grasping rigid with static geometry (mesh) not supported"
-
Use my TransformDevice in a native object, and link my rigid to it, so I can grasp objects and collide with deformables too. The problem with this option is that, when releasing the object fo example in the Net, the net will react to the rigid collision, but the rigid won’t stop because will be following the TransformDevice, that will overstep(?) the net.
-
Modify the C++ rigid code to implement a function that sets the rigid pose only once (when called), so I can set to the iMSTK rigid the position and rotation of the Unity Object when is realased. Obviously, this needs to:
- Add native rigidbody and collider to the iMSTK-Unity rigid
- Not updating the rigid position and rotation with the iMSTK info during the grab time.
I think 1 and 3 are the best options, and option 3 will be more useful for using some of the code that is already implemented and using our Unity native rigids grasping system. What do you think?
If you’re curious, I have tried to implement RigidGrasping.cs but runtime errors are shown and I can’t find them in the code, basically is Grasping.cs but using PbdRigidBodyGrasping (from iMSTK). I thought it would be easy:
namespace ImstkUnity
{
public class RigidGrasping : ImstkInteractionBehaviour
{
public enum GraspType
{
Vertex,
Cell,
}
public Rigid rigidModel;
public GeometryFilter graspingGeometry;
public Rigid graspedObject;
[Tooltip ("If not null the collision will be disabled when a grasp happened")]
public CollisionInteraction collisionToDisable;
public GraspType graspType = GraspType.Cell;
public bool isTwoWay = false;
Imstk.PbdRigidObjectGrasping interaction;
private string _collisionDetectionType;
public override Imstk.SceneObject GetImstkInteraction()
{
if (rigidModel == null || graspedObject == null)
{
Debug.LogError("Both models need to be assigned for the interaction to work");
}
_collisionDetectionType = CollisionInteraction.GetCDType(rigidModel, graspedObject);
if (_collisionDetectionType == "")
{
Debug.LogError("Could not determine collision type for grasping in " + gameObject.name);
}
if (! rigidModel.isActiveAndEnabled || !graspedObject.isActiveAndEnabled)
{
return null;
}
interaction = new Imstk.PbdRigidObjectGrasping(rigidModel.GetDynamicObject() as Imstk.PbdObject, graspedObject.GetDynamicObject() as Imstk.RigidObject2);//Two-Way
Imstk.Geometry geom = rigidModel.GetDynamicObject().getCollidingGeometry();
Imstk.AnalyticalGeometry analytical = Imstk.Utils.CastTo<Imstk.AnalyticalGeometry>(geom);
if (analytical == null)
{
Debug.LogError("Can't convert to analytical geometry" + geom.getTypeName());
}
return interaction;
}
public void StartGrasp()
{
if (interaction == null) return;
Imstk.Geometry rigidGeometry = rigidModel.GetDynamicObject().getCollidingGeometry();
Imstk.AnalyticalGeometry analyticalGraspingGeom;
if (graspingGeometry == null)
{
analyticalGraspingGeom = Imstk.Utils.CastTo<Imstk.AnalyticalGeometry>(rigidGeometry);
}
else
{
analyticalGraspingGeom = Imstk.Utils.CastTo<Imstk.AnalyticalGeometry>(graspingGeometry.GetOutputGeometry());
analyticalGraspingGeom.setTransform(rigidGeometry.getTransform());
analyticalGraspingGeom.updatePostTransformData();
}
if (analyticalGraspingGeom == null)
{
Debug.LogError("Grasping Geometry can't be null in " + gameObject.name);
return;
}
switch (graspType)
{
case (GraspType.Cell):
interaction.beginCellGrasp(analyticalGraspingGeom);
break;
case (GraspType.Vertex):
interaction.beginVertexGrasp(analyticalGraspingGeom);
break;
}
}
private void Update()
{
if (interaction != null && collisionToDisable != null)
{
var imstkCollision = Imstk.Utils.CastTo<Imstk.CollisionInteraction>(collisionToDisable.GetImstkInteraction());
if (interaction.hasConstraints())
{
imstkCollision.setEnabled(false);
}
else
{
imstkCollision.setEnabled(true);
}
}
}
public void EndGrasp()
{
if (interaction != null)
{
interaction.endGrasp();
}
}
/// <summary>
/// Will return true whenever constraints where generated, this means
/// that something has _actually_ been grasped.
/// NOTE it takes at least one simulation manager FixedUpdate() for this
/// to return a correct value, check in the next frame after calling
/// StartGrasp()
/// </summary>
public bool HasConstraints()
{
return interaction != null && interaction.hasConstraints();
}
}
}