[SOLVED] Pendulums Won't Swing!

Post Reply
skosh2
Posts: 5
Joined: Thu Dec 08, 2016 11:46 pm

[SOLVED] Pendulums Won't Swing!

Post by skosh2 »

I have Bullet2.84/Ogre3D2.1 trying to swing a pendulum, in the form of a small sphere under a box. It won't swing freely, though forcing the sphere up with another collidable lets it traverse and bounce up and down along the straight line of the slider constraint. How to I get this pendulum to swing upon collision using the box as its axis? I want to be able to hit this sphere with another collidable and have it swing about wildly.

I used code from Thread: simple pendulum sticks and Thread: Newton's cradle not transforming force properly. However, though the slider contraint seems to be working properly, I don't get the swing from supernewb's video. In fact, though supernewb sets btPoint2PointConstraint::setLowerAngLimit( btVector3() )- apparently controlling this swing- this method is gone from Bullet2.84.

P.S. Disregard the filled-in kinematic icosphere, which is used as a camera rotation cursor and collision tester.

My pendulum object:

Code: Select all

class PendulumObj: public GameObj{
public:
	PendulumObj( OgreWinApp *ogre_app, BulletApp *bt_app ){

		btScalar x_pos = 0;
		btScalar y_pos = 0;
		btScalar length = 3;
		btScalar mass = 1;

		// Setup collision shapes
		btBoxShape *box_shape = new btBoxShape( btVector3( 0.5, 0.5, 0.5 ) );
		btSphereShape *sphere_shape = new btSphereShape( 0.5 );

		btTransform alpha_trans, beta_trans;
		alpha_trans.setOrigin( btVector3( btScalar( x_pos ), btScalar( 5 ), btScalar( 0 ) ) );
		alpha_trans.setRotation( btQuaternion( 0, 0, 1, 0 ) ); //we use -Y like up Axis
		beta_trans.setOrigin( btVector3( btScalar( x_pos ), btScalar( 1 ), btScalar( 0 ) ) );
		beta_trans.setRotation( btQuaternion( 0, 0, 1, 0 ) ); //we use -Y like up Axis

		btDefaultMotionState *alpha_motion_state = new btDefaultMotionState();
		btRigidBody::btRigidBodyConstructionInfo alpha_ci( mass, alpha_motion_state, box_shape );
		btRigidBody *alpha_rbody = new btRigidBody( alpha_ci );
		alpha_rbody->setCenterOfMassTransform( alpha_trans );
		bt_app->getWorld()->addRigidBody( alpha_rbody );
		alpha_rbody->setActivationState( DISABLE_DEACTIVATION );

		btDefaultMotionState *beta_motion_state = new btDefaultMotionState();
		btRigidBody::btRigidBodyConstructionInfo beta_ci( mass, beta_motion_state, sphere_shape );
		btRigidBody *beta_rbody = new btRigidBody( beta_ci );
		beta_rbody->setCenterOfMassTransform( beta_trans );
		bt_app->getWorld()->addRigidBody( beta_rbody );
		beta_rbody->setActivationState( DISABLE_DEACTIVATION );

		// Point 2 Point nailing alpha to world
		btVector3 pivot( btVector3( 0.0f, 0.0f, 0.0f ) );
		btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint( *alpha_rbody, pivot );
		p2pconst->setDbgDrawSize( btScalar( 2.f ) );
		bt_app->getWorld()->addConstraint( p2pconst, true );

		// Slider constraining beta's movement
		btTransform alpha_trans2, beta_trans2;
		alpha_trans2.setIdentity();
		beta_trans2.setIdentity();
		btQuaternion qt;
		qt.setEuler( 0, 0, SIMD_HALF_PI );
		alpha_trans2.setRotation( qt ); //we use -Y like up Axis
		beta_trans2.setRotation( qt ); //we use -Y like up Axis

		//Obtain the position of bottomSphere in local reference frame of topSphere
		btVector3 bottomSphereInTopSphereLRF = (alpha_rbody->getWorldTransform().inverse()(beta_rbody->getWorldTransform().getOrigin()));
		alpha_trans2.setOrigin( bottomSphereInTopSphereLRF );

		btSliderConstraint* sliderConst = new btSliderConstraint( *alpha_rbody, *beta_rbody, alpha_trans2, beta_trans2, true );
		sliderConst->setDbgDrawSize( btScalar( 0.5f ) );
		sliderConst->setLowerLinLimit( btScalar( -length ) );
		sliderConst->setUpperLinLimit( btScalar( 0 ) );
		sliderConst->setLowerAngLimit( btScalar( 0 ) );
		sliderConst->setUpperAngLimit( btScalar( 0 ) );

		// from http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=8674
		//sliderConst->setAngularLowerLimit( btVector3( -SIMD_EPSILON, -SIMD_EPSILON, -SIMD_EPSILON ) );	// Does not exist in 2.84
		//sliderConst->setAngularUpperLimit( btVector3( SIMD_EPSILON, SIMD_EPSILON, SIMD_EPSILON ) );
		sliderConst->setLowerAngLimit( btScalar( SIMD_EPSILON ) );	// Seems to do nothing
		sliderConst->setUpperAngLimit( btScalar( -SIMD_EPSILON ) );
		
		bt_app->getWorld()->addConstraint( sliderConst, true );
	}
};
edit: typo
Attachments
pendulum.png
pendulum.png (34.28 KiB) Viewed 5970 times
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Pendulums Won't Swing!

