DLLEXPORT void domeAFL_FOV_Stereo_init(
	miState	*state,
	struct dsDomeAFL_FOV_Stereo *params,
	miBoolean *inst_init_req)
{
	if (!params) {
		// version output
		mi_info(_VER_);
		*inst_init_req = miTRUE;
	} else {
		fov_angle = *mi_eval_scalar(&params->FOV_Angle);
		viewport_offset = *mi_eval_vector(&params->View_Offset);
		camera = *mi_eval_integer(&params->Camera);
		dome_radius = *mi_eval_scalar(&params->Dome_Radius);
		dome_tilt = *mi_eval_scalar(&params->Dome_Tilt);
		cameras_separation = *mi_eval_scalar(&params->Cameras_Separation);
		dome_tilt_compensation = *mi_eval_boolean(&params->Dome_Tilt_Compensation);
		vertical_mode = *mi_eval_boolean(&params->Vertical_Mode);
//mi_info("II-> fov=%f,cam=%i,rad=%f,tilt=%f,sep=%f,comp=%i,vert=%i",fov_angle,camera,dome_radius,dome_tilt,cameras_separation,dome_tilt_compensation,vertical_mode);

		// Convert input angles from degrees to radians...
		fov_angle = (miScalar)(fov_angle*M_PI/180.0);
		dome_tilt = (miScalar)(dome_tilt*M_PI/180.0);
	}
}
Exemple #2
0
extern "C" DLLEXPORT miBoolean mib_volume(
	miColor		*result,	/* in: color at far end, out */
	miState		*state,
	struct mib_volume *paras)
{
	miColor		*color;		/* fog color */
	miScalar	max, fade;	/* max opcity distance, fade factor */

	if (!*mi_eval_boolean(&paras->lightrays) && state->type==miRAY_LIGHT)
		return(miTRUE);				/* ignore light rays?*/

	color =  mi_eval_color (&paras->color);
	max   = *mi_eval_scalar(&paras->max);
	if (state->dist <= 0 ||				/* infinite distance */
	    state->dist >= max) {			/* full-opacity dist */
		fade = 1 - color->a;
		result->r = fade * result->r + color->r;
		result->g = fade * result->g + color->g;
		result->b = fade * result->b + color->b;
		result->a = fade * result->a + color->a;
		return(miTRUE);
	}

	fade = (float)state->dist / max;			/* fade to fog color */
	fade = (1 - fade * fade) * color->a;

	result->r = fade * result->r + (1-fade) * color->r;
	result->g = fade * result->g + (1-fade) * color->g;
	result->b = fade * result->b + (1-fade) * color->b;
	result->a = fade * result->a + (1-fade) * color->a;
	return(miTRUE);
}
Exemple #3
0
extern "C" DLLEXPORT miBoolean mib_texture_filter_lookup(
	miColor		*result,
	miState		*state,
	struct mib_texture_filter_lookup *paras)
{
	miTag		tex = *mi_eval_tag(&paras->tex);
	miVector	*coord;
	miUint		space;
	miTag		remap;
	miVector	p[3], t[3];
	miMatrix	ST;
	miTexfilter	ell_opt;
	miScalar	disc_r;

	if (!tex) {
		result->r = result->g = result->b = result->a = 0;
		return(miFALSE);
	}
	coord  = mi_eval_vector(&paras->coord);
	space  = *mi_eval_integer(&paras->space);
	disc_r = *mi_eval_scalar(&paras->disc_r);
	if (disc_r <= 0)
		disc_r = DISC_R;
	if (state->reflection_level == 0 &&
	    mi_texture_filter_project(p, t, state, disc_r, space) &&
	    (remap = *mi_eval_tag(&paras->remap))) {
		mi_call_shader_x((miColor*)&t[0], miSHADER_TEXTURE,
						state, remap, &t[0]);
		mi_call_shader_x((miColor*)&t[1], miSHADER_TEXTURE,
						state, remap, &t[1]);
		mi_call_shader_x((miColor*)&t[2], miSHADER_TEXTURE,
						state, remap, &t[2]);
		if (mi_texture_filter_transform(ST, p, t)) {
			ell_opt.eccmax	  = *mi_eval_scalar(&paras->eccmax);
			ell_opt.max_minor = *mi_eval_scalar(&paras->maxminor);
			ell_opt.bilinear  = *mi_eval_boolean(&paras->bilinear);
			ell_opt.circle_radius = CIRCLE_R;
			/*
			 * when no bump-mapping is used, coord and ST[..]
			 * are identical. for bump mapping, the projection
			 * matrix is calculated for the current raster
			 * position, the ellipse is translated to the
			 * bump position
			 */
			ST[2*4+0] = coord->x;
			ST[2*4+1] = coord->y;
			if (mi_lookup_filter_color_texture(result, state,
							tex, &ell_opt, ST))
				return(miTRUE);
		}
	}
	/* fallback to standard pyramid or nonfiltered texture lookup */
	return(mi_lookup_color_texture(result, state, tex, coord));
}
Exemple #4
0
extern "C" DLLEXPORT miBoolean mib_reflect(
	miColor		*result,
	miState		*state,
	struct mr	*paras)
{
	miBoolean	ok;
	miBoolean	notrace;
	miColor		*reflect =  mi_eval_color(&paras->reflect);
	miColor		inp;
	miVector	dir;
	miScalar	save_ior;

