view plaincopy to clipboardprint?
//------------------------------------------------------------------------------------------------
void TriangleMeshData::addVertexData(const VertexData *vertex_data,
const VertexData *blended_data,
const Mesh::IndexMap *indexMap)
{
if (!vertex_data)
return;
const VertexData *data = (blended_data) ? blended_data: vertex_data;
const unsigned int prev_size = _vertex_count;
_vertex_count += (unsigned int)data->vertexCount;
Ogre::Vector3* tmp_vert = new Ogre::Vector3[_vertex_count];
if (_vertices)
{
memcpy(tmp_vert,_vertices,sizeof(Vector3) * prev_size);
delete[] _vertices;
}
_vertices = tmp_vert;
// Get the positional buffer element
{
const Ogre::VertexElement* posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
float* pReal;
Ogre::Vector3 * curVertices = &_vertices[prev_size];
const unsigned int vertexCount = (unsigned int)data->vertexCount;
for(unsigned int j = 0; j < vertexCount; ++j)
{
posElem->baseVertexPointerToElement(vertex, &pReal);
vertex += vSize;
curVertices->x = (*pReal++);
curVertices->y = (*pReal++);
curVertices->z = (*pReal++);
// *curVertices = _transform * (*curVertices);
curVertices++;
}
vbuf->unlock();
}
// Get the bone index element
if (_entity && _entity->hasSkeleton())
{
Ogre::MeshPtr mesh = _entity->getMesh ();
const Ogre::VertexElement* bneElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_BLEND_INDICES);
assert (bneElem);
{
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(bneElem->getSource());
const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
unsigned char* pBone;
if (!_bone_mapping)
_bone_mapping = new BoneMapping();
BoneMapping::iterator i;
Ogre::Vector3 * curVertices = &_vertices[prev_size];
const unsigned int vertexCount = (unsigned int)vertex_data->vertexCount;
for(unsigned int j = 0; j < vertexCount; ++j)
{
bneElem->baseVertexPointerToElement(vertex, &pBone);
vertex += vSize;
const unsigned char currBone = (indexMap) ? (*indexMap)[*pBone] : *pBone;
i = _bone_mapping->find (currBone);
Vector3Array* l = 0;
if (i == _bone_mapping->end())
{
l = new Vector3Array;
_bone_mapping->insert(BoneMappingKey(currBone, l));
}
else
{
l = i->second;
}
l->push_back(*curVertices);
curVertices++;
}
vbuf->unlock();
}
}
}
//------------------------------------------------------------------------------------------------
void TriangleMeshData::addVertexData(const VertexData *vertex_data,
const VertexData *blended_data,
const Mesh::IndexMap *indexMap)
{
if (!vertex_data)
return;
const VertexData *data = (blended_data) ? blended_data: vertex_data;
const unsigned int prev_size = _vertex_count;
_vertex_count += (unsigned int)data->vertexCount;
Ogre::Vector3* tmp_vert = new Ogre::Vector3[_vertex_count];
if (_vertices)
{
memcpy(tmp_vert,_vertices,sizeof(Vector3) * prev_size);
delete[] _vertices;
}
_vertices = tmp_vert;
// Get the positional buffer element
{
const Ogre::VertexElement* posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
float* pReal;
Ogre::Vector3 * curVertices = &_vertices[prev_size];
const unsigned int vertexCount = (unsigned int)data->vertexCount;
for(unsigned int j = 0; j < vertexCount; ++j)
{
posElem->baseVertexPointerToElement(vertex, &pReal);
vertex += vSize;
curVertices->x = (*pReal++);
curVertices->y = (*pReal++);
curVertices->z = (*pReal++);
// *curVertices = _transform * (*curVertices);
curVertices++;
}
vbuf->unlock();
}
// Get the bone index element
if (_entity && _entity->hasSkeleton())
{
Ogre::MeshPtr mesh = _entity->getMesh ();
const Ogre::VertexElement* bneElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_BLEND_INDICES);
assert (bneElem);
{
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(bneElem->getSource());
const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
unsigned char* pBone;
if (!_bone_mapping)
_bone_mapping = new BoneMapping();
BoneMapping::iterator i;
Ogre::Vector3 * curVertices = &_vertices[prev_size];
const unsigned int vertexCount = (unsigned int)vertex_data->vertexCount;
for(unsigned int j = 0; j < vertexCount; ++j)
{
bneElem->baseVertexPointerToElement(vertex, &pBone);
vertex += vSize;
const unsigned char currBone = (indexMap) ? (*indexMap)[*pBone] : *pBone;
i = _bone_mapping->find (currBone);
Vector3Array* l = 0;
if (i == _bone_mapping->end())
{
l = new Vector3Array;
_bone_mapping->insert(BoneMappingKey(currBone, l));
}
else
{
l = i->second;
}
l->push_back(*curVertices);
curVertices++;
}
vbuf->unlock();
}
}
}
从ogre中设置terrain的物理效果我认为可以分成两类:
第一类很简单是从高度图直接读出然后建立定点索引序列,自己动手创建地形;
第二类是从实体创建,很简单的说就是从mesh模型来创建,这样的好处就是不用自己渲染了。。。
现在只实现了第二类的方法,其实本质就是从mesh里提取顶点信息和索引信息然后填充到
NxTriangleMeshDesc* triangleMeshDesc; 剩下的无非是生成对应的模型而已;
view plaincopy to clipboardprint?
NxActor* PhysxTool::CreateTriangleMesh(TriangleMeshData* data,NxPhysicsSDK *gPhysicsSDK,NxScene*gScene)
{
NxTriangleMeshDesc* triangleMeshDesc;
// Create descriptor for triangle mesh
triangleMeshDesc= new NxTriangleMeshDesc();
triangleMeshDesc->numVertices = data->getVertexCount();
triangleMeshDesc->pointStrideBytes = sizeof(NxVec3);
triangleMeshDesc->points = (void*)data->getVertices();
triangleMeshDesc->numTriangles = data->getIndexCount()/3;
triangleMeshDesc->flags = 0;
triangleMeshDesc->triangles = (void*)data->getIndices();
triangleMeshDesc->triangleStrideBytes = 3 * sizeof(NxU32);
triangleMeshDesc->heightFieldVerticalAxis= NX_Y;
triangleMeshDesc->heightFieldVerticalExtent= -1000.0f;
// The actor has one shape, a triangle mesh
NxInitCooking();
MemoryWriteBuffer buf;
bool status = NxCookTriangleMesh(*triangleMeshDesc, buf);
NxTriangleMesh* pMesh;
if (status)
{
pMesh = gPhysicsSDK->createTriangleMesh(MemoryReadBuffer(buf.data));
}
else
{
assert(false);
pMesh = NULL;
}
NxCloseCooking();
// Create TriangleMesh above code segment.
NxTriangleMeshShapeDesc tmsd;
tmsd.meshData = pMesh;
tmsd.userData = triangleMeshDesc;
tmsd.localPose.t = NxVec3(0, 0, 0);
tmsd.meshPagingMode = NX_MESH_PAGING_AUTO;
tmsd.shapeFlags = NX_SF_FEATURE_INDICES;
NxActorDesc actorDesc;
assert(tmsd.isValid());
actorDesc.shapes.pushBack(&tmsd);
if (pMesh)
return gScene->createActor(actorDesc);
else
return NULL;
}
NxActor* PhysxTool::CreateTriangleMesh(TriangleMeshData* data,NxPhysicsSDK *gPhysicsSDK,NxScene*gScene)
{
NxTriangleMeshDesc* triangleMeshDesc;
// Create descriptor for triangle mesh
triangleMeshDesc= new NxTriangleMeshDesc();
triangleMeshDesc->numVertices = data->getVertexCount();
triangleMeshDesc->pointStrideBytes = sizeof(NxVec3);
triangleMeshDesc->points = (void*)data->getVertices();
triangleMeshDesc->numTriangles = data->getIndexCount()/3;
triangleMeshDesc->flags = 0;
triangleMeshDesc->triangles = (void*)data->getIndices();
triangleMeshDesc->triangleStrideBytes = 3 * sizeof(NxU32);
triangleMeshDesc->heightFieldVerticalAxis= NX_Y;
triangleMeshDesc->heightFieldVerticalExtent= -1000.0f;
// The actor has one shape, a triangle mesh
NxInitCooking();
MemoryWriteBuffer buf;
bool status = NxCookTriangleMesh(*triangleMeshDesc, buf);
NxTriangleMesh* pMesh;
if (status)
{
pMesh = gPhysicsSDK->createTriangleMesh(MemoryReadBuffer(buf.data));
}
else
{
assert(false);
pMesh = NULL;
}
NxCloseCooking();
// Create TriangleMesh above code segment.
NxTriangleMeshShapeDesc tmsd;
tmsd.meshData = pMesh;
tmsd.userData = triangleMeshDesc;
tmsd.localPose.t = NxVec3(0, 0, 0);
tmsd.meshPagingMode = NX_MESH_PAGING_AUTO;
tmsd.shapeFlags = NX_SF_FEATURE_INDICES;
NxActorDesc actorDesc;
assert(tmsd.isValid());
actorDesc.shapes.pushBack(&tmsd);
if (pMesh)
return gScene->createActor(actorDesc);
else
return NULL;
}
返回的actor就可以直接使用了,因为没有设置body,所以默认为static,当有物体落到表面是自动进行碰撞检测;
这个实现的关键还在于对mesh的数据的提取,这是从ogreode中“剽窃”的一段代码,演示如何提取顶点数据和索引数据;
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
//const bool isHWanimated = isSkeletonAnimated && entity->isHardwareAnimationEnabled();
if (isSkeletonAnimated)
{
_entity->addSoftwareAnimationRequest(false);
_entity->_updateAnimation();
}
if (_entity->getMesh()->sharedVertexData)
{
if (!isSkeletonAnimated)
addVertexData (_entity->getMesh()->sharedVertexData);
else
addVertexData (_entity->getMesh()->sharedVertexData,
_entity->_getSkelAnimVertexData(),
&_entity->getMesh()->sharedBlendIndexToBoneIndexMap);
}
for(unsigned int i = 0;i < _entity->getNumSubEntities();++i)
{
SubMesh *sub_mesh = _entity->getSubEntity(i)->getSubMesh();
if (!sub_mesh->useSharedVertices)
{
addIndexData(sub_mesh->indexData,_vertex_count);
if (!isSkeletonAnimated)
addVertexData (sub_mesh->vertexData);
else
addVertexData (sub_mesh->vertexData,
_entity->getSubEntity(i)->_getSkelAnimVertexData(),
&sub_mesh->blendIndexToBoneIndexMap);
}
else
{
addIndexData (sub_mesh->indexData);
}
}
//const bool isHWanimated = isSkeletonAnimated && entity->isHardwareAnimationEnabled();
if (isSkeletonAnimated)
{
_entity->addSoftwareAnimationRequest(false);
_entity->_updateAnimation();
}
if (_entity->getMesh()->sharedVertexData)
{
if (!isSkeletonAnimated)
addVertexData (_entity->getMesh()->sharedVertexData);
else
addVertexData (_entity->getMesh()->sharedVertexData,
_entity->_getSkelAnimVertexData(),
&_entity->getMesh()->sharedBlendIndexToBoneIndexMap);
}
for(unsigned int i = 0;i < _entity->getNumSubEntities();++i)
{
SubMesh *sub_mesh = _entity->getSubEntity(i)->getSubMesh();
if (!sub_mesh->useSharedVertices)
{
addIndexData(sub_mesh->indexData,_vertex_count);
if (!isSkeletonAnimated)
addVertexData (sub_mesh->vertexData);
else
addVertexData (sub_mesh->vertexData,
_entity->getSubEntity(i)->_getSkelAnimVertexData(),
&sub_mesh->blendIndexToBoneIndexMap);
}
else
{
addIndexData (sub_mesh->indexData);
}
}
addindex和addvertex分别向该类中写入数据:
view plaincopy to clipboardprint?
void TriangleMeshData::addIndexData(IndexData *data, const unsigned int offset)
{
const unsigned int prev_size = _index_count;
_index_count += (unsigned int)data->indexCount;
TriangleIndex* tmp_ind = new TriangleIndex[_index_count];
if (_indices)
{
memcpy (tmp_ind, _indices, sizeof(unsigned int) * prev_size);
delete[] _indices;
}
_indices = tmp_ind;
const unsigned int numTris = (unsigned int) data->indexCount / 3;
HardwareIndexBufferSharedPtr ibuf = data->indexBuffer;
const bool use32bitindexes = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT);
unsigned int index_offset = prev_size;
if (use32bitindexes)
{
const unsigned int* pInt = static_cast<unsigned int*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
for(unsigned int k = 0; k < numTris; ++k)
{
_indices[index_offset ++] = offset + *pInt++;
_indices[index_offset ++] = offset + *pInt++;
_indices[index_offset ++] = offset + *pInt++;
}
ibuf->unlock();
}
else
{
const unsigned short* pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
for(unsigned int k = 0; k < numTris; ++k)
{
_indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
_indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
_indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
}
ibuf->unlock();
}
}
void TriangleMeshData::addIndexData(IndexData *data, const unsigned int offset)
{
const unsigned int prev_size = _index_count;
_index_count += (unsigned int)data->indexCount;
TriangleIndex* tmp_ind = new TriangleIndex[_index_count];
if (_indices)
{
memcpy (tmp_ind, _indices, sizeof(unsigned int) * prev_size);
delete[] _indices;
}
_indices = tmp_ind;
const unsigned int numTris = (unsigned int) data->indexCount / 3;
HardwareIndexBufferSharedPtr ibuf = data->indexBuffer;
const bool use32bitindexes = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT);
unsigned int index_offset = prev_size;
if (use32bitindexes)
{
const unsigned int* pInt = static_cast<unsigned int*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
for(unsigned int k = 0; k < numTris; ++k)
{
_indices[index_offset ++] = offset + *pInt++;
_indices[index_offset ++] = offset + *pInt++;
_indices[index_offset ++] = offset + *pInt++;
}
ibuf->unlock();
}
else
{
const unsigned short* pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
for(unsigned int k = 0; k < numTris; ++k)
{
_indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
_indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
_indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
}
ibuf->unlock();
}
}
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/liu3xing3long/archive/2009/01/30/3855286.aspx