Esempio n. 1
0
/**
 * Determines whether point is within the object or on the surface
 * @param point :: Point to be tested
 * @returns true if point is within object or on surface
 */
bool MeshObject::isValid(const Kernel::V3D &point) const {

  BoundingBox bb = getBoundingBox();
  if (!bb.isPointInside(point)) {
    return false;
  }

  Kernel::V3D direction(0.0, 0.0, 1.0); // direction to look for intersections
  std::vector<Kernel::V3D> intersectionPoints;
  std::vector<TrackDirection> entryExitFlags;

  getIntersections(point, direction, intersectionPoints, entryExitFlags);

  if (intersectionPoints.empty()) {
    return false;
  }

  // True if point is on surface
  for (const auto &intersectionPoint : intersectionPoints) {
    if (point.distance(intersectionPoint) < M_TOLERANCE) {
      return true;
    }
  }

  // Look for nearest point then check its entry-exit flag
  double nearestPointDistance = point.distance(intersectionPoints[0]);
  size_t nearestPointIndex = 0;
  for (size_t i = 1; i < intersectionPoints.size(); ++i) {
    if (point.distance(intersectionPoints[i]) < nearestPointDistance) {
      nearestPointDistance = point.distance(intersectionPoints[i]);
      nearestPointIndex = i;
    }
  }
  return (entryExitFlags[nearestPointIndex] == TrackDirection::LEAVING);
}
Esempio n. 2
0
/**
 * Determines wither point is on the surface.
 * @param point :: Point to check
 * @returns true if the point is on the surface
 */
bool MeshObject::isOnSide(const Kernel::V3D &point) const {

  BoundingBox bb = getBoundingBox();
  if (!bb.isPointInside(point)) {
    return false;
  }

  const std::vector<Kernel::V3D> directions = {
      Kernel::V3D{0, 0, 1}, Kernel::V3D{0, 1, 0},
      Kernel::V3D{1, 0, 0}}; // directions to look for intersections
  // We have to look in several directions in case a point is on a face
  // or edge parallel to the first direction or also the second direction.
  for (const auto &direction : directions) {
    std::vector<Kernel::V3D> intersectionPoints;
    std::vector<TrackDirection> entryExitFlags;

    getIntersections(point, direction, intersectionPoints, entryExitFlags);

    if (intersectionPoints.empty()) {
      return false;
    }

    for (const auto &intersectionPoint : intersectionPoints) {
      if (point.distance(intersectionPoint) < M_TOLERANCE) {
        return true;
      }
    }
  }
  return false;
}
Esempio n. 3
0
/**
 * Given a track, fill the track with valid section
 * @param UT :: Initial track
 * @return Number of segments added
 */
int MeshObject::interceptSurface(Geometry::Track &UT) const {

  int originalCount = UT.count(); // Number of intersections original track
  BoundingBox bb = getBoundingBox();
  if (!bb.doesLineIntersect(UT)) {
    return 0;
  }

  std::vector<Kernel::V3D> intersectionPoints;
  std::vector<TrackDirection> entryExit;

  getIntersections(UT.startPoint(), UT.direction(), intersectionPoints,
                   entryExit);
  if (intersectionPoints.empty())
    return 0; // Quit if no intersections found

  // For a 3D mesh, a ray may intersect several segments
  for (size_t i = 0; i < intersectionPoints.size(); ++i) {
    UT.addPoint(entryExit[i], intersectionPoints[i], *this);
  }
  UT.buildLink();

  return UT.count() - originalCount;
}
Esempio n. 4
0
	Vector3d traceRay(Ray* ray, vector<SceneObject*>* objects, vector<SceneObject*>* lights, int remainingDepth) {
		Vector3d backgroundColour(0, 0, 0);
		Vector3d ambientLight(25, 25, 25);

		/*Vector3d RED(255, 0, 0);
		Vector3d GREEN(0, 255, 0);
		Vector3d BLUE(255, 0, 255);
		Vector3d YELLOW(255, 255, 0);
		Vector3d CYAN(0, 255, 255);
		Vector3d MAJENTA(255, 0, 255);*/

		if (remainingDepth <= 0)
			return backgroundColour;

		vector<Intersection*>* intersections = getIntersections(objects, ray, NULL, false, (remainingDepth < 2));
		Intersection* closestIntersection = getClosestIntersection(ray->origin, intersections);
		Vector3d closestOrigin;
		Vector3d closestDirection;
		SceneObject* closestObject;

		if (closestIntersection != NULL) {
			closestOrigin = *(closestIntersection->origin);
			closestDirection = *(closestIntersection->direction);
			closestObject = closestIntersection->object;
		}

		freeIntersections(intersections);
		intersections->clear();
		delete intersections;

		if (closestIntersection != NULL) {
			Vector3d fullLightColour = ambientLight;
			Vector3d surfaceColour = *(closestIntersection->object->colour);

			//for each light, add it to the full light on this point (if not blocked)
			for (unsigned int lightNum = 0; lightNum < lights->size(); lightNum++) {
				SceneObject* light = (*lights)[lightNum];
				Vector3d toLight = *(light->position) - closestOrigin;
				Vector3d toLightNormalized = toLight.normalized();
				double dot = toLightNormalized.dot(closestDirection);

				if (dot > 0) {
					intersections = getIntersections(objects, new Ray(&closestOrigin, &toLightNormalized), closestObject, true, false);
					bool inLight = false;
					if (intersections->size() == 0) {
						inLight = true;
					}
					else {
						Intersection* intersection = (*intersections)[0];
						Vector3d intersectionOrigin = Vector3d(*(intersection->origin));
						Vector3d intersectionDirection = Vector3d(*(intersection->direction));
						SceneObject* obj = intersection->object;

						if ((intersectionOrigin - closestOrigin).norm() > toLight.norm()) {
							inLight = true;
						}
					}

					if (inLight) {
						fullLightColour += *(light->colour) * dot;
					}

					freeIntersections(intersections);
					intersections->clear();
					delete intersections;
				}
			}

			double reflectivity = closestObject->reflectivity;
			if (reflectivity > 0) {
				Vector3d rayDirection = *(ray->direction);
				Vector3d normal = closestDirection;
				Vector3d reflectedDirection = rayDirection - ((2 * (normal.dot(rayDirection))) * normal);
				Ray* reflectedRay = new Ray(&closestOrigin, &reflectedDirection);

				Vector3d reflectionColour = traceRay(reflectedRay, objects, lights, remainingDepth - 1);
				delete reflectedRay;

				surfaceColour *= 1 - reflectivity;
				surfaceColour += reflectionColour * reflectivity;
			}

			Vector3d endColour = surfaceColour;
			endColour[0] *= fullLightColour[0] / 255;
			endColour[1] *= fullLightColour[1] / 255;
			endColour[2] *= fullLightColour[2] / 255;

			return endColour;
		}
		else {
			return backgroundColour;
		}
	}