Exemplo n.º 1
0
        public static float CalcRollingFriction(WheelContactPoint contactPoint)
        {
	        float j1=0f;

	        Vector3 contactPosWorld = contactPoint.m_frictionPositionWorld;

	        Vector3 rel_pos1 = contactPosWorld - contactPoint.m_body0.GetCenterOfMassPosition(); 
	        Vector3 rel_pos2 = contactPosWorld - contactPoint.m_body1.GetCenterOfMassPosition();
        	
	        float maxImpulse  = contactPoint.m_maxImpulse;
        	
	        Vector3 vel1 = contactPoint.m_body0.GetVelocityInLocalPoint(ref rel_pos1);
	        Vector3 vel2 = contactPoint.m_body1.GetVelocityInLocalPoint(ref rel_pos2);
	        Vector3 vel = vel1 - vel2;

	        float vrel = Vector3.Dot(contactPoint.m_frictionDirectionWorld,vel);

	        // calculate j that moves us to zero relative velocity
	        j1 = -vrel * contactPoint.m_jacDiagABInv;
	        j1 = System.Math.Min(j1,maxImpulse);
	        j1 = System.Math.Max(j1, -maxImpulse);

	        return j1;
        }
Exemplo n.º 2
0
        public virtual void UpdateFriction(float timeStep)
        {
	        //calculate the impulse, so that the wheels don't move sidewards
	        int numWheel = GetNumWheels();
	        if (numWheel == 0)
		        return;

            //m_forwardWS.resize(numWheel);
            //m_axle.resize(numWheel);
            //m_forwardImpulse.resize(numWheel);
            //m_sideImpulse.resize(numWheel);
    		
	        int numWheelsOnGround = 0;
    	

	        //collapse all those loops into one!
	        for (int i=0;i<numWheel;i++)
	        {
		        WheelInfo wheelInfo = m_wheelInfo[i];
		        RigidBody groundObject = (RigidBody) wheelInfo.m_raycastInfo.m_groundObject;
		        if (groundObject != null)
                {
			        numWheelsOnGround++;
                }
		        m_sideImpulse[i] = 0f;
		        m_forwardImpulse[i] = 0f;

	        }

            if (numWheelsOnGround != 4)
            {
                int ibreak = 0;
            }

	        {
    	
                //foreach(WheelInfo wheelInfo in m_wheelInfo)
		        for(int i=0;i<numWheel;++i)
                {
                    WheelInfo wheelInfo = m_wheelInfo[i];
			        RigidBody groundObject = (RigidBody) wheelInfo.m_raycastInfo.m_groundObject;

			        if (groundObject != null)
			        {

				        Matrix wheelTrans = GetWheelTransformWS( i );

				        Matrix wheelBasis0 = wheelTrans;
				        m_axle[i] = MathUtil.MatrixColumn(ref wheelBasis0,m_indexRightAxis);
    					
				        Vector3 surfNormalWS = wheelInfo.m_raycastInfo.m_contactNormalWS;
				        float proj = Vector3.Dot(m_axle[i],surfNormalWS);
				        m_axle[i] -= surfNormalWS * proj;
				        m_axle[i].Normalize();
    					
				        m_forwardWS[i] = Vector3.Cross(surfNormalWS,m_axle[i]);
				        m_forwardWS[i].Normalize();

                        Vector3 tempAxle = m_axle[i];
                        float tempImpulse = m_sideImpulse[i];
                        ContactConstraint.ResolveSingleBilateral(m_chassisBody, ref wheelInfo.m_raycastInfo.m_contactPointWS,
                                  groundObject, ref wheelInfo.m_raycastInfo.m_contactPointWS,
                                  0f, ref tempAxle, ref tempImpulse, timeStep);
                        m_sideImpulse[i] = (tempImpulse * sideFrictionStiffness2);
			        }
		        }
	        }

            float sideFactor = 1f;
            float fwdFactor = 0.5f;

            bool sliding = false;
            {
	            for (int wheel =0;wheel <numWheel;wheel++)
	            {
		            WheelInfo wheelInfo = m_wheelInfo[wheel];
		            RigidBody groundObject = (RigidBody) wheelInfo.m_raycastInfo.m_groundObject;

		            float	rollingFriction = 0f;

		            if(groundObject != null)
		            {
                        if(wheelInfo.m_engineForce != 0.0f)
			            {
				            rollingFriction = wheelInfo.m_engineForce* timeStep;
			            } 
                        else
			            {
				            float defaultRollingFrictionImpulse = 0f;
				            float maxImpulse = (wheelInfo.m_brake != 0f) ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
                            Vector3 tempWheel = m_forwardWS[wheel];
				            WheelContactPoint contactPt = new WheelContactPoint(m_chassisBody,groundObject,ref wheelInfo.m_raycastInfo.m_contactPointWS,ref tempWheel,maxImpulse);
                            m_forwardWS[wheel] = tempWheel;
				            rollingFriction = CalcRollingFriction(contactPt);
			            }
		            }

		            //switch between active rolling (throttle), braking and non-active rolling friction (no throttle/break)

		            m_forwardImpulse[wheel] = 0f;
		            m_wheelInfo[wheel].m_skidInfo= 1f;

		            if (groundObject != null)
		            {
			            m_wheelInfo[wheel].m_skidInfo= 1f;
        				
			            float maximp = wheelInfo.m_wheelsSuspensionForce * timeStep * wheelInfo.m_frictionSlip;
			            float maximpSide = maximp;

			            float maximpSquared = maximp * maximpSide;
			            m_forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep;

			            float x = (m_forwardImpulse[wheel] ) * fwdFactor;
			            float y = (m_sideImpulse[wheel] ) * sideFactor;
        				
			            float impulseSquared = (x*x + y*y);

			            if (impulseSquared > maximpSquared)
			            {
				            sliding = true;
        					
				            float factor = (float)(maximp / System.Math.Sqrt(impulseSquared));
        					
				            m_wheelInfo[wheel].m_skidInfo *= factor;
			            }
		            } 

	            }
            }

            if (sliding)
            {
                for (int wheel = 0; wheel < numWheel; wheel++)
                {
                    if (m_sideImpulse[wheel] != 0f)
                    {
                        if (m_wheelInfo[wheel].m_skidInfo < 1f)
                        {
                            m_forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
                            m_sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
                        }
                    }
                }
            }

            // apply the impulses
            {
	            for (int wheel = 0;wheel<numWheel ; wheel++)
	            {
		            WheelInfo wheelInfo = m_wheelInfo[wheel];

		            Vector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS - 
				            m_chassisBody.GetCenterOfMassPosition();


                    if (m_forwardImpulse[wheel] > 5f || m_sideImpulse[wheel] > 5f)
                    {
                        int ibreak = 0;
                    }

		            if (m_forwardImpulse[wheel] != 0f)
		            {
                        m_chassisBody.ApplyImpulse(m_forwardWS[wheel] * (m_forwardImpulse[wheel]), rel_pos);
		            }
                    if (m_sideImpulse[wheel] != 0f)
                    {
                        RigidBody groundObject = (RigidBody)m_wheelInfo[wheel].m_raycastInfo.m_groundObject;

                        Vector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS -
                            groundObject.GetCenterOfMassPosition();

                        Vector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];

                        MathUtil.VectorComponentMultiplyAssign(ref rel_pos, m_indexUpAxis, wheelInfo.m_rollInfluence);

                        if (sideImp.LengthSquared() > 1f)
                        {
                            int ibreak = 0;
                        }

                        m_chassisBody.ApplyImpulse(ref sideImp, ref rel_pos);

                        //apply friction impulse on the ground
                        Vector3 temp = -sideImp;
                        groundObject.ApplyImpulse(ref temp, ref rel_pos2);
                    }
	            }
	        }
        }