Esempio n. 1
0
void FDice::create(const XYZ& p0, const XYZ& p1, const XYZ& p2)
{
	p_obj[0] = P[0] = p0;
	p_obj[1] = P[1] = p1;
	p_obj[2] = P[2] = p2;
	
	V[0] = p1 - p0;
	edge_length[0] = V[0].length();
	
	V[1] = p2 - p1;
	edge_length[1] = V[1].length();
	
	V[2] = p0 - p2;
	edge_length[2] = V[2].length();
	
	area = 0.5*sqrt(edge_length[0]*edge_length[0]*edge_length[2]*edge_length[2] - (V[0].dot(V[2]))*(V[0].dot(V[2])));
	
	V[0].normalize();
	V[1].normalize();
	V[2].normalize();
	
	int a , b;
	
	if(edge_length[0] > edge_length[1] && edge_length[0] > edge_length[2])
	{
		a = 0;
		b = 1;
	}
	else if(edge_length[1] > edge_length[2] && edge_length[1] > edge_length[0])
	{
		a = 1;
		b = 2;
	}
	else
	{
		a = 2;
		b = 0;
	}
	
	XYZ side = V[a];
	XYZ front = side^V[b]; front.normalize();
	XYZ up = front^side;
	
	m_space.setOrientations(side, up, front);
	m_space.setTranslation(P[a]);
	m_space.inverse();
	
	m_space.transform(p_obj[0]);
	m_space.transform(p_obj[1]);
	m_space.transform(p_obj[2]);
	
	f120 = barycentric_coord(p_obj[1].x, p_obj[1].y, p_obj[2].x, p_obj[2].y, p_obj[0].x, p_obj[0].y);
	f201 = barycentric_coord(p_obj[2].x, p_obj[2].y, p_obj[0].x, p_obj[0].y, p_obj[1].x, p_obj[1].y);
	f012 = barycentric_coord(p_obj[0].x, p_obj[0].y, p_obj[1].x, p_obj[1].y, p_obj[2].x, p_obj[2].y);
}
Esempio n. 2
0
Point render::de_casteljau(Points Q, float dt) {
	for (uint kk = 1, n = Q.size(); kk < n; kk++) {
		for (uint ii = 0; ii < n - kk; ii++) {
			Q.at(ii) = barycentric_coord(Q.at(ii), Q.at(ii+1), dt);
		}
	}
	return Q.front();
}
Esempio n. 3
0
VectorF PointLocator::compute_barycentric_coord(const VectorF& v,
        size_t elem_idx) {
    const size_t dim = m_mesh->get_dim();
    MatrixF solver = m_barycentric_solvers.block(elem_idx*dim, 0, dim, dim);
    VectorF last_v = m_last_vertices.row(elem_idx);
    VectorF sol = solver * (v - last_v);
    VectorF barycentric_coord(m_vertex_per_element);
    barycentric_coord.segment(0, dim) = sol;
    barycentric_coord[dim] = 1.0 - sol.sum();
    return barycentric_coord;
}
Esempio n. 4
0
char BindTriangle::set(const XY* corner, const XY& at, const XYZ* positions, const XYZ& topos, const float* distance, triangle_bind_info& res)
{
	//res.wei[0] = 1.0f;
	//res.wei[1] = res.wei[2] = 0.0f;
	
	XYZ dto = topos - positions[0];
	if(dto.length() > distance[0]*2) return 0;
	
	dto = topos - positions[1];
	if(dto.length() > distance[1]*2) return 0;
	
	dto = topos - positions[2];
	if(dto.length() > distance[2]*2) return 0;
	
	float f120 = barycentric_coord(corner[1].x, corner[1].y, corner[2].x, corner[2].y, corner[0].x, corner[0].y);
	float f201 = barycentric_coord(corner[2].x, corner[2].y, corner[0].x, corner[0].y, corner[1].x, corner[1].y);
	float f012 = barycentric_coord(corner[0].x, corner[0].y, corner[1].x, corner[1].y, corner[2].x, corner[2].y);
	
	float alpha, beta, gamma;
	
	alpha = barycentric_coord(corner[1].x,corner[1].y, corner[2].x, corner[2].y, at.x, at.y)/f120;
	if(alpha<0 || alpha>1) return 0;
	beta = barycentric_coord(corner[2].x, corner[2].y, corner[0].x, corner[0].y, at.x, at.y)/f201;
	if(beta<0 || beta>1) return 0;
	gamma = barycentric_coord(corner[0].x, corner[0].y, corner[1].x, corner[1].y, at.x, at.y)/f012;
	if(gamma<0 || gamma>1) return 0;
			
	res.wei[0] = alpha;
	res.wei[1] = beta;
	res.wei[2] = gamma;
	
	return 1;
}
Esempio n. 5
0
char BindTriangle::set(const XY* corner, const XY& at, triangle_bind_info& res)
{
	float f120 = barycentric_coord(corner[1].x, corner[1].y, corner[2].x, corner[2].y, corner[0].x, corner[0].y);
	float f201 = barycentric_coord(corner[2].x, corner[2].y, corner[0].x, corner[0].y, corner[1].x, corner[1].y);
	float f012 = barycentric_coord(corner[0].x, corner[0].y, corner[1].x, corner[1].y, corner[2].x, corner[2].y);
	res.wei[0] = 1.0f;
	res.wei[1] = res.wei[2] = 0.0f;

	float alpha, beta, gamma;
	
	alpha = barycentric_coord(corner[1].x,corner[1].y, corner[2].x, corner[2].y, at.x, at.y)/f120;
	if(alpha<0.f || alpha>1.f) return 0;
	beta = barycentric_coord(corner[2].x, corner[2].y, corner[0].x, corner[0].y, at.x, at.y)/f201;
	if(beta<0.f || beta>1.f) return 0;
	gamma = barycentric_coord(corner[0].x, corner[0].y, corner[1].x, corner[1].y, at.x, at.y)/f012;
	if(gamma<0.f || gamma>1.f) return 0;
			
	res.wei[0] = alpha;
	res.wei[1] = beta;
	res.wei[2] = gamma;
	
	return 1;
}
Esempio n. 6
0
void FDice::rasterize(const float delta, const CoeRec* vertex_coe, DHair* res, CoeRec* coe_res, int& count)
{
	float x_max = 0, y_max = 0;
	float x_min = 10e8, y_min = 10e8;
	for(int i=0; i<3; i++)
	{
		if(p_obj[i].x > x_max) x_max = p_obj[i].x;
		if(p_obj[i].y > y_max) y_max = p_obj[i].y;
		if(p_obj[i].x < x_min) x_min = p_obj[i].x;
		if(p_obj[i].y < y_min) y_min = p_obj[i].y;
	}
	
	float dens_x_0, dens_x_1, dens_y_0, dens_y_1;
	
	for(int i=0; i<3; i++)
	{
		if(p_obj[i].x == x_min) dens_x_0 = data[i].density;
		if(p_obj[i].x == x_max) dens_x_1 = data[i].density;
		if(p_obj[i].y == y_min) dens_y_0 = data[i].density;
		if(p_obj[i].x == y_max) dens_y_1 = data[i].density;
	}

	float alpha, beta, gamma, x, y, varydens;
	XYZ p_interp, n_interp, t_interp, bn_interp, wind_interp;
	float s_interp, curl_interp, coord_s, coord_t;
	
	float dy = delta/(dens_y_0+0.1);
	float dx = delta/(dens_x_0+0.1);
	
	for(float jy=y_min; jy<y_max; jy+= dy)
	{
		y = jy + dy*0.5;
		
		varydens = dens_y_0 + (dens_y_1-dens_y_0)*(jy-y_min)/(y_max-y_min);
		
		dy = delta/(varydens+0.1);
		
		
		for(float ix=x_min; ix<x_max; ix+= dx)
		{
			x = ix+dx*0.5;
			
			varydens = dens_x_0 + (dens_x_1-dens_x_0)*(ix-x_min)/(x_max-x_min);
			
			dx = delta/(varydens+0.1);
			
			alpha = barycentric_coord(p_obj[1].x, p_obj[1].y, p_obj[2].x, p_obj[2].y, x, y)/f120;
			if(alpha<0 || alpha>1) continue;
			beta = barycentric_coord(p_obj[2].x, p_obj[2].y, p_obj[0].x, p_obj[0].y, x, y)/f201;
			if(beta<0 || beta>1) continue;
			gamma = barycentric_coord(p_obj[0].x, p_obj[0].y, p_obj[1].x, p_obj[1].y, x, y)/f012;
			if(gamma<0 || gamma>1) continue;
			
			p_interp = data[0].root*alpha + data[1].root*beta + data[2].root*gamma;
			n_interp = data[0].normal*alpha + data[1].normal*beta + data[2].normal*gamma;n_interp.normalize();
			t_interp = data[0].tangent*alpha + data[1].tangent*beta + data[2].tangent*gamma; t_interp.normalize();
			bn_interp = data[0].binormal*alpha + data[1].binormal*beta + data[2].binormal*gamma;bn_interp.normalize();
			s_interp = data[0].scale*alpha + data[1].scale*beta + data[2].scale*gamma;
			curl_interp = data[0].curl*alpha + data[1].curl*beta + data[2].curl*gamma;
			wind_interp = data[0].wind*alpha + data[1].wind*beta + data[2].wind*gamma;
			coord_s = data[0].s*alpha + data[1].s*beta + data[2].s*gamma;
			coord_t = data[0].t*alpha + data[1].t*beta + data[2].t*gamma;
			
			res[count].root = p_interp;
			res[count].normal = n_interp;
			res[count].tangent = t_interp;
			res[count].binormal = bn_interp;
			res[count].scale = s_interp;
			res[count].curl = curl_interp;
			res[count].wind = wind_interp;
			
			res[count].up = res[count].tangent^res[count].binormal;
			res[count].up.normalize();
			
			res[count].binormal = res[count].up^res[count].tangent;
			res[count].binormal.normalize();
			
			res[count].s = coord_s;
			res[count].t = coord_t;
			
			for(int k=0; k<16; k++)
			{
				coe_res[count].data[k] = vertex_coe[data[0].id].data[k] * alpha + vertex_coe[data[1].id].data[k] * beta + vertex_coe[data[2].id].data[k] * gamma;
			}
			
			count++;
		}
	}
}