bool EQPhysics::GetRaycastClosestHit(const glm::vec3 & src, const glm::vec3 & dest, glm::vec3 &hit, std::string *name, EQPhysicsFlags flag) const
{
	btVector3 src_bt(src.x, src.y, src.z);
	btVector3 dest_bt(dest.x, dest.y, dest.z);

	btCollisionWorld::ClosestRayResultCallback ray_hit(src_bt, dest_bt);
	ray_hit.m_collisionFilterGroup = (short)flag;
	ray_hit.m_collisionFilterMask = (short)flag;
	ray_hit.m_flags |= 1;

	imp->collision_world->rayTest(src_bt, dest_bt, ray_hit);

	if (ray_hit.hasHit()) {
		hit.x = ray_hit.m_hitPointWorld.x();
		hit.y = ray_hit.m_hitPointWorld.y();
		hit.z = ray_hit.m_hitPointWorld.z();
		if (name) {
			GetEntityHit(ray_hit.m_collisionObject, *name);
		}
		return true;
	}

	hit.x = 0.0f;
	hit.y = 0.0f;
	hit.z = 0.0f;
	return false;
}
Exemple #2
0
/*
 * Trace a ray, calculating the color of this ray.
 * This function is called recursively for recursive light.
 *
 * @param scene     The scene object, which contains all geometries information.
 * @param recursion The level of recursive light. If the level is larger or 
 *                  equal to 4, stop recursion.
 * @param ray_dir   Direction vector of ray.
 * @param ray_pos   Start point of ray.
 * @param tMin      Minimum legal time cost for this ray.
 * @param tMax      Maximum legal time cost for this ray.
 *
 * @return  The color of this ray.
 */
Color3 Raytracer::trace_ray(Scene const*scene,      // geometries
                            const int recursion,    // recursion level
                            const Vector3 &ray_dir, const Vector3 &ray_pos, // ray
                            const float tMin,       const float tMax        // ray range
                           )
{
    // if this function go beyond the last recursive level, stop and return black color.
    if (recursion <= 0)
        return Color3(0, 0, 0);

    // intersection point information
    HitVertexInfor hit_vertex;

    // if not hit any geometry, return background color
    bool bHit = ray_hit(scene, ray_dir, ray_pos, tMin, tMax, hit_vertex);
    if (!bHit)
        return scene->background_color;

    // if hit, compute color and return it
    Color3 DI_light (0, 0, 0);
    Color3 reflected_light(0, 0, 0);
    Color3 refracted_light(0, 0, 0);

    // 1. direct illumination
    if (hit_vertex.refractive_index == 0)
        DI_light = calculate_DI_light(scene, hit_vertex);

    // 2. reflection light
    if (hit_vertex.specular != Color3(0, 0, 0)) // avoid non-necessary reflection calculation
    {
        // reflection ray direction
        Vector3 rfl_ray_dir = normalize(
            ray_dir - 2 * dot(ray_dir, hit_vertex.normal) * hit_vertex.normal);

        reflected_light = hit_vertex.specular * hit_vertex.tex_color *
                          trace_ray(scene, recursion-1, rfl_ray_dir, hit_vertex.position,
                                    SLOPE_FACTOR, 1000000);
    }

    if (hit_vertex.refractive_index == 0)   // avoid non-necessary refraction calculation
        return DI_light + reflected_light;

    // 3. refraction light
    Vector3 rfr_ray_dir; // refractive ray direction
    float R;
    if (refraction_happened(scene, ray_dir, hit_vertex, rfr_ray_dir, R))
        refracted_light = hit_vertex.tex_color *
                          trace_ray(scene, recursion-1, rfr_ray_dir, hit_vertex.position, 
                                    SLOPE_FACTOR, 1000000);

    return DI_light + R * reflected_light + (1-R) * refracted_light;
}
Exemple #3
0
/* 
 * Calculate direct illumination light.
 *
 * @param scene         The scene object, which contains all geometries 
 *                      information.
 * @param hit_vertex    A struct storing all useful intersection point 
 *                      information.
 *
 * @return Direct illumination color.
 */
Color3 Raytracer::calculate_DI_light(Scene const*scene, 
                                     const HitVertexInfor &hit_vertex)
{
    // ambient light
    Color3 ambient_light = hit_vertex.ambient * scene->ambient_light;

    // accumulate all point light diffuse components
    Color3 diffuse_light(0, 0, 0);
    const PointLight* pPointLights = scene->get_lights();
    for (size_t i=0; i<scene->num_lights(); i++)
    {
        // point light
        PointLight point_light = pPointLights[i];

        // ray from hit point to light
        Vector3 shadow_ray_pos = hit_vertex.position;
        Vector3 shadow_ray_dir = point_light.position - shadow_ray_pos;
        real_t distance = length(shadow_ray_dir);
        shadow_ray_dir = normalize(shadow_ray_dir);

        // shadow ray hit test
        HitVertexInfor tmp_hit_vertex; // temp variable, didn't use it actually
        bool bExistObstacle = ray_hit(scene, shadow_ray_dir, shadow_ray_pos,
            distance/1000000, distance, tmp_hit_vertex);

        // if did not hit other geometry, accumulate diffuse light
        if (!bExistObstacle)
        {
            diffuse_light += point_light.get_attenuation_color(distance) *
                             hit_vertex.diffuse *
                             std::max(dot(hit_vertex.normal, shadow_ray_dir), 0.0f);
        }
    }

    // final direct illumination is multiplication of texture color and diffuse light
    return hit_vertex.tex_color * (ambient_light + diffuse_light);
}