📄 ogrecapsulemeshcollisionshape.cpp
字号:
void CapsuleMeshCollisionShape::createCapsule(const std::string& strName, const float radius, const float height, const int nRings, const int nSegments)
{
MeshPtr pCapsule = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
SubMesh *pCapsuleVertex = pCapsule->createSubMesh();
pCapsule->sharedVertexData = new VertexData();
VertexData* vertexData = pCapsule->sharedVertexData;
// define the vertex format
VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
size_t currOffset = 0;
// positions
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
// normals
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
// two dimensional texture coordinates
vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
currOffset += VertexElement::getTypeSize(VET_FLOAT2);
// allocate the vertex buffer
vertexData->vertexCount = (nRings + 1) * (nSegments+1);
HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
VertexBufferBinding* binding = vertexData->vertexBufferBinding;
binding->setBinding(0, vBuf);
float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
// allocate index buffer
pCapsuleVertex->indexData->indexCount = 6 * nRings * (nSegments + 1);
pCapsuleVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pCapsuleVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf = pCapsuleVertex->indexData->indexBuffer;
unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
float fDeltaRingAngle = (PI / nRings);
float fDeltaSegAngle = (2 * PI / nSegments);
unsigned short wVerticeIndex = 0 ;
// Generate the group of rings for the sphere
for( int ring = 0; ring <= nRings; ring++ ) {
float r0 = radius * sinf (ring * fDeltaRingAngle);
float y0 = radius * cosf (ring * fDeltaRingAngle);
// Generate the group of segments for the current ring
for(int seg = 0; seg <= nSegments; seg++) {
float x0 = r0 * sinf(seg * fDeltaSegAngle);
float z0 = r0 * cosf(seg * fDeltaSegAngle);
// Add one vertex to the strip which makes up the sphere
*pVertex++ = x0;
*pVertex++ = y0;
*pVertex++ = z0;
Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
*pVertex++ = vNormal.x;
*pVertex++ = vNormal.y;
*pVertex++ = vNormal.z;
*pVertex++ = (float) seg / (float) nSegments;
*pVertex++ = (float) ring / (float) nRings;
if (ring != nRings) {
// each vertex (except the last) has six indices pointing to it
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex;
*pIndices++ = wVerticeIndex + nSegments;
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex + 1;
*pIndices++ = wVerticeIndex;
wVerticeIndex ++;
}
}; // end for seg
} // end for ring
// Unlock
vBuf->unlock();
iBuf->unlock();
// Generate face list
pCapsuleVertex->useSharedVertices = true;
// the original code was missing this line:
pCapsule->_setBounds( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ), false );
pCapsule->_setBoundingSphereRadius(radius);
// this line makes clear the mesh is loaded (avoids memory leaks)
pCapsule->load();
}
//------------------------------------------------------------------------
/// <TODO: insert function description here>
/// @param [in, out] ent Entity * <TODO: insert parameter description here>
/// @return bool <TODO: insert return value description here>
bool CapsuleMeshCollisionShape::load(const Ogre::String& name, SceneNode* scnNode, const float radius, const float height, const int nRings, const int nSegments)
{
assert(!mVertexBuf && !mFaceBuf);
createCapsule(name , radius, height, nRings, nSegments);
mEntity = CollisionManager::getSingletonPtr()->getSceneManager()->createEntity(name,name);
if (mEntity->hasSkeleton()) {
#ifdef BUILD_AGAINST_AZATHOTH
mEntity->addSoftwareSkinningRequest(false);
#else
mEntity->addSoftwareAnimationRequest(false);
#endif
}
mParentNode = scnNode;
mFullTransform = mParentNode->_getFullTransform();
//mParentNode->getWorldTransforms(&mFullTransform);
return rebuild();
}
//------------------------------------------------------------------------
/// <TODO: insert function description here>
/// @return bool <TODO: insert return value description here>
bool CapsuleMeshCollisionShape::rebuild()
{
assert(mEntity);
// NOTE: Assuming presence or absence of skeleton hasn't changed!
size_t vertex_count = 0;
size_t index_count = 0;
countIndicesAndVertices(mEntity, index_count, vertex_count);
// Re-Allocate space for the vertices and indices
if (mVertexBuf && numVertices != vertex_count) {
delete [] mVertexBuf;
mVertexBuf = 0;
}
if (mFaceBuf && numFaces != index_count/3) {
delete [] mFaceBuf;
mFaceBuf = 0;
}
if (!mVertexBuf)
mVertexBuf = new float[vertex_count * 3];
if (!mFaceBuf)
mFaceBuf = new size_t[index_count];
convertMeshData(mEntity, mVertexBuf, vertex_count, mFaceBuf, index_count );
numFaces = index_count / 3;
numVertices = vertex_count;
opcMeshAccess.SetNbTriangles(numFaces);
opcMeshAccess.SetNbVertices(numVertices);
opcMeshAccess.SetPointers((IceMaths::IndexedTriangle*)mFaceBuf, (IceMaths::Point*)mVertexBuf);
//opcMeshAccess.SetStrides(sizeof(int) * 3, sizeof(float) * 3);
return _rebuildFromCachedData();
}
//------------------------------------------------------------------------
/// <TODO: insert function description here>
/// @return bool <TODO: insert return value description here>
bool CapsuleMeshCollisionShape::_rebuildFromCachedData()
{
assert(mEntity && mVertexBuf && mFaceBuf);
Opcode::OPCODECREATE opcc;
_prepareOpcodeCreateParams(opcc);
opcModel.Build(opcc);
calculateSize();
//computeIceABB();
return true;
}
//------------------------------------------------------------------------
/// <TODO: insert function description here>
/// @return bool <TODO: insert return value description here>
bool CapsuleMeshCollisionShape::refit()
{
// bail if we don't need to refit
if ( mShapeIsStatic )
return true;
assert(mEntity && mVertexBuf);
#ifdef _DEBUG
size_t vertex_count = 0;
size_t index_count = 0;
countIndicesAndVertices(mEntity, index_count, vertex_count);
assert(numVertices == vertex_count);
#endif
convertMeshData(mEntity, mVertexBuf, numVertices);
return _refitToCachedData();
}
//------------------------------------------------------------------------
/// <TODO: insert function description here>
/// @return bool <TODO: insert return value description here>
bool CapsuleMeshCollisionShape::_refitToCachedData()
{
assert(mEntity && mVertexBuf);
// rebuild tree
if (!opcModel.Refit())
{
LogManager::getSingleton().logMessage(
"OgreOpcode::CapsuleMeshCollisionShape::_refitToCachedData(): OPCODE Quick refit not possible with the given tree type.");
// Backup plan -- rebuild full tree
opcMeshAccess.SetPointers((IceMaths::IndexedTriangle*)mFaceBuf, (IceMaths::Point*)mVertexBuf);
Opcode::OPCODECREATE opcc;
_prepareOpcodeCreateParams(opcc);
opcModel.Build(opcc);
}
calculateSize();
//computeIceABB();
return true;
}
/*
//------------------------------------------------------------------------
bool CapsuleMeshCollisionShape::contains( const Vector3& point ) const
{
Line line( start, end );
return line.squaredDistance(point) <= (radius*radius);
}
//------------------------------------------------------------------------
bool CapsuleMeshCollisionShape::intersects( const Aabb& aabb ) const
{
// TODO: optimize this code for the AABB case.
OrientedBox obb( aabb );
return intersects( obb );
}
//------------------------------------------------------------------------
bool CapsuleMeshCollisionShape::intersects( const sphere& s ) const
{
Line line( start, end);
Real sqrDist = line.squaredDistance( s.p );
Real rsum = radius + s.radius;
return sqrDist <= (rsum*rsum);
}
//------------------------------------------------------------------------
bool CapsuleMeshCollisionShape::intersects( const OrientedBox& obb ) const
{
Line line( start, end );
return line.squaredDistance(obb) <= (radius*radius);
}
//------------------------------------------------------------------------
bool CapsuleMeshCollisionShape::intersects( const CapsuleMeshCollisionShape& cap ) const
{
Line me( start, end );
Line it( cap.start, cap.end );
Real sqrDist = me.squaredDistance( it );
Real rsum = radius + cap.radius;
return sqrDist <= (rsum*rsum);;
}
//------------------------------------------------------------------------
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -