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); }
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(); }
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; }
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; }
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; }
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++; } } }