Exemple #1
0
btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
{
	
	btScalar halfHeight = m_height * btScalar(0.5);

 if (v[m_coneIndices[1]] > v.length() * m_sinAngle)
 {
	btVector3 tmp;

	tmp[m_coneIndices[0]] = btScalar(0.);
	tmp[m_coneIndices[1]] = halfHeight;
	tmp[m_coneIndices[2]] = btScalar(0.);
	return tmp;
 }
  else {
    btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]);
    if (s > SIMD_EPSILON) {
      btScalar d = m_radius / s;
	  btVector3 tmp;
	  tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d;
	  tmp[m_coneIndices[1]] = -halfHeight;
	  tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d;
	  return tmp;
    }
    else  {
		btVector3 tmp;
		tmp[m_coneIndices[0]] = btScalar(0.);
		tmp[m_coneIndices[1]] = -halfHeight;
		tmp[m_coneIndices[2]] = btScalar(0.);
		return tmp;
	}
  }

}
Exemple #2
0
float du_get_body_speed(du_body_id body)
{
    btRigidBody *bt_body = reinterpret_cast <btRigidBody*>(body);
    const btVector3 velocity = bt_body->getLinearVelocity();
    float speed_ms = velocity.length();
    float speed = speed_ms *= 3.6;
    return speed;
}
bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& pointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& sphereCenter, btScalar fRadius, btScalar maxContactDistance ) 
{
	const btBoxShape* boxShape= (const btBoxShape*)boxObjWrap->getCollisionShape();
	btVector3 const &boxHalfExtent = boxShape->getHalfExtentsWithoutMargin();
	btScalar boxMargin = boxShape->getMargin();
	penetrationDepth = 1.0f;

	// convert the sphere position to the box's local space
	btTransform const &m44T = boxObjWrap->getWorldTransform();
	btVector3 sphereRelPos = m44T.invXform(sphereCenter);

	// Determine the closest point to the sphere center in the box
	btVector3 closestPoint = sphereRelPos;
	closestPoint.setX( btMin(boxHalfExtent.getX(), closestPoint.getX()) );
	closestPoint.setX( btMax(-boxHalfExtent.getX(), closestPoint.getX()) );
	closestPoint.setY( btMin(boxHalfExtent.getY(), closestPoint.getY()) );
	closestPoint.setY( btMax(-boxHalfExtent.getY(), closestPoint.getY()) );
	closestPoint.setZ( btMin(boxHalfExtent.getZ(), closestPoint.getZ()) );
	closestPoint.setZ( btMax(-boxHalfExtent.getZ(), closestPoint.getZ()) );
	
	btScalar intersectionDist = fRadius + boxMargin;
	btScalar contactDist = intersectionDist + maxContactDistance;
	normal = sphereRelPos - closestPoint;

	//if there is no penetration, we are done
	btScalar dist2 = normal.length2();
	if (dist2 > contactDist * contactDist)
	{
		return false;
	}

	btScalar distance;

	//special case if the sphere center is inside the box
	if (dist2 == 0.0f)
	{
		distance = -getSpherePenetration(boxHalfExtent, sphereRelPos, closestPoint, normal);
	}
	else //compute the penetration details
	{
		distance = normal.length();
		normal /= distance;
	}

	pointOnBox = closestPoint + normal * boxMargin;
//	v3PointOnSphere = sphereRelPos - (normal * fRadius);	
	penetrationDepth = distance - intersectionDist;

	// transform back in world space
	btVector3 tmp = m44T(pointOnBox);
	pointOnBox = tmp;
//	tmp = m44T(v3PointOnSphere);
//	v3PointOnSphere = tmp;
	tmp = m44T.getBasis() * normal;
	normal = tmp;

	return true;
}
Exemple #4
0
/** Kernel for pressure */
inline float VRFluids::kernel_spiky(btVector3 v, float h) {
    float r = v.length();
    float diff = h - r;
    if (diff > 0) {
        return (15.0 / (Pi * pow(h,6))) * diff*diff*diff;
    } else {
        return 0.0;
    }
}
Exemple #5
0
/**
 *  Kernel_visc laplacian function for viscosity
 *  Source: mueller
 */
