/// <summary> /// Computes the new (desired) hand position considering the offset of the collider (to avoid self-collisions) /// </summary> /// <param name="targetHandPosition"></param> /// <param name="currentPosture"></param> /// <returns></returns> private MVector3 ComputeNewPositionWithOffset(MVector3 targetHandPosition, MAvatarPostureValues currentPosture) { //Optionally ensure that the object does not intersect the avatar MCollider collider = this.SceneAccess.GetColliderById(this.objectTransform.ID); //Determine the offset based on the respective collider float offset = 0; if (collider.SphereColliderProperties != null) { offset = (float)collider.SphereColliderProperties.Radius; } if (collider.BoxColliderProperties != null) { offset = (float)collider.BoxColliderProperties.Size.Magnitude(); } if (collider.CapsuleColliderProperties != null) { offset = Math.Max((float)collider.CapsuleColliderProperties.Height, (float)collider.CapsuleColliderProperties.Radius); } //The offset could be also dynamically determined (using the mesh intersection distance or using Physics Compute Pentration in unity) this.SkeletonAccess.SetChannelData(currentPosture); //Get the shoulder positions MVector3 leftShoulderPosition = this.SkeletonAccess.GetGlobalJointPosition(this.AvatarDescription.AvatarID, MJointType.LeftShoulder); MVector3 rightShoulderPosition = this.SkeletonAccess.GetGlobalJointPosition(this.AvatarDescription.AvatarID, MJointType.RightShoulder); //Compute the direction vector pointing from the avatar towards the respective hand MVector3 dir = new MVector3(0, 0, 0); switch (this.handJoint) { case MJointType.LeftWrist: dir = leftShoulderPosition.Subtract(rightShoulderPosition).Normalize(); break; case MJointType.RightWrist: dir = rightShoulderPosition.Subtract(leftShoulderPosition).Normalize(); break; } //Add an offset on top of the position return(targetHandPosition.Add(dir.Multiply(offset))); }
/// <summary> /// Sets up the collider of the MSceneObject /// </summary> private void SetupCollider() { try { //Set the collider (if defined) if (this.GetComponent <Collider>() != null) { //Create a new MCollider instance MCollider mCollider = new MCollider() { ID = this.MSceneObject.ID }; //Get the collider instance Collider collider = this.GetComponent <Collider>(); //Check if collider is a box collider and create corresponding representation in MMI framework if (collider is BoxCollider) { mCollider.Type = MColliderType.Box; BoxCollider boxCollider = collider as BoxCollider; //Set the specific box collider properties mCollider.BoxColliderProperties = new MBoxColliderProperties { //Calculate the size by consdering the scaling Size = new MVector3(boxCollider.size.x * this.transform.localScale.x, boxCollider.size.y * this.transform.localScale.y, boxCollider.size.z * this.transform.localScale.z) }; mCollider.PositionOffset = new MVector3(boxCollider.center.x * this.transform.localScale.x, boxCollider.center.y * this.transform.localScale.y, boxCollider.center.z * this.transform.localScale.z); } //Check if collider is a sphere collider and create corresponding representation in MMI framework if (collider is SphereCollider) { mCollider.Type = MColliderType.Sphere; SphereCollider sphereCollider = collider as SphereCollider; //Set the specific sphere collider properties mCollider.SphereColliderProperties = new MSphereColliderProperties { Radius = sphereCollider.radius * Mathf.Max(this.transform.localScale.x, this.transform.localScale.y, this.transform.localScale.z) }; mCollider.PositionOffset = new MVector3(sphereCollider.center.x * this.transform.localScale.x, sphereCollider.center.y * this.transform.localScale.y, sphereCollider.center.z * this.transform.localScale.z); } //Check if collider is a capsule collider and create corresponding representation in MMI framework if (collider is CapsuleCollider) { mCollider.Type = MColliderType.Capsule; CapsuleCollider capsuleCollider = collider as CapsuleCollider; //Set the specific capsule collider properties mCollider.CapsuleColliderProperties = new MCapsuleColliderProperties { Radius = capsuleCollider.radius * Mathf.Max(this.transform.localScale.x, this.transform.localScale.z), Height = capsuleCollider.height * this.transform.localScale.y, }; //Set the position offset mCollider.PositionOffset = new MVector3(capsuleCollider.center.x * this.transform.localScale.x, capsuleCollider.center.y * this.transform.localScale.y, capsuleCollider.center.z * this.transform.localScale.z); } //Check if collider is a mesh collider and create corresponding representation in MMI framework if (collider is MeshCollider) { mCollider.Type = MColliderType.Mesh; MeshCollider meshCollider = collider as MeshCollider; mCollider.MeshColliderProperties = new MMeshColliderProperties(); mCollider.MeshColliderProperties.Vertices = meshCollider.sharedMesh.vertices.Select(s => s.ToMVector3()).ToList(); mCollider.MeshColliderProperties.Triangles = meshCollider.sharedMesh.triangles.ToList(); //To do provide further option to just consider the bounds as approximation of the mesh collider } //Assign the collider this.MSceneObject.Collider = mCollider; } } catch (System.Exception e) { Debug.LogError("Problem setting up the collider: " + e.Message + " " + e.StackTrace); } }
/// <summary> /// Creates a Unity collider based on the MCollider and a transform /// </summary> /// <param name="collider"></param> /// <param name="transform"></param> /// <returns></returns> public static Collider CreateCollider(MCollider collider, MTransform transform) { if (collider == null || transform == null) { return(null); } GameObject result = null; switch (collider.Type) { case MColliderType.Box: MBoxColliderProperties mboxCollider = collider.BoxColliderProperties; if (mboxCollider == null) { Debug.Log("Box collider is null"); return(null); } GameObject boxGameObject = GameObject.CreatePrimitive(PrimitiveType.Cube); boxGameObject.transform.position = transform.Position.ToVector3(); boxGameObject.transform.rotation = transform.Rotation.ToQuaternion(); //Assign the properties of the collider BoxCollider boxCollider = boxGameObject.GetComponent <BoxCollider>(); boxCollider.center = collider.PositionOffset.ToVector3(); boxCollider.size = mboxCollider.Size.ToVector3(); result = boxGameObject; break; case MColliderType.Sphere: MSphereColliderProperties mSphereCollider = collider.SphereColliderProperties; if (mSphereCollider == null) { Debug.Log("Sphere collider is null"); return(null); } GameObject sphereGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphereGameObject.transform.position = transform.Position.ToVector3(); sphereGameObject.transform.rotation = transform.Rotation.ToQuaternion(); SphereCollider sphereCollider = sphereGameObject.GetComponent <SphereCollider>(); sphereCollider.center = collider.PositionOffset.ToVector3(); sphereCollider.radius = (float)mSphereCollider.Radius; result = sphereGameObject; break; case MColliderType.Capsule: MCapsuleColliderProperties mCapsuleCollider = collider.CapsuleColliderProperties; if (mCapsuleCollider == null) { Debug.Log("Capsule collider is null"); return(null); } GameObject capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule); capsule.transform.position = transform.Position.ToVector3(); capsule.transform.rotation = transform.Rotation.ToQuaternion(); CapsuleCollider capsuleCollider = capsule.GetComponent <CapsuleCollider>(); capsuleCollider.center = collider.PositionOffset.ToVector3(); capsuleCollider.radius = (float)mCapsuleCollider.Radius; capsuleCollider.height = (float)mCapsuleCollider.Height; result = capsule; break; case MColliderType.Mesh: MMeshColliderProperties mMeshCollider = collider.MeshColliderProperties; if (mMeshCollider == null) { Debug.Log("Mesh collider is null"); return(null); } //To do break; } return(result.GetComponent <Collider>()); }