Bullet select object

Runemaster
Posts: 4
Joined: Wed Apr 13, 2011 11:37 am

Bullet select object

Post by Runemaster »

Hello. I'm using qt + ogre + bullet. Then i try clicked my object selected, but then i try clicked in hole my object they selected (although should not be).
Question.jpg
code pick object:

Code: Select all

void RenderWidget::mousePressEvent(QMouseEvent* event)
{
    if(event->buttons().testFlag(Qt::LeftButton))
    {
        Ogre::Real x = event->pos().x() / (float)(this->width());
        Ogre::Real y = event->pos().y() / (float)(this->height());

        _raycast(x, y);
    }
}

void RenderWidget::_raycast(Ogre::Real x, Ogre::Real y)
{
    Ogre::Ray  ray = camera_->getCameraToViewportRay(x, y);
    btVector3 rayFrom, rayTo;

    rayFrom.setX(ray.getOrigin().x); rayFrom.setY(ray.getOrigin().y); rayFrom.setZ(ray.getOrigin().z);
    
	Ogre::Vector3 dest = ray.getPoint(1000);

    rayTo.setX(dest.x); rayTo.setY(dest.y); rayTo.setZ(dest.z);

    btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom, rayTo);
    collisionWorld_->rayTest(rayFrom, rayTo, rayCallback);

    if(rayCallback.hasHit())
    {
        collisionObject_ = rayCallback.m_collisionObject;
    }
    else
    {
        collisionObject_ = NULL;
    }
}
code create physical object:

Code: Select all

void RenderObject::_createPhysicBody()
{
    collisionObject_ = new btCollisionObject();
    meshStrider_     = new MeshStrider(entity_->getMesh().getPointer());

    collisionShape_ = new btConvexTriangleMeshShape(meshStrider_);

    collisionObject_->setCollisionShape(collisionShape_);
    collisionWorld_->addCollisionObject(collisionObject_);
}
class MeshStrider:

.h

Code: Select all

#ifndef MESHSTRIDER_H
#define MESHSTRIDER_H

#include <Ogre.h>
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionShapes/btStridingMeshInterface.h>
#include <BulletCollision/CollisionShapes/btCollisionShape.h>

class MeshStrider : public btStridingMeshInterface
{
    public:
        MeshStrider(Ogre::Mesh* mesh);
        virtual ~MeshStrider();

        inline void setMesh(Ogre::Mesh* mesh) { assert(mesh); mesh_ = mesh; }

        virtual int  getNumSubParts() const;
        virtual void getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type,
                                              int& stride, unsigned char** indexbase, int & indexstride,
                                              int& numfaces, PHY_ScalarType& indicestype, int subpart = 0);
        virtual void getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type,
                                                      int& stride, const unsigned char** indexbase, int& indexstride,
                                                      int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) const;
        virtual void    unLockVertexBase(int subpart);
        virtual void    unLockReadOnlyVertexBase(int subpart) const;
        virtual void    preallocateVertices(int numverts);
        virtual void    preallocateIndices(int numindices);

    private:
        Ogre::Mesh* mesh_;
};

#endif // MESHSTRIDER_H
.cpp

Code: Select all

#include "MeshStrider.h"

MeshStrider::MeshStrider(Ogre::Mesh* mesh) : mesh_(mesh)
{
    //ctor
}

MeshStrider::~MeshStrider()
{
    //dtor
}

int MeshStrider::getNumSubParts() const
{
    int result = mesh_->getNumSubMeshes();
    assert(result);
    return result;
}

void MeshStrider::getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type,
                                           int& stride, unsigned char** indexbase, int& indexstride,
                                           int& numfaces, PHY_ScalarType& indicestype, int subpart)
{
    assert(0);
}

void MeshStrider::getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type,
                                                   int& stride, const unsigned char** indexbase, int& indexstride,
                                                   int& numfaces, PHY_ScalarType& indicestype, int subpart) const
{
    Ogre::SubMesh* subMesh = mesh_->getSubMesh(subpart);

    Ogre::VertexData* vertexData = subMesh->useSharedVertices ? mesh_->sharedVertexData : subMesh->vertexData;

    const Ogre::VertexElement* positionElements = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
    Ogre::HardwareVertexBufferSharedPtr vertexBuffer = vertexData->vertexBufferBinding->getBuffer(positionElements->getSource());

    *vertexbase = reinterpret_cast<unsigned char*>(vertexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

    float* real;
    positionElements->baseVertexPointerToElement((void*) *vertexbase, &real);
    *vertexbase = (unsigned char*) real;

    stride = (int) vertexBuffer->getVertexSize();

    numverts = (int) vertexData->vertexCount;
    assert(numverts);

    type = PHY_FLOAT;

    Ogre::IndexData* indexData = subMesh->indexData;
    Ogre::HardwareIndexBufferSharedPtr indexBuffer = indexData->indexBuffer;

    if(indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT) { indicestype = PHY_INTEGER; }
    else if (indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT) { indicestype = PHY_SHORT; }

    if(subMesh->operationType == Ogre::RenderOperation::OT_TRIANGLE_LIST)
    {
        numfaces    = (int) indexData->indexCount / 3;
        indexstride = (int) indexBuffer->getIndexSize() * 3;
    }
    else if(subMesh->operationType == Ogre::RenderOperation::OT_TRIANGLE_STRIP)
    {
        numfaces    = (int) indexData->indexCount - 2;
        indexstride = (int) indexBuffer->getIndexSize();
    }
    else { assert(0); }

    *indexbase = reinterpret_cast<unsigned char*>(indexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
}

void MeshStrider::unLockReadOnlyVertexBase(int subpart) const
{
    Ogre::SubMesh* subMesh = mesh_->getSubMesh(subpart);

    Ogre::VertexData* vertexData = subMesh->useSharedVertices ? mesh_->sharedVertexData : subMesh->vertexData;

    const Ogre::VertexElement* positionElements = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
    Ogre::HardwareVertexBufferSharedPtr vertexBuffer = vertexData->vertexBufferBinding->getBuffer(positionElements->getSource());

    vertexBuffer->unlock();

    Ogre::HardwareIndexBufferSharedPtr indexBuffer = subMesh->indexData->indexBuffer;
    indexBuffer->unlock();
}

void MeshStrider::unLockVertexBase(int subpart) { assert(0); }
void MeshStrider::preallocateVertices(int numverts) { assert(0); }
void MeshStrider::preallocateIndices(int numindices) { assert(0); }
P.S. Thank you
You do not have the required permissions to view the files attached to this post.
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Bullet select object

Post by dphil »

Without going into too much detail in your code, my first thought is that you are using btConvexTriangleMeshShape. If you read the API, the resulting physics shape is actually the convex hull of the mesh you provide in construction. Hence, I'm guessing that as long as your mouse click intersects the convex hull of your shape - and not necessarily just the mesh triangles - it will register a hit.

In general, the various convex collision shapes (see collision shapes) do not have a notion of being hollow or having holes. They are "filled in", for collision purposes. Thus if you want accurate collision detection (for a bullet raycast, for example) with your torus knot, I would suggest using btGImpactMeshShape (if it needs to be dynamic) or btBvhTriangleMeshShape (if it is static, non-moving), both of which represent concave shapes based on triangle meshes with accurate collision on their triangles.
Runemaster
Posts: 4
Joined: Wed Apr 13, 2011 11:37 am

Re: Bullet select object

Post by Runemaster »

Thank you very much helped btGImpactMeshShape