Пример #1
0
void Ball::AngularAcceleration(const Vertex3Ds& hitnormal)
{
	const Vertex3Ds bccpd = -radius * hitnormal;    // vector ball center to contact point displacement

	const float bnv = vel.Dot(hitnormal);       // ball normal velocity to hit face

	const Vertex3Ds bvn = bnv * hitnormal;      // project the normal velocity along normal

	const Vertex3Ds bvt = vel - bvn;            // calc the tangent velocity

	Vertex3Ds bvT = bvt;                        // ball tangent velocity Unit Tangent
	bvT.Normalize();	

	const Vertex3Ds bstv =						// ball surface tangential velocity
	CrossProduct(m_angularvelocity, bccpd);		// velocity of ball surface at contact point

	const float dot = bstv.Dot(bvT);			// speed ball surface contact point tangential to contact surface point
	const Vertex3Ds cpvt = dot * bvT;           // contact point velocity tangential to hit face

	const Vertex3Ds slideVel = bstv - cpvt;     // contact point slide velocity with ball center velocity -- slide velocity

	// If the point and the ball are travelling in opposite directions,
	// and the point's velocity is at least the magnitude of the balls,
	// then we have a natural roll
	
	Vertex3Ds cpctrv = -slideVel;				//contact point co-tangential reverse velocity

    if (vel.LengthSquared() > (float)(0.7*0.7))
    {
        // Calculate the maximum amount the point velocity can change this
        // time segment due to friction
        Vertex3Ds FrictionForce = cpvt + bvt;

        // If the point can change fast enough to go directly to a natural roll, then do it.

        if (FrictionForce.LengthSquared() > (float)(ANGULARFORCE*ANGULARFORCE))
            FrictionForce.Normalize(ANGULARFORCE);

        cpctrv -= FrictionForce;
    }

	// Divide by the inertial tensor for a sphere in order to change
	// linear force into angular momentum
	cpctrv *= (float)(2.0/5.0); // Inertial tensor for a sphere

	const Vertex3Ds vResult = CrossProduct(bccpd, cpctrv); // ball center contact point displacement X reverse contact point co-tan vel

	m_angularmomentum *= 0.99f;
	m_angularmomentum += vResult; // add delta
	m_angularvelocity = m_inverseworldinertiatensor.MultiplyVector(m_angularmomentum);
}
Пример #2
0
HitLine3D::HitLine3D(const Vertex3Ds& v1, const Vertex3Ds& v2)
{
	Vertex3Ds vLine = v2 - v1;
	vLine.Normalize();

	// Axis of rotation to make 3D cylinder a cylinder along the z-axis
	Vertex3Ds transaxis;
	/*const Vertex3Ds vup(0,0,1.0f);
	CrossProduct(vLine, vup, &transaxis);*/
	transaxis.x = vLine.y;
	transaxis.y = -vLine.x;
	transaxis.z = 0.0f;

	if (transaxis.LengthSquared() <= 1e-6f)     // line already points in z axis?
		transaxis.Set(1, 0, 0);                 // choose arbitrary rotation vector
	else
		transaxis.Normalize();

	// Angle to rotate the line into the z-axis
	const float dot = vLine.z; //vLine.Dot(&vup);

	const float transangle = acosf(dot);

	matTrans.RotationAroundAxis(transaxis, -transangle);

	const Vertex3Ds vtrans1 = matTrans * v1;
	const Vertex3Ds vtrans2 = matTrans * v2;

	// set up HitLineZ parameters
	m_xy.x = vtrans1.x;
	m_xy.y = vtrans1.y;
	m_zlow = min(vtrans1.z, vtrans2.z);
	m_zhigh = max(vtrans1.z, vtrans2.z);

    m_rcHitRect.left = min(v1.x, v2.x);
    m_rcHitRect.right = max(v1.x, v2.x);
    m_rcHitRect.top = min(v1.y, v2.y);
    m_rcHitRect.bottom = max(v1.y, v2.y);
    m_rcHitRect.zlow = min(v1.z, v2.z);
    m_rcHitRect.zhigh = max(v1.z, v2.z);
}