Inertia Causing Extremely odd effects.

Started by
5 comments, last by BlueSpud 9 years, 8 months ago

Hey,
So I downloaded bullet today because I've heard nothing but good things about it. Unfortunately, after reading a quick tutorial, something went terribly wrong XD. So I created plane to serve as the ground and then added a sphere above it and let it fall onto the plane. It hits the ground like I'd expect and then just starts infinitely accelerating towards the negative x and keeping a constant z and y. Here is my code:


//
//  physics.cpp
//  Spud Engine
//
//  Created by Logan on 8/6/14.
//  Copyright (c) 2014 Logan. All rights reserved.
//

#include "physics.h"


physicsWorld::physicsWorld()
    {
        //create all the world components
        bulletConfiguration = new btDefaultCollisionConfiguration();
        bulletDispatcher = new btCollisionDispatcher(bulletConfiguration);
        bulletBroadPhaseInterface = new btDbvtBroadphase();
        bulletSolver = new btSequentialImpulseConstraintSolver();
        
        //create the world
        bulletWorld = new btDiscreteDynamicsWorld(bulletDispatcher,bulletBroadPhaseInterface,bulletSolver,bulletConfiguration);
        bulletWorld->setGravity(btVector3(0,-10,0));
        
        //here are some temp gemoetries
        btTransform t;
        t.setIdentity();
        t.setOrigin(btVector3(0,0,0));
        
        btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0,1,0),0.0);
        btMotionState* motionStatePlane = new btDefaultMotionState(t);
        btRigidBody::btRigidBodyConstructionInfo info(0.0,motionStatePlane,plane);
        btRigidBody* planeBody = new btRigidBody(info);
        
        
        rigidBodies.push_back(planeBody);
        bulletWorld->addRigidBody(planeBody);
        
        addRigidSpehere(1, glm::vec3(0,3,0));
        
        
    }

physicsWorld::~physicsWorld()
    {
        //delete all the rigid bodies
        for (int i = 0; i <  rigidBodies.size(); i ++)
        {
            delete rigidBodies[i];
        }

        
        //delete everything
        delete bulletWorld;
        delete bulletSolver;
        delete bulletBroadPhaseInterface;
        delete bulletDispatcher;
        delete bulletConfiguration;
        
    }

void physicsWorld::update(double time)
    {
        bulletWorld->stepSimulation(time);
    }

btRigidBody* physicsWorld::addRigidSpehere(float rad, glm::vec3 position)
    {
        btTransform t;
        t.setIdentity();
        t.setOrigin(btVector3(position.x,position.y,position.z));
        
        btSphereShape* sphere = new btSphereShape(rad);
        
        //calculate inertia
        btVector3 inertia(0.0,0.0,0.0);
        sphere->calculateLocalInertia(1.0, inertia);
        
        btMotionState* motionState = new btDefaultMotionState(t);
        btRigidBody::btRigidBodyConstructionInfo info(1.0,motionState,sphere,inertia);
        btRigidBody* sphereBody = new btRigidBody(info);
        
        rigidBodies.push_back(sphereBody);
        bulletWorld->addRigidBody(sphereBody);
        
        return sphereBody;
    }

And Im updating it with:


 SceneRenderer.currentScene->PhysicsWorld->update(1.0/60.0);

Also, both printing out and rendering are demonstrating that problem. Here is the code for that bit:


//temp to test out physics
        btTransform t;
        btVector3 origin;
        float mat[16];
        PhysicsWorld->rigidBodies[1]->getMotionState()->getWorldTransform(t);
        t.getOpenGLMatrix(mat);
        origin = t.getOrigin();
        
        std::cout << origin.x() << " " << origin.y() << " " << origin.z() << std::endl;
        
        RenderEngine.translateToCameraSpace(cam);
        glMultMatrixf(mat);
        PhysicsSpehere->render(program);

I just started messing around with this, so if anyone can help, I would really appreciate it. Thanks.

EDIT: after a bit more messing around as well as implementing a few other things, it seems that there is a problem with the inertia. Is there something Im doing wrong there?

Advertisement

I am unable to reproduce this problem. I copy pasted your code and sphere stops at position {0.000000000, 0.999999821, 0.000000000, 0.000000000}.

