Esempio n. 1
0
void GMBoundingFrustum::createCorners()
{
    corners[0] = intersectionPoint(near, left, top);
    corners[1] = intersectionPoint(near, right, top);
    corners[2] = intersectionPoint(near, right, bottom);
    corners[3] = intersectionPoint(near, left, bottom);
    corners[4] = intersectionPoint(far, left, top);
    corners[5] = intersectionPoint(far, right, top);
    corners[6] = intersectionPoint(far, right, bottom);
    corners[7] = intersectionPoint(far, left, bottom);
}
Esempio n. 2
0
double Ray::intersect(Triangle triangle)
{

  // check if the normal is facing the right direction
  if(direction.dot(triangle.normal) < 0)
    {
      return -1;
    }

  // check if the bounding sphere is hit
  Vector3 difference = start - triangle.center;
  if(square(direction.dot(difference)) -  difference.dot(difference) + square(triangle.radius) < 0)
    {
      return -1;
    }
  
  // get the actual intersectoin point
  Vector3 point = intersectionPoint(triangle.vertexA, triangle.normal);

  Vector3 edgeC = point - triangle.vertexA;

  double AA = triangle.edgeA.dot(triangle.edgeA);
  double BB = triangle.edgeB.dot(triangle.edgeB);
  double AB = triangle.edgeA.dot(triangle.edgeB);
  double AC = triangle.edgeA.dot(edgeC);
  double BC = triangle.edgeB.dot(edgeC);
  
  double D = AA*BB - AB*AB;

  if(D != 0)
    {
      double u = (BB*AC - AB*BC)/D;
      double v = (AA*BC - AB*AC)/D;

      if(u+v <= 1 && (v >= 0 && u >= 0))
	{
	  return u+v;
	}
    }
  return -1;
  
}
Esempio n. 3
0
intersectionPoint triangleMesh::intersect(const ray& r) const
{
  intersectionPoint ip;

  // check bounding box, and bail if not hit
  if(!_boundingBox.isHit(r)) return ip;

  // for every triangle
  for(std::vector<triangle>::const_iterator itr = _triangles.begin(); itr != _triangles.end(); itr++)
  {
    // hit & closer?
    float t;
    vec3d barycentric;
    if(itr->intersect(r, barycentric, t))  // hit?
      if(ip > t)                           // closer by?
	ip = intersectionPoint(r, barycentric, t, *itr, _material);
  }

  // Done.
  return ip;
}
Esempio n. 4
0
File: exo1.c Progetto: roddehugo/utc
int intersectionTriangle(unTriangle T1, unTriangle T2, unTriangle *T3)
{
    //connu : dansTriangle(unTriangle T, unPoint P)
    //connu : intersectionPoint(unPoint S1, unPoint S2, unPoint P1, unPoint P2, unPoint *PI)
    //on regarde si les sommets de T2 sont dans T1
    int i, nbpt = 0, sommetDansTriangle = {0,0,0};
    for (i=0; i<3; i++) { //on commence la lecture à 0 dans le tableau
        sommetDansTriangle[i] = dansTriangle(T1,T2.point[i]);
        nbpt += sommetDansTriangle[i]; //On stock quels sommets sont dans le triangle précédent
    }

    if(nbpt == 1) {
        //Bon je ne suis pas sur non plus... il faut tester ts les cas possible...
        for(i=0; i<3; i++)
            for(j=0; j<3; j++)
                if(sommetDansTriangle[i]) && i!=j)
                    intersectionPoint(T1.point[i], T1.point[j], T2.point[i], T2.point[j], T3.point[i]);

                    return 1;
                } else
        return 0;
