/** * Creates or configures a RigidBody based on the current settings. Does not alter the internal state of this component in any way. * Can be used to create copies of this BRigidBody for use in other physics simulations. */ public virtual bool CreateMultiBody(ref MultiBody mb, ref BulletSharp.Math.Vector3 localInertia, CollisionShape cs) { localInertia = BulletSharp.Math.Vector3.Zero; if (_mass > 0) { cs.CalculateLocalInertia(_mass, out localInertia); } if (mb == null) { int nbLinks = Links.Count; foreach (BMultiBodyLink link in Links) { nbLinks += link.NbLinks; } Debug.Log("Adding multibody with " + nbLinks + " links"); mb = new MultiBody(nbLinks, _mass, localInertia, false, false); mb.BaseWorldTransform = transform.localToWorldMatrix.ToBullet(); mb.HasSelfCollision = SelfCollision; var collider = new MultiBodyLinkCollider(mb, -1); collider.CollisionShape = cs; collider.WorldTransform = transform.localToWorldMatrix.ToBullet(); collider.CollisionFlags = collisionFlags; collider.UserObject = UserObject ?? this; BPhysicsWorld.Get().world.AddCollisionObject(collider, groupsIBelongTo, collisionMask); mb.BaseCollider = collider; m_collisionObject = collider; BulletMultiBodyLinkColliderProxy baseProxy = gameObject.GetComponent <BulletMultiBodyLinkColliderProxy>(); if (baseProxy == null) { baseProxy = gameObject.AddComponent <BulletMultiBodyLinkColliderProxy>(); } baseProxy.target = collider; try { int currentLinkIndex = 0; for (int i = 0; i < Links.Count; ++i) { currentLinkIndex += Links[i].AddLinkToMultiBody(this, currentLinkIndex, -1, transform); } mb.FinalizeMultiDof(); } catch (Exception e) // if an error occurs, don't add the object, otherwise unity will crash { Debug.LogErrorFormat("Error occured while setting MultiBody : {0}\n{1}", e.Message, e.StackTrace); BPhysicsWorld.Get().world.RemoveCollisionObject(collider); return(false); } mb.CanSleep = false; mb.UserObject = UserObject ?? this; } return(true); }
public void CreateUnityMultiBodyLinkColliderProxy(MultiBodyLinkCollider body) { GameObject cube = Instantiate <GameObject>(cubePrefab); CollisionShape cs = body.CollisionShape; if (cs is BoxShape) { BoxShape bxcs = cs as BoxShape; BulletSharp.Math.Vector3 s = bxcs.HalfExtentsWithMargin; MeshRenderer mr = cube.GetComponentInChildren <MeshRenderer>(); mr.transform.localScale = s.ToUnity() * 2f; Matrix4x4 m = body.WorldTransform.ToUnity(); cube.transform.position = BSExtensionMethods2.ExtractTranslationFromMatrix(ref m); cube.transform.rotation = BSExtensionMethods2.ExtractRotationFromMatrix(ref m); cube.transform.localScale = BSExtensionMethods2.ExtractScaleFromMatrix(ref m); Destroy(cube.GetComponent <BulletRigidBodyProxy>()); BulletMultiBodyLinkColliderProxy cp = cube.AddComponent <BulletMultiBodyLinkColliderProxy>(); cp.target = body; } else { Debug.LogError("Not implemented"); } }
public int AddLinkToMultiBody(BMultiBody mb, int currentLinkIndex, int parentIndex, Transform parent) { if (isLinked) { Debug.LogErrorFormat("Cannot add link {0} to multibody {1} bacause it is already linked", name, mb.name); return(0); } BCollisionShape collisionShape = GetComponent <BCollisionShape>(); if (collisionShape == null) { throw new MissingComponentException("Could not find " + typeof(BCollisionShape).Name + " component on BodyLink " + name); } multiBody = mb; linkId = currentLinkIndex; parentLinkId = parentIndex; parentTransform = parent; CollisionShape shape = collisionShape.GetCollisionShape(); if (shape == null) { throw new MissingComponentException("Could not get collision shape from " + collisionShape.GetType().Name + " shape component on BodyLink " + name); } BulletSharp.Math.Vector3 linkInertia; shape.CalculateLocalInertia(Mass, out linkInertia); if (BPhysicsWorld.Get().debugType >= BulletUnity.Debugging.BDebug.DebugType.Debug) { Debug.LogFormat(this, "Adding link {0} : {1} to parent {2} of multibody {3}", currentLinkIndex, name, parentIndex, mb.name); } SetupLink(linkInertia); linkCollider = new MultiBodyLinkCollider(mb.MultiBody, currentLinkIndex); linkCollider.CollisionShape = shape; linkCollider.WorldTransform = transform.localToWorldMatrix.ToBullet(); linkCollider.CollisionFlags = collisionFlags; linkCollider.Friction = Friction; linkCollider.RollingFriction = RollingFriction; linkCollider.Restitution = Restitution; linkCollider.UserObject = this; BPhysicsWorld.Get().world.AddCollisionObject(linkCollider, groupsIBelongTo, collisionMask); m_collisionObject = linkCollider; BulletMultiBodyLinkColliderProxy proxy = gameObject.GetComponent <BulletMultiBodyLinkColliderProxy>(); if (proxy == null) { proxy = gameObject.AddComponent <BulletMultiBodyLinkColliderProxy>(); } mb.MultiBody.GetLink(currentLinkIndex).Collider = linkCollider; proxy.target = linkCollider; isLinked = true; foreach (BMultiBodyConstraint mbc in Constraints) { mbc.AddConstraintToMultiBody(MultiBody, LinkId); } int addedLinks = 1; for (int i = 0; i < Links.Count; ++i) { addedLinks += Links[i].AddLinkToMultiBody(mb, i + currentLinkIndex + 1, currentLinkIndex, transform); } return(addedLinks); }