00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "CollisionTools.h"
00026 #include "../SO3SceneGraph/SO3Entity.h"
00027 #include "../SO3SceneGraph/SO3Scene.h"
00028
00029 MFACEDATA::MFACEDATA()
00030 {
00031 point = Vector3::ZERO;
00032 indexFace = 0;
00033 v1 = Vector3::ZERO;
00034 v2 = Vector3::ZERO;
00035 v3 = Vector3::ZERO;
00036 pReal1 = Vector2::ZERO;
00037 pReal2 = Vector2::ZERO;
00038 pReal3 = Vector2::ZERO;
00039 uvResult = Vector2::ZERO;
00040 }
00041
00042 MFACEDATA::MFACEDATA(const MFACEDATA& faceData)
00043 {
00044 point = faceData.point;
00045 indexFace = faceData.indexFace;
00046 v1 = faceData.v1;
00047 v2 = faceData.v2;
00048 v3 = faceData.v3;
00049 pReal1 = faceData.pReal1;
00050 pReal2 = faceData.pReal2;
00051 pReal3 = faceData.pReal3;
00052 uvResult = faceData.uvResult;
00053 }
00054
00055 namespace MOC {
00056
00057 #ifdef ETM_TERRAIN
00058 CollisionTools::CollisionTools(Ogre::SceneManager* sceneMgr, const ET::TerrainInfo* terrainInfo)
00059 {
00060 mRaySceneQuery = sceneMgr->createRayQuery(Ogre::Ray());
00061 if(NULL == mRaySceneQuery)
00062 {
00063
00064 return;
00065 }
00066 mRaySceneQuery->setSortByDistance(true);
00067
00068 mTSMRaySceneQuery = NULL;
00069
00070 mTerrainInfo = terrainInfo;
00071
00072 _heightAdjust = 0.0f;
00073 }
00074 #endif
00075
00076 CollisionTools::CollisionTools(Ogre::SceneManager* sceneMgr)
00077 {
00078 mSceneMgr = sceneMgr;
00079
00080 mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
00081 if(NULL == mRaySceneQuery)
00082 {
00083
00084 return;
00085 }
00086 mRaySceneQuery->setSortByDistance(true);
00087
00088 mTSMRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
00089
00090 _heightAdjust = 0.0f;
00091 }
00092
00093 CollisionTools::~CollisionTools()
00094 {
00095 if(mRaySceneQuery != NULL)
00096 delete mRaySceneQuery;
00097
00098 if(mTSMRaySceneQuery != NULL)
00099 delete mTSMRaySceneQuery;
00100 }
00101
00102 bool CollisionTools::collidesWithEntity(const Vector3& fromPoint, const Vector3& toPoint, const float collisionRadius, const float rayHeightLevel, const uint32 queryMask)
00103 {
00104 Vector3 fromPointAdj(fromPoint.x, fromPoint.y + rayHeightLevel, fromPoint.z);
00105 Vector3 toPointAdj(toPoint.x, toPoint.y + rayHeightLevel, toPoint.z);
00106 Vector3 normal = toPointAdj - fromPointAdj;
00107 float distToDest = normal.normalise();
00108
00109 Vector3 myResult(0, 0, 0);
00110 Ogre::Entity* myObject = NULL;
00111 float distToColl = 0.0f;
00112
00113 if(raycastFromPoint(fromPointAdj, normal, myResult, (ulong&)myObject, distToColl, queryMask))
00114 {
00115 distToColl -= collisionRadius;
00116 return (distToColl <= distToDest);
00117 }
00118 else
00119 {
00120 return false;
00121 }
00122 }
00123
00124 float CollisionTools::getTSMHeightAt(const float x, const float z) {
00125 float y=0.0f;
00126
00127 static Ray updateRay;
00128
00129 updateRay.setOrigin(Vector3(x,9999,z));
00130 updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
00131
00132 mTSMRaySceneQuery->setRay(updateRay);
00133 RaySceneQueryResult& qryResult = mTSMRaySceneQuery->execute();
00134
00135 RaySceneQueryResult::iterator i = qryResult.begin();
00136 if(i != qryResult.end() && i->worldFragment)
00137 {
00138 y=i->worldFragment->singleIntersection.y;
00139 }
00140 return y;
00141 }
00142
00143 void CollisionTools::calculateY(SceneNode*n, const bool doTerrainCheck, const bool doGridCheck, const float gridWidth, const uint32 queryMask)
00144 {
00145 Vector3 pos = n->getPosition();
00146
00147 float x = pos.x;
00148 float z = pos.z;
00149 float y = pos.y;
00150
00151 Vector3 myResult(0,0,0);
00152 Ogre::Entity* myObject=NULL;
00153 float distToColl = 0.0f;
00154
00155 float terrY = 0, colY = 0, colY2 = 0;
00156
00157 if( raycastFromPoint(Vector3(x,y,z),Vector3::NEGATIVE_UNIT_Y,myResult,(ulong&)myObject, distToColl, queryMask)){
00158 if(myObject != NULL) {
00159 colY = myResult.y;
00160 } else {
00161 colY = -99999;
00162 }
00163 }
00164
00165
00166 if(doGridCheck) {
00167 if( raycastFromPoint(Vector3(x,y,z)+(n->getOrientation()*Vector3(0,0,gridWidth)),Vector3::NEGATIVE_UNIT_Y,myResult,(ulong&)myObject, distToColl, queryMask)){
00168 if(myObject != NULL) {
00169 colY = myResult.y;
00170 } else {
00171 colY = -99999;
00172 }
00173 }
00174 if(colY<colY2)
00175 colY = colY2;
00176 }
00177
00178
00179 if(doTerrainCheck) {
00180
00181 #ifdef ETM_TERRAIN
00182
00183 terrY = mTerrainInfo->getHeightAt(x,z);
00184 #else
00185
00186 terrY = getTSMHeightAt(x,z);
00187 #endif
00188
00189 if(terrY < colY ) {
00190 n->setPosition(x,colY+_heightAdjust,z);
00191 } else {
00192 n->setPosition(x,terrY+_heightAdjust,z);
00193 }
00194 } else {
00195 if(!doTerrainCheck && colY == -99999) colY = y;
00196 n->setPosition(x,colY+_heightAdjust,z);
00197 }
00198 }
00199
00200
00201
00202
00203 bool CollisionTools::raycastFromPoint(const Vector3 &point,
00204 const Vector3 &normal,
00205 Vector3 &result,ulong &target,float &closest_distance,
00206 const uint32 queryMask)
00207 {
00208
00209 static Ogre::Ray ray;
00210 ray.setOrigin(point);
00211 ray.setDirection(normal);
00212
00213 int index = 0;
00214
00215 return raycast(ray, result, target, closest_distance,index,NULL, queryMask,false);
00216 }
00217
00218 bool CollisionTools::raycast(const Ray &ray, Vector3 &result,ulong &target,float &closest_distance,int &indexSubEntity,MFACEDATA* faceData, const uint32 queryMask,bool extendedInfo)
00219 {
00220 target = NULL;
00221 bool priority = false;
00222
00223 if(mRaySceneQuery != NULL)
00224 {
00225
00226 mRaySceneQuery->setRay(ray);
00227 mRaySceneQuery->setSortByDistance(true);
00228 mRaySceneQuery->setQueryMask(queryMask);
00229
00230 if(mRaySceneQuery->execute().size() <= 0)
00231 {
00232
00233 return (false);
00234 }
00235 }
00236 else
00237 {
00238 return (false);
00239 }
00240
00241 closest_distance = -1.0f;
00242 float* pReal1;
00243 float* pReal2;
00244 float* pReal3;
00245 Ogre::Vector3 closest_result;
00246 Ogre::RaySceneQueryResult &query_result = mRaySceneQuery->getLastResults();
00247 for (size_t qr_idx = 0; qr_idx < query_result.size()&&!priority; qr_idx++)
00248 {
00249 if((closest_distance >= 0.0f) &&
00250 (closest_distance < query_result[qr_idx].distance))
00251 {
00252
00253 }
00254
00255 if((query_result[qr_idx].movable != NULL) &&
00256 (query_result[qr_idx].movable->getMovableType().compare("Entity") == 0))
00257 {
00258
00259 Ogre::Entity* pentity = static_cast<Ogre::Entity*>(query_result[qr_idx].movable);
00260 bool new_closest_found = false;
00261 String name = pentity->getName();
00262
00263 SScene* mScene = getSceneByName(mSceneMgr->getName());
00264 if(mScene==NULL)
00265 return false;
00266
00267 SEntity* curEntity = static_cast <SEntity*> (mScene->GetNode(name));
00268 if(curEntity==NULL)
00269 return false;
00270
00271 if(curEntity->getSceneNodeIsMouseClick()&&pentity->isVisible())
00272 {
00273 int numSubMeshes = pentity->getMesh()->getNumSubMeshes();
00274 size_t vertex_count;
00275 size_t index_count;
00276 Ogre::Vector3* vertices;
00277 unsigned long* indices;
00278 for(int i = 0; i<numSubMeshes; i++)
00279 {
00280 Ogre::Node* pentityParentNode = pentity->getParentNode();
00281 Ogre::SubMesh* submesh = pentity->getMesh()->getSubMesh(i);
00282 GetSubMeshInformation(curEntity, submesh, i, vertex_count, vertices, index_count, indices,
00283 pentityParentNode->_getDerivedPosition(),
00284 pentityParentNode->_getDerivedOrientation(),
00285 pentityParentNode->_getDerivedScale());
00286
00287 Ogre::RenderOperation tmpRenderOperation;
00288 submesh->_getRenderOperation(tmpRenderOperation);
00289
00290 if(tmpRenderOperation.operationType == Ogre::RenderOperation::OT_TRIANGLE_LIST)
00291 {
00292 for (int j = 0; j < static_cast<int>(index_count); j += 3)
00293 {
00294 std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, vertices[indices[j]], vertices[indices[j+1]], vertices[indices[j+2]], true, false);
00295 if(hit.first)
00296 {
00297 if(curEntity->getSceneNodeIsMouseForeground())
00298 closest_distance = -1.0f;
00299
00300 if((closest_distance < 0.0f) || (hit.second < closest_distance))
00301 {
00302
00303 closest_distance = hit.second;
00304 new_closest_found = true;
00305
00306 faceData->indexFace = j/3;
00307 if(faceData!=NULL && extendedInfo)
00308 {
00309 faceData->v1 = vertices[indices[j]];
00310 faceData->v2 = vertices[indices[j+1]];
00311 faceData->v3 = vertices[indices[j+2]];
00312 faceData->point = ray.getPoint(hit.second);
00313 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? submesh->parent->sharedVertexData : submesh->vertexData;
00314 const Ogre::VertexElement* vertex_element1 = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
00315
00316 if(vertex_data->vertexDeclaration->getElementCount()>2)
00317 {
00318 Ogre::HardwareVertexBufferSharedPtr vbuf1 = vertex_data->vertexBufferBinding->getBuffer(vertex_element1->getSource());
00319 unsigned char* vertex1 = static_cast<unsigned char*>(vbuf1->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00320 vertex1 += indices[j]*vbuf1->getVertexSize();
00321 vertex_element1->baseVertexPointerToElement(vertex1, &pReal1);
00322 vbuf1->unlock();
00323
00324 const Ogre::VertexElement* vertex_element2 = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
00325 Ogre::HardwareVertexBufferSharedPtr vbuf2 = vertex_data->vertexBufferBinding->getBuffer(vertex_element2->getSource());
00326 unsigned char* vertex2 = static_cast<unsigned char*>(vbuf2->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00327 vertex2 += indices[j+1]*vbuf2->getVertexSize();
00328 vertex_element2->baseVertexPointerToElement(vertex2, &pReal2);
00329 vbuf2->unlock();
00330
00331 const Ogre::VertexElement* vertex_element3 = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
00332 Ogre::HardwareVertexBufferSharedPtr vbuf3 = vertex_data->vertexBufferBinding->getBuffer(vertex_element3->getSource());
00333 unsigned char* vertex3 = static_cast<unsigned char*>(vbuf3->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00334 vertex3 += indices[j+2]*vbuf3->getVertexSize();
00335 vertex_element3->baseVertexPointerToElement(vertex3, &pReal3);
00336 vbuf3->unlock();
00337
00338 faceData->pReal1.x = pReal1[0];
00339 faceData->pReal1.y = pReal1[1];
00340 faceData->pReal2.x = pReal2[0];
00341 faceData->pReal2.y = pReal2[1];
00342 faceData->pReal3.x = pReal3[0];
00343 faceData->pReal3.y = pReal3[1];
00344
00345 Ogre::Vector3 d1 = faceData->point - faceData->v1;
00346 Ogre::Vector3 d2 = faceData->point - faceData->v2;
00347 Ogre::Vector3 d3 = faceData->point - faceData->v3;
00348
00349 Ogre::Vector3 d12 = faceData->v1 - faceData->v2;
00350 Ogre::Vector3 d13 = faceData->v1 - faceData->v3;
00351 Ogre::Vector3 d23 = faceData->v2 - faceData->v3;
00352
00353 Vector3 B = GetBarycentricCoordinates(faceData->v1, faceData->v2, faceData->v3, faceData->point);
00354 Vector2 T = faceData->pReal1*B.x + faceData->pReal2*B.y + faceData->pReal3*B.z;
00355
00356 faceData->uvResult.x = abs(T.x) - abs((int)T.x);
00357 faceData->uvResult.y = abs(T.y) - abs((int)T.y);
00358
00359 if(T.x<0)
00360 faceData->uvResult.x = 1 - faceData->uvResult.x;
00361 if(T.y<0)
00362 faceData->uvResult.y = 1 - faceData->uvResult.y;
00363
00364 if(curEntity->getSceneNodeIsMouseForeground())
00365 priority = true;
00366 }
00367 }
00368 }
00369 }
00370 }
00371 }
00372 delete[] vertices;
00373 delete[] indices;
00374 }
00375 }
00376
00377 if(new_closest_found)
00378 {
00379 target = (ulong)pentity;
00380 closest_result = ray.getPoint(closest_distance);
00381 }
00382 }
00383 }
00384
00385
00386 if(closest_distance >= 0.0f)
00387 {
00388
00389 result = closest_result;
00390 return (true);
00391 }
00392 else
00393 {
00394
00395 return (false);
00396 }
00397 }
00398 Vector3 CollisionTools::GetBarycentricCoordinates(const Vector3 &P1, const Vector3 &P2, const Vector3 &P3, const Vector3 &P)
00399 {
00400 Vector3 Coordinates(0.0);
00401 Real denom = (-P1.x * P3.y - P2.x * P1.y + P2.x * P3.y + P1.y * P3.x + P2.y * P1.x - P2.y * P3.x);
00402 if(fabs(denom) >= 1e-6)
00403 {
00404 Coordinates.x = (P2.x * P3.y - P2.y * P3.x - P.x * P3.y + P3.x * P.y - P2.x * P.y + P2.y * P.x) / denom;
00405 Coordinates.y = -(-P1.x * P.y + P1.x * P3.y + P1.y * P.x - P.x * P3.y + P3.x * P.y - P1.y * P3.x) / denom;
00406 }
00407 else
00408 {
00409 denom = (-P1.x * P3.z - P2.x * P1.z + P2.x * P3.z + P1.z * P3.x + P2.z * P1.x - P2.z * P3.x);
00410 if(fabs(denom) >= 1e-6)
00411 {
00412 Coordinates.x = (P2.x * P3.z - P2.z * P3.x - P.x * P3.z + P3.x * P.z - P2.x * P.z + P2.z * P.x) / denom;
00413 Coordinates.y = -(-P1.x * P.z + P1.x * P3.z + P1.z * P.x - P.x * P3.z + P3.x * P.z - P1.z * P3.x) / denom;
00414 }
00415 else
00416 {
00417 denom = (-P1.y * P3.z - P2.y * P1.z + P2.y * P3.z + P1.z * P3.y + P2.z * P1.y - P2.z * P3.y);
00418 if(fabs(denom) >= 1e-6)
00419 {
00420 Coordinates.x = (P2.y * P3.z - P2.z * P3.y - P.y * P3.z + P3.y * P.z - P2.y * P.z + P2.z * P.y) / denom;
00421 Coordinates.y = -(-P1.y * P.z + P1.y * P3.z + P1.z * P.y - P.y * P3.z + P3.y * P.z - P1.z * P3.y) / denom;
00422 }
00423 }
00424 }
00425 Coordinates.z = 1 - Coordinates.x - Coordinates.y;
00426 return Coordinates;
00427 }
00428
00429
00430
00431 void CollisionTools::GetMeshInformation(const Entity* mEntity,
00432 size_t &vertex_count,
00433 Ogre::Vector4* &vertices,
00434 size_t &index_count,
00435 unsigned long* &indices,
00436 const Ogre::Vector3 &position,
00437 const Ogre::Quaternion &orient,
00438 const Ogre::Vector3 &scale)
00439 {
00440 bool added_shared = false;
00441 size_t current_offset = 0;
00442 size_t shared_offset = 0;
00443 size_t next_offset = 0;
00444 size_t index_offset = 0;
00445
00446 vertex_count = index_count = 0;
00447
00448 Ogre::MeshPtr mesh = mEntity->getMesh();
00449
00450 bool useSoftwareBlendingVertices = mEntity->hasSkeleton();
00451 bool useSoftwareMorphingVertices = mEntity->hasVertexAnimation();
00452
00453
00454 for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
00455 {
00456 Ogre::SubMesh* submesh = mesh->getSubMesh( i );
00457
00458 if(submesh->useSharedVertices)
00459 {
00460 if( !added_shared )
00461 {
00462 vertex_count += mesh->sharedVertexData->vertexCount;
00463 added_shared = true;
00464 }
00465 }
00466 else
00467 {
00468 vertex_count += submesh->vertexData->vertexCount;
00469 }
00470
00471 index_count += submesh->indexData->indexCount;
00472 }
00473
00474 vertices = new Ogre::Vector4[vertex_count];
00475 indices = new unsigned long[index_count];
00476
00477 added_shared = false;
00478
00479
00480 for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
00481 {
00482 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
00483
00484
00485 Ogre::VertexData* vertex_data;
00486
00487
00488 if(useSoftwareBlendingVertices&&useSoftwareMorphingVertices)
00489 vertex_data = submesh->useSharedVertices ? mEntity->_getSkelAnimVertexData() : mEntity->getSubEntity(i)->_getSkelAnimVertexData();
00490 else if(!useSoftwareBlendingVertices&&useSoftwareMorphingVertices)
00491 vertex_data = submesh->useSharedVertices ? mEntity->_getSoftwareVertexAnimVertexData() : mEntity->getSubEntity(i)->_getSoftwareVertexAnimVertexData();
00492 else
00493 vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
00494
00495 if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
00496 {
00497 if(submesh->useSharedVertices)
00498 {
00499 added_shared = true;
00500 shared_offset = current_offset;
00501 }
00502
00503 const Ogre::VertexElement* posElem =
00504 vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
00505
00506 Ogre::HardwareVertexBufferSharedPtr vbuf =
00507 vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
00508
00509 unsigned char* vertex =
00510 static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00511
00512 float* pReal;
00513
00514 for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
00515 {
00516 posElem->baseVertexPointerToElement(vertex, &pReal);
00517
00518 Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
00519
00520 vertices[current_offset + j] = (orient * (pt * scale)) + position;
00521 vertices[current_offset + j].w = (float)(i);
00522 }
00523
00524 vbuf->unlock();
00525 next_offset += vertex_data->vertexCount;
00526 }
00527
00528
00529 Ogre::IndexData* index_data = submesh->indexData;
00530 size_t numTris = index_data->indexCount / 3;
00531 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
00532
00533 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
00534
00535 unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00536 unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);
00537
00538
00539 size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;
00540
00541 if( use32bitindexes )
00542 {
00543 for ( size_t k = 0; k < numTris*3; ++k)
00544 {
00545 indices[index_offset++] = pLong[k] + static_cast<unsigned long>(offset);
00546 }
00547 }
00548 else
00549 {
00550 for ( size_t k = 0; k < numTris*3; ++k)
00551 {
00552 indices[index_offset++] = static_cast<unsigned long>(pShort[k]) +
00553 static_cast<unsigned long>(offset);
00554 }
00555 }
00556
00557 ibuf->unlock();
00558 current_offset = next_offset;
00559 }
00560 }
00561
00562
00563 void CollisionTools::GetSubMeshInformation(SEntity* mEntity,
00564 Ogre::SubMesh* submesh,
00565 int i,
00566 size_t &vertex_count,
00567 Ogre::Vector3* &vertices,
00568 size_t &index_count,
00569 unsigned long* &indices,
00570 const Ogre::Vector3 &position,
00571 const Ogre::Quaternion &orient,
00572 const Ogre::Vector3 &scale)
00573 {
00574 bool added_shared = false;
00575 size_t current_offset = 0;
00576 size_t shared_offset = 0;
00577 size_t next_offset = 0;
00578 size_t index_offset = 0;
00579 vertex_count = index_count = 0;
00580
00581 Ogre::MeshPtr mesh = mEntity->getOgreEntityPointer()->getMesh();
00582
00583 bool useSoftwareBlendingVertices = mEntity->getOgreEntityPointer()->hasSkeleton();
00584 bool useSoftwareMorphingVertices = mEntity->getOgreEntityPointer()->hasVertexAnimation();
00585
00586
00587
00588 if(submesh->useSharedVertices)
00589 {
00590 if(!added_shared)
00591 {
00592 vertex_count += mesh->sharedVertexData->vertexCount;
00593 added_shared = true;
00594 }
00595 }
00596 else
00597 {
00598 vertex_count += submesh->vertexData->vertexCount;
00599 }
00600
00601
00602 index_count += submesh->indexData->indexCount;
00603
00604 vertices = new Ogre::Vector3[vertex_count];
00605 indices = new unsigned long[index_count];
00606
00607 added_shared = false;
00608
00609 Ogre::VertexData* vertex_data;
00610 if(useSoftwareBlendingVertices&&mEntity->getOgreEntityPointer()->_isAnimated())
00611 {
00612 vertex_data = submesh->useSharedVertices ? mEntity->getOgreEntityPointer()->_getSkelAnimVertexData() : mEntity->getOgreEntityPointer()->getSubEntity(i)->_getSkelAnimVertexData();
00613 }
00614 else if(!useSoftwareBlendingVertices&&useSoftwareMorphingVertices&&mEntity->getOgreEntityPointer()->_isAnimated()&&mEntity->getOgreEntityPointer()->getMesh()->getPoseCount()==0)
00615 vertex_data = submesh->useSharedVertices ? mEntity->getOgreEntityPointer()->_getSoftwareVertexAnimVertexData() : mEntity->getOgreEntityPointer()->getSubEntity(i)->_getSoftwareVertexAnimVertexData();
00616 else
00617 vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
00618
00619 if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
00620 {
00621 if(submesh->useSharedVertices)
00622 {
00623 added_shared = true;
00624 shared_offset = current_offset;
00625 }
00626 const Ogre::VertexElement * posElem =
00627 vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
00628
00629 Ogre::HardwareVertexBufferSharedPtr vbuf =
00630 vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
00631
00632 unsigned char* vertex =
00633 static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00634
00635 float* pReal;
00636 for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
00637 {
00638 posElem->baseVertexPointerToElement(vertex, &pReal);
00639
00640 Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
00641
00642 vertices[current_offset + j] = (orient * (pt * scale)) + position;
00643 }
00644
00645 vbuf->unlock();
00646 next_offset += vertex_data->vertexCount;
00647 }
00648 Ogre::IndexData* index_data = submesh->indexData;
00649 size_t numTris = index_data->indexCount / 3;
00650 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
00651
00652 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
00653
00654 unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00655 unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);
00656
00657
00658 size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;
00659
00660 if( use32bitindexes )
00661 {
00662 for ( size_t k = 0; k < numTris*3; ++k)
00663 {
00664 indices[index_offset++] = pLong[k] + static_cast<unsigned long>(offset);
00665 }
00666 }
00667 else
00668 {
00669 for ( size_t k = 0; k < numTris*3; ++k)
00670 {
00671 indices[index_offset++] = static_cast<unsigned long>(pShort[k]) +
00672 static_cast<unsigned long>(offset);
00673 }
00674 }
00675
00676 ibuf->unlock();
00677 current_offset = next_offset;
00678
00679 }
00680 void CollisionTools::setHeightAdjust(const float heightadjust) {
00681 _heightAdjust = heightadjust;
00682 }
00683
00684 float CollisionTools::getHeightAdjust(void) {
00685 return _heightAdjust;
00686 }
00687
00688 };