        /* check for illegal calls */
        if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) {
		return(miFALSE);
	}

	if (reflect->r == 0.0 && reflect->g == 0.0 &&
	    reflect->b == 0.0 && reflect->a == 0.0) {
		*result = *mi_eval_color(&paras->input);
		return(miTRUE);
	}
	notrace    = *mi_eval_boolean(&paras->notrace);
	save_ior   = state->ior;
	state->ior = state->ior_in;

	mi_reflection_dir(&dir, state);
	ok = miFALSE;
	if (!notrace &&
	    state->reflection_level < state->options->reflection_depth &&
	    state->reflection_level + state->refraction_level <
						state->options->trace_depth)
		ok = mi_trace_reflection(result, state, &dir);

	if (!ok) {
		miTag savevol = state->volume;
		state->volume = 0;
		ok = mi_trace_environment(result, state, &dir) || !notrace;
		state->volume = savevol;
	}

	if (reflect->r != 1.0 || reflect->g != 1.0 ||
	    reflect->b != 1.0 || reflect->a != 1.0) {
		inp = *mi_eval_color(&paras->input);
		result->r = result->r * reflect->r + inp.r * (1 - reflect->r);
		result->g = result->g * reflect->g + inp.g * (1 - reflect->g);
		result->b = result->b * reflect->b + inp.b * (1 - reflect->b);
		result->a = result->a * reflect->a + inp.a * (1 - reflect->a);
	}
	state->ior = save_ior;
	return(ok);
}
Exemple #5
0
extern "C" DLLEXPORT miBoolean mib_lens_clamp(
	miColor*	result,
	miState*	state,
	mibClamp_t*	paras)
{
	miBoolean 	res;
	miScalar 	f = *mi_eval_scalar(&paras->floor);
	miScalar 	c = *mi_eval_scalar(&paras->ceiling);
	miBoolean	b = *mi_eval_boolean(&paras->luminance);

	if (c == 0.0f) {
		c = 1.0f;
	}
	if (f == c) {
		f = 0.0f;
	}

	res = mi_trace_eye(result, state, &state->org, &state->dir);

	if(b) {
		/* clamp based on luminance. */
		miScalar	lum = mi_luminance(state, result);
	
		if(lum < f) {
			*result = *mi_eval_color(&paras->floor_color);
		} else if (lum > c) {
			*result = *mi_eval_color(&paras->ceil_color);
		} else {
			lum = (lum - f)/(c - f);
			result->r *= lum;
			result->g *= lum;
			result->b *= lum;
		}
	} else {	
		/* clamp based on color components */
		result->r = result->r > f ? 
			(result->r < c ? (result->r-f)/(c-f) : 1) : 0;
		result->g = result->g > f ? 
			(result->g < c ? (result->g-f)/(c-f) : 1) : 0;
		result->b = result->b > f ? 
			(result->b < c ? (result->b-f)/(c-f) : 1) : 0;
	}

	return res;
}
DLLEXPORT miBoolean latlong_lens
(
	miColor * out_pResult,
	miState * state,
	latlong_lens_params * in_pParams
)
{

	miBoolean vmirror;

	miScalar uval, vval, rayx, rayy, rayz;
	miVector raydir, raydir_internal; 



	vmirror = *mi_eval_boolean(&(in_pParams->m_vmirror));

	if (vmirror==miTRUE)
	{
	uval = (state->camera->x_resolution - state->raster_x) / state->camera->x_resolution;
	}
	else
	{
	uval = state->raster_x / state->camera->x_resolution;	
	}

	vval = (state->camera->y_resolution - state->raster_y) / state->camera->y_resolution;

	rayx = (float)(sin(vval*M_PI)*cos(M_PI*(2*uval+0.5))); 
	rayy = (float)(cos(vval*M_PI));
	rayz = (float)(sin(vval*M_PI)*sin(M_PI*(2*uval+0.5)));


	raydir.x = rayx; raydir.y = rayy; raydir.z = rayz;

	mi_vector_from_camera(state, &raydir_internal, &raydir);

  return (mi_trace_eye(out_pResult, state, &state->org, &raydir_internal));


	
}
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(&param->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(&param->distance_measure);
  
  miScalar scale = dist_scale(dist_measure) * (*mi_eval_scalar(&param->scale)) * (*mi_eval_scalar(&param->scaleX));
	miBoolean jagged = *mi_eval_boolean(&param->jagged_gap);
  
  miScalar s = 1.0;
  {
    miScalar gap_size = *mi_eval_scalar(&param->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(&param->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);
}
Exemple #8
0
miBoolean contour_contrast_function_levels(
	miStdInfo	*info1,
	miStdInfo	*info2,
	int		level,
	miState		*state,
	Contour_Contrast_Parameters_Levels *paras)
{

	/*
	 * No contour if level too near or too deep
	 */
	if (level < *mi_eval_integer(&paras->min_level) || 
			*mi_eval_integer(&paras->max_level) < level)
		return(miFALSE);

	/*
	 * Contour if one ray intersected an object and one ray hit background
	 */
	miASSERT(info1 || info2);
	if ((info1 == NULL) != (info2 == NULL))
		return(miTRUE);

	miASSERT(info1 && info2);

	/*
	 * Contour if sufficiently large difference in depth
	 */
	if (fabs(info1->point.z - info2->point.z) > 
				*mi_eval_scalar(&paras->zdelta))
		return(miTRUE);

	/*
	 * Contour if sufficiently large change in normal
	 */
	if (mi_vector_dot(&info1->normal, &info2->normal) <
			cos(*mi_eval_scalar(&paras->ndelta) * M_PI/180.0))
		return(miTRUE);

	/*
	 * Contour if different materials (if specified)
	 */
	if (*mi_eval_boolean(&paras->diff_mat)
				&& info1->material != info2->material)
		return(miTRUE);

	/*
	 * Contour if different object labels (if specified)
	 */
	if (*mi_eval_boolean(&paras->diff_label) 
				&& info1->label != info2->label)
		return(miTRUE);

	/*
	 * Contour if different triangle indices (if specified)
	 */
	if (*mi_eval_boolean(&paras->diff_index) && 
				(info1->index != info2->index ||
				  mi_vector_dot(&info1->normal_geom,
						&info2->normal_geom) < 0.9999))
		return(miTRUE);

	/*
	 * Contour if color contrast (if specified) --- doesn't work properly
	 * on objects behind semitransparent objects since there can be a
	 * contrast on the semistransparent object caused by the color
	 * difference behind it (as a result, it looks like the contrast
	 * shader of the semitransparent object is used on the object behind
	 * even though it isn't).
	 */
	if (*mi_eval_boolean(&paras->contrast) &&
	   (fabs(info1->color.r-info2->color.r) > state->options->contrast.r ||
	    fabs(info1->color.g-info2->color.g) > state->options->contrast.g ||
	    fabs(info1->color.b-info2->color.b) > state->options->contrast.b))
		return(miTRUE);

	/*
	 * No contour otherwise
	 */
	return(miFALSE);
}
DLLEXPORT miBoolean LatLong_Stereo(
	miColor	*result,
	miState	*state,
	struct dsLatLong_Stereo *params)
{
	miScalar	cameras_separation_multiplier = *mi_eval_scalar(&params->Cameras_Separation_Map);
	miScalar	head_tilt = *mi_eval_scalar(&params->Head_Tilt_Map);

	miVector	org, ray, target, htarget;
	miMatrix	tilt;
	double		x, y, phi, theta, tmp;
	double		sinP, cosP, sinT, cosT;

	miBoolean	zenithMode = *mi_eval_boolean(&params->Zenith_Mode);

	// Normalize image coordinates btwn [-1,-1] and [1,1]...
	x = 2.0*state->raster_x/state->camera->x_resolution-1.0;
	y = 2.0*state->raster_y/state->camera->y_resolution-1.0;

	// Calculate phi and theta...
	phi = x*(fov_horiz_angle/2.0);
	if (zenithMode)
		theta = M_PI_2-y*(fov_vert_angle/2.0);
	else
		theta = y*(fov_vert_angle/2.0);

	// Start by matching camera (center camera)
	// mi_point_to_camera(state, &org, &state->org);
	org.x = org.y = org.z = 0.0;

	// Saves common used values for performance reasons
	sinP = sin(phi); cosP = cos(phi);
	sinT = sin(theta); cosT = cos(theta);

	// Center camera target vector (normalized)
	if (zenithMode) {
		target.x = (miScalar)(sinP*sinT);
		target.y = (miScalar)(-cosP*sinT);
		target.z = (miScalar)(-cosT);
	} else {
		target.x = (miScalar)(sinP*cosT);
		target.y = (miScalar)(sinT);
		target.z = (miScalar)(-cosP*cosT);
	}

	if (camera != CENTERCAM) {
		// Camera selection and initial position
		if (camera == LEFTCAM) {
			org.x = (miScalar)(-cameras_separation*cameras_separation_multiplier/2);
		} else if (camera == RIGHTCAM) {
			org.x = (miScalar)(cameras_separation*cameras_separation_multiplier/2);
		}

		// Head rotation = phi
		// Rotate camera
		if (zenithMode) {
			tmp = org.x*cosP-org.y*sinP;
			org.y = (miScalar)(org.y*cosP+org.x*sinP);
			org.x = (miScalar)tmp;
		} else {
			tmp = org.x*cosP-org.z*sinP;
			org.z = (miScalar)(org.z*cosP+org.x*sinP);
			org.x = (miScalar)tmp;
		}

		// Calculate head target
		htarget.x = (miScalar)(sinP*sinT);
		htarget.y = (miScalar)(-cosP*sinT);
		htarget.z = (miScalar)target.z;

		// Head tilt
		head_tilt = (miScalar)((head_tilt-0.5)*M_PI);
		mi_matrix_ident(tilt);
		mi_matrix_rotate_axis(tilt, &htarget, head_tilt);
		mi_vector_transform(&org, &org, tilt);

		// Calculate ray from camera to target
		target.x *= parallax_distance;
		target.y *= parallax_distance;
		target.z *= parallax_distance;
		ray.x = target.x-org.x;
		ray.y = target.y-org.y;
		ray.z = target.z-org.z;
		mi_vector_normalize(&ray);
	} else{		
    // Center camera
    ray = target;
	}

//mi_debug("II->,Phi=%f,Theta=%f,rot=%f,camx=%f,camy=%f", (miScalar)phi, (miScalar)theta, (miScalar)rot, (miScalar)org.x, (miScalar)org.y);

	// Flip the X ray direction about the Y-axis
	if(*mi_eval_boolean(&params->Flip_Ray_X)) { 
		org.x = (-org.x);
		ray.x = (-ray.x);
	}
	// Flip the Y ray direction about the X-axis
	if(*mi_eval_boolean(&params->Flip_Ray_Y)) {
		if(zenithMode) {
			org.z = (-org.z);
			ray.z = (-ray.z);
		} else {
			org.y = (-org.y);
			ray.y = (-ray.y);
		}
	}

  #if 1
    /* Adjust the ray differentials */
    rotate_ray_differentials(state, ray);
  #endif
  
	// Convert ray from camera space
	mi_vector_from_camera(state, &ray, &ray);
	mi_point_from_camera(state, &org, &org);

	// Trace new ray...
	return(mi_trace_eye(result, state, &org, &ray));

}
DLLEXPORT miBoolean domeAFL_FOV(
	miColor	*result,
	miState	*state,
	register struct dsDomeAFL_FOV *params)
{
	miScalar	fov_angle_deg = *mi_eval_scalar(&params->FOV_Angle);
	miGeoScalar	fov_angle_rad;

	miVector	viewpt_offset = *mi_eval_vector(&params->View_Offset);
	miVector	ray;

	miGeoScalar x, y, r, phi, theta;

   	/* normalize image coordinates btwn [-1,1]... */
	/* [ah] Rotate the cartesian axis 90 deg CW   */
	x = -2.0*state->raster_y/state->camera->y_resolution+1.0;
	y = 2.0*state->raster_x/state->camera->x_resolution-1.0;
	
	/* Calcaulate the radius value */
	r = MI_SQRT( ( x * x ) + ( y * y ) );

	if ( r < 1.0 ) {

		/* Calculate phi... */
		if ( (r > -EPSILON) && (r < EPSILON) ) {
			phi = 0.0;
		} else {
			phi = atan2(x,y);	// [rz] using atan2 instead of original if-then formula
		}

		/* Convert FOV angle of fisheye from degrees to radians... */
		fov_angle_rad = fov_angle_deg * M_PI / 180.0;

		/* Calculate theta... */
		
		theta = r * ( fov_angle_rad / 2.0 );

		/* Calculate Ray direction vector... */
		ray.x = (float)(sin(theta) * cos(phi));
		ray.y = (float)(-sin(theta) * sin(phi));
			/* -Z is Look At Direction*/
		ray.z = (float)(-cos(theta));

		/* Account for view offset... */
   		/* Offset is added to y & z components because 
   		   they are negative values...*/
		ray.x = ray.x - viewpt_offset.x;
		ray.y = ray.y + viewpt_offset.y;
			/* Add because MR uses -Z as Look At */
		ray.z = ray.z + viewpt_offset.z;
	
 		/* Flip the ray direction about the y-axis */
		if(*mi_eval_boolean(&params->Flip_Ray_X)) { 
			ray.x = (-ray.x);
		}

        	/* Flip the ray direction about the x-axis */
		if(*mi_eval_boolean(&params->Flip_Ray_Y)) {
			ray.y = (-ray.y);		
		}

		/* Convert ray from camera space */
		mi_vector_from_camera(state, &ray, &ray);

		/* Trace new ray... */
	        return(mi_trace_eye(result, state, &state->org, &ray));          
	
	} else {

		/* Set the return colors to Black */
		result->r = result->g =
		result->b = result->a = 0;
		return(miFALSE);
	}

} /* end of dome_FOV_AFL() */
extern "C" DLLEXPORT miBoolean maya_light_point(
	miColor		*result,
	miState		*state,
	struct maya_light_point *paras)
{
	miScalar	d, t, start, stop;

	/***********************************************************
	 * MAYA
	 *
	 * Pointers to access the shader state
	 ***********************************************************/
	miBoolean *diffuse = NULL, *specular = NULL;

	*result = *mi_eval_color(&paras->color);
	if (state->type != miRAY_LIGHT)			/* visible area light*/
		return(miTRUE);
	if (*mi_eval_boolean(&paras->atten)) {			/* dist atten*/
		stop = *mi_eval_scalar(&paras->stop);
		if (state->dist >= stop)
			return(miFALSE);

		start = *mi_eval_scalar(&paras->start);
		if (state->dist > start && fabs(stop - start) > EPS) {
			t = 1.0F - (
			((float)(state->dist) - start) / (stop - start));
			result->r *= t;
			result->g *= t;
			result->b *= t;
		}
	}
	if (*mi_eval_boolean(&paras->shadow)) {			/* shadows: */
		d = *mi_eval_scalar(&paras->factor);
		if (d < 1) {
			miColor filter;
			filter.r = filter.g = filter.b = filter.a = 1;
								/* opaque */
			if (!mi_trace_shadow(&filter,state) || BLACK(filter)) {
				result->r *= d;
				result->g *= d;
				result->b *= d;
				if (d == 0)
					return(miFALSE);
			} else {				/* transparnt*/
				float omf = 1 - d;
				result->r *= d + omf * filter.r;
				result->g *= d + omf * filter.g;
				result->b *= d + omf * filter.b;
			}
		}
	}

	/***********************************************************
	 * MAYA
	 *
	 * Set custom Maya light properties.
	 *
	 * mayabase_stateitem_get returns pointer to
	 * specified MbStateItem in the shader state.
	 * MBSI_LIGHTDIFFUSE and MBSI_LIGHTSPECULAR
	 * contains information whether the light
	 * emits diffuse and/or specular.
	 * These values are used by material shaders.
	 * The variable-length parameter should terminated
	 * with MBSI_NULL.
	 ***********************************************************/
	if (mayabase_stateitem_get(state,
		MBSI_LIGHTDIFFUSE, &diffuse,
		MBSI_LIGHTSPECULAR, &specular,
		MBSI_NULL)) {

		/***********************************************************
		 * MAYA
		 *
		 * Sets
		 * MBSI_LIGHTDIFFUSE and MBSI_LIGHTSPECULAR
		 * 
		 ***********************************************************/
		*diffuse  = *mi_eval_boolean(&paras->emitDiffuse);
		*specular = *mi_eval_boolean(&paras->emitSpecular);
	}

	return(miTRUE);
}
DLLEXPORT miBoolean domeAFL_WxH(
	miColor	*result,
	miState	*state,
	register struct dsDomeAFL_WxH *params)
{
	miScalar	diameter = *mi_eval_scalar(&params->Diameter);
	miScalar	height   = *mi_eval_scalar(&params->Height);
	
	miGeoScalar	fov;	    /* Field-of-View of specified dome */
	miGeoScalar	radius;	    /* Radius of dome being subtended */
	
	/* Does this need to be a pointer? */
	miVector	viewpt_offset = *mi_eval_vector(&params->View_Offset);
	miVector	ray;

	miGeoScalar	x, y, r, phi, theta;

	/* normalize image coordinates btwn [-1,1]... */
	x = (2.0 * state->raster_x) / state->camera->x_resolution - 1.0;
	y = (2.0 * state->raster_y) / state->camera->y_resolution - 1.0;

	/* Calculate FOV for given Diameter & height of dome...          */
	/* Equations obtained from:                                      */
	/*    http://mathforum.org/dr.math/faq/faq.circle.segment.html#8 */
	radius =  ((diameter * diameter) + (4 * height * height)) / (8 * height);
	fov = 2 * asin(diameter / (2 * radius));
	
	/* Calcaulate the radius value */
	r = MI_SQRT( ( x * x ) + ( y * y ) );

	if ( r < 1.0 ) {

		/* Calculate phi... */
		if ( (r > -EPSILON) && (r < EPSILON) ) {
			phi = 0.0;
		} else {
			phi = atan2(x,y);	// [rz] using atan2 instead of original if-then formula
		}

		/* Calculate theta... */
		theta = r * ( fov / 2.0 );

		/* Calculate Ray direction vector... */
		ray.x = (float)(sin(theta) * cos(phi));
		ray.y = (float)(-sin(theta) * sin(phi));
			/* -Z is Look At Direction*/
		ray.z = (float)(-cos(theta));

		/* Account for view offset... */
		/* Offset is added to y & z components because 
		   they are negative values...*/
		ray.x = ray.x - viewpt_offset.x;
		ray.y = ray.y + viewpt_offset.y; 
			/* Add because MR uses -Z as Look At */
		ray.z = ray.z + viewpt_offset.z;

		// Flip the ray direction about the y-axis
		if(*mi_eval_boolean(&params->Flip_Ray_X)) { 
 			ray.x = (-ray.x);
		}

        	/* Flip the ray direction about the x-axis */
		if(*mi_eval_boolean(&params->Flip_Ray_Y)) {
			ray.y = (-ray.y);		
		}

		/* Convert ray from camera space */
		mi_vector_from_camera(state, &ray, &ray);

		/* Trace new ray... */
		return(mi_trace_eye(result, state, &state->org, &ray));

	} else {

		/* Set return color to Black */
		result->r = result->g =
		result->b = result->a = 0;
		return(miFALSE);
	}

} /* end of domeAFL_WxH() */
Exemple #13
0
extern "C" DLLEXPORT miBoolean mib_bent_normal_env(
	miColor     *result,
	miState     *state,
	struct mib_bent_normal_env_p *paras)
{
	miTag  original_env = state->environment;
	miTag  environment  = *mi_eval_tag(&paras->environment);
	miColor   normal    = *mi_eval_color(&paras->bent_normals);
	miColor   occlus    = *mi_eval_color(&paras->occlusion);
	miScalar  strength  = *mi_eval_scalar(&paras->strength);
	miColor   color;      /* Work color */
	miVector  bent;       /* Bent normals */
	miVector  bent_i;     /* Bent normals in internal space */
	miUint	  samples;    /* # of samples */

	/* Displace or light - makes no sense */
	if (state->type == miRAY_DISPLACE || state->type == miRAY_LIGHT)
	    return miFALSE;

	if (strength == 0.0) {
	    result->r = result->g = result->b = 0.0;
	    result->a = 1.0;
	    return miTRUE;
	}

	color.r = color.b = color.g = 0.0;

	/* Does occlusion live in "alpha" component of bn data? */
	if (*mi_eval_boolean(&paras->occlusion_in_alpha))
	    strength *= normal.a;
    
	bent.x = (normal.r * 2.0) - 1.0;
	bent.y = (normal.g * 2.0) - 1.0;
	bent.z = (normal.b * 2.0) - 1.0;

	mi_vector_normalize(&bent);

	/* The different coordinate spaces */
	switch(*mi_eval_integer(&paras->coordinate_space)) {
		case 0: /* No change */
			bent_i = bent;
			break;
		case 1: /* By matrix */
			mi_vector_transform(&bent_i,
				&bent,
				mi_eval_transform(&paras->matrix));
			break;
		case 2: /* World */
			mi_normal_from_world(state, &bent_i, &bent);
			break;
		case 3: /* Camera */
			mi_normal_from_camera(state, &bent_i, &bent);
			break;
		case 4: /* Object */
			mi_normal_from_object(state, &bent_i, &bent);
			break;
	}
    
	samples = *mi_eval_integer(&paras->env_samples);

	/* Temporarily override the environment */
	if (environment)
	    state->environment = environment;

	if (samples <= 1) {
		/* Single sampling */		      
		mi_trace_environment(&color, state, &bent_i);
	} else {
		/* Multisampling */
		double	 sample[3];
		int	 counter = 0;
		miScalar spread  = *mi_eval_scalar(&paras->samples_spread);
		miColor  work_color;

		/* Clear color */
		color.r = color.g = color.b = 0.0;
			
		while (mi_sample(sample, &counter, state, 3, &samples)) {
			miVector trace_dir;
			trace_dir.x = bent_i.x + (sample[0] - 0.5) * spread;
			trace_dir.y = bent_i.y + (sample[1] - 0.5) * spread;
			trace_dir.z = bent_i.z + (sample[2] - 0.5) * spread;
			
			mi_vector_normalize(&trace_dir);

			mi_trace_environment(&work_color, state, &trace_dir);
			color.r += work_color.r;
			color.g += work_color.g;
			color.b += work_color.b;
		}

		color.r /= samples;
		color.g /= samples;
		color.b /= samples;
	}

	/* Reset original environment */
	state->environment = original_env;

	result->r = color.r * occlus.r * strength;
	result->g = color.g * occlus.g * strength;
	result->b = color.b * occlus.b * strength;
	result->a = 1.0;

	return miTRUE;
}
Exemple #14
0
extern "C" DLLEXPORT miBoolean mib_amb_occlusion(
	miColor     *result,
	miState     *state,
	struct mib_amb_occlusion_p *paras)
{
	double sample[3], near_clip, far_clip;
	int	  counter  = 0;
	miUint	  samples  = *mi_eval_integer(&paras->samples);
	miScalar  clipdist = *mi_eval_scalar(&paras->max_distance);
	miBoolean reflecto = *mi_eval_boolean(&paras->reflective);
	miBoolean ret_type = *mi_eval_integer(&paras->return_type);

	miTag	   org_env = state->environment; /* Original environ. */

	miVector orig_normal, trace_dir;
	miScalar output      = 0.0, 
		 samplesdone = 0.0;
	miScalar spread     = *mi_eval_scalar(&paras->spread);
	miScalar o_m_spread = 1.0f - spread;
	
	miColor   env_total;	/* environment Total */ 	
	miVector  norm_total;	/* Used for adding up normals */
	miBoolean occ_alpha = *mi_eval_boolean(&paras->occlusion_in_alpha);

        miScalar  falloff   = 1.0;
        miao_trace_info ti;
        int       version = 1;

	/* If called as user area light source, return "no more samples" for	
	   any call beyond the first */
	if (state->type == miRAY_LIGHT && state->count > 0) 
		return (miBoolean)2;

        /* Figure out the call version */
        mi_query(miQ_DECL_VERSION, 0, state->shader->function_decl, &version); 
        if (version >= 2)
        {
            falloff = *mi_eval_scalar(&paras->falloff);
            if (falloff <= 0.0) 
                falloff = 1.0;
            ti.id_inclexcl   = *mi_eval_integer(&paras->id_includeexclude);
            ti.id_nonself    = *mi_eval_integer(&paras->id_nonself);

            /* None of these options used, go into compatible mode */
            ti.compatible = (ti.id_inclexcl   == 0 && 
                             ti.id_nonself    == 0 
                             );
        }
        else
        {
            ti.compatible = miTRUE;
        }

	/* Used for adding up environment */
	env_total.r = env_total.g = env_total.b = env_total.a = 0;

	far_clip = near_clip = clipdist;

	orig_normal  = state->normal;
	norm_total   = state->normal; /* Begin by standard normal */

	/* Displacement? Shadow? Makes no sense */
	if (state->type == miRAY_DISPLACE ||
            state->type == miRAY_SHADOW) {
		result->r = result->g = result->b = result->a = 0.0;
		return (miTRUE); 
	}

	if (clipdist > 0.0) 
		mi_ray_falloff(state, &near_clip, &far_clip);

	/* Avoid recursion: If we are designated as environment shader,
	   we will be called with rays of type miRAY_ENVIRON, and if so
	   we switch the environment to the global environment */

	if (state->type == miRAY_ENVIRONMENT)
	    state->environment = state->camera->environment;

	while (mi_sample(sample, &counter, state, 2, &samples)) {
		mi_reflection_dir_diffuse_x(&trace_dir, state, sample);
		trace_dir.x = orig_normal.x*o_m_spread + trace_dir.x*spread;
		trace_dir.y = orig_normal.y*o_m_spread + trace_dir.y*spread;
		trace_dir.z = orig_normal.z*o_m_spread + trace_dir.z*spread;
	
		mi_vector_normalize(&trace_dir);

		if (reflecto) {
			miVector ref;
			miScalar nd = state->dot_nd;
			/* Calculate the reflection direction */
			state->normal = trace_dir;
			state->dot_nd = mi_vector_dot(
						&state->dir,
						&state->normal);
			/* Bugfix: mi_reflection_dir(&ref, state);
			   for some reason gives me the wrong result,
			   doing it "manually" works better */
			ref    = state->dir;
			ref.x -= state->normal.x*state->dot_nd*2.0f;
			ref.y -= state->normal.y*state->dot_nd*2.0f;
			ref.z -= state->normal.z*state->dot_nd*2.0f;
			state->normal = orig_normal;
			state->dot_nd = nd;
			trace_dir = ref;
		}

		if (mi_vector_dot(&trace_dir, &state->normal_geom) < 0.0) 
			continue;

		output	    += 1.0; /* Add one */
		samplesdone += 1.0;

		if (state->options->shadow &&
		    miao_trace_the_ray(state, &trace_dir, &state->point, &ti)) {
			/* we hit something */
    
			if (clipdist == 0.0) 
				output -= 1.0;
			else if (state->child->dist < clipdist) {
				miScalar f = pow(state->child->dist / clipdist,
                                                 (double) falloff);

				output -= (1.0 - f);

				norm_total.x += trace_dir.x * f;
				norm_total.y += trace_dir.y * f;
				norm_total.z += trace_dir.z * f;

				switch (ret_type) {
					case 1: 
					  { 
					    /* Environment sampling */
					    miColor envsample;
					    mi_trace_environment(&envsample, 
						state, &trace_dir);

					    env_total.r += envsample.r * f;
					    env_total.g += envsample.g * f;
					    env_total.b += envsample.b * f;
					  }
					  break;
					
					default: 
					  /* Most return types need no 
						special stuff */
					  break;
				}
			}
		}
		else {
			/* We hit nothing */
			norm_total.x += trace_dir.x;
			norm_total.y += trace_dir.y;
			norm_total.z += trace_dir.z;

			switch (ret_type) {
				case 1: /* Environment sampling */
					{
					   miColor envsample;

					   mi_trace_environment(&envsample, 
						   state, &trace_dir);

					   env_total.r += envsample.r;
					   env_total.g += envsample.g;
					   env_total.b += envsample.b;
					}
					break;
				default:
					/* Most return types need no 
						special treatment */
					break; 
			}
		}
	}

	if (clipdist > 0.0) 
		mi_ray_falloff(state, &near_clip, &far_clip);
    
	if (samplesdone <= 0.0) /* No samples? */
		samplesdone = 1.0;  /* 1.0 to not to break divisons below */

	switch (ret_type) {
		case -1:  /* Plain old occlusion with untouched normal*/
		case 0:   /* Plain old occlusion */
		default:  /* (also the default for out-of-bounds values) */
		{
			miVector old_dir = state->dir;
			output /= (miScalar) samplesdone;

			if (ret_type == -1)
				norm_total = state->normal;
			else {
				mi_vector_normalize(&norm_total);

				/* If the color shaders use the normal....
					give them the bent one... */
				state->normal = norm_total;  
				state->dir    = norm_total;
			}
			if (output == 0.0)
				*result = *mi_eval_color(&paras->dark);
			else if (output >= 1.0)
				*result = *mi_eval_color(&paras->bright);
			else {
				miColor bright, dark;
				bright = *mi_eval_color(&paras->bright);
				dark   = *mi_eval_color(&paras->dark);

				result->r = bright.r * output + dark.r * 
					(1.0 - output);
				result->g = bright.g * output + dark.g * 
					(1.0 - output);
				result->b = bright.b * output + dark.b * 
					(1.0 - output);

				if (occ_alpha)
					result->a = output;
				else
					result->a = bright.a * output 
						   + dark.a * (1.0 - output);
			}

			state->normal = orig_normal;
			state->dir    = old_dir;
		}
		break;
		case 1: /* Sampled environment */
		{
			miColor br	= *mi_eval_color(&paras->bright),
				drk	= *mi_eval_color(&paras->dark);

			result->r = drk.r + (br.r * env_total.r / samplesdone);
			result->g = drk.g + (br.g * env_total.g / samplesdone);
			result->b = drk.b + (br.b * env_total.b / samplesdone);
			if (occ_alpha)
				result->a = output/ samplesdone;
			else
				result->a = 1.0;
		}
		break;
		case 2: /* Bent normals, world */
		case 3: /* Bent normals, camera */
		case 4: /* Bent normals, object */
		{
			miVector retn; /* returned Normal */

			mi_vector_normalize(&norm_total);

			if (ret_type == 2)
				mi_normal_to_world(state, &retn, &norm_total);
			if (ret_type == 3)
				mi_normal_to_camera(state, &retn, &norm_total);
			if (ret_type == 4)
				mi_normal_to_object(state, &retn, &norm_total);

			result->r = (retn.x + 1.0) / 2.0;
			result->g = (retn.y + 1.0) / 2.0;
			result->b = (retn.z + 1.0) / 2.0;
		
			if (occ_alpha)
				result->a = output/ samplesdone;
			else
				result->a = 1.0;
		}
		break;
	}

	if (state->type == miRAY_LIGHT) {
		 /* Are we a light shader? */
		int type;
		mi_query(miQ_FUNC_CALLTYPE, state, 0, &type);

		/* Make sure we are called as light shader */
		if (type == miSHADER_LIGHT) {
			/* If so, move ourselves to above the point... */
			state->org.x = state->point.x + state->normal.x;
			state->org.y = state->point.y + state->normal.y;
			state->org.z = state->point.z + state->normal.z;
			/* ...and set dot_nd to 1.0 to illuminate fully */
			state->dot_nd = 1.0;
		}
	}
	/* Reset environment, if we changed it */
	state->environment = org_env;
	return miTRUE;
}
miTag createNativeParticles(miState *state, mrParticleGeoShader_paras *paras, PartioContainer& pc)
{
	miBoolean useAllAttributes = *mi_eval_boolean(&paras->useAllAttributes);
	int i_a = *mi_eval_integer(&paras->i_attributeNames);
	int n_a = *mi_eval_integer(&paras->n_attributeNames);
	miTag *attributeNames = mi_eval_tag(paras->attributeNames) + i_a;

	if( !pc.good())
	{
		mi_info("createNativeParticles: Invalid patioContainer");
		return miNULLTAG;
	}

	Partio::ParticleAttribute posAttr;
	if(!pc.assertAttribute("position", posAttr))
	{
		mi_info("createNativeParticles: partioContainer: no position.");
		return miNULLTAG;
	}

	Partio::ParticleAttribute idAttr;
	bool hasId = true;
	if(!pc.assertAttribute("id", idAttr))
		hasId = false;

	Partio::ParticleAttribute radiusPPAttr;
	bool hasRadiusPP = true;
	if(!pc.assertAttribute("radiusPP", radiusPPAttr))
		hasRadiusPP = false;

	Partio::ParticleAttribute radiusRGBPPAttr;
	bool hasRgbPP = true;
	if(!pc.assertAttribute("rgbPP", radiusRGBPPAttr))
		hasRgbPP = false;

	mi_info("Creating native particles for cache file: %s", pc.cacheFileName.c_str());

	// declare the map as a 3-dimensional map
	mi_api_map_decl_dim ( 3 );

	// the 'mi_api_map_field_decl' function takes four arguments:
	//
	// miParam_type type: basic type of the field (miTYPE_SCALAR or miTYPE_INTEGER)
	// char *name : field name
	// int dimension : dimension of the field, 0 for single values, > 0 for arrays
	// miBoolean global : miTRUE if it's a global field, miFALSE otherwise

	// add the "extension" field as a single float
	miParameter *extension_field = mi_api_map_field_decl (
	miTYPE_SCALAR , mi_mem_strdup("extension") , 0 , miFALSE );

	// add the "color" field as an array of 1 color
	miParameter *color_field = mi_api_map_field_decl (
	miTYPE_SCALAR , mi_mem_strdup("color") , 3 , miFALSE );

	// append the color to the extension for the declaration
	// (this also frees the 'color_field' miParameter)
	miParameter *fields_list = mi_api_map_field_append ( extension_field , color_field );

	// create a declaration called "particles" with the given fields list
	// (this also frees the 'fields_list' miParameter)
	miMap_decl *decl = mi_api_map_decl_begin ( mi_mem_strdup("particles") , fields_list );

	// ends the declaration
	mi_api_map_decl_end ();

//	Then you begin the object definition, by calling 'mi_api_object_begin' and possibly setting the object flags as needed, then you begin the definition of the particle object as a set of spheres:
	miObject *obj = mi_api_object_begin(mi_mem_strdup("TestParticleObject"));
	obj->visible = miTRUE;

	// begin the definition of the particle object as spheres
	mi_api_map_obj_type ( mi_mem_strdup("spheres") );

	// the 'mi_api_map_obj_field' function takes 2 arguments:
	//
	// char *field_name : name of the field to map ("radius" in this case)
	// char *mapped_name : name of the mapped field ("extension" in this case)

	// maps the "radius" field to the "extension" field of this map
	mi_api_map_obj_field( mi_mem_strdup("radius") , mi_mem_strdup("extension") );	

	// begins the definition of the map, taking "particles" as the declaration name
	mi_api_map_begin ( mi_mem_strdup("particles") );

	int num_elements = pc.data->numParticles();

	for ( int i = 0 ; i < num_elements ; ++i ) 
	{
		
		float pos[3];
		pc.getPosition(i, pos);

		// define the position of this element
		mi_api_map_value ( miTYPE_SCALAR , &pos[0] );
		mi_api_map_value ( miTYPE_SCALAR , &pos[1] );
		mi_api_map_value ( miTYPE_SCALAR , &pos[2] );
		mi_api_map_field_end ();

		float radiusPP = 1.0f;
		if( hasRadiusPP )
			radiusPP = *pc.data->data<float>(radiusPPAttr, i);
		radiusPP = rnd() * 0.3;
		// define the radius of this element
		mi_api_map_value ( miTYPE_SCALAR , &radiusPP );
		mi_api_map_field_end ();

		//
		// compute the color in r, g and b
		//
		miScalar r = rnd();
		miScalar g = rnd();
		miScalar b = rnd();
		miColor col;
		col.r = r;
		col.g = g;
		col.b = b;
		// define the color of this element
		//mi_api_map_value ( miTYPE_COLOR , &col );
		mi_api_map_value ( miTYPE_SCALAR , &r );
		mi_api_map_value ( miTYPE_SCALAR , &g );
		mi_api_map_value ( miTYPE_SCALAR , &b );
		mi_api_map_field_end();

		// end the definition of this element
		mi_api_map_element_end ();
	}

	// terminates the map definition and stores it in the DB
	miTag map_tag = mi_api_map_end ( 0 );

	miTag particleObjTag = mi_api_object_end();

	miEchoOptions options;
	memset(&options, 0, sizeof(options));
	options.ascii_output = true;
	options.compressed_output = false;
	options.dont_echo = false;
	
	mi_info("Writing to geodump.mi file.");
	const char *mode = "w";
	FILE *fh = fopen("C:/daten/3dprojects/Maya2013/scenes/geodump.mi", mode);
	//mi_geoshader_echo_tag(fh, particleObjTag, &options);
	fclose(fh);

	mi::shader::Access_map  map(map_tag);
	mi::shader::Map_status	    status;
	mi::shader::Map_declaration map_declaration(map, &status);
	mi::shader::Map_field_id field_id = map_declaration->get_field_id(mi_mem_strdup("color"), &status);
	if (!status.is_ok())
	{
		mi_error("problems getting field_id for color");
		return particleObjTag;
	}
	mi_info("Field id %d", field_id);
	mi::shader::Map_field_type f_type;
	miUint f_dimension;
	bool f_is_global;
	status = map_declaration->get_field_info(field_id, f_type, f_dimension, f_is_global);
	if (!status.is_ok())
	{
		mi_error("problems get_field_info");
		return particleObjTag;
	}
	mi_info("Field type %d is global %d", f_type.type(), f_is_global);
	return particleObjTag;
}