88 Ogre::Vector3* &vertices,
90 unsigned long* &indices,
91 const Ogre::Vector3 &position,
92 const Ogre::Quaternion &orient,
93 const Ogre::Vector3 &scale)
95 bool added_shared =
false;
96 size_t current_offset = 0;
97 size_t shared_offset = 0;
98 size_t next_offset = 0;
99 size_t index_offset = 0;
101 vertex_count = index_count = 0;
104 for (
unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
106 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
108 if (submesh->useSharedVertices)
112 vertex_count += mesh->sharedVertexData->vertexCount;
118 vertex_count += submesh->vertexData->vertexCount;
121 index_count += submesh->indexData->indexCount;
125 vertices =
new Ogre::Vector3[vertex_count];
126 indices =
new unsigned long[index_count];
128 added_shared =
false;
131 for (
unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
133 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
135 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
137 if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
139 if (submesh->useSharedVertices)
142 shared_offset = current_offset;
145 const Ogre::VertexElement* posElem =
146 vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
148 Ogre::HardwareVertexBufferSharedPtr vbuf =
149 vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
151 unsigned char* vertex =
152 static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
160 for (
size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
162 posElem->baseVertexPointerToElement(vertex, &pReal);
163 Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
164 vertices[current_offset + j] = (orient * (pt * scale)) + position;
168 next_offset += vertex_data->vertexCount;
171 Ogre::IndexData* index_data = submesh->indexData;
172 size_t numTris = index_data->indexCount / 3;
173 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
175 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
176 size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset;
180 Ogre::uint32* pLong =
static_cast<Ogre::uint32*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
181 for (
size_t k = 0; k < numTris * 3; ++k)
183 indices[index_offset++] = pLong[k] +
static_cast<unsigned long>(offset);
188 Ogre::uint16* pShort =
static_cast<Ogre::uint16*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
189 for (
size_t k = 0; k < numTris * 3; ++k)
191 indices[index_offset++] =
static_cast<unsigned long>(pShort[k]) +
static_cast<unsigned long>(offset);
196 current_offset = next_offset;
208SRaycastResult SRaycast::Cast(Ogre::Camera* camera,
const float& relativePosX,
const float& relativePosY, Ogre::SubEntity* subEntity,
bool getUvCoordonate)
216 Ogre::Any bindedCustomEntity = subEntity->getUserObjectBindings().getUserAny(
"SEntity");
218 assert(bindedCustomEntity.has_value());
219 results.
entity = Ogre::any_cast<SEntity*> (bindedCustomEntity);
226 if(!getUvCoordonate && results.
material)
228 getUvCoordonate =
true;
231 Ogre::Ray ray = camera->getCameraToViewportRay(fabs(relativePosX), fabs(relativePosY));
234 float closest_distance = -1.0f;
235 Ogre::SubMesh* submesh = subEntity->getSubMesh();
237 Ogre::RenderOperation tmpRenderOperation;
238 submesh->_getRenderOperation(tmpRenderOperation);
239 if (tmpRenderOperation.operationType == Ogre::RenderOperation::OT_TRIANGLE_LIST)
242 size_t vertex_count = 0;
243 if (submesh->useSharedVertices)
244 vertex_count = submesh->parent->sharedVertexData->vertexCount;
246 vertex_count = submesh->vertexData->vertexCount;
249 size_t index_count = submesh->indexData->indexCount;
250 unsigned long* indices =
new unsigned long[index_count];
253 Ogre::IndexData* index_data = submesh->indexData;
254 size_t numTris = index_data->indexCount / 3;
255 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
256 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
258 size_t index_offset = 0;
261 Ogre::uint32* pLong =
static_cast<Ogre::uint32*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
262 for (
size_t k = 0; k < numTris * 3; ++k)
263 indices[index_offset++] = pLong[k];
267 Ogre::uint16* pShort =
static_cast<Ogre::uint16*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
268 for (
size_t k = 0; k < numTris * 3; ++k)
269 indices[index_offset++] =
static_cast<unsigned long>(pShort[k]);
273 Ogre::Entity* parentEntity = subEntity->getParent();
274 bool useSoftwareBlendingVertices = parentEntity->hasSkeleton();
275 bool useSoftwareMorphingVertices = parentEntity->hasVertexAnimation();
277 Ogre::SceneNode* attachedNode = parentEntity->getParentSceneNode();
278 assert(attachedNode != 0);
279 Ogre::Vector3 position = attachedNode->_getDerivedPosition();
280 Ogre::Quaternion orient = attachedNode->_getDerivedOrientation();
281 Ogre::Vector3 scale = attachedNode->_getDerivedScale();
283 int closestVerticeIndex = 0;
286 Ogre::VertexData* vertex_data;
287 if (useSoftwareBlendingVertices && parentEntity->_isAnimated())
288 vertex_data = submesh->useSharedVertices ? parentEntity->_getSkelAnimVertexData() : subEntity->_getSkelAnimVertexData();
289 else if (!useSoftwareBlendingVertices && useSoftwareMorphingVertices && parentEntity->_isAnimated() && (parentEntity->getMesh()->getPoseList().size() == 0))
290 vertex_data = submesh->useSharedVertices ? parentEntity->_getSoftwareVertexAnimVertexData() : subEntity->_getSoftwareVertexAnimVertexData();
292 vertex_data = submesh->useSharedVertices ? submesh->parent->sharedVertexData : submesh->vertexData;
294 const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
295 Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
296 if (!vbuf->isLocked())
298 unsigned char* vertex =
static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
300 for (
int j = 0; j < static_cast<int>(index_count); j += 3)
305 posElem->baseVertexPointerToElement(vertex + indices[j] * vbuf->getVertexSize(), &pReal1);
306 posElem->baseVertexPointerToElement(vertex + indices[j + 1] * vbuf->getVertexSize(), &pReal2);
307 posElem->baseVertexPointerToElement(vertex + indices[j + 2] * vbuf->getVertexSize(), &pReal3);
309 Ogre::Vector3 pt1(pReal1[0], pReal1[1], pReal1[2]);
310 Ogre::Vector3 pt2(pReal2[0], pReal2[1], pReal2[2]);
311 Ogre::Vector3 pt3(pReal3[0], pReal3[1], pReal3[2]);
312 pt1 = (orient * (pt1 * scale)) + position;
313 pt2 = (orient * (pt2 * scale)) + position;
314 pt3 = (orient * (pt3 * scale)) + position;
316 std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, pt1, pt2, pt3,
true,
false);
319 if ((closest_distance < 0.0f) || (hit.second < closest_distance))
322 closest_distance = hit.second;
323 closestVerticeIndex = j;
329 results.
point = ray.getPoint(hit.second);
339 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? submesh->parent->sharedVertexData : submesh->vertexData;
340 const Ogre::VertexElement* vertex_element = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
341 if (vertex_data->vertexDeclaration->getElementCount() > 2)
347 Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(vertex_element->getSource());
348 unsigned char* vertex =
static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
350 vertex_element->baseVertexPointerToElement(vertex + indices[closestVerticeIndex] * vbuf->getVertexSize(), &pReal1);
351 vertex_element->baseVertexPointerToElement(vertex + indices[closestVerticeIndex + 1] * vbuf->getVertexSize(), &pReal2);
352 vertex_element->baseVertexPointerToElement(vertex + indices[closestVerticeIndex + 2] * vbuf->getVertexSize(), &pReal3);
357 results.
pReal1.x = pReal1[0];
358 results.
pReal1.y = pReal1[1];
359 results.
pReal2.x = pReal2[0];
360 results.
pReal2.y = pReal2[1];
361 results.
pReal3.x = pReal3[0];
362 results.
pReal3.y = pReal3[1];
365 Ogre::Vector3 v0 = results.
v3 - results.
v1;
366 Ogre::Vector3 v1 = results.
v2 - results.
v1;
367 Ogre::Vector3 v2 = results.
point - results.
v1;
370 float dot00 = v0.dotProduct(v0);
371 float dot01 = v0.dotProduct(v1);
372 float dot02 = v0.dotProduct(v2);
373 float dot11 = v1.dotProduct(v1);
374 float dot12 = v1.dotProduct(v2);
377 float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
378 float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
379 float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
402 Ogre::Ray ray = Ogre::Ray(pos, dir);
405 if (rq->execute().size() <= 0)
411 Ogre::Real closestDist = -1.0f;
412 Ogre::Vector3 closestResult;
413 Ogre::RaySceneQueryResult queryResult = rq->getLastResults();
415 for (
size_t qr_idx = 0; qr_idx < queryResult.size(); qr_idx++)
419 if (((closestDist >= 0.0f) && (closestDist < queryResult[qr_idx].distance)) || closestDist >= maxdist)
421 if (closestDist >= maxdist)
427 if ((queryResult[qr_idx].movable != NULL) && (queryResult[qr_idx].movable->getMovableType().compare(
"Entity") == 0))
430 Ogre::Entity *pentity =
static_cast<Ogre::Entity*
>(queryResult[qr_idx].movable);
435 Ogre::Vector3 *vertices;
436 unsigned long *indices;
440 pentity->getParentNode()->_getDerivedPosition(),
441 pentity->getParentNode()->_getDerivedOrientation(),
442 pentity->getParentNode()->_getDerivedScale());
445 bool new_closest_found =
false;
446 for (
int i = 0; i < static_cast<int>(index_count); i += 3)
449 std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, vertices[indices[i]],
450 vertices[indices[i + 1]], vertices[indices[i + 2]],
true,
false);
455 if ((closestDist < 0.0f) || (hit.second < closestDist))
458 closestDist = hit.second;
459 new_closest_found =
true;
471 if (new_closest_found)
473 closestResult = ray.getPoint(closestDist);
479 if ((closestDist >= 0.0f) && !toofar)
482 results.
point = closestResult;