Example #1
0
        // not using GetComponentsInChildren because the order in which links are discovered is important.
        private bool GetLinksInChildrenAndNumber(Transform t, List <BMultiBodyLink> links, int parentIndex)
        {
            BMultiBodyLink mbl = t.GetComponent <BMultiBodyLink>();

            if (mbl != null)
            {
                links.Add(mbl);
                mbl.index       = links.Count - 1;
                mbl.parentIndex = parentIndex;
            }
            for (int i = 0; i < t.childCount; i++)
            {
                int newParent;
                if (mbl == null)
                {
                    newParent = parentIndex;
                }
                else
                {
                    newParent = mbl.index;
                }
                if (!GetLinksInChildrenAndNumber(t.GetChild(i), links, newParent))
                {
                    return(false);
                }
            }
            return(true);
        }
Example #2
0
 private bool ValidateMultiBodyHierarchy(List <BMultiBodyLink> links)
 {
     for (int i = 0; i < links.Count; i++)
     {
         BMultiBodyLink link = links[i];
         if (link.transform.parent.GetComponent <BMultiBodyLink>() == null &&
             link.transform.parent.GetComponent <BMultiBody>() == null)
         {
             Debug.LogErrorFormat("Bad multibody hierarchy. The parent of link {0} does not have a BMultiBodyLink or BMultiBody component", link.name);
             return(false);
         }
     }
     return(true);
 }
Example #3
0
        protected void OnDrawGizmosSelected()
        {
            if (!m_doDrawGizmos)
            {
                return;
            }

            BMultiBodyLink link = GetComponent <BMultiBodyLink>();

            if (link != null)
            {
                if (link.rotationAxis != Vector3.zero)
                {
                    float arcLen = m_jointUpperLimit - m_jointLowerLimit;
                    UnityEditor.Handles.color = new Color(.7f, .5f, .5f, .6f);
                    Vector3 p = transform.TransformPoint(link.localPivotPosition);
                    Vector3 from;
                    Vector3 axisOfRotation;
                    if (link.axesAreFrozen)
                    {
                        axisOfRotation = transform.parent.TransformDirection(link.rotationAxisInParentFrame);
                        from           = transform.parent.TransformDirection(link.jointToThisCOMInParentFrame);
                    }
                    else
                    {
                        axisOfRotation = transform.TransformDirection(link.rotationAxis);
                        from           = transform.TransformDirection(-link.localPivotPosition);
                        if (from.magnitude < 10E-7f)
                        {
                            from = p - transform.parent.position;
                        }

                        from = Vector3.ProjectOnPlane(from, axisOfRotation);
                    }
                    if (from.magnitude > 10E-7f)
                    {
                        from.Normalize();
                        Quaternion q = Quaternion.AngleAxis(m_jointLowerLimit, axisOfRotation);
                        from = q * from;
                        UnityEditor.Handles.DrawSolidArc(p, axisOfRotation, from, arcLen, 1f * link.gizmoScale);
                    }
                }
            }
        }
Example #4
0
 public MultiBodyConstraint CreateMultiBodyConstraint(MultiBody mb)
 {
     if (m_multiBodyConstraintPtr == null)
     {
         BMultiBodyLink mbl = GetComponent <BMultiBodyLink>();
         if (mbl == null)
         {
             Debug.LogError("BMultiBodyConstraint must have a BMultiBodyLink");
             return(null);
         }
         if (mbl.index == -1)
         {
             Debug.LogError("Bad BMultiBodyLink index");
             return(null);
         }
         m_multiBodyConstraintPtr = _CreateConstraint(mb, mbl.index);
     }
     return(m_multiBodyConstraintPtr);
 }
Example #5
0
        public bool AddMultiBody(BMultiBody mb)
        {
            if (!_isDisposed)
            {
                if (m_worldType < WorldType.MultiBodyWorld)
                {
                    Debug.LogError("World type must be be multibody");
                }
                if (debugType >= BDebug.DebugType.Debug)
                {
                    Debug.LogFormat("Adding multibody {0} to world", mb);
                }
                // This is complicated because the native parts for multiple components are created by bullet when the MultiBody is created. We
                // need to let Bullet create these then get the references to the native parts and assign them to the components.
                if (mb._BuildMultiBody())
                {
                    ((MultiBodyDynamicsWorld)m_world).AddMultiBody(mb.GetMultiBody(), (int)mb.groupsIBelongTo, (int)mb.collisionMask);
                    mb.CreateColliders();
                    if (debugType >= BDebug.DebugType.Debug)
                    {
                        Debug.LogFormat("Adding MultiBodyBaseCollider {0} to world", mb);
                    }
                    m_world.AddCollisionObject(mb.GetBaseCollider(), mb.groupsIBelongTo, mb.collisionMask);
                    List <BMultiBodyLink> links = mb.GetLinks();
                    for (int i = 0; i < links.Count; i++)
                    {
                        BMultiBodyLink link = links[i];
                        if (debugType >= BDebug.DebugType.Debug)
                        {
                            Debug.LogFormat("Adding MultiBodyLinkCollider {0} to world", link);
                        }
                        m_world.AddCollisionObject(link.GetLinkCollider(), link.groupsIBelongTo, link.collisionMask);
                        link.isInWorld = true;
                        BMultiBodyConstraint bmbc = link.GetComponent <BMultiBodyConstraint>();
                        if (bmbc != null)
                        {
                            MultiBodyConstraint mbc = bmbc.CreateMultiBodyConstraint(mb.GetMultiBody());
                            mbc.FinalizeMultiDof();
                            if (mbc != null)
                            {
                                if (debugType >= BDebug.DebugType.Debug)
                                {
                                    Debug.LogFormat("Adding MultiBodyLinkConstraint {0} to world", mbc);
                                }
                                ((MultiBodyDynamicsWorld)m_world).AddMultiBodyConstraint(mbc);
                                bmbc.isInWorld = true;
                            }
                        }
                    }

                    MultiBody mbb = mb.GetMultiBody();
                    for (int i = 0; i < links.Count; i++)
                    {
                        MultiBodyLink mbLink = mbb.GetLink(i);
                        links[i].AssignMultiBodyLinkOnCreation(mb, mbLink);
                    }

                    mb.isInWorld = true;
                }
                else
                {
                    if (debugType >= BDebug.DebugType.Debug)
                    {
                        Debug.LogWarningFormat("Failed To Add MultiBody {0} to world ", mb);
                    }
                }
                return(true);
            }
            return(false);
        }
Example #6
0
        void CreateOrConfigureMultiBody(ref MultiBody mb, float baseMass, BCollisionShape[] shapes, BMultiBodyConstraint[] constraints)
        {
            BulletSharp.Math.Vector3 inertia = BulletSharp.Math.Vector3.Zero;
            if (baseMass != 0)
            {
                CollisionShape cs = m_baseCollisionShape.GetCollisionShape();
                cs.CalculateLocalInertia(baseMass, out inertia);
            }

            mb = new MultiBody(m_links.Count, baseMass, inertia, fixedBase, canSleep);
            mb.BasePosition = transform.position.ToBullet();
            UnityEngine.Quaternion r = UnityEngine.Quaternion.Inverse(transform.rotation);
            mb.WorldToBaseRot = r.ToBullet();
            for (int i = 0; i < m_links.Count; i++)
            {
                //Debug.Log("Found link " + i + " parent " + m_links[i].parentIndex + " index " + m_links[i].index);
                BMultiBodyLink link = m_links[i];
                CollisionShape cs   = shapes[i].GetCollisionShape();
                if (cs != null)
                {
                    cs.CalculateLocalInertia(link.mass, out inertia);
                }
                else
                {
                    inertia = BulletSharp.Math.Vector3.Zero;
                }
                FeatherstoneJointType jt = link.jointType;
                int parentIdx            = link.parentIndex;

                // Vector from parent pivot (COM) to the joint pivot point in parent's frame
                UnityEngine.Vector3 parentCOM2ThisPivotOffset;
                link.FreezeJointAxis();
                if (link.parentIndex >= 0)
                {
                    parentCOM2ThisPivotOffset = link.parentCOM2JointPivotOffset;
                }
                else
                {
                    parentCOM2ThisPivotOffset = transform.InverseTransformPoint(link.transform.TransformPoint(link.localPivotPosition));
                }
                // Vector from the joint pivot point to link's pivot point (COM) in link's frame.
                UnityEngine.Vector3 thisPivotToThisCOMOffset = link.thisPivotToJointCOMOffset;

                // Should rotate vectors in parent frame to vectors in local frame
                UnityEngine.Quaternion parentToThisRotation = link.parentToJointRotation;
                switch (jt)
                {
                case FeatherstoneJointType.Fixed:
                    mb.SetupFixed(i, link.mass, inertia, link.parentIndex, parentToThisRotation.ToBullet(), parentCOM2ThisPivotOffset.ToBullet(), thisPivotToThisCOMOffset.ToBullet(), false);
                    break;

                case FeatherstoneJointType.Planar:
                    mb.SetupPlanar(i, link.mass, inertia, link.parentIndex, parentToThisRotation.ToBullet(), link.rotationAxis.ToBullet(), thisPivotToThisCOMOffset.ToBullet(), false);
                    break;

                case FeatherstoneJointType.Prismatic:
                    mb.SetupPrismatic(i, link.mass, inertia, link.parentIndex, parentToThisRotation.ToBullet(), link.rotationAxis.ToBullet(), parentCOM2ThisPivotOffset.ToBullet(), thisPivotToThisCOMOffset.ToBullet(), false);
                    break;

                case FeatherstoneJointType.Revolute:
                    mb.SetupRevolute(i, link.mass, inertia, link.parentIndex, parentToThisRotation.ToBullet(), link.rotationAxis.ToBullet(), parentCOM2ThisPivotOffset.ToBullet(), thisPivotToThisCOMOffset.ToBullet(), false);
                    break;

                case FeatherstoneJointType.Spherical:
                    mb.SetupSpherical(i, link.mass, inertia, link.parentIndex, parentToThisRotation.ToBullet(), parentCOM2ThisPivotOffset.ToBullet(), thisPivotToThisCOMOffset.ToBullet(), false);
                    break;

                default:
                    Debug.LogError("Invalid joint type for link " + link.name);
                    break;
                }
            }
            mb.CanSleep         = true;
            mb.HasSelfCollision = false;
            mb.UseGyroTerm      = true;

            bool damping = true;

            if (damping)
            {
                mb.LinearDamping  = 0.1f;
                mb.AngularDamping = 0.9f;
            }
            else
            {
                mb.LinearDamping  = 0;
                mb.AngularDamping = 0;
            }

            mb.FinalizeMultiDof();
            m_multibody = mb;
        }