public void ProcessIsland(List <CollisionObject> bodies, List <PersistentManifold> manifolds, int numManifolds, int islandID)
            {
                //also add all non-contact constraints/joints for this island
                List <TypedConstraint> startConstraint = new List <TypedConstraint>();
                int numCurConstraints = 0;
                int startIndex        = 0;
                int i;

                //find the first constraint for this island
                for (i = 0; i < _sortedConstraints.Count; i++)
                {
                    if (TypedConstraint.GetConstraintIslandId(_sortedConstraints[i]) == islandID)
                    {
                        //startConstraint = &m_sortedConstraints[i];
                        startIndex = i;
                        break;
                    }
                }
                //count the number of constraints in this island
                for (; i < _sortedConstraints.Count; i++)
                {
                    if (TypedConstraint.GetConstraintIslandId(_sortedConstraints[i]) == islandID)
                    {
                        numCurConstraints++;
                    }
                }

                for (i = startIndex; i < startIndex + numCurConstraints; i++)
                {
                    startConstraint.Add(_sortedConstraints[i]);
                }

                _solver.SolveGroup(bodies, manifolds, numManifolds, startConstraint, _solverInfo, _debugDrawer);
            }
        protected void CalculateSimulationIslands()
        {
            SimulationIslandManager.UpdateActivationState(this, Dispatcher);

            for (int i = 0; i < _constraints.Count; i++)
            {
                TypedConstraint constraint = _constraints[i];

                RigidBody colObj0 = constraint.RigidBodyA;
                RigidBody colObj1 = constraint.RigidBodyB;

                if (((colObj0 != null) && (colObj0.MergesSimulationIslands)) &&
                    ((colObj1 != null) && (colObj1.MergesSimulationIslands)))
                {
                    if (colObj0.IsActive || colObj1.IsActive)
                    {
                        SimulationIslandManager.UnionFind.Unite((colObj0).IslandTag,
                                                                (colObj1).IslandTag);
                    }
                }
            }

            //Store the island id in each body
            SimulationIslandManager.StoreIslandActivationState(this);
        }
Пример #3
0
		internal static int GetConstraintIslandId(TypedConstraint lhs)
		{
			int islandId;

			CollisionObject colObjA = lhs.RigidBodyA;
			CollisionObject colObjB = lhs.RigidBodyB;
			islandId = colObjA.IslandTag >= 0 ? colObjA.IslandTag : colObjB.IslandTag;
			return islandId;
		}
Пример #4
0
        internal static int GetConstraintIslandId(TypedConstraint lhs)
        {
            int islandId;

            CollisionObject colObjA = lhs.RigidBodyA;
            CollisionObject colObjB = lhs.RigidBodyB;

            islandId = colObjA.IslandTag >= 0 ? colObjA.IslandTag : colObjB.IslandTag;
            return(islandId);
        }
Пример #5
0
		public static int SortConstraintOnIslandPredicate(TypedConstraint left, TypedConstraint right)
		{
			int rightIslandID, leftIslandID;
			rightIslandID = GetConstraintIslandId(right);
			leftIslandID = GetConstraintIslandId(left);
			if (leftIslandID < rightIslandID)
				return -1;
			else
				return 1;
			return 0;
		}
Пример #6
0
        public static int SortConstraintOnIslandPredicate(TypedConstraint left, TypedConstraint right)
        {
            int rightIslandID, leftIslandID;

            rightIslandID = GetConstraintIslandId(right);
            leftIslandID  = GetConstraintIslandId(left);
            if (leftIslandID < rightIslandID)
            {
                return(-1);
            }
            else
            {
                return(1);
            }
            return(0);
        }
Пример #7
0
		public virtual void RemoveConstraint(TypedConstraint constraint) { }
Пример #8
0
		public virtual void AddConstraint(TypedConstraint constraint) { }
Пример #9
0
 public override void RemoveConstraint(TypedConstraint constraint)
 {
     _constraints.Remove(constraint);
 }
Пример #10
0
 public override void AddConstraint(TypedConstraint constraint)
 {
     _constraints.Add(constraint);
 }
Пример #11
0
 public virtual void RemoveConstraint(TypedConstraint constraint)
 {
 }
Пример #12
0
 public virtual void AddConstraint(TypedConstraint constraint)
 {
 }
Пример #13
0
        /// <summary>
        /// Called when the game has determined that game logic needs to be processed.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to this function.</param>
        protected override void Update(GameTime gameTime)
        {
            MouseState mouseState = Mouse.GetState();
            Vector3 rayTo = getRayTo(mouseState.X, mouseState.Y);

            if (mouseState.LeftButton == ButtonState.Pressed && _prevMouseState.LeftButton == ButtonState.Released)
            {
                shootBox(rayTo);
            }
            if (mouseState.MiddleButton == ButtonState.Pressed && _prevMouseState.MiddleButton == ButtonState.Released)
            {
                if (_world != null)
                {
                    CollisionWorld.ClosestRayResultCallback rayCallback = new CollisionWorld.ClosestRayResultCallback(_camera.Position, rayTo);
                    _world.RayTest(_camera.Position, rayTo, rayCallback);
                    if (rayCallback.HasHit)
                    {
                        RigidBody body = RigidBody.Upcast(rayCallback.CollisionObject);
                        if (body != null)
                        {
                            //other exclusions?
                            if (!(body.IsStaticObject || body.IsKinematicObject))
                            {
                                _pickedBody = body;
                                _pickedBody.ActivationState = ActivationState.DisableDeactivation;

                                Vector3 pickPos = rayCallback.HitPointWorld;

                                Vector3 localPivot = Vector3.Transform(pickPos, XnaDevRu.BulletX.MathHelper.InvertMatrix(body.CenterOfMassTransform));

                                Point2PointConstraint p2p = new Point2PointConstraint(body, localPivot);
                                _world.AddConstraint(p2p);
                                _pickConstraint = p2p;

                                //save mouse position for dragging
                                _oldPickingPos = rayTo;

                                Vector3 eyePos = new Vector3(_camera.Position.X, _camera.Position.Y, _camera.Position.Z);

                                _oldPickingDist = (eyePos - pickPos).Length();

                                //very weak constraint for picking
                                p2p.Settings.Tau = 1.1f;
                            }
                        }
                    }
                }
            }
            else if (mouseState.MiddleButton == ButtonState.Released && _prevMouseState.MiddleButton == ButtonState.Pressed)
            {
                if (_pickConstraint != null && _world != null)
                {
                    _world.RemoveConstraint(_pickConstraint);
                    _pickConstraint = null;
                    _pickedBody.ForceActivationState(ActivationState.Active);
                    _pickedBody.DeactivationTime = 0f;
                    _pickedBody = null;
                }
            }

            if (_pickConstraint != null)
            {
                //move the constraint pivot
                Point2PointConstraint p2p = _pickConstraint as Point2PointConstraint;
                if (p2p != null)
                {
                    //keep it at the same picking distance
                    Vector3 dir = rayTo - _camera.Position;
                    dir.Normalize();
                    dir *= _oldPickingDist;

                    Vector3 newPos = _camera.Position + dir;
                    p2p.PivotInB = newPos;
                }
            }

            _prevMouseState = mouseState;

            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                //world.stepSimulation(1.0f/60.0f,0);
                int numObjects = _world.CollisionObjectsCount;

                for (int i = 0; i < numObjects; i++)
                {
                    CollisionObject colObj = _world.CollisionObjects[i];
                    RigidBody body = RigidBody.Upcast(colObj);
                    if (body != null)
                    {
                        if (body.MotionState != null)
                        {
                            DefaultMotionState myMotionState = (DefaultMotionState)body.MotionState;
                            myMotionState.GraphicsWorldTransform = myMotionState.StartWorldTransform;
                            colObj.WorldTransform = myMotionState.GraphicsWorldTransform;
                            colObj.InterpolationWorldTransform = myMotionState.StartWorldTransform;
                            colObj.Activate();
                        }

                        //removed cached contact points
                        _world.Broadphase.CleanProxyFromPairs(colObj.Broadphase);

                        if (body != null && !body.IsStaticObject)
                        {
                            RigidBody.Upcast(colObj).LinearVelocity = new Vector3(0, 0, 0);
                            RigidBody.Upcast(colObj).AngularVelocity = new Vector3(0, 0, 0);
                        }
                    }
                }
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Escape) || GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                Exit();
            }
            else
            {
                //world.stepSimulation(1.0f / 60.0f, 1);
            }

            base.Update(gameTime);
        }
