Пример #1
0
void PointLightInteractionHandler::setLightPosFromScreenCoords(const vec2& normalizedScreenCoord) {
    vec2 deviceCoord(2.f * (normalizedScreenCoord - 0.5f));
    // Flip vertical axis since mouse event y position starts at top of screen
    deviceCoord.y *= -1.f;
    // Use half distance between look from and look to positions as scene radius.
    float sceneRadius = 0.5f * glm::length(camera_->getLookTo() - camera_->getLookFrom());
    vec3 rayOrigin = camera_->getWorldPosFromNormalizedDeviceCoords(vec3(deviceCoord, 0.f));
    vec3 rayDir = glm::normalize(
        camera_->getWorldPosFromNormalizedDeviceCoords(vec3(deviceCoord, 1.f)) - rayOrigin);
    float t0 = 0, t1 = std::numeric_limits<float>::max();
    float lightRadius = glm::length(lightPosition_->get());

    if (raySphereIntersection(vec3(0.f), sceneRadius, rayOrigin, rayDir, &t0, &t1)) {
        lightPosition_->set(glm::normalize(rayOrigin + t1 * rayDir) * lightRadius);
    } else {
        // Project it to the rim of the sphere
        t0 = 0;
        t1 = std::numeric_limits<float>::max();
        if (rayPlaneIntersection(camera_->getLookTo(),
                                 glm::normalize(camera_->getLookTo() - camera_->getLookFrom()),
                                 rayOrigin, rayDir, &t0, &t1)) {
            // Project it to the edge of the sphere
            lightPosition_->set(glm::normalize(rayOrigin + t1 * rayDir) * lightRadius);
        }
    }
    // Ensure that up vector is same as camera afterwards
    setLookUp(camera_->getLookUp());
}
Пример #2
0
/* @param t distance */
static intersection ray_hit_object(const point3 e, const point3 d,
                                   double t0, double t1,
                                   const rectangular_node rectangulars,
                                   rectangular_node *hit_rectangular,
                                   const sphere_node spheres,
                                   sphere_node *hit_sphere)
{
    /* set these to not hit */
    *hit_rectangular = NULL;
    *hit_sphere = NULL;

    point3 biased_e;
    multiply_vector(d, t0, biased_e);
    add_vector(biased_e, e, biased_e);

    double nearest = t1;
    intersection result, tmpresult;

    for (rectangular_node rec = rectangulars; rec; rec = rec->next) {
        if (rayRectangularIntersection(biased_e, d, &(rec->element),
                                       &tmpresult, &t1) && (t1 < nearest)) {
            /* hit is closest so far */
            *hit_rectangular = rec;
            nearest = t1;
            result = tmpresult;
        }
    }

    /* check the spheres */
    for (sphere_node sphere = spheres; sphere; sphere = sphere->next) {
        if (raySphereIntersection(biased_e, d, &(sphere->element),
                                  &tmpresult, &t1) && (t1 < nearest)) {
            *hit_sphere = sphere;
            *hit_rectangular = NULL;
            nearest = t1;
            result = tmpresult;
        }
    }

    return result;
}
Пример #3
0
//Ray-Object intersection--------------------------------------------------------------------------
float rayObjectIntersection(Ray ray, SPHERE sphere, POLY4 poly, Point3dPtr n, Point3dPtr interp, float * kd)
{
	float t1, t2;		// The two distances;
	float *kd1, *kd2;

	Point3dPtr n1, n2, interp1, interp2;
	n1 = (Point3dPtr)malloc(sizeof(Point3d));
	n2 = (Point3dPtr)malloc(sizeof(Point3d));
	interp1 = (Point3dPtr)malloc(sizeof(Point3d));
	interp2 = (Point3dPtr)malloc(sizeof(Point3d));
	kd1 = (float*)malloc(sizeof(*kd1));
	kd2 = (float*)malloc(sizeof(*kd2));

	t1 = raySphereIntersection(ray, sphere, n1, interp1, kd1);
	t2 = rayPolygonIntersection(ray, poly, n2, interp2, kd2);

	if (t1 == 0.0 && t2 == 0.0)
		return 0.0;
	else if (t2 == 0)
	{
		//the normal = n1;
		n->x = n1->x;
		n->y = n1->y;
		n->z = n1->z;

		//the intersection point = interp1;
		interp->x = interp1->x;
		interp->y = interp1->y;
		interp->z = interp1->z;

		*kd = *kd1;
		return t1;
	}
	else if (t1 == 0.0)
	{
		//the normal = n2;
		n->x = n2->x;
		n->y = n2->y;
		n->z = n2->z;

		//the intersection point = interp2;
		interp->x = interp2->x;
		interp->y = interp2->y;
		interp->z = interp2->z;

		*kd = *kd2;
		return t2;
	}
	else if (t1 < t2)
	{
		//the normal = n1;
		n->x = n1->x;
		n->y = n1->y;
		n->z = n1->z;

		//the intersection point = interp1;
		interp->x = interp1->x;
		interp->y = interp1->y;
		interp->z = interp1->z;

		*kd = *kd1;
		return t1;
	}
	else
	{
		//the normal = n2;
		n->x = n2->x;
		n->y = n2->y;
		n->z = n2->z;

		//the intersection point = interp2;
		interp->x = interp2->x;
		interp->y = interp2->y;
		interp->z = interp2->z;

		*kd = *kd2;
		return t2;
	}
	free(n1);
	free(n2);
	free(interp1);
	free(interp2);
	free(kd1);
	free(kd2);
}