⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogrecapsulemeshcollisionshape.cpp

📁 opcode是功能强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -