Example #1
0
Intersection Model::intersect(Ray r) {
	Intersection xsect;
	xsect.init();

	Vector3 e = invMat.transform_point(r.e);
	Vector3 d = normalize(invMat.transform_vector(r.d));
	Mesh::MeshTriangleList m;
	m = kdtree->Test(e, d);

	real_t min_dis = 9999999.9;

	// Convert each triangle into a "Triangle" Class object, and pass
	// it to that class's intersection test. Yay DRY.
	for (size_t i = 0; i < m.size(); i++) {
		MeshTriangle tri = m[i];
		Triangle t;
		for (size_t j = 0; j < 3; j++) {
			Triangle::Vertex& tv = t.vertices[j];
			const MeshVertex& mv = mesh->vertices[tri.vertices[j]];
			tv.position = mv.position;
			tv.normal = mv.normal;
			tv.tex_coord = mv.tex_coord;
			tv.material = material;
		}
		t.position = position;
		t.orientation = orientation;
		t.scale = scale;
		t.invMat = invMat;
		t.normMat = normMat;
		Intersection ti = t.intersect(r);
		if (ti.exists && ti.squared_dist < min_dis) {
			min_dis = ti.squared_dist;
			xsect = ti;
		}
	}
	return xsect;
}
Example #2
0
Intersection Triangle::intersect(Ray r) {
    Intersection xsect;
    xsect.init();

    real_t min_dis = 999999.9;
    Vector3 e = invMat.transform_point(r.e);
    Vector3 d = normalize(invMat.transform_vector(r.d));

    Vector3 abc = vertices[0].position - vertices[1].position;
    Vector3 def = vertices[0].position - vertices[2].position;
    Vector3 fed = Vector3(def.z, def.y, def.x);
    Vector3 ghi = d;
    Vector3 ihg = Vector3(ghi.z, ghi.y, ghi.x);
    Vector3 jkl = vertices[0].position - e;

    Vector3 det_1 = Vector3(def.y * ghi.z - ghi.y * def.z, ghi.x * def.z - def.x * ghi.z, def.x * ghi.y - def.y * ghi.x);
    Vector3 det_2 = Vector3(abc.x * jkl.y - jkl.x * abc.y, jkl.x * abc.z - abc.x * jkl.z, abc.y * jkl.z - jkl.y * abc.z);

    // barycentric weighting factors
    real_t M = dot(abc, det_1);
    real_t beta = dot(jkl, det_1) / M;
    real_t gamma = dot(ihg, det_2) / M;
    real_t theta = -1 * dot(fed, det_2) / M;

    if (beta < 0 || beta > 1 - gamma || gamma < 0 || gamma > 1 || theta < epsilon)
        return xsect;

    Matrix4 inv;
    make_transformation_matrix(&inv, position, orientation, scale);

    Vector3 local_pos = e + theta * d;
    Vector3 world_pos = inv.transform_point(local_pos);
    real_t dist = squared_distance(r.e, world_pos);

    if (dist >= min_dis * min_dis) {
        return xsect;
    }

    xsect.squared_dist = dist;
    xsect.position = world_pos;

    Vector3 local_norm = normalize(vertices[0].normal + vertices[1].normal + vertices[2].normal);
    xsect.normal = normalize(normMat * local_norm);

    xsect.exists = true;

    real_t material_mult[3] = {1 - beta - gamma, beta, gamma};

    xsect.mat.black_out();

    Vector2 texel = Vector2::Zero();

    // Use the weighting factors to interpolate values at this point
    for (int i = 0; i < 3; ++i)
    {
        xsect.mat.ambient += vertices[i].material->ambient * material_mult[i];
        xsect.mat.diffuse += vertices[i].material->diffuse * material_mult[i];
        xsect.mat.specular += vertices[i].material->specular * material_mult[i];
        xsect.mat.refractive_index += vertices[i].material->refractive_index * material_mult[i];
        texel += vertices[i].tex_coord * material_mult[i];
    }

    texel.x -= floor(texel.x);
    texel.y -= floor(texel.y);

    int w, h;

    for (int i = 0; i < 3; ++i)
    {
        vertices[i].material->get_texture_size(&w, &h);
        xsect.texel += vertices[i].material->get_texture_pixel((int)(texel.x * w), (int)(texel.y * h)) * material_mult[i];
    }

    return xsect;
}