Ejemplo n.º 1
0
miScalar lume_plane_ray_intersection(miVector *intersection,
				      miVector *plane_point, 
				      miVector *plane_dir,
				      miVector *ray_point,
				      miVector *ray_dir)
{
  miScalar q;
  miScalar t;

  q = mi_vector_dot(plane_dir, ray_dir);

  if (fabs(q) < 0.0001)
    return 0;  /* parallel */
    
  t = (mi_vector_dot(plane_point, plane_dir) -
       mi_vector_dot(plane_dir, ray_point)) / q;

  *intersection = *ray_dir;

  mi_vector_mul(intersection, t);
  mi_vector_add(intersection, intersection, ray_point);

  return t;

}
Ejemplo n.º 2
0
static void raymarch(
	miColor		*result,
	miState		*state,
	struct mrm	*p)
{
	miVector	step, pos, ppos;
	miVector	old_point, old_normal;
	miScalar	step_size;
	miColor		col, prev;
	miBoolean	has_prev = miFALSE;
	int		i;

	step       = state->dir;
	step_size  = state->dist / ((miScalar)p->num - 1);
	mi_vector_mul(&step, step_size);

	old_point  = state->point;
	old_normal = state->normal;
	pos        = state->org;

	/* begin raymarch */
	for (i=0; i < p->num; i++) {
		state->point  = pos;
		state->normal = state->dir;
		state->pri    = 0;	/* cats rays from empty space */

		mi_call_shader_x(&col, miSHADER_MATERIAL, state, p->s, NULL);

		if (has_prev && p->subdiv &&
				color_contrast(&prev, &col, &p->contrast))
		/* adaptive sampling */
			recurse(result, state, ppos, state->dir, step_size,
							&prev, &col, 1, p);
		result->r += col.r;
		result->g += col.g;
		result->b += col.b;
		result->a += col.a;

		prev     = col;
		ppos     = pos;
		has_prev = miTRUE;
		mi_vector_add(&pos, &pos, &step);
	}
	state->point  = old_point;
	state->normal = old_normal;
}
Ejemplo n.º 3
0
static void recurse(
	miColor		*result,
	miState		*state,
	miVector	from,
	miVector	dir,
	miScalar	dist,
	miColor		*prev,
	miColor		*next,
	miInteger	level,
	struct mrm	*p)
{
	miVector	step, pos;
	miColor		col;

	if (level > p->subdiv)
		return;

	step = dir;
	mi_vector_mul(&step, dist*0.5);

	pos = from;
	mi_vector_add(&pos, &pos, &step);

	state->point  = pos;
	state->normal = dir;
	state->pri    = 0;	/* required for ray casting from empty space */

	mi_call_shader_x(&col, miSHADER_MATERIAL, state, p->s, NULL);