Esempio n. 5
0
void PolygonLine :: computeIntersectionPoints(Line *l, std :: vector< FloatArray > &oIntersectionPoints)
{
    printf("Warning: entering  PolygonLine :: computeIntersectionPoints(Line *l, std::vector< FloatArray > &oIntersectionPoints).\n");

#ifdef __BOOST_MODULE


    int numSeg = this->giveNrVertices() - 1;


    // Segment
    bPoint2 lineP1( l->giveVertex ( 1 )->at(1), l->giveVertex ( 1 )->at(2) );
    bPoint2 lineP2( l->giveVertex ( 2 )->at(1), l->giveVertex ( 2 )->at(2) );
    bSeg2 lineSeg(lineP1, lineP2);


    double distTol = 1.0e-9;

    bool foundOverlap = false;

    // Loop over the crack segments and test each segment for
    // overlap with the element
    for ( int segId = 1; segId <= numSeg; segId++ ) {
        // Crack segment
        bPoint2 crackP1( this->giveVertex ( segId )->at(1), this->giveVertex ( segId )->at(2) );
        bPoint2 crackP2( this->giveVertex ( segId + 1 )->at(1), this->giveVertex ( segId + 1 )->at(2) );
        bSeg2 crackSeg(crackP1, crackP2);

        bPoint2 intersectionPoint(0.0, 0.0);
        double d = bDist(crackSeg, lineSeg, & intersectionPoint);
        if ( d < distTol ) {
            if ( !foundOverlap ) {
                foundOverlap = true;
                oIntersectionPoints.emplace_back({intersectionPoint.x(), intersectionPoint.y()});
            }
        }
    }

#endif
}
Esempio n. 6
0
/**  Always set m_fp before calling this function!!!
 *   callOnVertices will use data from tmod to find the vertices described by
 *   tmod.ray and tmod.radius, and call m_fp on them.
 *  \param tmod data about the modification
 *  \param call_outside true means that m_fp will be called on non-exsisting
    vertices as well. tmod.in_terrain flag will distinguish them
 *  \param call_in_square true means that m_fp is called if the distance is < r
 *  along (x || z) axis
 */
