I'm using Ogre and Bullet for a project and I currently have a first person camera set up with a Capsule Collision Shape. I've created a model of a cave (which will serve as the main part of the level) and imported it into my game. I'm now trying to create an OgreBulletCollisions::TriangleMeshCollisionShape of the cave.
The code I've got so far is this but it isn't working. It compiles but the Capsule shape passes straight through the cave shape. Also I have debug outlines on and there are none being drawn around the cave mesh.
Entity *cave = mSceneMgr->createEntity("Cave", "pCube1.mesh");
SceneNode *caveNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
caveNode->setPosition(0, 10, 250);
caveNode->setScale(10, 10, 10);
caveNode->rotate(Quaternion(0.5, 0.5, -0.5, 0.5));
caveNode->attachObject(cave);
OgreBulletCollisions::StaticMeshToShapeConverter *smtsc = new OgreBulletCollisions::StaticMeshToShapeConverter();
smtsc->addEntity(cave);
OgreBulletCollisions::TriangleMeshCollisionShape *tri = smtsc->createTrimesh();
OgreBulletDynamics::RigidBody *caveBody = new OgreBulletDynamics::RigidBody("cave", mWorld);
caveBody->setStaticShape(tri, 0.1, 0.8);
mShapes.push_back(tri);
mBodies.push_back(caveBody);
Any suggestions are welcome.
To clarify. It compiles but the Capsule shape passes straight through the cave shape. Also I have debug outlines on and there are none being drawn around the cave mesh
I used your code and got exactly the same result - my vehicle passed right through the trimesh.
Looking at the examples in:
ogrebullet/Demos/src/OgreBulletListener.cpp
it would seem to be that instead of calling:
caveBody->setStaticShape(tri, 0.1, 0.8);
you instead need to invoke:
caveBody->setStaticShape(caveNode, tri, 0.1, 0.8, Ogre::Vector3( position_x, position_y, position_z ));`
When I made this change, the collisions work as expected
In the end I had to use a btScaledBvhTriangleMeshShape. So my code now looks like
OgreBulletCollisions::StaticMeshToShapeConverter *smtsc =
new OgreBulletCollisions::StaticMeshToShapeConverter();
smtsc->addEntity(cave);
OgreBulletCollisions::TriangleMeshCollisionShape *tri = smtsc->createTrimesh();
OgreBulletDynamics::RigidBody *caveBody = new OgreBulletDynamics::RigidBody("cave", mWorld);
btScaledBvhTriangleMeshShape *triShape = new btScaledBvhTriangleMeshShape((btBvhTriangleMeshShape*)(tri->getBulletShape()), btVector3(150, 150, 150));
caveBody->setStaticShape(triShape, 0.0, 5, Vector3::ZERO, rotationQuaternion);
caveBody->setDebugDisplayEnabled(true);
Related
I have an interesting bug that has been "bugging" me for a few days now.
I am currently using OpenGL to draw text on a screen. I am utilizing the OGLFT library to assist the drawing. This library actually uses the freetype2 library. I am actually not doing anything special with the text. I am only looking for monochromatic text.
Anyways, after implementing the library, I noticed that the text is only drawn correct when I have glStipple enabled. I believe that there is some interference issue between the OGLFT library and what I am enabling.
I was wondering if there is anyone out there with some experience on using the OGLFT library. I am posting a minimalist example of my code to demonstrate what is going on:
(Please note that there are some variables that are used to st the zoom factor of my glCanvas and the position of the camera and that this is only for 2D)
double _zoomX = 1.0;
double _zoomY = 1.0;
double _cameraX = 0;
double _cameraY = 0;
/* This function gets called everytime a draw routine is needed */
void modelDefinition::onPaintCanvas(wxPaintEvent &event)
{
wxGLCanvas::SetCurrent(*_geometryContext);// This will make sure the the openGL commands are routed to the wxGLCanvas object
wxPaintDC dc(this);// This is required for drawing
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
updateProjection();
OGLFT::Monochrome *testface = new OGLFT::Monochrome( "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 8);
testface->draw(0, 0, "test");
glEnable(GL_LINE_STIPPLE);// WHen I comment out this line, the text is unable to be drawn
glLineStipple(1, 0b0001100011000110);
glBegin(GL_LINES);
glVertex2d(_startPoint.x, _startPoint.y);
glVertex2d(_endPoint.x, _endPoint.y);
glEnd();
glDisable(GL_LINE_STIPPLE);
SwapBuffers();
}
void modelDefinition::updateProjection()
{
// First, load the projection matrix and reset the view to a default view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-_zoomX, _zoomX, -_zoomY, _zoomY, -1.0, 1.0);
//Reset to modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, (double)this->GetSize().GetWidth(), (double)this->GetSize().GetHeight());
/* This section will handle the translation (panning) and scaled (zooming).
* Needs to be called each time a draw occurs in order to update the placement of all the components */
if(_zoomX < 1e-9 || _zoomY < 1e-9)
{
_zoomX = 1e-9;
_zoomY = _zoomX;
}
if(_zoomX > 1e6 || _zoomY > 1e6)
{
_zoomX = 1e6;
_zoomY = _zoomX;
}
glTranslated(-_cameraX, -_cameraY, 0.0);
}
Also one thing to note is that the code below the glEnable(GL_LINE_STIPPLE); is required. It is as if the glStipple needs to be drawn correctly for the text to be displayed correctly.
Looking through your code, I believe that your intention is to render it as a greyscale? If so, then you can simply use the OGLFT::Grayscale *testface = new OGLFT::Grayscale( "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 8);
This will get what you need without having to worry about the issue that you posted. In fact, I recommend doing it this way too.
What is the problem? It does not show the sprite the first time.
playerSprite = Sprite::create("ip.png");
playerSprite->setPosition(Vec2(visibleSize.width/2,visibleSize.height));
//this->addChild(playerSprite,1);
auto body = PhysicsBody::createCircle
(playerSprite->getContentSize().width / 2.5);
body->setContactTestBitmask(true);
body->setDynamic(true);
playerSprite->setPhysicsBody(body);
this->addChild(playerSprite,0);
Try Using Another Z-Order of your Sprite. this->addChild(playerSprite,TRY_WITH_SOME_LARGE_VALUE);`
AND see if the result are Same.
Since you questions is not much defined, answer might be incorrect.
First of all, make sure that image is placed correctly and there is no typos in image name.
playerSprite position is in the middle of the top. to center it:
->setPosition(Point(visibleSize.widht * 0.5, visibleSize.height * 0.5));
If this == Scene you can do it like this.
->setPosition(Point(this->getContentSize().width * 0.5, this->getContentSize().height * 0.5));
Also when adding Sprite make sure there is no other Sprite above by setting zOrder to a bigger number
this->addChild(playerSprite, 100);
I am using Box2D and SFML to create a simple game. However, my object (ball) does not completely lands after it hits the ground. It seems that 50% of the ball has passed through my border, which looks really awkward. Below are some pictures for illustration.
Ball Before:
Ball After hitting the border at the ground:
As you can see, 50% of the ball has dissapeared (most probably due to offsets or what). Anyone know how to fix it?
Below are my code for the object creation:
circ_ = sf::CircleShape(radius);
circ_.setOrigin(sf::Vector2f(size.x/2,size.y/2));
circ_.setFillColor(sf::Color(255, 255, 255, 255));
circ_.setOutlineThickness(1);
circ_.setOutlineColor(sf::Color::Black);
bodyDef_.position = b2Vec2(position.x/PIXEL_PER_METER, position.y/PIXEL_PER_METER);
bodyDef_.type = b2_staticBody;
bodyFixtureDef_.density = 1.0f;
bodyFixtureDef_.friction = 0.3f;
bodyFixtureDef_.restitution = 0.8f;
Where on my SFML code, I have created the Box2D object using:
Ball basketBall(world, basketBallSize, basketBallPos, 0.0, basketBallRadius, false);
Where radius = 32.
Anybody could help me with this? Thanks.
Box2d uses the center of a circle/polygon shape as position while SFML uses the top left corner of the sprite/shape as position, so you need to take that into account when translating between SFML and Box2d positions. Also keep in mind Box2d uses meters instead of pixles and radians instead of degrees.
Just do like that:
#include <cmath> // for M_PI define
Sprite.setPosition(sf::Vector2f(b2BallBody->GetPosition().x * PIXEL_PER_METER - Sprite.getGlobalBounds().width * 0.5f,
b2BallBody->GetPosition().y * PIXEL_PER_METER - Sprite.getGlobalBounds().height * 0.5f));
Sprite.setRotation(b2BallBody->GetAngle() * (float)(180.0 / M_PI));
I am using the GL_SELECT method to achieve mouse selection in OpenGL using JOGL Java Library.
I know the method is deprecated and such, but it is a simple school assignment and this should do it.
However I am having some trouble: even though something is rendered in GL_SELECT mode, glRenderMode(GL_RENDER) returns zero hits. The problem is deterministic, but I don't see a kind of pattern; for example, if I have a sphere in the center, it works if I click on its upper part, but not on its lower part. For a cube, it only won't work on one specific face. For a rectangle it works alright.
I have tested commenting out the glRenderMode(GL_SELECT) to check if something was indeed being rendered and yes, I could see the shape, but even so glRenderMode(GL_RENDER) gave me zero.
EDIT: I have also tested removing the call to gluPickMatrix() and the glRenderMode(GL_SELECT), which gave me exactly the same as the normal (non-picking) render, so the projection and model view matrixes are set up correctly I think.
So, I don't think I am rendering incorrectly in select mode. What can be going on?
EDIT: maybe this could be a hardware problem, as the method is deprecated. Is that possible?
Thanks in advance.
// Get required information
point.y = getHeight() - point.y;
gl.glGetIntegerv(GL2.GL_VIEWPORT, view, 0);
// Setup OpenGL for selection
gl.glSelectBuffer(64, buffer);
gl.glRenderMode(GL2.GL_SELECT);
gl.glInitNames();
// Setup projection matrix
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
Util.glu.gluPickMatrix( point.x, point.y, 5.0, 5.0, view, 0 );
Util.glu.gluPerspective(camera.getFieldOfView(), getWidth() * 1.0 / getHeight(),
camera.getCloseDistance(), camera.getFarDistance() );
// Setup model view matrix for rendering
gl.glMatrixMode(GL2.GL_MODELVIEW);
camera.setView(gl); // Set to model view and use glLookAt
gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
// Render objects
for(int i = 0; i < shapeList.size(); i++) {
gl.glPushName(i);
// Execute transformations for translation/rotation/scale and render shape
shapeList.get(i).display(gl, false);
gl.glPopName();
}
// Process hits
hits = gl.glRenderMode(GL2.GL_RENDER);
System.out.println("Hits = " + hits);
// ... Process hits here ...
// Reset matrixes
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
camera.setView function:
public void setView( GL2 gl ) {
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
Util.glu.gluLookAt( eye[Axis.X], eye[Axis.Y], eye[Axis.Z],
target[Axis.X], target[Axis.Y], target[Axis.Z],
up[Axis.X], up[Axis.Y], up[Axis.Z] );
}
I've just started implementing bullet into my Ogre project. I follows the install instructions here: http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+1
And the rest if the tutorial here:
http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+2
I got that to work fine however now I wanted to extend it to a handle a first person camera. I created a CapsuleShape and a Rigid Body (like the tutorial did for the boxes) however when I run the game the capsule falls over and rolls around on the floor, causing the camera swing wildly around.
I need a way to fix the capsule to always stay upright, but I have no idea how
Below is the code I'm using.
(part of) Header File
OgreBulletDynamics::DynamicsWorld *mWorld; // OgreBullet World
OgreBulletCollisions::DebugDrawer *debugDrawer;
std::deque<OgreBulletDynamics::RigidBody *> mBodies;
std::deque<OgreBulletCollisions::CollisionShape *> mShapes;
OgreBulletCollisions::CollisionShape *character;
OgreBulletDynamics::RigidBody *characterBody;
Ogre::SceneNode *charNode;
Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
Ogre::RenderWindow* mWindow;
main file
bool MinimalOgre::go(void)
{
...
mCamera = mSceneMgr->createCamera("PlayerCam");
mCamera->setPosition(Vector3(0,0,0));
mCamera->lookAt(Vector3(0,0,300));
mCamera->setNearClipDistance(5);
mCameraMan = new OgreBites::SdkCameraMan(mCamera);
OgreBulletCollisions::CollisionShape *Shape;
Shape = new OgreBulletCollisions::StaticPlaneCollisionShape(Vector3(0,1,0), 0); // (normal vector, distance)
OgreBulletDynamics::RigidBody *defaultPlaneBody = new OgreBulletDynamics::RigidBody(
"BasePlane",
mWorld);
defaultPlaneBody->setStaticShape(Shape, 0.1, 0.8); // (shape, restitution, friction)
// push the created objects to the deques
mShapes.push_back(Shape);
mBodies.push_back(defaultPlaneBody);
character = new OgreBulletCollisions::CapsuleCollisionShape(1.0f, 1.0f, Vector3(0, 1, 0));
charNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
charNode->attachObject(mCamera);
charNode->setPosition(mCamera->getPosition());
characterBody = new OgreBulletDynamics::RigidBody("character", mWorld);
characterBody->setShape( charNode,
character,
0.0f, // dynamic body restitution
10.0f, // dynamic body friction
10.0f, // dynamic bodymass
Vector3(0,0,0),
Quaternion(0, 0, 1, 0));
mShapes.push_back(character);
mBodies.push_back(characterBody);
...
}
You can lock the angular motion of the capsule in order to prevent it from tipping over. Ogre doesn't expose this functionality directly, but you should be able to access the underlying bullet rigid body to accomplish what you need:
characterBody->getBulletRigidBody()->setAngularFactor(btVector3(0.0f,1.0f,0.0f));
This would lock rotation on the xaxis and zaxis, preventing the capsule from tipping over, but allowing rotation around the yaxis, so that the character can still turn.
At some point you may want to looking into using a kinematic character controller, but that's an answer to a different question.