I am unable to reproduce this problem. I copy pasted your code and sphere stops at position {0.000000000, 0.999999821, 0.000000000, 0.000000000}.

What version are you using? Im using 2.82, maybe its bugged?

I probably have 2.82 too. Are you sure you're not modifying it somewhere accidently; like force, velocity, or position?

I used this loop and a debugger to inspect values:


	while(1) {
		bulletWorld->stepSimulation(1.0 / 60.0);
		OutputDebugString(to_wstring(sphere->getWorldTransform().getOrigin().getX()).c_str());
		OutputDebugString(L", ");
		OutputDebugString(to_wstring(sphere->getWorldTransform().getOrigin().getY()).c_str());
		OutputDebugString(L", ");
		OutputDebugString(to_wstring(sphere->getWorldTransform().getOrigin().getZ()).c_str());
		OutputDebugString(L"\n");
	}

First few values are 3.0 and lower, but eventually it stops at 0.000000, 1.000000, 0.000000 and just spams that.

(seems debugger and outputting to debug console gives different numbers; rounding?).

I probably have 2.82 too. Are you sure you're not modifying it somewhere accidently; like force, velocity, or position?

I used this loop and a debugger to inspect values:


	while(1) {
		bulletWorld->stepSimulation(1.0 / 60.0);
		OutputDebugString(to_wstring(sphere->getWorldTransform().getOrigin().getX()).c_str());
		OutputDebugString(L", ");
		OutputDebugString(to_wstring(sphere->getWorldTransform().getOrigin().getY()).c_str());
		OutputDebugString(L", ");
		OutputDebugString(to_wstring(sphere->getWorldTransform().getOrigin().getZ()).c_str());
		OutputDebugString(L"\n");
	}

First few values are 3.0 and lower, but eventually it stops at 0.000000, 1.000000, 0.000000 and just spams that.

(seems debugger and outputting to debug console gives different numbers; rounding?).

Im also visually debugging it and the sphere hits the ground and just starts rolling and rolling.Im going to try to recompile it and see if that helps.

EDIT:

recompiling it didn't make a difference. I still have no idea whats wrong.

That's weird. Could you try to replace your main / WinMain method with this code just to test whether you get correct results with minimal code?

And of course you'll need to fix Bullet paths.


#include <iostream>
using std::cout;
#include <DirectXMath.h>
using DirectX::XMFLOAT3;
#include "../Bullet Physics/btBulletCollisionCommon.h"
#include "../Bullet Physics/btBulletDynamicsCommon.h"
#pragma comment(lib, "../x64/Debug/Bullet Physics.lib")

btRigidBody* addRigidSpehere(float rad, XMFLOAT3 position)
{
	btTransform t;
	t.setIdentity();
	t.setOrigin(btVector3(position.x, position.y, position.z));

	btSphereShape* sphere = new btSphereShape(rad);

	//calculate inertia
	btVector3 inertia(0.0, 0.0, 0.0);
	sphere->calculateLocalInertia(1.0, inertia);

	btMotionState* motionState = new btDefaultMotionState(t);
	btRigidBody::btRigidBodyConstructionInfo info(1.0, motionState, sphere, inertia);
	btRigidBody* sphereBody = new btRigidBody(info);

	return sphereBody;
}

void main() {
	auto bulletConfiguration = new btDefaultCollisionConfiguration();
	auto bulletDispatcher = new btCollisionDispatcher(bulletConfiguration);
	auto bulletBroadPhaseInterface = new btDbvtBroadphase();
	auto bulletSolver = new btSequentialImpulseConstraintSolver();

	auto bulletWorld = new btDiscreteDynamicsWorld(bulletDispatcher, bulletBroadPhaseInterface, bulletSolver, bulletConfiguration);
	bulletWorld->setGravity(btVector3(0, -10, 0));

	btTransform t;
	t.setIdentity();
	t.setOrigin(btVector3(0, 0, 0));

	btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0, 1, 0), 0.0);
	btMotionState* motionStatePlane = new btDefaultMotionState(t);
	btRigidBody::btRigidBodyConstructionInfo info(0.0, motionStatePlane, plane);
	btRigidBody* planeBody = new btRigidBody(info);

	bulletWorld->addRigidBody(planeBody);

	auto sphere = addRigidSpehere(1, XMFLOAT3(0, 3, 0));
	bulletWorld->addRigidBody(sphere);

	while(1) {
		bulletWorld->stepSimulation(1.0 / 60.0);
		cout << sphere->getWorldTransform().getOrigin().getX() << ", ";
		cout << sphere->getWorldTransform().getOrigin().getY() << ", ";
		cout << sphere->getWorldTransform().getOrigin().getZ() << "\n";
	}
}