Post by benelot »

Hello skosh2,

Have you seen my pendulum example in the bullet example browser? There you can find a properly swinging pendulum, which is the final product of what you based some of your code on.
skosh2
Posts: 5
Joined: Thu Dec 08, 2016 11:46 pm

Re: Pendulums Won't Swing!

Post by skosh2 »

benelot,

If you're talking about "SDK/examples/Constraints/ConstraintDemo.cpp", then yes I have. But you'll notice the code doesn't actually do anything much differently than I've been trying to do it. Is there anything I'm missing in my code or anything that I've made unclear?

This is maddeningly frustrating..

Code: Select all

// "ConstraintDemo.cpp", lines 232-270
	//point to point constraint (ball socket)
	{
		btRigidBody* body0 = createRigidBody( mass,trans,shape);
		trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));

		mass = 1.f;
//		btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
//		btRigidBody* body1 = createRigidBody( 0.0,trans,0);
		//body1->setActivationState(DISABLE_DEACTIVATION);
		//body1->setDamping(0.3,0.3);

		btVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS);
		btVector3 axisInA(0,0,1);

	//	btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA;
//		btVector3 axisInB = body1?
//			(body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
		body0->getCenterOfMassTransform().getBasis() * axisInA;

#define P2P
#ifdef P2P
		btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
		//btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
		//btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB);
		m_dynamicsWorld->addConstraint(p2p);
		p2p->setDbgDrawSize(btScalar(5.f));
#else
		btHingeConstraint* hinge = new btHingeConstraint(*body0,pivotInA,axisInA);
		
		//use zero targetVelocity and a small maxMotorImpulse to simulate joint friction
		//float	targetVelocity = 0.f;
		//float	maxMotorImpulse = 0.01;
		float	targetVelocity = 1.f;
		float	maxMotorImpulse = 1.0f;
		hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse);
		m_dynamicsWorld->addConstraint(hinge);
		hinge->setDbgDrawSize(btScalar(5.f));
#endif //P2P
	}
P.S. Do you know what btTypedConstraint::setBreakingImpulseThreshold( btScalar ) actually does? It's not very well documented and all I see it do is make my btPoint2PointConstraint'ed box (non-swinging, mind you) just fall into eternity when I collide with it (as if it fell off a hook). I ask because it's one of the only member functions to twiddle with on the btPoint2PointConstraint class; all of the examples all over the forums of using btPoint2PointConstraint::setAngularLowerLimit(), e.g do not work in 2.84.
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Pendulums Won't Swing!

Post by benelot »

No, I mean this example consisting of multiple pendula, basically you only want one, that is a parameter of the example.

https://github.com/bulletphysics/bullet ... Cradle.cpp
Post Reply