double Test_RayCubeIntersect(glm::vec3 const& P0, glm::vec3 const& V0, glm::mat4 const& T) { //Lets just split our cube up into triangles, and send transformed rays + tris to //the triangle intersection method. double t = -1; double d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,-.5,.5), glm::vec3(.5,-.5,.5), glm::vec3(-.5,.5,.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(.5,-.5,.5), glm::vec3(.5,.5,.5), glm::vec3(-.5,.5,.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,-.5,-.5), glm::vec3(.5,-.5,-.5), glm::vec3(-.5,.5,-.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(.5,-.5,-.5), glm::vec3(.5,.5,-.5), glm::vec3(-.5,.5,-.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(.5,-.5,.5), glm::vec3(.5,-.5,-.5), glm::vec3(.5,.5,-.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(.5,.5,-.5), glm::vec3(.5,.5,.5), glm::vec3(.5,-.5,.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,-.5,.5), glm::vec3(-.5,-.5,-.5), glm::vec3(-.5,.5,-.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,.5,-.5), glm::vec3(-.5,.5,.5), glm::vec3(-.5,-.5,.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,.5,.5), glm::vec3(-.5,.5,-.5), glm::vec3(.5,.5,-.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,.5,.5), glm::vec3(.5,.5,-.5), glm::vec3(.5,.5,.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,-.5,.5), glm::vec3(-.5,-.5,-.5), glm::vec3(.5,-.5,-.5), T); if(d > 0 && d < t) {t = d;} d = Test_RayPolyIntersect(P0, V0, glm::vec3(-.5,-.5,.5), glm::vec3(.5,-.5,-.5), glm::vec3(.5,-.5,.5), T); if(d > 0 && d < t) {t = d;} //Hurts to read. I'll use a more efficient algorithm later. return t; }
Node* DisplayClass::recIntersection(glm::vec3 P, glm::vec3 V, Node* n) { *n->t = -1.0; Node* c = NULL; double res; double cT; //Node* ch = NULL; if (n->furniture != NULL) { for (int i = 0; i < n->furniture->primitives->size(); i++) { switch(*n->furniture->primitives->at(i)) { case 0: res = Test_RayCubeIntersect(P, V, *n->furniture->inverses->at(i)); if (res != -1) { if (c == NULL || res < *c->t) { c = n; *c->t = res; glm::vec4 p4(P.x, P.y, P.z, 1.0f); glm::vec4 v4(V.x, V.y, V.z, 0.0f); p4 = *n->furniture->inverses->at(i) * p4; v4 = *n->furniture->inverses->at(i) * v4; glm::vec4 inters = p4 + ((float)res) * v4; glm::vec4 myNorm; bool forward = inters.z > 0.4999 && inters.z < 0.5001; bool backward = inters.z < -0.4999 && inters.z > -0.5001; bool right = inters.x > 0.4999 && inters.x < 0.5001; bool left = inters.x < -0.4999 && inters.x > -0.5001; bool up = inters.y > 0.4999 && inters.y < 0.5001; bool down = inters.y < -0.4999 && inters.y > -0.5001; if (forward) { myNorm.x = 0.0f; myNorm.y = 0.0f; myNorm.z = 1.0f; } else if (backward) { myNorm.x = 0.0f; myNorm.y = 0.0f; myNorm.z = -1.0f; } else if (right) { myNorm.x = 1.0f; myNorm.y = 0.0f; myNorm.z = 0.0f; } else if (left) { myNorm.x = -1.0f; myNorm.y = 0.0f; myNorm.z = 0.0f; } else if (up) { myNorm.x = 0.0f; myNorm.y = 1.0f; myNorm.z = 0.0f; } else if (down) { myNorm.x = 0.0f; myNorm.y = -1.0f; myNorm.z = 0.0f; } myNorm[3] = 0.0f; myNorm = glm::normalize(glm::transpose(*n->furniture->inverses->at(i)) * myNorm); *c->currentWorldTransform = *n->furniture->worldTransforms->at(i); c->normal->x = myNorm.x; c->normal->y = myNorm.y; c->normal->z = myNorm.z; } } break; case 1: res = Test_RayCylinderIntersect(P, V, *n->furniture->inverses->at(i)); if (res != -1) { if (c == NULL || res < *c->t) { c = n; *c->t = res; glm::vec4 p4(P.x, P.y, P.z, 1.0f); glm::vec4 v4(V.x, V.y, V.z, 0.0f); p4 = *n->furniture->inverses->at(i) * p4; v4 = *n->furniture->inverses->at(i) * v4; glm::vec4 inters = p4 + ((float)res) * v4; glm::vec4 myNorm(2.0f * inters.x, 0.0f, 2.0f * inters.z, 0.0f); myNorm = glm::normalize(glm::transpose(*n->furniture->inverses->at(i)) * myNorm); *c->currentWorldTransform = *n->furniture->worldTransforms->at(i); c->normal->x = myNorm.x; c->normal->y = myNorm.y; c->normal->z = myNorm.z; } } break; case 2: res = Test_RaySphereIntersect(P, V, *n->furniture->inverses->at(i)); if (res != -1) { if (c == NULL || res < *c->t) { c = n; *c->t = res; glm::vec4 p4(P.x, P.y, P.z, 1.0f); glm::vec4 v4(V.x, V.y, V.z, 0.0f); p4 = *n->furniture->inverses->at(i) * p4; v4 = *n->furniture->inverses->at(i) * v4; glm::vec4 inters = p4 + ((float)res) * v4; glm::vec4 myNorm(inters.x * 2.0f, inters.y * 2.0f, inters.z * 2.0f, 0.0f); myNorm = glm::normalize(glm::transpose(*n->furniture->inverses->at(i)) * myNorm); *c->currentWorldTransform = *n->furniture->worldTransforms->at(i); c->normal->x = myNorm.x; c->normal->y = myNorm.y; c->normal->z = myNorm.z; } } /*else { glm::vec3 x; }*/ break; } } //do intersection tests, get intersection with minimum t-value } else if (n->shape != NULL) { if (*n->shape->kind < 97 || Test_RayCubeIntersect(P, V, *n->boundTrans) != -1) { glm::vec3 p1; glm::vec3 p2; glm::vec3 p3; glm::vec4 norm(0.0f, 0.0f, 0.0f, 0.0f); double minT = -1; for (int q = 0; q < *n->shape->numVbo; q+=12) { p1.x = n->shape->vbo[q]; p1.y = n->shape->vbo[q + 1]; p1.z = n->shape->vbo[q + 2]; p2.x = n->shape->vbo[q + 4]; p2.y = n->shape->vbo[q + 5]; p2.z = n->shape->vbo[q + 6]; p3.x = n->shape->vbo[q + 8]; p3.y = n->shape->vbo[q + 9]; p3.z = n->shape->vbo[q + 10]; res = Test_RayPolyIntersect(P, V, p1, p2, p3, *n->inv); if (res != -1 && (minT > res || minT == -1)) { minT = res; norm.x = n->shape->nbo[q]; norm.y = n->shape->nbo[q + 1]; norm.z = n->shape->nbo[q + 2]; } } if (minT != -1) { if (c == NULL || *c->t == -1 || res < *c->t) { c = n; *c->t = minT; norm = glm::normalize(glm::transpose(*n->inv) * norm); *c->currentWorldTransform = *n->worldTransform; c->normal->x = norm.x; c->normal->y = norm.y; c->normal->z = norm.z; } } } //loop through triangles and find intersection with minimum t-value } Node* ch = NULL; for (int i = 0; i < n->children->size(); i++) { ch = recIntersection(P, V, n->children->at(i)); if (ch != NULL) { if (c == NULL || *c->t == -1 || *ch->t < *c->t) { c = ch; } } } return c; }
float Mesh::Test_RayMeshIntersect(const double P0[], const double V0[], const double matrix[], vec3 &normOut, vec3 &inPoint){ float t = -1; int smallIndex = faces[0][0][1]; //double ps[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; vector<vec3> ps; vec3 point; vec3 norm; for(int i=0; i<faces.size();i++){ int index = faces[i][0][1]; std::cout<<"\n\n------------------------\nINDEX i = "<<i<<std::endl; ps.clear(); for(int j = 0; j<faces[i].size();j++){ //std::cout<<faces[i].size()<<std::endl; std::cout<<"\nVertex j = "<<j<<std::endl; std::cout<<"Vector x : "<<i<<"= "<<vertices[faces[i][j][0]][0]<<std::endl; std::cout<<"Vector y : "<<i<<"= "<<vertices[faces[i][j][0]][1]<<std::endl; std::cout<<"Vector z : "<<i<<"= "<<vertices[faces[i][j][0]][2]<<"\n"<<std::endl; vec3 p(vertices[faces[i][j][0]][0],vertices[faces[i][j][0]][1],vertices[faces[i][j][0]][2]); ps.push_back(p); } float ti = -1; norm = normals[index]; if(faces[i].size() == 3){ double p1[3] = {ps[0][0],ps[0][1],ps[0][2]}; double p2[3] = {ps[1][0],ps[1][1],ps[1][2]}; double p3[3] = {ps[2][0],ps[2][1],ps[2][2]}; /*cout<<"PS 0 : x = "<<p1[0]<<" y = "<<p1[1]<<" z = "<<p1[2]<<endl; cout<<"PS 1 : x = "<<p2[0]<<" y = "<<p2[1]<<" z = "<<p2[2]<<endl; cout<<"PS 2 : x = "<<p3[0]<<" y = "<<p3[1]<<" z = "<<p3[2]<<endl;*/ ti = Test_RayPolyIntersect(P0,V0,p1,p2,p3,matrix,norm,point); //cout<<"ti: "<<ti<<endl; } else if(faces[i].size() == 4){ double p1[3] = {ps[0][0],ps[0][1],ps[0][2]}; double p2[3] = {ps[1][0],ps[1][1],ps[1][2]}; double p3[3] = {ps[2][0],ps[2][1],ps[2][2]}; double p4[3] = {ps[3][0],ps[3][1],ps[3][2]}; /*cout<<"PS 0 : x = "<<p1[0]<<" y = "<<p1[1]<<" z = "<<p1[2]<<endl; cout<<"PS 1 : x = "<<p2[0]<<" y = "<<p2[1]<<" z = "<<p2[2]<<endl; cout<<"PS 2 : x = "<<p3[0]<<" y = "<<p3[1]<<" z = "<<p3[2]<<endl; cout<<"PS 3 : x = "<<p4[0]<<" y = "<<p4[1]<<" z = "<<p4[2]<<endl;*/ ti = Test_RayPlaneIntersect(P0,V0,p1,p2,p3,p4,matrix,norm,point); //cout<<"ti: "<<ti<<endl; } else if(faces[i].size() > 4){ double p1[3], p2[3], p3[3]; p1[0] = ps[0][0]; p1[1] = ps[0][1]; p1[2] = ps[0][2]; for(int n = 1; n<(ps.size()-1) && ti<0; n++){ p2[0] = ps[n][0]; p2[1] = ps[n][1]; p2[2] = ps[n][2]; p3[0] = ps[n+1][0]; p3[1] = ps[n+1][1]; p3[2] = ps[n+1][2]; /*cout<<"\nPS 0 : x = "<<p1[0]<<" y = "<<p1[1]<<" z = "<<p1[2]<<endl; cout<<"PS 1 : x = "<<p2[0]<<" y = "<<p2[1]<<" z = "<<p2[2]<<endl; cout<<"PS 2 : x = "<<p3[0]<<" y = "<<p3[1]<<" z = "<<p3[2]<<endl;*/ ti = Test_RayPolyIntersect(P0,V0,p1,p2,p3,matrix,norm,point); } } if(ti >= 0 && (t<0 || ti<t)){ t = ti; smallIndex = index; inPoint = point; } } normOut = normals[smallIndex]; /*std::cout<<"Normal x : "<<"= "<<normOut[0]<<std::endl; std::cout<<"Normal y : "<<"= "<<normOut[1]<<std::endl; std::cout<<"Normal z : "<<"= "<<normOut[2]<<"\n"<<std::endl;*/ return t; }