	/* recurse further if necessary */
	if (color_contrast(prev, &col, &p->contrast))
		recurse(result, state, from, dir, dist*0.5, prev, &col,
								level+1, p);
	if (color_contrast(next, &col, &p->contrast))
		recurse(result, state, pos, dir, dist*0.5, &col, next,
								level+1, p);
	/* accumulate result */
	result->r += 0.5*(col.r - 0.5*(prev->r - next->r)) * dist;
	result->g += 0.5*(col.g - 0.5*(prev->g - next->g)) * dist;
	result->b += 0.5*(col.b - 0.5*(prev->b - next->b)) * dist;
	result->a += 0.5*(col.a - 0.5*(prev->a - next->a)) * dist;
}
miTag createMeshParticles(miState *state, mrParticleGeoShader_paras *paras, PartioContainer& pc)
{
	mi_info("Creating mesh particles for cache file: %s", pc.cacheFileName.c_str());
	if( ! pc.good())
	{
		mi_error("Invalid PartioContainer.");
		return miNULLTAG;
	}

	Partio::ParticleAttribute posAttr;
	if(!pc.assertAttribute("position", posAttr))
		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 velocityAttr;
	bool hasVelocity = true;
	if(!pc.assertAttribute("velocity", velocityAttr))
		hasVelocity = false;
	
	miObject *obj = beginObject();

	float *fpos;
	srand(123345);
	int numParticles = pc.data->numParticles();
	float sizeMultiplier = *mi_eval_scalar(&paras->sizeMultiplier);
	float density = *mi_eval_scalar(&paras->density);
	float size = *mi_eval_scalar(&paras->size);
	float sizeVariation = *mi_eval_scalar(&paras->sizeVariation);

	// particle number can vary because of density value
	int numWrittenParticles = 0;

	// define vectors
	for(int vtxId = 0; vtxId < numParticles; vtxId++)
	{
		miVector pos;
		fpos = (float *)pc.data->data<float>(posAttr, vtxId);

		int id = vtxId;
		if( hasId)
			id = *pc.data->data<int>(idAttr, vtxId);

		float radiusPP = 1.0f;
		if( hasRadiusPP )
			radiusPP = *pc.data->data<float>(radiusPPAttr, vtxId);

		miVector vel = {0.0, 0.0, 0.0};
		if(hasVelocity)
		{
			float *v;
			v = (float *)pc.data->data<float>(velocityAttr, vtxId);
			vel.x = v[0];
			vel.y = v[1];
			vel.z = v[2];
			// velocity ist distance/sekunde, eine velocity von 24 legt also eine Distanz von 1 Einheit pro frame bei 24fps zurück
			// zusätzlich muss man noch den shutter angle beachten, bei 140° sind das -.2 -> 0.2 also 0.4 * 1 und damit grob .4 Einheiten
			float factor = 1.0f/24.0f * 0.4f;
			mi_vector_mul(&vel, factor);
		}

		pos.x = fpos[0];
		pos.y = fpos[1];
		pos.z = fpos[2];

		miVector camPos = pos;

		// ich transformiere das particle in camera space und gehe dann einfach size/2 nach rechts und oben
		miMatrix matrix;
		mi_matrix_ident(matrix);
		miInstance *inst = (miInstance *)mi_db_access(state->instance);
		mi_matrix_copy(matrix, inst->tf.global_to_local);
		mi_db_unpin(state->instance);
		
		mi_point_from_world(state, &camPos, &pos);
		mi_point_from_world(state, &camPos, &camPos);
		mi_point_to_camera(state, &camPos, &camPos);

		float psize = radiusPP * sizeMultiplier;
		int pId = vtxId;
		double rndVal = rnd(id * state->camera->frame + 5);
		if( rndVal > density)
			continue;
		
		float srndVal = (rndVal - 0.5f) * 2.0f;
		psize *= size + (size * srndVal * sizeVariation * 0.5f);
		psize = fabs(psize);
		if(psize == 0.0f)
			continue;

		miVector upRight, bottomLeft;
		upRight = camPos;
		upRight.x += psize/2.0f;
		upRight.y += psize/2.0f;
		bottomLeft = camPos;
		bottomLeft.x -= psize/2.0f;
		bottomLeft.y -= psize/2.0f;

		// checkScreenSpace in Screenspace und testet auf minPixelSize. 
		if(!checkScreenSpace(state, paras, camPos, bottomLeft, upRight) )
			continue;
		numWrittenParticles++;

		miVector v0, v1, v2, v3;
		v0 = bottomLeft;
		v2 = upRight;
		v1 = bottomLeft;
		v1.y = upRight.y;
		v3 = upRight;
		v3.y = bottomLeft.y;

		mi_point_from_camera(state, &v0, &v0);
		mi_point_from_camera(state, &v1, &v1);
		mi_point_from_camera(state, &v2, &v2);
		mi_point_from_camera(state, &v3, &v3);

		mi_point_to_world(state, &v0, &v0);
		mi_point_to_world(state, &v1, &v1);
		mi_point_to_world(state, &v2, &v2);
		mi_point_to_world(state, &v3, &v3);

		miVector v01, v02, v03;
		mi_vector_sub(&v01, &v0, &v1);
		mi_vector_sub(&v02, &v0, &v2);
		mi_vector_sub(&v03, &v0, &v3);
		mi_vector_transform(&v01, &v01, matrix);
		mi_vector_transform(&v02, &v02, matrix);
		mi_vector_transform(&v03, &v03, matrix);
		mi_vector_add(&v1, &v0, &v01);
		mi_vector_add(&v2, &v0, &v02);
		mi_vector_add(&v3, &v0, &v03);

		// add geometry vectors 
		// e.g. -0.5 -0.5 0.5
		add_vector(v0.x, v0.y, v0.z);
		add_vector(v1.x, v1.y, v1.z);
		add_vector(v2.x, v2.y, v2.z);
		add_vector(v3.x, v3.y, v3.z);

		// single motion vector per particle
		add_vector(vel.x, vel.y, vel.z);

	}

	// uv coordinates
	miVector uvw;
	uvw.x = uvw.y = uvw.z = 0.0f;
	uvw.z = 123.0f;
	mi_api_vector_xyz_add( &uvw );
	uvw.x = 1.0;
	mi_api_vector_xyz_add( &uvw );
	uvw.y = 1.0;
	mi_api_vector_xyz_add( &uvw );
	uvw.x = 0.0;
	mi_api_vector_xyz_add( &uvw );


	// define vertices
	// depending on the attributes we have x vectors per vertex:
	// 0: pos1
	// 1: pos2
	// 2: pos3
	// 3: pos4
	// 4: vel
	// tex0 = numWrittenParticles * 5 - 4

	// num done particles für rnd density
	int texIndex = numWrittenParticles * 5;
	for(int vtxId = 0; vtxId < numWrittenParticles; vtxId++)
	{
		int vertexIndex = vtxId * 5;
		int mvIndex = vtxId * 5 + 4;
		// add vertex definitions
		// e.g. v 0 n 8 t 32 m 46
		mi_api_vertex_add(vertexIndex);
		mi_api_vertex_tex_add( texIndex, -1, -1);
		mi_api_vertex_motion_add(mvIndex);

		mi_api_vertex_add(vertexIndex + 1);
		mi_api_vertex_tex_add( texIndex + 1, -1, -1);
		mi_api_vertex_motion_add(mvIndex);

		mi_api_vertex_add(vertexIndex + 2);
		mi_api_vertex_tex_add( texIndex + 2, -1, -1);
		mi_api_vertex_motion_add(mvIndex);

		mi_api_vertex_add(vertexIndex + 3);
		mi_api_vertex_tex_add( texIndex + 3, -1, -1);
		mi_api_vertex_motion_add(mvIndex);
	}


	// add poly for every particle

	for( int pId = 0; pId < numWrittenParticles; pId++)
	{
		int vtxId = pId * 4;
		mi_api_poly_begin_tag(1, miNULLTAG);

		mi_api_poly_index_add(vtxId);
		mi_api_poly_index_add(vtxId + 1);
		mi_api_poly_index_add(vtxId + 2);
		mi_api_poly_index_add(vtxId + 3);

		mi_api_poly_end();

	}
	miTag objTag = finishObject();
	return objTag;
   
}