inline float VRFluids::kernel_visc_laplacian(btVector3 v, float h) {
    float r = v.length();
    if (r <= h && r >= 0) {
        float diff = h - r;
        return (45.0 / (Pi * pow(h,6))) * diff;
    } else {
        return 0.0;
    }
}
Exemple #6
0
/** Kernel for pressure */
inline btVector3 VRFluids::kernel_spiky_gradient(btVector3 v, float h) {
    float r = v.length();
    float diff = h - r;
    if (diff > 0 && r > 0) { // NOTE > should be >= but things won't work then for some reason
        return (-45.0 / (Pi * pow(h,6))) * (v/r) * diff*diff;
    } else {
        return btVector3(0,0,0);
    }
}
// static helper method
static btVector3
getNormalizedVector(const btVector3& v)
{
	btVector3 n(0, 0, 0);

	if (v.length() > SIMD_EPSILON) {
		n = v.normalized();
	}
	return n;
}
Exemple #8
0
btVector3 EntityPhysic::colVelocity(btVector3 velocity_)
{

	int MAX=120;
	int MIN=50;
	if(velocity_.length()>MAX)
	{
		float radio=velocity_.length()/MAX;
		velocity_=btVector3(velocity_.getX()/radio,
				velocity_.getY()/radio,
				velocity_.getZ()/radio);
	}
	if(velocity_.length()<MIN)
	{
		float radio=velocity_.length()/MIN;
		velocity_=btVector3(velocity_.getX()/radio,
				velocity_.getY()/radio,
				velocity_.getZ()/radio);
	}
	return velocity_;
}
Exemple #9
0
/** Kernel for viscosity */
inline float VRFluids::kernel_visc(btVector3 v, float h) {
    float r = v.length();
    if (r <= h) {
        float h2 = h*h;
        float h3 = h2*h;
        float r2 = r*r;
        float r3 = r2*r;
        float a = -1*r3 / (h3+h3);
        float b = r2 / h2;
        float c = h / (r+r);
        return (15.0 / (2*Pi*h3)) * (a + b + c - 1);
    } else {
        return 0.0;
    }
}
/**
 * Returns the unit vector in the direction of this spring.
 */
const btVector3 tgBulletCompressionSpring::getAnchorDirectionUnitVector() const
{
    // Get the unit vector for the direction of the force, this is needed for
    // applying the force to the rigid bodies.
    const btVector3 dist =
	  anchor2->getWorldPosition() - anchor1->getWorldPosition();
    // The unit vector of the direction of the force will be needed later
    // In order to have a positive force move the two rigid bodies away
    // from each other, this unit vector must be in the opposite direction
    // of this calculation. Otherwise, a positive force brings them closer
    // together. Needs a minus.
    // note that dist.length is a scalar double.
    const btVector3 unitVector = - dist / dist.length();
    return unitVector;
}
Exemple #11
0
btMatrix3x3 GetOrientedBasis(btVector3 const &z)
{
	btAssert(fabsf(z.length()-1) < 0.01f);
	btVector3 t(0,0,0);
	if(fabsf(z.z() < 0.999f))
	{
		t.setZ(1);
	}
	else
	{
		t.setX(1);
	}
	btVector3 x = t.cross(z).normalize();
	btVector3 y = z.cross(x).normalize();
	return btMatrix3x3(	x.x(), y.x(), z.x(),
						x.y(), y.y(), z.y(),
						x.z(), y.z(), z.z());
}
void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const
{
	//start with static aabb
	getAabb(curTrans,temporalAabbMin,temporalAabbMax);

	btScalar temporalAabbMaxx = temporalAabbMax.getX();
	btScalar temporalAabbMaxy = temporalAabbMax.getY();
	btScalar temporalAabbMaxz = temporalAabbMax.getZ();
	btScalar temporalAabbMinx = temporalAabbMin.getX();
	btScalar temporalAabbMiny = temporalAabbMin.getY();
	btScalar temporalAabbMinz = temporalAabbMin.getZ();

	// add linear motion
	btVector3 linMotion = linvel*timeStep;
	///@todo: simd would have a vector max/min operation, instead of per-element access
	if (linMotion.x() > btScalar(0.))
		temporalAabbMaxx += linMotion.x(); 
	else
		temporalAabbMinx += linMotion.x();
	if (linMotion.y() > btScalar(0.))
		temporalAabbMaxy += linMotion.y(); 
	else
		temporalAabbMiny += linMotion.y();
	if (linMotion.z() > btScalar(0.))
		temporalAabbMaxz += linMotion.z(); 
	else
		temporalAabbMinz += linMotion.z();

	//add conservative angular motion
	btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep;
	btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion);
	temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz);
	temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz);

	temporalAabbMin -= angularMotion3d;
	temporalAabbMax += angularMotion3d;
}
Exemple #13
0
void AIInput::step(JeepActor* jeep, btVector3 const & pathDir1, btVector3 const & pathDir2, btVector3 const & trackVector, btVector3 const & segmentVec1, btVector3 const & segmentVec2) {
	btVector3 trackDirection = pathDir1;
	btVector3 actorHeading = quatRotate(jeep->orientation, btVector3(1,0,0)).normalize();

	AcceleratePressed = true;

	float angleToTrack = trackDirection.dot(actorHeading);
	float turnDir = trackDirection.cross(actorHeading).getY();
	if (turnDir > 0) turnDir = 1;
	else if (turnDir < 0) turnDir = -1;
	else turnDir = 0;

	int parallelize = 0;
	float parallelizationThreshold = LoadFloat("config/ai.xml","parallelization_threshold");
	float hardParallelizationThreshold = LoadFloat("config/ai.xml","hard_parallelization_threshold");
	if ((1.0 - angleToTrack) * turnDir > hardParallelizationThreshold) parallelize = 2;
	if ((1.0 - angleToTrack) * turnDir > parallelizationThreshold) parallelize = 1;
	else if ((1.0 - angleToTrack) * turnDir < -hardParallelizationThreshold) parallelize = -2;
	else if ((1.0 - angleToTrack) * turnDir < -parallelizationThreshold) parallelize = -1;

	int onTrack = 0;
	btVector3 pathVec = trackVector;
	float distFromTrack = pathVec.length();

	turnDir = trackDirection.cross(pathVec).getY();
	if (turnDir > 0) turnDir = 1;
	else if (turnDir < 0) turnDir = -1;
	else turnDir = 0;

	float distanceThreshold = LoadFloat("config/ai.xml","distance_threshold");
	float farDistanceThreshold = LoadFloat("config/ai.xml","far_distance_threshold");
	if (distFromTrack > farDistanceThreshold && turnDir > 0)  onTrack = 2;
	if (distFromTrack > distanceThreshold && turnDir > 0) onTrack = 1;
	else if (distFromTrack > farDistanceThreshold && turnDir < 0)  onTrack = -2;
	else if (distFromTrack > distanceThreshold && turnDir < 0) onTrack = -1;
	//std::cout << distFromTrack << std::endl;

	float distToNextSeg = segmentVec1.length();
	float distToNextSeg2 = segmentVec2.length();
	int turnAnticipation1 = 0;
	int turnAnticipation2 = 0;
	//std::cout << distToNextSeg << "\t" << distToNextSeg2 << std::endl;

	float turnAnticipationThreshold = LoadFloat("config/ai.xml","turn_anticipation_threshold");
	float farTurnAnticipationThreshold = LoadFloat("config/ai.xml","far_turn_anticipation_threshold");
	if (distToNextSeg < turnAnticipationThreshold) {
		trackDirection = pathDir1;
		angleToTrack = trackDirection.dot(actorHeading);
		turnDir = trackDirection.cross(actorHeading).getY();
		if (turnDir > 0) turnDir = 1;
		else if (turnDir < 0) turnDir = -1;
		else turnDir = 0;
		
		if ((1.0 - angleToTrack) * turnDir > 0.2) turnAnticipation1 = 2;
		else if ((1.0 - angleToTrack) * turnDir < -0.2) turnAnticipation1 = -2;
	}
	if (distToNextSeg2 < farTurnAnticipationThreshold) {
		trackDirection = pathDir2;
		angleToTrack = trackDirection.dot(actorHeading);
		turnDir = trackDirection.cross(actorHeading).getY();
		if (turnDir > 0) turnDir = 1;
		else if (turnDir < 0) turnDir = -1;
		else turnDir = 0;
		
		if ((1.0 - angleToTrack) * turnDir > 0.2) turnAnticipation2 = 1;
		else if ((1.0 - angleToTrack) * turnDir < -0.2) turnAnticipation2 = -1;
	}
	// std::cout << parallelize << " " << onTrack << " " << turnAnticipation1 << " " << turnAnticipation2 << std::endl;

	XAxis = parallelize + onTrack + turnAnticipation1 + turnAnticipation2;
	if (XAxis > 0) XAxis = 1;
	else if (XAxis < 0) XAxis = -1;
	else XAxis = 0;
}
void btSolve2LinearConstraint::resolveUnilateralPairConstraint(
												   btRigidBody* body1,
		btRigidBody* body2,

						const btMatrix3x3& world2A,
						const btMatrix3x3& world2B,
						
						const btVector3& invInertiaADiag,
						const btScalar invMassA,
						const btVector3& linvelA,const btVector3& angvelA,
						const btVector3& rel_posA1,
						const btVector3& invInertiaBDiag,
						const btScalar invMassB,
						const btVector3& linvelB,const btVector3& angvelB,
						const btVector3& rel_posA2,

					  btScalar depthA, const btVector3& normalA, 
					  const btVector3& rel_posB1,const btVector3& rel_posB2,
					  btScalar depthB, const btVector3& normalB, 
					  btScalar& imp0,btScalar& imp1)
{
	(void)linvelA;
	(void)linvelB;
	(void)angvelB;
	(void)angvelA;



	imp0 = btScalar(0.);
	imp1 = btScalar(0.);

	btScalar len = btFabs(normalA.length()) - btScalar(1.);
	if (btFabs(len) >= SIMD_EPSILON)
		return;

	btAssert(len < SIMD_EPSILON);


	//this jacobian entry could be re-used for all iterations
	btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA,
		invInertiaBDiag,invMassB);
	btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA,
		invInertiaBDiag,invMassB);
	
	//const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
	//const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);

	const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1));
	const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1));

//	btScalar penetrationImpulse = (depth*contactTau*timeCorrection)  * massTerm;//jacDiagABInv
	btScalar massTerm = btScalar(1.) / (invMassA + invMassB);


	// calculate rhs (or error) terms
	const btScalar dv0 = depthA  * m_tau * massTerm - vel0 * m_damping;
	const btScalar dv1 = depthB  * m_tau * massTerm - vel1 * m_damping;


	// dC/dv * dv = -C
	
	// jacobian * impulse = -error
	//

	//impulse = jacobianInverse * -error

	// inverting 2x2 symmetric system (offdiagonal are equal!)
	// 


	btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
	btScalar	invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
	
	//imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
	//imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;

	imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
	imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;

	//[a b]								  [d -c]
	//[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc)

	//[jA nD] * [imp0] = [dv0]
	//[nD jB]   [imp1]   [dv1]

}
Exemple #15
0
void collisionWithBound(btVector3 &vel, btVector3 &pos, const btVector3 &normal, const btScalar &penetrationDist)
{
    if( penetrationDist < btScalar(0.0) )
	{
        
        pos = pos - normal * penetrationDist;
        
        vel = vel - (1 + Constant.m_boundaryRestitution * (-penetrationDist) / (Constant.m_timeStep * vel.length())) * vel.dot(normal) * normal;
	}
}
    //-----------------------------------------------------------------------
    //                 s t e p F o r w a r d A n d S t r a f e
    //-----------------------------------------------------------------------
    void TKinematicCharacterTest::stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove)
    {
        btVector3 originalDir = walkMove.normalized();
        if (walkMove.length() < SIMD_EPSILON)
        {
            originalDir.setValue(0.f,0.f,0.f);
        }
        //	printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
        // phase 2: forward and strafe
        btTransform start, end;
        m_targetPosition = m_currentPosition + walkMove;
        start.setIdentity ();
        end.setIdentity ();

        btScalar fraction = 1.0;
        btScalar distance2 = (m_currentPosition-m_targetPosition).length2();
        //	printf("distance2=%f\n",distance2);

        if (m_touchingContact)
        {
            if (originalDir.dot(m_touchingNormal) > btScalar(0.0))
                updateTargetPositionBasedOnCollision (m_touchingNormal);
        }

        int maxIter = 10;

        while (fraction > btScalar(0.01) && maxIter-- > 0)
        {
            start.setOrigin (m_currentPosition);
            end.setOrigin (m_targetPosition);

            TKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
            callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
            callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;


            btScalar margin = m_convexShape->getMargin();
            m_convexShape->setMargin(margin + m_addedMargin);


            if (m_useGhostObjectSweepTest)
            {
                m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
            } else
            {
                collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
            }

            m_convexShape->setMargin(margin);


            fraction -= callback.m_closestHitFraction;

            if (callback.hasHit())
            {	
                if(callback.m_hitCollisionObject->isStaticObject())
                {
                    // we moved only a fraction
                    btScalar hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
                    if (hitDistance<0.f)
                    {
                        //				printf("neg dist?\n");
                    }

                    /* If the distance is farther than the collision margin, move */
                    if (hitDistance > m_addedMargin)
                    {
                        //				printf("callback.m_closestHitFraction=%f\n",callback.m_closestHitFraction);
                        m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
                    }

                    updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
                    btVector3 currentDir = m_targetPosition - m_currentPosition;
                    distance2 = currentDir.length2();
                    if (distance2 > SIMD_EPSILON)
                    {
                        currentDir.normalize();
                        /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
                        if (currentDir.dot(originalDir) <= btScalar(0.0))
                        {
                            break;
                        }
                    } else
                    {
                        //				printf("currentDir: don't normalize a zero vector\n");
                        break;
                    }
                }
            } else {
                // we moved whole way
                m_currentPosition = m_targetPosition;
            }

            //	if (callback.m_closestHitFraction == 0.f)
            //		break;

        }
    }
/**
 * Returns the distance between the two anchors.
 * This is similar to the getActualLength function in tgBulletSpringCable.
 */
const double tgBulletCompressionSpring::getCurrentAnchorDistance() const
{
    const btVector3 dist =
      this->anchor2->getWorldPosition() - this->anchor1->getWorldPosition();
    return dist.length();
}