2012-02-23 16 views
9

मुझे बॉक्स में माउस हिट का पता लगाने के लिए मेरी किरण कास्टिंग एल्गोरिदम में त्रुटियों के साथ समस्या हो रही है। मैं इसे ठीक तरह से ठीक करने के तरीके के रूप में पूरी तरह से नुकसान में हूं और यह मुझे हफ्तों तक चिपका रहा है।रे कास्टिंग के साथ ऑब्जेक्ट पिकिंग

समस्या का सबसे आसान एक तस्वीर के साथ वर्णन किया गया है (बॉक्स के आसपास केंद्रित [0, 0, -30]):

screen shot of problem

काले लाइनों वास्तविक hitbox जो तैयार की है प्रतिनिधित्व करते हैं और हरे बॉक्स का प्रतिनिधित्व करता है वास्तव में हिट पाने के लिए क्या प्रतीत होता है। ध्यान दें कि यह ऑफ़सेट कैसे होता है (जो बॉक्स को मूल से आगे होने पर बड़ा लगता है) और खींचे गए हिटबॉक्स से थोड़ा छोटा है।

यहाँ कुछ प्रासंगिक कोड है,

रे बॉक्स डाली:

GLint viewport[4]; 
GLdouble modelMatrix[16]; 
GLdouble projectionMatrix[16]; 

glGetIntegerv(GL_VIEWPORT, viewport); 
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); 
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); 

GLfloat winY = GLfloat(viewport[3] - mouse_y); 

Ray3 ray; 
double x, y, z; 
gluUnProject((double) mouse_x, winY, 0.0f, // Near 
       modelMatrix, projectionMatrix, viewport, 
       &x, &y, &z); 
ray.origin = Vector3(x, y, z); 

gluUnProject((double) mouse_x, winY, 1.0f, // Far 
       modelMatrix, projectionMatrix, viewport, 
      &x, &y, &z); 
ray.direction = Vector3(x, y, z); 

if(bbox.checkBoxIntersection(ray) != -1) { 
    std::cout << "Hit!" << std::endl; 
} 

मैं एक के रूप में वास्तविक रे ड्राइंग की कोशिश की है:

double BBox::checkFaceIntersection(Vector3 points[4], Vector3 normal, Ray3 ray) { 

    double rayDotNorm = ray.direction.dot(normal); 
    if(rayDotNorm == 0) return -1; 

    Vector3 intersect = points[0] - ray.origin; 
    double t = intersect.dot(normal)/rayDotNorm; 
    if(t < 0) return -1; 

    // Check if first point is from under or below polygon 
    bool positive = false; 
    double firstPtDot = ray.direction.dot((ray.origin - points[0]).cross(ray.origin - points[1])); 
    if(firstPtDot > 0) positive = true; 
    else if(firstPtDot < 0) positive = false; 
    else return -1; 

    // Check all signs are the same 
    for(int i = 1; i < 4; i++) { 
     int nextPoint = (i+1) % 4; 
     double rayDotPt = ray.direction.dot((ray.origin - points[i]).cross(ray.origin - points[nextPoint])); 
     if(positive && rayDotPt < 0) { 
      return -1; 
     } 
     else if(!positive && rayDotPt > 0) { 
      return -1; 
     } 
    } 

    return t; 
} 

माउस रे करने के लिए रेखा और ऐसा लगता है कि खींचे गए बॉक्स को सही ढंग से छेड़छाड़ करना है।

मुझे ऑफ़सेट समस्या आंशिक रूप से सभी बिंदुओं और किरणों की उत्पत्ति के आधार पर रेस मूल/दिशा को कम करके तय की गई थी, लेकिन मुझे नहीं पता कि यह क्यों काम करता है और हिटबॉक्स का आकार अभी भी गलत बना हुआ है।

कोई विचार/वैकल्पिक दृष्टिकोण? यदि आवश्यक हो तो मेरे पास आपूर्ति करने के लिए अन्य कोड है।

उत्तर

10

आप गलत दिशा मान रहे हैं। सही होगा:

ray.direction = Vector3(far.x - near.x, far.y - near.y, far.z - near.z); 

पास और दूर चौराहे बिंदुओं को घटाए बिना, आपकी दिशा बंद हो जाएगी।

+0

धन्यवाद! यह बिल्कुल था, बहुत सराहना की :) – sler

संबंधित मुद्दे