That's weird. Could you try to replace your main / WinMain method with this code just to test whether you get correct results with minimal code?

And of course you'll need to fix Bullet paths.


#include <iostream>
using std::cout;
#include <DirectXMath.h>
using DirectX::XMFLOAT3;
#include "../Bullet Physics/btBulletCollisionCommon.h"
#include "../Bullet Physics/btBulletDynamicsCommon.h"
#pragma comment(lib, "../x64/Debug/Bullet Physics.lib")

btRigidBody* addRigidSpehere(float rad, XMFLOAT3 position)
{
	btTransform t;
	t.setIdentity();
	t.setOrigin(btVector3(position.x, position.y, position.z));

	btSphereShape* sphere = new btSphereShape(rad);

	//calculate inertia
	btVector3 inertia(0.0, 0.0, 0.0);
	sphere->calculateLocalInertia(1.0, inertia);

	btMotionState* motionState = new btDefaultMotionState(t);
	btRigidBody::btRigidBodyConstructionInfo info(1.0, motionState, sphere, inertia);
	btRigidBody* sphereBody = new btRigidBody(info);

	return sphereBody;
}

void main() {
	auto bulletConfiguration = new btDefaultCollisionConfiguration();
	auto bulletDispatcher = new btCollisionDispatcher(bulletConfiguration);
	auto bulletBroadPhaseInterface = new btDbvtBroadphase();
	auto bulletSolver = new btSequentialImpulseConstraintSolver();

	auto bulletWorld = new btDiscreteDynamicsWorld(bulletDispatcher, bulletBroadPhaseInterface, bulletSolver, bulletConfiguration);
	bulletWorld->setGravity(btVector3(0, -10, 0));

	btTransform t;
	t.setIdentity();
	t.setOrigin(btVector3(0, 0, 0));

	btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0, 1, 0), 0.0);
	btMotionState* motionStatePlane = new btDefaultMotionState(t);
	btRigidBody::btRigidBodyConstructionInfo info(0.0, motionStatePlane, plane);
	btRigidBody* planeBody = new btRigidBody(info);

	bulletWorld->addRigidBody(planeBody);

	auto sphere = addRigidSpehere(1, XMFLOAT3(0, 3, 0));
	bulletWorld->addRigidBody(sphere);

	while(1) {
		bulletWorld->stepSimulation(1.0 / 60.0);
		cout << sphere->getWorldTransform().getOrigin().getX() << ", ";
		cout << sphere->getWorldTransform().getOrigin().getY() << ", ";
		cout << sphere->getWorldTransform().getOrigin().getZ() << "\n";
	}
}

No, same thing. Heres the output:


