void Camera::step_throw() { float dist_to_target = distance3(this->pos, *(this->focus)); const float threshold = 130.0f; // throw the camera ahead of bike. if (dist_to_target > threshold) { this->pos[0] = this->focus->at(0) + threshold * this->target_dir->at(0); this->pos[2] = this->focus->at(2) + threshold * this->target_dir->at(1); } }
void point_distances3(miState *state,texture_worleynoise3d_t *param, miVector *pt, miScalar *f1, miVector *p1, miScalar *f2, miVector *p2, miScalar *f3, miVector *p3) { miScalar cube_dist = CUBE_DIST * (*mi_eval_scalar(¶m->scale)); miVector cube = point_cube3(pt,cube_dist); worley_context3 *context; mi_query(miQ_FUNC_TLS_GET, state, miNULLTAG, &context); miInteger dist_measure = *mi_eval_integer(¶m->distance_measure); *f3 = FLT_MAX; *f2 = *f3 - 1; *f1 = *f2 - 1; update_cache3(context, &cube, cube_dist); miVector *cache = context->cacheVals; for(int i=0; i < CACHE_SIZE; ++i) { miVector p = cache[i]; miScalar d = distance3(dist_measure, pt, &p); if(d < *f3) { if(d < *f2) { *f3 = *f2; *p3 = *p2; if(d < *f1) { *f2 = *f1; *p2 = *p1; *f1 = d; *p1 = p; } else { *f2 = d; *p2 = p; } } else { *f3 = d; *p3 = p; } } } }
int get_normal_phi_map(double* phi_map, double* centered_point_map, int* step_up, int* step_down, int height, int width) { int h,w, ph, nh; double * xyz_hw, * xyz_phw, * xyz_nhw; double phi_p, phi_n, phi_c; double dia_p, dia_c, dia_n; double dz_p, dz_n, dz_c, dd_p, dd_n, dd_c; double rad_p,rad_n,rad_c; double dist_p, dist_n, dist_c; int k; xyz_hw = (double *) malloc(3*sizeof(double)); xyz_phw = (double *) malloc(3*sizeof(double)); xyz_nhw = (double *) malloc(3*sizeof(double)); for (w = 0; w < width; w++) { for (h = 0; h < height; h++) { ph = step_up[h*width + w]; nh = step_down[h*width + h]; phi_c = -1000; for (k = 0; k < 3; k++) { xyz_hw[k] = centered_point_map[k*height*width+h*width+w]; xyz_phw[k] = centered_point_map[k*height*width+ph*width+w]; xyz_nhw[k] = centered_point_map[k*height*width+nh*width+w]; } if (norm3(xyz_hw) > 0.01) { dist_p = distance3(xyz_phw,xyz_hw); dist_n = distance3(xyz_hw,xyz_nhw); dist_c = distance3(xyz_phw,xyz_nhw); dia_p = sqrt(pow(xyz_phw[0],2) + pow(xyz_phw[1],2)); dia_c = sqrt(pow(xyz_hw[0],2) + pow(xyz_hw[1],2)); dia_n = sqrt(pow(xyz_nhw[0],2) + pow(xyz_nhw[1],2)); dd_p = dia_p - dia_c; dd_n = dia_c - dia_n; dd_c = dia_p - dia_n; dz_p = xyz_phw[2]-xyz_hw[2]; dz_n = xyz_hw[2]-xyz_nhw[2]; dz_c = xyz_phw[2]-xyz_nhw[2]; rad_p = sqrt(pow(dd_p,2)+pow(dz_p,2)); rad_n = sqrt(pow(dd_n,2)+pow(dz_n,2)); rad_c = sqrt(pow(dd_c,2)+pow(dz_c,2)); phi_p = -asin(dd_p/rad_p); phi_n = -asin(dd_n/rad_n); if (norm3(xyz_nhw) > 0.01 && norm3(xyz_phw) && h > 0 && nh < height && dist_c > 0.01 && rad_c > 0) { phi_c = -asin(dd_c/rad_c); } else if (norm3(xyz_nhw) > 0.01 && nh < height && dist_n > 0.01 && rad_n > 0) { phi_c = -phi_n; } else if (norm3(xyz_phw) > 0.01 && h > 0 && dist_p > 0.01 && rad_p > 0) { phi_c = -phi_p; } } phi_map[h*width+w] = phi_c; } } free(xyz_hw); free(xyz_phw); free(xyz_nhw); }
int get_normal_theta_map(double* theta_map, double* centered_point_map, int* step_left, int* step_right, int height, int width) { int h,w, pw, nw; double * xyz_hw, * xyz_phw, * xyz_nhw; double * pt_p, * pt_n, *pt_c; double theta_p, theta_n, theta_c; double dist_p, dist_n, dist_c; int k; xyz_hw = (double *) malloc(3*sizeof(double)); xyz_phw = (double *) malloc(3*sizeof(double)); xyz_nhw = (double *) malloc(3*sizeof(double)); pt_p = (double *) malloc(2*sizeof(double)); pt_n = (double *) malloc(2*sizeof(double)); pt_c = (double *) malloc(2*sizeof(double)); for (h = 0; h < height; h++) { for (w = 0; w < width; w++) { pw = step_left[height*width + h*width + w]; nw = step_right[height*width + h*width + w]; theta_c = -1000; for (k = 0; k < 3; k++) { xyz_hw[k] = centered_point_map[k*height*width+h*width+w]; xyz_phw[k] = centered_point_map[k*height*width+h*width+pw]; xyz_nhw[k] = centered_point_map[k*height*width+h*width+nw]; } if (norm3(xyz_hw) > 0.01) { direction_between_vectors_phi_theta(pt_p, xyz_phw, xyz_hw); direction_between_vectors_phi_theta(pt_n, xyz_hw, xyz_nhw); direction_between_vectors_phi_theta(pt_c, xyz_phw, xyz_nhw); dist_p = distance3(xyz_phw,xyz_hw); dist_n = distance3(xyz_hw,xyz_nhw); dist_c = distance3(xyz_phw,xyz_nhw); theta_p = pt_p[1]-PI/2; theta_n = pt_n[1]-PI/2; if (norm3(xyz_nhw) > 0.01 && norm3(xyz_phw) && dist_c > 0.01) { theta_c = pt_c[1]-PI/2; } else if (norm3(xyz_nhw) > 0.01 && dist_n > 0.01) { theta_c = theta_n; } else if (norm3(xyz_phw) > 0.01 && dist_p > 0.01) { theta_c = theta_p; } if (theta_c <= -PI && theta_c != -1000) { theta_c = theta_c + 2*PI; } } theta_map[h*width+w] = theta_c; } } free(xyz_hw); free(xyz_phw); free(xyz_nhw); free(pt_p); free(pt_n); }
miScalar worleynoise3d_val(miState *state,texture_worleynoise3d_t *param) { miScalar f1, f2, f3; miVector p1, p2, p3; // ways to get the current point: // state->tex_list[0]; // yields good results only in the x and y coordinate // state->point // usable for 3D, but problematic for getting a smooth 2D texture as x,y and z all have to be somehow incorporated in the 2D vector to use // state->tex // does not yield usable results / seems to be constant // // instead, we just take an u and v value explicitly; they would usually be provided by a 2D placement node. // note: getting current values must always be wrapped in mi_eval... calls! miVector pt; miScalar *m = mi_eval_transform(¶m->matrix); mi_point_transform(&pt,&state->point,m); point_distances3(state,param,&pt,&f1,&p1,&f2,&p2,&f3,&p3); miInteger dist_measure = *mi_eval_integer(¶m->distance_measure); miScalar scale = dist_scale(dist_measure) * (*mi_eval_scalar(¶m->scale)) * (*mi_eval_scalar(¶m->scaleX)); miBoolean jagged = *mi_eval_boolean(¶m->jagged_gap); miScalar s = 1.0; { miScalar gap_size = *mi_eval_scalar(¶m->gap_size); miVector ptX = pt; // jagged edges. useful for broken earth crusts if(jagged) { miVector seed = pt; mi_vector_mul(&seed,3 / scale); miScalar jaggingX = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2; ptX.x += jaggingX; seed.x += 1000; miScalar jaggingY = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2; ptX.y += jaggingY; seed.y += 1000; miScalar jaggingZ = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2; ptX.z += jaggingZ; } miScalar f1X, f2X, f3X; miVector p1X, p2X, p3X; point_distances3(state,param,&ptX,&f1X,&p1X,&f2X,&p2X,&f3X,&p3X); // based on code from "Advanced Renderman" // this leads to gaps of equal width, in contrast to just simple thresholding of f2 - f1. miScalar scaleFactor = (distance3(dist_measure, &p1X, &p2X) * scale) / (f1X + f2X); // FIXME: there may be some adjustment needed for distance measures that are not just dist_linear if(gap_size * scaleFactor > f2X - f1X) // on left side s = -1.0; } { f1 /= scale; f2 /= scale; f3 /= scale; } miScalar dist = 0.0; { miInteger dist_mode = *mi_eval_integer(¶m->distance_mode); switch(dist_mode) { case DIST_F1: dist = f1; break; case DIST_F2_M_F1: dist = f2 - f1; break; case DIST_F1_P_F2: dist = (2 * f1 + f2) / 3; break; case DIST_F3_M_F2_M_F1: dist = (2 * f3 - f2 - f1) / 2; break; case DIST_F1_P_F2_P_F3: dist = (0.5 * f1 + 0.33 * f2 + (1 - 0.5 - 0.33) * f3); break; default: ; } } return s * scaling_function(dist); }