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; }
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; }
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; }