0, 2.99722, 0
0, 2.99167, 0
0, 2.98333, 0
0, 2.97222, 0
0, 2.95833, 0
0, 2.94167, 0
0, 2.92222, 0
0, 2.9, 0
0, 2.875, 0
0, 2.84722, 0
0, 2.81667, 0
0, 2.78333, 0
0, 2.74722, 0
0, 2.70833, 0
0, 2.66667, 0
0, 2.62222, 0
0, 2.575, 0
0, 2.525, 0
0, 2.47222, 0
0, 2.41667, 0
0, 2.35833, 0
0, 2.29722, 0
0, 2.23333, 0
0, 2.16667, 0
0, 2.09722, 0
0, 2.025, 0
0, 1.95, 0
0, 1.87222, 0
0, 1.79167, 0
0, 1.70833, 0
0, 1.62222, 0
0, 1.53333, 0
0, 1.44167, 0
0, 1.34722, 0
0, 1.25, 0
0, 1.15, 0
0, 1.04722, 0
0, 0.941667, 0
-0.00136054, 0.988333, 0
-0.00399887, 0.990667, 0
-0.00721497, 0.992533, 0
-0.0110322, 0.994027, 0
-0.0154692, 0.995221, 0
-0.0205409, 0.996177, 0
-0.0262592, 0.996942, 0
-0.0326338, 0.997553, 0
-0.0396722, 0.998043, 0
-0.0473806, 0.998434, 0
-0.0557639, 0.998747, 0
-0.064826, 0.998998, 0
-0.07457, 0.999198, 0
-0.0849984, 0.999359, 0
-0.0961132, 0.999487, 0
-0.107916, 0.99959, 0
-0.120408, 0.999672, 0
-0.133591, 0.999737, 0
-0.147464, 0.99979, 0
-0.16203, 0.999832, 0
-0.177288, 0.999865, 0
-0.193238, 0.999892, 0
-0.209882, 0.999914, 0
-0.227219, 0.999931, 0
-0.24525, 0.999945, 0
-0.263974, 0.999956, 0
-0.283393, 0.999965, 0
-0.303505, 0.999972, 0
-0.324311, 0.999977, 0
-0.345812, 0.999982, 0
-0.368007, 0.999986, 0
-0.390896, 0.999988, 0
-0.414479, 0.999991, 0
-0.438757, 0.999993, 0
-0.463729, 0.999994, 0
-0.489395, 0.999995, 0
-0.515756, 0.999996, 0
-0.542811, 0.999997, 0
-0.570561, 0.999998, 0
-0.599005, 0.999998, 0
-0.628143, 0.999998, 0
-0.657976, 0.999999, 0
-0.688503, 0.999999, 0
-0.719725, 0.999999, 0
-0.751641, 0.999999, 0
-0.784252, 1, 0
-0.817557, 1, 0
-0.851556, 1, 0
-0.88625, 1, 0
-0.921638, 1, 0
-0.957721, 1, 0
-0.994498, 1, 0
-1.03197, 1, 0
-1.07014, 1, 0
-1.109, 1, 0
-1.14855, 1, 0
-1.1888, 1, 0
-1.22975, 1, 0
-1.27138, 1, 0
-1.31372, 1, 0
-1.35674, 1, 0
-1.40047, 1, 0
-1.44488, 1, 0
-1.48999, 1, 0
-1.5358, 1, 0
-1.5823, 1, 0
-1.62949, 1, 0
-1.67738, 1, 0
-1.72596, 1, 0
-1.77524, 1, 0
-1.82521, 1, 0
-1.87588, 1, 0
-1.92724, 1, 0
-1.97929, 1, 0
-2.03204, 1, 0
-2.08549, 1, 0
-2.13962, 1, 0
-2.19446, 1, 0
-2.24998, 1, 0
-2.30621, 1, 0
-2.36312, 1, 0
-2.42073, 1, 0
-2.47904, 1, 0
-2.53804, 1, 0
-2.59773, 1, 0
-2.65812, 1, 0
-2.7192, 1, 0
-2.78098, 1, 0
-2.84345, 1, 0
-2.90662, 1, 0
-2.97048, 1, 0
-3.03503, 1, 0
-3.10028, 1, 0
-3.16623, 1, 0
-3.23286, 1, 0
-3.3002, 1, 0
-3.36822, 1, 0
-3.43695, 1, 0
-3.50636, 1, 0
-3.57647, 1, 0
-3.64728, 1, 0
-3.71878, 1, 0
-3.79097, 1, 0
-3.86386, 1, 0
-3.93744, 1, 0
-4.01172, 1, 0
-4.08669, 1, 0
-4.16236, 1, 0
-4.23872, 1, 0
-4.31577, 1, 0
-4.39352, 1, 0
-4.47197, 1, 0
-4.5511, 1, 0

It would seem that my issue is actually a compilation error, its listed in the bit hub here:

https://github.com/bulletphysics/bullet3/issues/49

I've been trying to compile bullet 3 as a .framework like I had done for 2.82, but to no avail.

EDIT: luckily they posted the fix in a commit, so I was able to go into 2.82 and modify the code causing an issue, works like a dream now.

This topic is closed to new replies.

Advertisement