Beispiel #1
0
static void compute_uvw_vectors(struct Camera *cam)
{
	double halfu, halfv;
	int i;

	/* assumes dir and up are normalized */
	VEC3_COPY(cam->wvec, cam->dir);
	VEC3_NORMALIZE(cam->wvec);

	VEC3_CROSS(cam->uvec, cam->wvec, cam->up);
	VEC3_NORMALIZE(cam->uvec);

	VEC3_CROSS(cam->vvec, cam->uvec, cam->wvec);
	VEC3_NORMALIZE(cam->vvec);

	halfv = tan(RADIAN(cam->fov/2));
	halfu = halfv * cam->aspect;

	for (i = 0; i < 3; i++) {
		cam->scrn_bottom_left[i] = cam->center[i] +
				cam->wvec[i] -
				halfu * cam->uvec[i] -
				halfv * cam->vvec[i];
	}

	VEC3_MUL_ASGN(cam->uvec, 2 * halfu);
	VEC3_MUL_ASGN(cam->vvec, 2 * halfv);
}
static void MyEvaluate(const void *self, const struct TraceContext *cxt,
		const struct SurfaceInput *in, struct SurfaceOutput *out)
{
	const struct ConstantShader *constant = NULL;
	float C_tex[3] = {0};

	constant = (struct ConstantShader *) self;

	/* C_tex */
	if (constant->texture != NULL) {
		TexLookup(constant->texture, in->uv[0], in->uv[1], C_tex);
		C_tex[0] *= constant->diffuse[0];
		C_tex[1] *= constant->diffuse[1];
		C_tex[2] *= constant->diffuse[2];
	}
	else {
		C_tex[0] = constant->diffuse[0];
		C_tex[1] = constant->diffuse[1];
		C_tex[2] = constant->diffuse[2];
	}

	/* Cs */
	VEC3_COPY(out->Cs, C_tex);
	out->Os = 1;
}
static int set_diffuse(void *self, const struct PropertyValue *value)
{
	struct ConstantShader *constant = (struct ConstantShader *) self;
	float diffuse[3] = {0};

	diffuse[0] = MAX(0, value->vector[0]);
	diffuse[1] = MAX(0, value->vector[1]);
	diffuse[2] = MAX(0, value->vector[2]);
	VEC3_COPY(constant->diffuse, diffuse);

	return 0;
}
Beispiel #4
0
void CamGetRay(const struct Camera *cam, const double *screen_uv, struct Ray *ray)
{
	int i;
	for (i = 0; i < 3; i++) {
		ray->dir[i] =
				cam->scrn_bottom_left[i] +
				screen_uv[0] * cam->uvec[i] +
				screen_uv[1] * cam->vvec[i] -
				cam->center[i];
	}
	VEC3_NORMALIZE(ray->dir);
	VEC3_COPY(ray->orig, cam->center);
	ray->tmin = cam->znear;
	ray->tmax = cam->zfar;
}
Beispiel #5
0
void CamGetRay(const struct Camera *cam, const double *screen_uv,
		double time, struct Ray *ray)
{
	const struct Transform *transform_interp = get_interpolated_transform(cam, time);
	double target[3] = {0, 0, 0};
	double eye[3] = {0, 0, 0};

	compute_ray_target(cam, screen_uv, target);
	XfmTransformPoint(transform_interp, target);
	XfmTransformPoint(transform_interp, eye);

	VEC3_SUB(ray->dir, target, eye);
	VEC3_NORMALIZE(ray->dir);
	VEC3_COPY(ray->orig, eye);

	ray->tmin = cam->znear;
	ray->tmax = cam->zfar;
}
/*
 * Function:	vdsClusterOctree
 * Description:	Builds an octree over the given leaf nodes using
 *		vdsClusterNodes().  Takes an array <nodes> of vdsNode pointers
 *		that represent vertices in the original model (i.e., leaf nodes
 *		in the vertex tree to be generated).  This array is partitioned
 *		into eight subarrays by splitting across the x, y, and z
 *		midplanes of the tightest-fitting bounding cube, and
 *		vdsClusterOctree() is called recursively on each subarray.
 *		Finally, vdsClusterNodes() is called on the 2-8 nodes returned
 *		by these recursive calls, and vdsClusterOctree returns the newly
 *		created internal node.
 */
vdsNode *vdsClusterOctree(vdsNode **nodes, int nnodes, int depth)
{
    vdsNode *thisnode;
    vdsNode *children[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
    int nchildren = 0;
    vdsNode **childnodes[8];
    int nchildnodes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    int i, j;
    vdsVec3 min, max, center, average = {0, 0, 0};

    assert(depth < VDS_MAXDEPTH);
    /* Overestimate array size needs for childnodes now; shrink later */
    for (i = 0; i < 8; i++) {
	childnodes[i] = (vdsNode **) malloc(sizeof(vdsNode *) * nnodes);
	assert(childnodes[i] != NULL);
    }
    /* Find the min and max bounds of nodes, and accumulate average coord */
    VEC3_COPY(min, nodes[0]->coord);
    VEC3_COPY(max, nodes[0]->coord);
    for (i = 0; i < nnodes; i++) {
	for (j = 0; j < 3; j++) {
	    if (nodes[i]->coord[j] > max[j]) {
		max[j] = nodes[i]->coord[j];
	    }
	    if (nodes[i]->coord[j] < min[j]) {
		min[j] = nodes[i]->coord[j];
	    }
	}
	VEC3_ADD(average, average, nodes[i]->coord);
    }
    VEC3_SCALE(average, 1.0 / (float) nnodes, average);
    VEC3_AVERAGE(center, min, max);
    if (VEC3_EQUAL(min, max)) {
	/* vertices coincide, just partition evenly among children */
	for (i = 0; i < nnodes; i++) {
	    int index = i % VDS_MAXDEGREE;
	    childnodes[index][nchildnodes[index]] = nodes[i];
	    nchildnodes[index] ++;
	}
    } else {
	/* Partition the nodes among the 8 octants defined by min and max */
	for (i = 0; i < nnodes; i++) {
	    int whichchild = 0;
	    if (nodes[i]->coord[0] > center[0]) {
		whichchild |= 1;
	    }
	    if (nodes[i]->coord[1] > center[1]) {
		whichchild |= 2;
	    }
	    if (nodes[i]->coord[2] > center[2]) {
		whichchild |= 4;
	    }

	    childnodes[whichchild][nchildnodes[whichchild]] = nodes[i];
	    nchildnodes[whichchild] ++;
	}
    }
    /* Resize childnodes arrays to use only as much space as necessary */
    for (i = 0; i < 8; i++) {
	childnodes[i] = (vdsNode **)
		realloc(childnodes[i], sizeof(vdsNode *) * nchildnodes[i]);
    }
    /* Recurse or store non-empty children */
    for (i = 0; i < 8; i++) {
	if (nchildnodes[i] > 0) {
	    if (nchildnodes[i] == 1) {	/* 1 node in octant; store directly  */
		children[nchildren] = childnodes[i][0];
	    } else {		/* 2 or more nodes in octant; recurse*/
		children[nchildren] =
		    vdsClusterOctree(childnodes[i], nchildnodes[i], depth + 1);
	    }
	    nchildren++;
	}

    }
    /* Finally, cluster nonempty children; this node is the resulting parent */
    thisnode = vdsClusterNodes(nchildren, children,
		       average[0], average[1], average[2]);
    for (i = 0; i < 8; i++) {
	if (nchildnodes[i]) {
	    free(childnodes[i]);
	}
    }
    return thisnode;
}