void Terrain::callOnVertices(TerrainMod* tmod, bool call_outside,
    bool call_in_square)
{
    s32 ix, iz, dx, dz;
    vector2df cpos;

    if (!intersectionPoint(tmod->ray, tmod->radius, &cpos, &ix, &iz))
        return;

    dx = (s32)(tmod->radius / (m_x / m_nx) + 1);
    dz = (s32)(tmod->radius / (m_z / m_nz) + 1);

    tmod->index = 0;
    for (s32 j = -dz; j <= dz; j++)
    for (s32 i = -dx; i <= dx; i++)
    {
        tmod->in_terrain = true;
        // check if the point is outside of the terrain
        if (ix + i < 1 || ix + i >(s32)m_nx - 2 || iz + j < 1 || iz + j >(s32)m_nz - 2)
            tmod->in_terrain = false;

        if (call_outside && !tmod->in_terrain) (*this.*m_fp_h)(*tmod, ix, iz, i, j);
        else if (tmod->in_terrain)
        {
            S3DVertex2TCoords vert = m_mesh.vertices[(iz + j) * m_nx + ix + i];
            vector2df pos;
            pos = vector2df(vert.Pos.X, vert.Pos.Z);

            // check if the point is in radius
            tmod->dist = tmod->radius - (cpos - pos).getLength();

            if (tmod->dist > 0 || call_in_square)
            {
                (*this.*m_fp_h)(*tmod, ix, iz, i, j);
            }
        }
        tmod->index += 1;
    } // for loop - square
} // callOnVertices
int main()
{
  Node * list1 = new Node(3);
  list1->next = new Node(6);
  list1->next->next = new Node(9);
  list1->next->next->next = new Node(12);
  list1->next->next->next->next = new Node(15);
  list1->next->next->next->next->next = new Node(18);

  Node * list2 = new Node(7);
  list2->next = new Node(10);
  list2->next->next = list1->next->next->next;

  printList(list1);
  printList(list2);

  Node * intersectingNode = intersectionPoint( list1 , list2 );
  if (intersectingNode) {
    std::cout << "Intersecting Node of lists is :" << intersectingNode->data << std::endl;
  } else {
    std::cout << "Lists do not interset" << std::endl;
  }
  return 0;
}
Esempio n. 8
0
// ----------------------------------------------------------------------------
vector3df Terrain::placeBBtoGround(const aabbox3d<f32>& box, line3d<float> ray)
{
    int ix, iz, dx, dz;
    vector2df cpos;
    if (!intersectionPoint(ray, 0, &cpos, &ix, &iz))
        return vector3df(cpos.X,0,cpos.Y);

    f32 max_h = -30000;
    dx = (int)(box.MaxEdge.X / (m_x / m_nx) + 1);
    dz = (int)(box.MaxEdge.Z / (m_z / m_nz) + 1);

    for (int i = -dx; i <= dx; i++)
        for (int j = -dz; j <= dz; j++)
        {
            // check if the point is outside of the terrain
            if (ix + i > 0 && ix + i < (s32)m_nx && iz + j > 0 && iz + j < (s32)m_nz)
            {
                max_h = std::max((m_mesh.vertices[(iz + j) * m_nx + ix + i].Pos.Y),max_h);
            } // this square point is a valid vertex
        } // for loop - critical rectangle

    return vector3df(cpos.X, max_h - box.MinEdge.Y, cpos.Y);

} // placeBBtoGround
Esempio n. 9
0
intersectionList::intersectionList(UnitigVector &unitigs) {

  for (uint32 ti=0; ti<unitigs.size(); ti++) {
    Unitig             *tig = unitigs[ti];

    if (tig == NULL)
      continue;

    intersectionEvidence *evidence = new intersectionEvidence [tig->ufpath.size()];

    for (uint32 fi=0; fi<tig->ufpath.size(); fi++) {
      ufNode  *frg = &tig->ufpath[fi];

      if (OG->isContained(frg->ident))
        continue;

      //  For my best overlap, the ID of the unitig that the overlapping fragment is in.

      evidence[fi].edge5 = *OG->getBestEdgeOverlap(frg->ident, false);
      evidence[fi].edge3 = *OG->getBestEdgeOverlap(frg->ident, true);

      evidence[fi].frag5tig = tig->fragIn(evidence[fi].edge5.fragId());
      evidence[fi].frag3tig = tig->fragIn(evidence[fi].edge3.fragId());

      //  Do NOT initialize these!  An earlier fragment could have already confirmed an end.
      //  Properly, only the 5' end of a forward fragment (or 3' end of a reverse fragment) can be
      //  confirmed already (otherwise the tig is nonsense), but we don't yet check that.
      //
      //evidence[fi].frag5confirmed = false;
      //evidence[fi].frag3confirmed = false;

      //  But, because the path could be promiscuous, not every overlap to a different tig is bad.
      //
      //  If my best overlap is to a different tig, but there is an overlapping fragment (in the
      //  unitig placement) with a best edge to me, I'm still good.  The BOG build this unitig using
      //  the edge from the other fragment to me.
      //
      //  If the fragments do not overlap in the layout (yet the best edge still exists) that is a
      //  self-intersection.
      //
      //  The two blocks are identical, except for 'edge3' and 'edge5'.

      if (evidence[fi].frag5tig == tig->id()) {
        uint32   ti  = tig->pathPosition(evidence[fi].edge5.fragId());
        ufNode  *trg = &tig->ufpath[ti];

        uint32  minf = (frg->position.bgn < frg->position.end) ? frg->position.bgn : frg->position.end;
        uint32  maxf = (frg->position.bgn < frg->position.end) ? frg->position.end : frg->position.bgn;

        uint32  mint = (trg->position.bgn < trg->position.end) ? trg->position.bgn : trg->position.end;
        uint32  maxt = (trg->position.bgn < trg->position.end) ? trg->position.end : trg->position.bgn;

        //  If they overlap, mark as confirmed, else remember an intersection.

        if (((minf < mint) && (mint < maxf)) ||  //  t begins inside f
            ((mint < minf) && (minf < maxt))) {  //  f begins inside t
          if (evidence[fi].edge5.frag3p())
            evidence[ti].frag3confirmed = true;
          else
            evidence[ti].frag5confirmed = true;

        } else {
          evidence[fi].frag5self = true;

          //  Not the correct place to report this.  Some of these get confirmed by later fragments.
          //writeLog("BUG1 F: %d,%d T %d,%d\n", minf, maxf, mint, maxt);
          //writeLog("INTERSECT from unitig %d frag %d end %d TO unitig %d frag %d end %d (SELF)\n",
          //        tig->id(), frg->ident, 5, evidence[fi].frag5tig, evidence[fi].edge5.fragId(), evidence[fi].edge5.frag3p() ? 3 : 5);
        }
      }



      if (evidence[fi].frag3tig == tig->id()) {
        uint32   ti  = tig->pathPosition(evidence[fi].edge3.fragId());
        ufNode  *trg = &tig->ufpath[ti];

        uint32  minf = (frg->position.bgn < frg->position.end) ? frg->position.bgn : frg->position.end;
        uint32  maxf = (frg->position.bgn < frg->position.end) ? frg->position.end : frg->position.bgn;

        uint32  mint = (trg->position.bgn < trg->position.end) ? trg->position.bgn : trg->position.end;
        uint32  maxt = (trg->position.bgn < trg->position.end) ? trg->position.end : trg->position.bgn;

        if (((minf < mint) && (mint < maxf)) ||  //  t begins inside f
            ((mint < minf) && (minf < maxt))) {  //  f begins inside t
          if (evidence[fi].edge3.frag3p())
            evidence[ti].frag3confirmed = true;
          else
            evidence[ti].frag5confirmed = true;

        } else {
          evidence[fi].frag3self = true;

          //  Not the correct place to report this.  Some of these get confirmed by later fragments.
          //writeLog("BUG2 F: %d,%d T %d,%d\n", minf, maxf, mint, maxt);
          //writeLog("INTERSECT from unitig %d frag %d end %d TO unitig %d frag %d end %d (SELF)\n",
          //        tig->id(), frg->ident, 3, evidence[fi].frag3tig, evidence[fi].edge3.fragId(), evidence[fi].edge3.frag3p() ? 3 : 5);
        }
      }
    }

    //
    //  Build the list.
    //

    for (uint32 fi=0; fi<tig->ufpath.size(); fi++) {
      ufNode             *frg = &tig->ufpath[fi];

      if ((evidence[fi].frag5tig != 0) &&
          (evidence[fi].frag5tig != tig->id()) &&
          (evidence[fi].frag5confirmed == false))
        isects.push_back(intersectionPoint(evidence[fi].edge5, frg->ident, false, false));

      if ((evidence[fi].frag5tig == tig->id()) &&
          (evidence[fi].frag5self == true) &&
          (evidence[fi].frag5confirmed == false))
        isects.push_back(intersectionPoint(evidence[fi].edge5, frg->ident, false, true));

      if ((evidence[fi].frag3tig != 0) &&
          (evidence[fi].frag3tig != tig->id()) &&
          (evidence[fi].frag3confirmed == false))
        isects.push_back(intersectionPoint(evidence[fi].edge3, frg->ident, true, false));

      if ((evidence[fi].frag3tig == tig->id()) &&
          (evidence[fi].frag3self == true) &&
          (evidence[fi].frag3confirmed == false))
        isects.push_back(intersectionPoint(evidence[fi].edge3, frg->ident, true, true));
    }

    delete [] evidence;
  }


  //  Sort the intersections by the ID of the intersected fragment, then build an index into the array.

  std::sort(isects.begin(), isects.end());

  //  Terminate the intersection list with a sentinal intersection.  This is CRITICAL
  //  to the way we iterate over intersections.

  isects.push_back(intersectionPoint(BestEdgeOverlap(), 0, true, true));

  //  Build a map from fragment id to the first intersection in the list.

  for (uint32 i=0; i<isects.size(); i++) {
    isectsNum[isects[i].isectFrg]++;

    if (isectsMap.find(isects[i].isectFrg) == isectsMap.end())
      isectsMap[isects[i].isectFrg] = i;
  }
}
Esempio n. 10
0
void disp(void){

	//clear all pixels:
	glClear(GL_COLOR_BUFFER_BIT);

	// RayTracing loop
	for (int i = 0; i < (viewport.xvmax - viewport.xvmin); i++)
	{
		for (int j = 0; j < (viewport.yvmax - viewport.yvmin); j++)
		{
			int intersection_object = -1; // negative to return false / no intersection

			// maximum positive double-precision floating-point number
			// found on Wikipedia (link: https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
			double t = 0x7fefffffffffffff;

			Ray ray, shadow_ray, reflected_ray;
			Pixel pixel;
			Intersection intersection, current_intersection,
				shadow_ray_intersection, reflected_ray_intersection,
				current_reflected_intersection;
			double shadowAngle;

			bool bShadow = false;

			pixel.i = i;
			pixel.j = j;

			// initiate RayTrace
			RayTrace(&ray, &view_point, &viewport, &pixel,
				&camera, -focal_distance);

			// check if ray hits an object
			for (int i = 0; i < NUM_SPHERES; i++) {

				if (intersectionPoint(&ray, &sphere[i], &intersection)) {

					// there is an intersection between ray and object
					// calculate normal intersection
					normalIntersection(&sphere[i], &intersection, &ray);

					// if the intersection minimum is smaller than current infinity number
					if (intersection.tmin < t) {
						t = intersection.tmin; // found intersection
						intersection_object = i; // intersection sphere number
						copyIntersection(&current_intersection, &intersection); // copy intersection
					}
				}
			}

			// determine the pixel colour
			if (intersection_object > -1)
			{
				ShadowRayTrace( &shadow_ray, &intersection, &light );

				shadowAngle = shadow_ray.direction.dotproduct( intersection.normal );

				for (int i = 0; i < NUM_SPHERES; i++)
				{
					if (i != intersection_object)
					{
						if (intersectionPoint(&shadow_ray, &sphere[i], &shadow_ray_intersection) && (shadowAngle > 0.0))
							bShadow = true;
					}
				}

				if (bShadow) {
					// if object in shadow, add only ambiental light to the surface colour
					colour = shadow(&sphere[intersection_object].ka_rgb, ambient_light_intensity);
				}
				else {
					// the intersection renders normal colour
					colour = render(&current_intersection, &light, &view_point,
						&sphere[intersection_object].kd_rgb, &sphere[intersection_object].ks_rgb,
						&sphere[intersection_object].ka_rgb, sphere[intersection_object].shininess,
						light_intensity, ambient_light_intensity);
				}

				glColor3f(colour.x, colour.y, colour.z);
				glBegin(GL_POINTS);
					glVertex2i(i, j);
				glEnd();

				intersection_object = -1;
				bShadow = false;
			}
			else {
				// draw the pixel with background colour
				glColor3f(0.0, 0.0, 0.0);

				glBegin(GL_POINTS);
					glVertex2i(i, j);
				glEnd();

				intersection_object = -1;
				bShadow = false;
			}

			t = 0x7fefffffffffffff;
		}
	}

	glutSwapBuffers();
}
Esempio n. 11
0
Point vanishFromSky(const Mat& img)
{
	auto sth=skyDetect(img);
	return intersectionPoint(sth[0],sth[1]);
}
Esempio n. 12
0
// called by Tcl Event loop to check for new data
void TclTimerProc(ClientData clientData)
{
	if (!isPenLoaderStarted()) {
		printLog("Timer stopped\n");
		return;
	}

	// get the next stroke to analyze
	Stroke stroke = getNextAvailableStroke();
	Tcl_CreateTimerHandler(TCL_TIMER_MS, &TclTimerProc, NULL);
	if (stroke.nSamples == 0) {
		return;
	}
	if (gameFinished) {
		printLog("   This game is already finished, skipping stroke\n");
		return;
	}


	// if already have the board, determine and make the move
	if (numBoardLines == 4) {
		Line testLine = newLine(boardCenterX, boardCenterY, stroke.bounds.centerX, stroke.bounds.centerY);
		int crossing = (doLinesIntersect(&testLine, boardLeft)) ? CROSS_LEFT : CROSS_NONE;
		crossing |= (doLinesIntersect(&testLine, boardRight)) ? CROSS_RIGHT : CROSS_NONE;
		crossing |= (doLinesIntersect(&testLine, boardTop)) ? CROSS_TOP : CROSS_NONE;
		crossing |= (doLinesIntersect(&testLine, boardBottom)) ? CROSS_BOTTOM : CROSS_NONE;

		int move = CrossToMove[crossing];
		if (move == -1) {
			printLog("   Invalid crossing value detected: %d, skipping\n", crossing);
			return;
		} else if (movesDone[move] != 0) {
			printLog("   Skipping duplicate move: %d\n", move);
			return;
		}

		movesDone[move] = currentPlayer;
		currentPlayer = (currentPlayer % 2) + 1;
		printLog("   Making move %d\n", move);
		char moveCommand[30];
		sprintf(moveCommand, "ReturnFromHumanMove %d", move);
		Tcl_Eval(tclInterpreter, moveCommand);
		if (checkForFinishCondition()) {
			gameFinished = TRUE;
			printLog("   Game finished\n");
		}
		return;
	}


	// otherwise, add the stroke to the board
	if (stroke.type != STROKE_LINE) {
		printLog("   Board isn't finished, skipping non-LINE stroke\n");
		return;
	}
	boardLines[numBoardLines] = stroke.line;
	numBoardLines++;
	if (numBoardLines < 4) {
		return;
	}


	// determine board lines (two pairs of non-intersecting lines)
	int idx, match1b, match2a, match2b;
	match1b = 0;
	for (idx = 1; idx < 4; idx++) {
		if (!doLinesIntersect(&boardLines[0], &boardLines[idx])) {
			if (match1b != 0) {
				// matched twice, so something is wrong
				match1b = 0;
				break;
			}
			match1b = idx;
			match2a = (idx == 1) ? 2 : 1;
			match2b = (idx == 3) ? 2 : 3;
		}
	}

	// verify that matched lines intersect properly
	if ((match1b == 0) ||
	    (!doLinesIntersect(&boardLines[match1b], &boardLines[match2a])) ||
	    (!doLinesIntersect(&boardLines[match1b], &boardLines[match2b])) ||
	    (doLinesIntersect(&boardLines[match2a], &boardLines[match2b]))) {
		printLog("   Could not match board lines, trying again without first line\n");
		boardLines[0] = boardLines[1];
		boardLines[1] = boardLines[2];
		boardLines[2] = boardLines[3];
		numBoardLines = 3;
		return;
	}

	// assign proper sides (within 90 degree range away from pure vertical or horizontal)
	double angle = fabs(boardLines[0].angleDegrees);
	BOOL isLeft, isTop;
	int leftIdx, rightIdx, topIdx, bottomIdx;
	if (angle >= 45 && angle < 135) {
		// match 1 is vertical, match 2 is horizontal
		isLeft = (boardLines[0].centerX < boardLines[match1b].centerX);
		isTop = (boardLines[match2a].centerY < boardLines[match2b].centerY);
		leftIdx = isLeft ? 0 : match1b;
		rightIdx = isLeft ? match1b : 0;
		topIdx = isTop ? match2a : match2b;
		bottomIdx = isTop ? match2b : match2a;
	} else {
		// match 2 is vertical, match 1 is horizontal
		isLeft = (boardLines[match2a].centerX < boardLines[match2b].centerX);
		isTop = (boardLines[0].centerY < boardLines[match1b].centerY);
		leftIdx = isLeft ? match2a : match2b;
		rightIdx = isLeft ? match2b : match2a;
		topIdx = isTop ? 0 : match1b;
		bottomIdx = isTop ? match1b : 0;
	}
	boardLeft = &boardLines[leftIdx];
	boardRight = &boardLines[rightIdx];
	boardTop = &boardLines[topIdx];
	boardBottom = &boardLines[bottomIdx];

	// calculate center of the board (average of the 4 intersection points)
	double iLeftTop = intersectionPoint(boardLeft, boardTop);
	double iLeftBottom = intersectionPoint(boardLeft, boardBottom);
	double iRightTop = intersectionPoint(boardRight, boardTop);
	double iRightBottom = intersectionPoint(boardRight, boardBottom);
	boardCenterX = projectedX(boardLeft, iLeftTop, TRUE);
	boardCenterX += projectedX(boardLeft, iLeftBottom, TRUE);
	boardCenterX += projectedX(boardRight, iRightTop, TRUE);
	boardCenterX += projectedX(boardRight, iRightBottom, TRUE);
	boardCenterY = projectedY(boardLeft, iLeftTop, TRUE);
	boardCenterY += projectedY(boardLeft, iLeftBottom, TRUE);
	boardCenterY += projectedY(boardRight, iRightTop, TRUE);
	boardCenterY += projectedY(boardRight, iRightBottom, TRUE);
	boardCenterX /= 4;
	boardCenterY /= 4;
	printLog("   Detected board strokes: Left %d, Right %d, Top %d, Bottom %d, with center (%.3f, %.3f)\n", \
	         leftIdx, rightIdx, topIdx, bottomIdx, boardCenterX, boardCenterY);
}
Esempio n. 13
0
Intersection* Plane3D::testRayIntersection(Ray r)
{
	/*std::cout << "ray start pos " << r.startPosition.x << " " << r.startPosition.y << " " << r.startPosition.z << std::endl;
	std::cout << "ray direction " << r.direction.x << " " << r.direction.y << " " << r.direction.z << std::endl;*/
	//The ray is described by Point on ray = start(O) + direction(D) * t
	//If a point B on the ray hits a surface it must be inside the plane of that surface
	//We can check if B is inside the surface by making a vector between a point on the surface(A) and B
	//and dot multiply it with the plan's normal and see if it becomes zero
	//(A-B)*n = 0
	//Then the point B is on the plane

	//We want to know at what t-value we get a point B on the ray that is inside the plane
	//After some calculations this formula was found
	//t = (O - A) dot n / D dot n

	//translate the plane to it's local coordinate system rotate it and tranlate it back
	glm::mat4 translation = glm::translate(glm::mat4(1.f), -position);
	glm::mat4 translationBack = glm::translate(glm::mat4(1.f), position);
	glm::mat4 rotat = glm::rotate(glm::rotate(glm::rotate(glm::mat4(1.f), -rotation.x, glm::vec3(1, 0, 0)), -rotation.y, glm::vec3(0, 1, 0)), -rotation.z, glm::vec3(0, 0, 1));
	glm::mat4 toLocal = rotat * translation;

	glm::vec4 temp(translationBack * toLocal * glm::vec4(position + glm::vec3(-dimensions.x / 2, -dimensions.y / 2, 0), 1));
	glm::vec3 lowerLeftCorner(temp.x, temp.y, temp.z);
	temp = glm::vec4(translationBack * toLocal * glm::vec4(position + glm::vec3(dimensions.x / 2, -dimensions.y / 2, 0), 1));
	glm::vec3 lowerRightCorner(temp.x, temp.y, temp.z);
	temp = glm::vec4(translationBack * toLocal * glm::vec4(position + glm::vec3(-dimensions.x / 2, dimensions.y / 2, 0), 1));
	glm::vec3 upperLeftCorner(temp.x, temp.y, temp.z);

	//Find plane normal
	glm::vec3 planeNormal(glm::normalize(glm::cross(lowerRightCorner - lowerLeftCorner, upperLeftCorner - lowerLeftCorner)));

	/*std::cout << "lower left " << lowerLeftCorner.x << " " << lowerLeftCorner.y << " " << lowerLeftCorner.z << std::endl;
	std::cout << "lower right " << lowerRightCorner.x << " " << lowerRightCorner.y << " " << lowerRightCorner.z << std::endl;
	std::cout << "upper left " << upperLeftCorner.x << " " << upperLeftCorner.y << " " << upperLeftCorner.z << std::endl;
	std::cout << "ray start pos " << r.startPosition.x << " " << r.startPosition.y << " " << r.startPosition.z << std::endl;
	std::cout << "ray direction " << r.direction.x << " " << r.direction.y << " " << r.direction.z << std::endl;*/

	//If D dot n == 0 the direction goes along the plane and the ray won't hit the plane
	//If D dot n < 0 the surface can't be seen from the ray's starting point
	//But if the ray is a shadow ray it doesn't matter if we can't see the object, just that it is in the way
	float DdotN = glm::dot(-r.direction, planeNormal);
	if (r.shadowRay)
	{
		if (DdotN < EPSILON && DdotN > -EPSILON)
			return nullptr;
	}
	else
		if (DdotN < EPSILON){
			//std::cout << "DdotN <= 0 " << std::endl;
			return nullptr;
		}

	//std::cout << "ray direction " << r.direction.x << " " << r.direction.y << " " << r.direction.z << std::endl;
	//std::cout << "planeNormal " << planeNormal.x << " " << planeNormal.y << " " << planeNormal.z << std::endl;
	//Find point inside plane -> position, which is the center of the plane
	//Find intersection
	float t;
	if (r.startPosition - position != planeNormal)
	{
		t = glm::dot(r.startPosition - position, planeNormal) / DdotN;
		//std::cout << "1t = " << t << std::endl;
	}
	else
	{
		glm::vec3 temp = r.startPosition - lowerLeftCorner;
		//std::cout << "vector on plane? " << temp.x << " " << temp.y << " " << temp.z << std::endl;
		t = glm::dot(r.startPosition - lowerLeftCorner, planeNormal) / DdotN;
		//std::cout << "2t = " << t << " dot " << glm::dot(r.startPosition - lowerLeftCorner, planeNormal) << std::endl;
	}

	//If t < 0 the plane is behind or inside the ray origin and we aren't interested in it
	if (t < EPSILON){
		//std::cout << "t <= 0 " << std::endl;
		return nullptr;
	}

	//Is B inside the surface bounds?
	//Create vectors that decribe the bounds
	//"Inside" is on the right side of the vector
	temp = glm::vec4(translationBack * toLocal * glm::vec4(position + glm::vec3(dimensions.x / 2, dimensions.y / 2, 0), 1));
	glm::vec3 upperRightCorner(temp.x, temp.y, temp.z);
	//std::cout << "upper right " << upperRightCorner.x << " " << upperRightCorner.y << " " << upperRightCorner.z << std::endl;

	glm::vec3 leftSide(upperLeftCorner - lowerLeftCorner);
	glm::vec3 topSide(upperRightCorner - upperLeftCorner);
	glm::vec3 rightSide(lowerRightCorner - upperRightCorner);
	glm::vec3 bottomSide(lowerLeftCorner - lowerRightCorner);

	//To know if B is on the correct side of the vector we take the cross product of
	//the bounding vector and a vector from the same starting point as the bounding vector and ends in B
	//If the result is a vector along the plane's normal, the point B is on the correct side of the bounding vector
	//If the result is a vector against the plane's normal the point is on the wrong side
	//To know if the vector is going along the normal we take the dot product between them
	//If it is larger than zero they go with each other

	//leftSide
	glm::vec3 B(r.startPosition + t * r.direction);
	glm::vec3 Bvector(B - lowerLeftCorner);
	if (glm::dot(glm::cross(Bvector, leftSide), planeNormal) > 0)
	{
		//topSide
		Bvector = glm::vec3(B - upperLeftCorner);
		if (glm::dot(glm::cross(Bvector, topSide), planeNormal) > 0)
		{
			//rightSide
			Bvector = glm::vec3(B - upperRightCorner);
			if (glm::dot(glm::cross(Bvector, rightSide), planeNormal) > 0)
			{
				//bottomSide
				Bvector = glm::vec3(B - lowerRightCorner);
				if (glm::dot(glm::cross(Bvector, bottomSide), planeNormal) > 0)
				{
					// If the object is blocked
					if (t > r.tMax){
						//std::cout << "t > r.tMax" << std::endl;
						return nullptr;
					}

					//else
					r.tMax = t;
					glm::vec3 intersectionPoint(r.startPosition + t * r.direction);
					//std::cout << "intersected object" << std::endl;
					return new Intersection(intersectionPoint, planeNormal, color, reflectionCoef, t);
				}
			}
		}
	}

	//std::cout << "not inside bounds" << std::endl;
	return nullptr;
}
Esempio n. 14
0
 ///
 /// \brief Get the intersection point between an AABB and a Ray
 ///
 static std::pair<bool, float> intersectionPoint(const Ray& r, const AABB& b) {
     return intersectionPoint(b, r);
 }
intersectionPoint boundingVolumeHierarchy::intersect(const ray& r) const
{
  if(_root->isBoundingBoxHit(r)) return _root->intersect(r, *_mesh);
  else return intersectionPoint();
}