mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 12:23:24 +02:00
more work on improved model picking
This commit is contained in:
parent
5ec9a9b6ed
commit
37ffa48fa3
3 changed files with 18 additions and 377 deletions
|
@ -263,383 +263,20 @@ EntityItemProperties RenderableModelEntityItem::getProperties() const {
|
|||
bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject) const {
|
||||
|
||||
// extents is the entity relative, scaled, centered extents of the entity
|
||||
glm::mat4 rotation = glm::mat4_cast(getRotation());
|
||||
glm::mat4 translation = glm::translate(getPosition());
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||
glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f));
|
||||
|
||||
float depth = depthOfRayIntersection(entityFrameOrigin, entityFrameDirection);
|
||||
|
||||
return true; // we only got here if we intersected our non-aabox
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void RenderableModelEntityItem::renderEntityAsBillboard() {
|
||||
TextureCache* textureCache = Application->getInstance()->getTextureCache();
|
||||
textureCache->getPrimaryFramebufferObject()->bind();
|
||||
|
||||
const int BILLBOARD_SIZE = 64;
|
||||
renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
|
||||
|
||||
//QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
|
||||
//glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
|
||||
|
||||
textureCache->getPrimaryFramebufferObject()->release();
|
||||
|
||||
return image;
|
||||
}
|
||||
*/
|
||||
|
||||
float RenderableModelEntityItem::depthOfRayIntersection(const glm::vec3& entityFrameOrigin, const glm::vec3& entityFrameDirection) const {
|
||||
qDebug() << "RenderableModelEntityItem::depthOfRayIntersection()....";
|
||||
qDebug() << "RenderableModelEntityItem::findDetailedRayIntersection()....";
|
||||
qDebug() << " origin:" << origin;
|
||||
glm::vec3 originInMeters = origin * (float)TREE_SCALE;
|
||||
qDebug() << " originInMeters:" << originInMeters;
|
||||
QString extraInfo;
|
||||
float localDistance;
|
||||
bool intersectsModel = _model->findRayIntersectionAgainstSubMeshes(originInMeters, direction, localDistance, face, extraInfo);
|
||||
|
||||
Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind();
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_LIGHTING); // enable?
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND); // we don't need blending
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
||||
// * we know the direction that the ray is coming into our bounding box.
|
||||
// * we know the location on our bounding box that the ray intersected
|
||||
// * because this API is theoretically called for things that aren't on the screen,
|
||||
// or could be off in the distance, but with an original ray pick origin ALSO off
|
||||
// in the distance, we don't really know the "pixel" size of the model at that
|
||||
// place in space. In fact that concept really doesn't make sense at all... so
|
||||
// we need to pick our own "scale" based on whatever level of precision makes
|
||||
// sense... what makes sense?
|
||||
// * we could say that we allow ray intersections down to some N meters (say 1cm
|
||||
// or 0.01 meters) in real space. The model's bounds in meters are known.
|
||||
//
|
||||
//
|
||||
float renderGranularity = 0.01f; // 1cm of render granularity - this could be ridiculous for large models
|
||||
|
||||
qDebug() << " renderGranularity:" << renderGranularity;
|
||||
|
||||
// note: these are in tree units, not meters
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::vec3 registrationPoint = getRegistrationPoint();
|
||||
glm::vec3 corner = -(dimensions * registrationPoint);
|
||||
|
||||
AABox entityFrameBox(corner, dimensions);
|
||||
entityFrameBox.scale((float)TREE_SCALE);
|
||||
|
||||
// rotationBetween(v1, v2) -- Helper function return the rotation from the first vector onto the second
|
||||
//glm::quat viewRotation = rotationBetween(entityFrameDirection, IDENTITY_FRONT);
|
||||
//glm::quat viewRotation = rotationBetween(IDENTITY_FRONT, entityFrameDirection);
|
||||
glm::quat viewRotation = rotationBetween(glm::vec3(0.0f, 1.0f, 0.0f), IDENTITY_FRONT);
|
||||
//glm::quat viewRotation = rotationBetween(IDENTITY_FRONT, IDENTITY_FRONT);
|
||||
|
||||
// I'd like to calculate the tightest bounding box around the entity for
|
||||
// the direction of the
|
||||
glm::vec3 minima(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
glm::vec3 maxima(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
const int VERTEX_COUNT = 8;
|
||||
for (int j = 0; j < VERTEX_COUNT; j++) {
|
||||
glm::vec3 vertex = entityFrameBox.getVertex((BoxVertex)j);
|
||||
qDebug() << " vertex[" << j <<"]:" << vertex;
|
||||
|
||||
glm::vec3 rotated = viewRotation * vertex;
|
||||
qDebug() << " rotated[" << j <<"]:" << rotated;
|
||||
|
||||
minima = glm::min(minima, rotated);
|
||||
maxima = glm::max(maxima, rotated);
|
||||
if (intersectsModel) {
|
||||
distance = localDistance / (float)TREE_SCALE;
|
||||
}
|
||||
|
||||
qDebug() << " minima:" << minima;
|
||||
qDebug() << " maxima:" << maxima;
|
||||
|
||||
int width = glm::round((maxima.x - minima.x) / renderGranularity);
|
||||
int height = glm::round((maxima.y - minima.y) / renderGranularity);
|
||||
|
||||
qDebug() << " width:" << width;
|
||||
qDebug() << " height:" << height;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glScissor(0, 0, width, height);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glLoadIdentity();
|
||||
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glm::vec3 axis = glm::axis(viewRotation);
|
||||
glRotatef(glm::degrees(glm::angle(viewRotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
glm::vec3 entityFrameOriginInMeters = entityFrameOrigin * (float)TREE_SCALE;
|
||||
glm::vec3 entityFrameDirectionInMeters = entityFrameDirection * (float)TREE_SCALE;
|
||||
//glTranslatef(entityFrameOriginInMerters.x, entityFrameOriginInMerters.y, entityFrameOriginInMerters.z);
|
||||
|
||||
Application::getInstance()->setupWorldLight();
|
||||
Application::getInstance()->updateUntranslatedViewMatrix();
|
||||
|
||||
|
||||
bool renderAsModel = true;
|
||||
|
||||
if (renderAsModel) {
|
||||
const float alpha = 1.0f;
|
||||
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenterInMeters();
|
||||
dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
//glm::vec3 axis = glm::axis(rotation);
|
||||
//glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
//glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
|
||||
//glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
//Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(0.5f, 15, 15);
|
||||
|
||||
//_model->setRotation(rotation);
|
||||
//_model->setScaleToFit(true, glm::vec3(1.0f,1.0f,1.0f));
|
||||
|
||||
//glm::vec3(0.0f,2.0f,0.0f)
|
||||
_model->setSnapModelToRegistrationPoint(true, glm::vec3(0.5f,0.5f,0.5f));
|
||||
_model->setTranslation(glm::vec3(0.0f,0.0f,0.0f));
|
||||
_model->simulate(0.0f);
|
||||
_model->render(alpha, Model::DEFAULT_RENDER_MODE);
|
||||
|
||||
//_model->render(1.0f, Model::DEFAULT_RENDER_MODE);
|
||||
|
||||
//_model->setScaleToFit(true, dimensions);
|
||||
_model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||
_model->setTranslation(position);
|
||||
_model->simulate(0.0f);
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(0.5f, 15, 15);
|
||||
glPopMatrix();
|
||||
|
||||
/*
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// low-z side - blue
|
||||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-z side - cyan
|
||||
glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
// low-x side - yellow
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-x side - red
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
|
||||
|
||||
// origin and direction - green
|
||||
float distanceToHit;
|
||||
BoxFace ignoreFace;
|
||||
|
||||
entityFrameBox.findRayIntersection(entityFrameOriginInMeters, entityFrameDirectionInMeters, distanceToHit, ignoreFace);
|
||||
glm::vec3 pointOfIntersection = entityFrameOriginInMeters + (entityFrameDirectionInMeters * distanceToHit);
|
||||
|
||||
qDebug() << "distanceToHit: " << distanceToHit;
|
||||
qDebug() << "pointOfIntersection: " << pointOfIntersection;
|
||||
|
||||
glm::vec3 pointA = pointOfIntersection + (entityFrameDirectionInMeters * -1.0f);
|
||||
glm::vec3 pointB = pointOfIntersection + (entityFrameDirectionInMeters * 1.0f);
|
||||
qDebug() << "pointA: " << pointA;
|
||||
qDebug() << "pointB: " << pointB;
|
||||
|
||||
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(pointA.x, pointA.y, pointA.z);
|
||||
glVertex3f(pointB.x, pointB.y, pointB.z);
|
||||
|
||||
glEnd();
|
||||
*/
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
} else {
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenterInMeters();
|
||||
dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glLineWidth(2.0f);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
//Application::getInstance()->getDeferredLightingEffect()->renderWireCube(1.0f);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(0.5f, 15, 15);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// low-z side - blue
|
||||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-z side - cyan
|
||||
glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
// low-x side - yellow
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-x side - red
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
|
||||
|
||||
// origin and direction - green
|
||||
float distanceToHit;
|
||||
BoxFace ignoreFace;
|
||||
|
||||
entityFrameBox.findRayIntersection(entityFrameOriginInMeters, entityFrameDirectionInMeters, distanceToHit, ignoreFace);
|
||||
glm::vec3 pointOfIntersection = entityFrameOriginInMeters + (entityFrameDirectionInMeters * distanceToHit);
|
||||
|
||||
qDebug() << "distanceToHit: " << distanceToHit;
|
||||
qDebug() << "pointOfIntersection: " << pointOfIntersection;
|
||||
|
||||
glm::vec3 pointA = pointOfIntersection + (entityFrameDirectionInMeters * -1.0f);
|
||||
glm::vec3 pointB = pointOfIntersection + (entityFrameDirectionInMeters * 1.0f);
|
||||
qDebug() << "pointA: " << pointA;
|
||||
qDebug() << "pointB: " << pointB;
|
||||
|
||||
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(pointA.x, pointA.y, pointA.z);
|
||||
glVertex3f(pointB.x, pointB.y, pointB.z);
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
QImage colorData(width, height, QImage::Format_ARGB32);
|
||||
QVector<float> depthData(width * height);
|
||||
|
||||
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, colorData.bits());
|
||||
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depthData.data());
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->release();
|
||||
|
||||
glViewport(0, 0, Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height());
|
||||
|
||||
QImage imageData = colorData.mirrored(false,true);
|
||||
|
||||
bool saved = imageData.save("/Users/zappoman/Development/foo.bmp");
|
||||
|
||||
qDebug() << " saved:" << saved;
|
||||
|
||||
|
||||
return 0.0f;
|
||||
return intersectsModel; // we only got here if we intersected our non-aabox
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -71,9 +71,6 @@ private:
|
|||
QString _currentTextures;
|
||||
QStringList _originalTextures;
|
||||
bool _originalTexturesRead;
|
||||
|
||||
float depthOfRayIntersection(const glm::vec3& entityFrameOrigin, const glm::vec3& entityFrameDirection) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_RenderableModelEntityItem_h
|
||||
|
|
|
@ -536,6 +536,8 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
return intersectedSomething;
|
||||
}
|
||||
|
||||
qDebug() << "Model::findRayIntersectionAgainstSubMeshes()...";
|
||||
|
||||
// extents is the entity relative, scaled, centered extents of the entity
|
||||
glm::vec3 position = _translation;
|
||||
glm::mat4 rotation = glm::mat4_cast(_rotation);
|
||||
|
@ -544,11 +546,14 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix);
|
||||
|
||||
Extents modelExtents = getMeshExtents(); // NOTE: unrotated
|
||||
qDebug() << " modelExtents:" << modelExtents;
|
||||
|
||||
glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum;
|
||||
glm::vec3 corner = dimensions * -0.5f; // since we're going to do the ray picking in the model frame of reference
|
||||
AABox overlayFrameBox(corner, dimensions);
|
||||
|
||||
qDebug() << " overlayFrameBox:" << overlayFrameBox;
|
||||
|
||||
glm::vec3 modelFrameOrigin = glm::vec3(worldToModelMatrix * glm::vec4(origin, 1.0f));
|
||||
glm::vec3 modelFrameDirection = glm::vec3(worldToModelMatrix * glm::vec4(direction, 0.0f));
|
||||
|
||||
|
@ -560,11 +565,13 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
float distanceToSubMesh;
|
||||
BoxFace subMeshFace;
|
||||
int subMeshIndex = 0;
|
||||
|
||||
|
||||
// If we hit the models box, then consider the submeshes...
|
||||
foreach(const AABox& subMeshBox, _calculatedMeshBoxes) {
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
|
||||
qDebug() << "subMeshBox[" << subMeshIndex <<"]:" << subMeshBox;
|
||||
if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace)) {
|
||||
if (distanceToSubMesh < bestDistance) {
|
||||
bestDistance = distanceToSubMesh;
|
||||
|
|
Loading…
Reference in a new issue