Пример #14
0
        public virtual float SolveGroupCacheFriendly(List <CollisionObject> bodies, List <PersistentManifold> manifolds, int numManifolds, List <TypedConstraint> constraints, ContactSolverInfo infoGlobal, IDebugDraw debugDrawer)
        {
            if (constraints.Count + numManifolds == 0)
            {
                return(0);
            }

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold manifold = manifolds[i];
                RigidBody          rbA      = (RigidBody)manifold.BodyA;
                RigidBody          rbB      = (RigidBody)manifold.BodyB;

                manifold.RefreshContactPoints(rbA.CenterOfMassTransform, rbB.CenterOfMassTransform);
            }

            int minReservation = manifolds.Count * 2;

            _tmpSolverBodyPool = new List <SolverBody>(minReservation);

            for (int i = 0; i < bodies.Count; i++)
            {
                RigidBody rb = RigidBody.Upcast(bodies[i]);
                if (rb != null && rb.IslandTag >= 0)
                {
                    BulletDebug.Assert(rb.CompanionID < 0);
                    int        solverBodyId = _tmpSolverBodyPool.Count;
                    SolverBody solverBody;
                    InitSolverBody(out solverBody, rb);
                    _tmpSolverBodyPool.Add(solverBody);
                    rb.CompanionID = solverBodyId;
                }
            }

            _tmpSolverConstraintPool         = new List <SolverConstraint>(minReservation);
            _tmpSolverFrictionConstraintPool = new List <SolverConstraint>(minReservation);

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold manifold = manifolds[i];
                RigidBody          rb0      = (RigidBody)manifold.BodyA;
                RigidBody          rb1      = (RigidBody)manifold.BodyB;

                int solverBodyIdA = -1;
                int solverBodyIdB = -1;

                //if (i == 89)
                //    System.Diagnostics.Debugger.Break();

                if (manifold.ContactsCount != 0)
                {
                    if (rb0.IslandTag >= 0)
                    {
                        solverBodyIdA = rb0.CompanionID;
                    }
                    else
                    {
                        //create a static body
                        solverBodyIdA = _tmpSolverBodyPool.Count;
                        SolverBody solverBody;
                        InitSolverBody(out solverBody, rb0);
                        _tmpSolverBodyPool.Add(solverBody);
                    }

                    if (rb1.IslandTag >= 0)
                    {
                        solverBodyIdB = rb1.CompanionID;
                    }
                    else
                    {
                        //create a static body
                        solverBodyIdB = _tmpSolverBodyPool.Count;
                        SolverBody solverBody;
                        InitSolverBody(out solverBody, rb1);
                        _tmpSolverBodyPool.Add(solverBody);
                    }
                }

                if (solverBodyIdB == -1 || solverBodyIdA == -1)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("We're in ass ! {0}", i));
                }

                for (int j = 0; j < manifold.ContactsCount; j++)
                {
                    ManifoldPoint cp = manifold.GetContactPoint(j);

                    int frictionIndex = _tmpSolverConstraintPool.Count;

                    if (cp.Distance <= 0)
                    {
                        Vector3 pos1 = cp.PositionWorldOnA;
                        Vector3 pos2 = cp.PositionWorldOnB;

                        Vector3 rel_pos1 = pos1 - rb0.CenterOfMassPosition;
                        Vector3 rel_pos2 = pos2 - rb1.CenterOfMassPosition;

                        float relaxation = 1;
                        {
                            SolverConstraint solverConstraint = new SolverConstraint();
                            _tmpSolverConstraintPool.Add(solverConstraint);

                            solverConstraint.SolverBodyIdA  = solverBodyIdA;
                            solverConstraint.SolverBodyIdB  = solverBodyIdB;
                            solverConstraint.ConstraintType = SolverConstraint.SolverConstraintType.Contact;

                            //can be optimized, the cross products are already calculated
                            float denom0 = rb0.ComputeImpulseDenominator(pos1, cp.NormalWorldOnB);
                            float denom1 = rb1.ComputeImpulseDenominator(pos2, cp.NormalWorldOnB);
                            float denom  = relaxation / (denom0 + denom1);
                            solverConstraint.JacDiagABInv = denom;

                            solverConstraint.ContactNormal      = cp.NormalWorldOnB;
                            solverConstraint.RelPosACrossNormal = Vector3.Cross(rel_pos1, cp.NormalWorldOnB);
                            solverConstraint.RelPosBCrossNormal = Vector3.Cross(rel_pos2, cp.NormalWorldOnB);

                            Vector3 vel1 = rb0.GetVelocityInLocalPoint(rel_pos1);
                            Vector3 vel2 = rb1.GetVelocityInLocalPoint(rel_pos2);

                            Vector3 vel = vel1 - vel2;
                            float   rel_vel;
                            rel_vel = Vector3.Dot(cp.NormalWorldOnB, vel);


                            solverConstraint.Penetration = cp.Distance;                            //btScalar(infoGlobal.m_numIterations);
                            solverConstraint.Friction    = cp.CombinedFriction;
                            float rest = RestitutionCurve(rel_vel, cp.CombinedRestitution);
                            if (rest <= 0)
                            {
                                rest = 0;
                            }

                            float penVel = -solverConstraint.Penetration / infoGlobal.TimeStep;
                            if (rest > penVel)
                            {
                                rest = 0;
                            }
                            solverConstraint.Restitution = rest;

                            solverConstraint.Penetration *= -(infoGlobal.Erp / infoGlobal.TimeStep);

                            solverConstraint.AppliedImpulse         = 0f;
                            solverConstraint.AppliedVelocityImpulse = 0f;

#warning Check to see if we need Vector3.Transform
                            Vector3 torqueAxis0 = Vector3.Cross(rel_pos1, cp.NormalWorldOnB);
                            solverConstraint.AngularComponentA = Vector3.TransformNormal(torqueAxis0, rb0.InvInertiaTensorWorld);
                            Vector3 torqueAxis1 = Vector3.Cross(rel_pos2, cp.NormalWorldOnB);
                            solverConstraint.AngularComponentB = Vector3.TransformNormal(torqueAxis1, rb1.InvInertiaTensorWorld);
                        }
                        //create 2 '1d axis' constraints for 2 tangential friction directions

                        //re-calculate friction direction every frame, todo: check if this is really needed
                        Vector3 frictionTangential0a = new Vector3(),
                                frictionTangential1b = new Vector3();

                        MathHelper.PlaneSpace1(cp.NormalWorldOnB, ref frictionTangential0a, ref frictionTangential1b);
                        {
                            SolverConstraint solverConstraint = new SolverConstraint();
                            _tmpSolverFrictionConstraintPool.Add(solverConstraint);
                            solverConstraint.ContactNormal = frictionTangential0a;

                            solverConstraint.SolverBodyIdA  = solverBodyIdA;
                            solverConstraint.SolverBodyIdB  = solverBodyIdB;
                            solverConstraint.ConstraintType = SolverConstraint.SolverConstraintType.Friction;
                            solverConstraint.FrictionIndex  = frictionIndex;

                            solverConstraint.Friction = cp.CombinedFriction;

                            solverConstraint.AppliedImpulse         = 0;
                            solverConstraint.AppliedVelocityImpulse = 0;

                            float denom0 = rb0.ComputeImpulseDenominator(pos1, solverConstraint.ContactNormal);
                            float denom1 = rb1.ComputeImpulseDenominator(pos2, solverConstraint.ContactNormal);
                            float denom  = relaxation / (denom0 + denom1);
                            solverConstraint.JacDiagABInv = denom;

                            {
                                Vector3 ftorqueAxis0 = Vector3.Cross(rel_pos1, solverConstraint.ContactNormal);
                                solverConstraint.RelPosACrossNormal = ftorqueAxis0;
                                solverConstraint.AngularComponentA  = Vector3.TransformNormal(ftorqueAxis0, rb0.InvInertiaTensorWorld);
                            }
                            {
                                Vector3 ftorqueAxis0 = Vector3.Cross(rel_pos2, solverConstraint.ContactNormal);
                                solverConstraint.RelPosBCrossNormal = ftorqueAxis0;
                                solverConstraint.AngularComponentB  = Vector3.TransformNormal(ftorqueAxis0, rb1.InvInertiaTensorWorld);
                            }
                        }


                        {
                            SolverConstraint solverConstraint = new SolverConstraint();
                            _tmpSolverFrictionConstraintPool.Add(solverConstraint);
                            solverConstraint.ContactNormal = frictionTangential1b;

                            solverConstraint.SolverBodyIdA  = solverBodyIdA;
                            solverConstraint.SolverBodyIdB  = solverBodyIdB;
                            solverConstraint.ConstraintType = SolverConstraint.SolverConstraintType.Friction;
                            solverConstraint.FrictionIndex  = frictionIndex;

                            solverConstraint.Friction = cp.CombinedFriction;

                            solverConstraint.AppliedImpulse         = 0;
                            solverConstraint.AppliedVelocityImpulse = 0;

                            float denom0 = rb0.ComputeImpulseDenominator(pos1, solverConstraint.ContactNormal);
                            float denom1 = rb1.ComputeImpulseDenominator(pos2, solverConstraint.ContactNormal);
                            float denom  = relaxation / (denom0 + denom1);
                            solverConstraint.JacDiagABInv = denom;
                            {
                                Vector3 ftorqueAxis1 = Vector3.Cross(rel_pos1, solverConstraint.ContactNormal);
                                solverConstraint.RelPosACrossNormal = ftorqueAxis1;
                                solverConstraint.AngularComponentA  = Vector3.TransformNormal(ftorqueAxis1, rb0.InvInertiaTensorWorld);
                            }
                            {
                                Vector3 ftorqueAxis1 = Vector3.Cross(rel_pos2, solverConstraint.ContactNormal);
                                solverConstraint.RelPosBCrossNormal = ftorqueAxis1;
                                solverConstraint.AngularComponentB  = Vector3.TransformNormal(ftorqueAxis1, rb1.InvInertiaTensorWorld);
                            }
                        }
                    }
                }
            }

            ContactSolverInfo info = infoGlobal;
            {
                for (int j = 0; j < constraints.Count; j++)
                {
                    TypedConstraint constraint = constraints[j];
                    constraint.BuildJacobian();
                }
            }

            int numConstraintPool = _tmpSolverConstraintPool.Count;
            int numFrictionPool   = _tmpSolverFrictionConstraintPool.Count;

            //todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
            List <int> gOrderTmpConstraintPool      = new List <int>(numConstraintPool);
            List <int> gOrderFrictionConstraintPool = new List <int>(numFrictionPool);
            {
                for (int i = 0; i < numConstraintPool; i++)
                {
                    gOrderTmpConstraintPool.Add(i);
                }
                for (int i = 0; i < numFrictionPool; i++)
                {
                    gOrderFrictionConstraintPool.Add(i);
                }
            }

            //should traverse the contacts random order...
            int iteration;
            {
                for (iteration = 0; iteration < info.IterationsCount; iteration++)
                {
                    int j;
                    if ((_solverMode & SolverMode.RandomizeOrder) != SolverMode.None)
                    {
                        if ((iteration & 7) == 0)
                        {
                            for (j = 0; j < numConstraintPool; ++j)
                            {
                                int tmp   = gOrderTmpConstraintPool[j];
                                int swapi = RandInt2(j + 1);
                                gOrderTmpConstraintPool[j]     = gOrderTmpConstraintPool[swapi];
                                gOrderTmpConstraintPool[swapi] = tmp;
                            }

                            for (j = 0; j < numFrictionPool; ++j)
                            {
                                int tmp   = gOrderFrictionConstraintPool[j];
                                int swapi = RandInt2(j + 1);
                                gOrderFrictionConstraintPool[j]     = gOrderFrictionConstraintPool[swapi];
                                gOrderFrictionConstraintPool[swapi] = tmp;
                            }
                        }
                    }

                    for (j = 0; j < constraints.Count; j++)
                    {
                        TypedConstraint constraint = constraints[j];
                        //todo: use solver bodies, so we don't need to copy from/to btRigidBody

                        if ((constraint.RigidBodyA.IslandTag >= 0) && (constraint.RigidBodyA.CompanionID >= 0))
                        {
                            _tmpSolverBodyPool[constraint.RigidBodyA.CompanionID].WriteBackVelocity();
                        }
                        if ((constraint.RigidBodyB.IslandTag >= 0) && (constraint.RigidBodyB.CompanionID >= 0))
                        {
                            _tmpSolverBodyPool[constraint.RigidBodyB.CompanionID].WriteBackVelocity();
                        }

                        constraint.SolveConstraint(info.TimeStep);

                        if ((constraint.RigidBodyA.IslandTag >= 0) && (constraint.RigidBodyA.CompanionID >= 0))
                        {
                            _tmpSolverBodyPool[constraint.RigidBodyA.CompanionID].ReadVelocity();
                        }
                        if ((constraint.RigidBodyB.IslandTag >= 0) && (constraint.RigidBodyB.CompanionID >= 0))
                        {
                            _tmpSolverBodyPool[constraint.RigidBodyB.CompanionID].ReadVelocity();
                        }
                    }

                    {
                        int numPoolConstraints = _tmpSolverConstraintPool.Count;
                        for (j = 0; j < numPoolConstraints; j++)
                        {
                            SolverConstraint solveManifold = _tmpSolverConstraintPool[gOrderTmpConstraintPool[j]];
                            ResolveSingleCollisionCombinedCacheFriendly(_tmpSolverBodyPool[solveManifold.SolverBodyIdA],
                                                                        _tmpSolverBodyPool[solveManifold.SolverBodyIdB], solveManifold, info);
                        }
                    }

                    {
                        int numFrictionPoolConstraints = _tmpSolverFrictionConstraintPool.Count;
                        for (j = 0; j < numFrictionPoolConstraints; j++)
                        {
                            SolverConstraint solveManifold        = _tmpSolverFrictionConstraintPool[gOrderFrictionConstraintPool[j]];
                            float            appliedNormalImpulse = _tmpSolverConstraintPool[solveManifold.FrictionIndex].AppliedImpulse;

                            ResolveSingleFrictionCacheFriendly(_tmpSolverBodyPool[solveManifold.SolverBodyIdA],
                                                               _tmpSolverBodyPool[solveManifold.SolverBodyIdB], solveManifold, info, appliedNormalImpulse);
                        }
                    }
                }
            }

            for (int i = 0; i < _tmpSolverBodyPool.Count; i++)
            {
                _tmpSolverBodyPool[i].WriteBackVelocity();
            }

            _tmpSolverBodyPool.Clear();
            _tmpSolverConstraintPool.Clear();
            _tmpSolverFrictionConstraintPool.Clear();

            return(0);
        }
Пример #15
0
 public override void RemoveConstraint(TypedConstraint constraint)
 {
     _constraints.Remove(constraint);
 }
Пример #16
0
 public override void AddConstraint(TypedConstraint constraint)
 {
     _constraints.Add(constraint);
 }