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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}