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: Select all
void RenderObject::_createPhysicBody()
{
collisionObject_ = new btCollisionObject();
meshStrider_ = new MeshStrider(entity_->getMesh().getPointer());
collisionShape_ = new btConvexTriangleMeshShape(meshStrider_);
collisionObject_->setCollisionShape(collisionShape_);
collisionWorld_->addCollisionObject(collisionObject_);
}
.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
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); }