コード例 #1
0
ValueBase
ValueNode_WPList::operator()(Time t)const
{
	if (getenv("SYNFIG_DEBUG_VALUENODE_OPERATORS"))
		printf("%s:%d operator()\n", __FILE__, __LINE__);

	std::vector<WidthPoint> ret_list;

	std::vector<ListEntry>::const_iterator iter;
	bool rising;

	WidthPoint curr;

	// go through all the list's entries
	for(iter=list.begin();iter!=list.end();++iter)
	{
		// how 'on' is this widthpoint?
		float amount(iter->amount_at_time(t,&rising));
		assert(amount>=0.0f);
		assert(amount<=1.0f);
		// we store the current width point
		curr=(*iter->value_node)(t).get(curr);
		// it's fully on
		if (amount > 1.0f - 0.0000001f)
		{
			// push back to the returning list
			ret_list.push_back(curr);
		}
		// it's partly on
		else if(amount>0.0f)
		{
			// This is where the interesting stuff happens
			Time off_time, on_time;
			if(!rising)	// if not rising, then we were fully 'on' in the past, and will be fully 'off' in the future
			{
				try{ on_time=iter->find_prev(t)->get_time(); }
				catch(...) { on_time=Time::begin(); }
				try{ off_time=iter->find_next(t)->get_time(); }
				catch(...) { off_time=Time::end(); }
			}
			else // otherwise we were fully 'off' in the past, and will be fully 'on' in the future
			{
				try{ off_time=iter->find_prev(t)->get_time(); }
				catch(...) { off_time=Time::begin(); }
				try{ on_time=iter->find_next(t)->get_time(); }
				catch(...) { on_time=Time::end(); }
			}
			// i_width is the interpolated width at current time given by fully 'on' surrounding width points
			Real i_width(interpolated_width(curr.get_norm_position(get_loop()), t));
			Real curr_width(curr.get_width());
			// linear interpolation by amount
			curr.set_width(i_width*(1.0-amount)+(curr_width)*amount);
			// now insert the calculated width point into the widht list
			ret_list.push_back(curr);
		}
	}
	if(list.empty())
		synfig::warning(string("ValueNode_WPList::operator()():")+_("No entries in list"));
	else
	if(ret_list.empty())
		synfig::warning(string("ValueNode_WPList::operator()():")+_("No entries in ret_list"));

	return ValueBase(ret_list,get_loop());
}
コード例 #2
0
ファイル: valuenode_composite.cpp プロジェクト: synfig/synfig
ValueBase
synfig::ValueNode_Composite::operator()(Time t)const
{
    if (getenv("SYNFIG_DEBUG_VALUENODE_OPERATORS"))
        printf("%s:%d operator()\n", __FILE__, __LINE__);

    Type &type(get_type());
    if (type == type_vector)
    {
        Vector vect;
        assert(components[0] && components[1]);
        vect[0]=(*components[0])(t).get(Vector::value_type());
        vect[1]=(*components[1])(t).get(Vector::value_type());
        return vect;
    }
    else if (type == type_color)
    {
        Color color;
        assert(components[0] && components[1] && components[2] && components[3]);
        color.set_r((*components[0])(t).get(Vector::value_type()));
        color.set_g((*components[1])(t).get(Vector::value_type()));
        color.set_b((*components[2])(t).get(Vector::value_type()));
        color.set_a((*components[3])(t).get(Vector::value_type()));
        return color;
    }
    else if (type == type_segment)
    {
        Segment seg;
        assert(components[0] && components[1] && components[2] && components[3]);
        seg.p1=(*components[0])(t).get(Point());
        seg.t1=(*components[1])(t).get(Vector());
        seg.p2=(*components[2])(t).get(Point());
        seg.t2=(*components[3])(t).get(Vector());
        return seg;
    }
    else if (type == type_bline_point)
    {
        BLinePoint ret;
        assert(components[0] && components[1] && components[2] && components[3] && components[4] && components[5] && components[6] && components[7]);
        ret.set_vertex((*components[0])(t).get(Point()));
        ret.set_width((*components[1])(t).get(Real()));
        ret.set_origin((*components[2])(t).get(Real()));
        ret.set_split_tangent_both((*components[3])(t).get(bool()));
        ret.set_split_tangent_radius((*components[6])(t).get(bool()));
        ret.set_split_tangent_angle((*components[7])(t).get(bool()));
        ret.set_tangent1((*components[4])(t).get(Vector()));
        ret.set_tangent2((*components[5])(t).get(Vector()));
        return ret;
    }
    else if (type == type_width_point)
    {
        WidthPoint ret;
        assert(components[0] && components[1] && components[2] && components[3] && components[4] && components[5]);
        ret.set_position((*components[0])(t).get(Real()));
        ret.set_width((*components[1])(t).get(Real()));
        ret.set_side_type_before((*components[2])(t).get(int()));
        ret.set_side_type_after((*components[3])(t).get(int()));
        ret.set_lower_bound((*components[4])(t).get(Real()));
        ret.set_upper_bound((*components[5])(t).get(Real()));
        return ret;
    }
    else if (type == type_dash_item)
    {
        DashItem ret;
        assert(components[0] && components[1] && components[2] && components[3]);
        Real offset((*components[0])(t).get(Real()));
        if(offset < 0.0) offset=0.0;
        Real length((*components[1])(t).get(Real()));
        if(length < 0.0) length=0.0;
        ret.set_offset(offset);
        ret.set_length(length);
        ret.set_side_type_before((*components[2])(t).get(int()));
        ret.set_side_type_after((*components[3])(t).get(int()));
        return ret;
    }
    else if (type == type_transformation)
    {
        Transformation ret;
        assert(components[0] && components[1] && components[2] && components[3]);
        ret.offset    = (*components[0])(t).get(Vector());
        ret.angle     = (*components[1])(t).get(Angle());
        ret.skew_angle = (*components[2])(t).get(Angle());
        ret.scale     = (*components[3])(t).get(Vector());
        return ret;
    }
    else if (dynamic_cast<types_namespace::TypeWeightedValueBase*>(&type) != NULL)
    {
        types_namespace::TypeWeightedValueBase *tp =
            dynamic_cast<types_namespace::TypeWeightedValueBase*>(&type);
        assert(components[0] && components[1]);
        return tp->create_weighted_value((*components[0])(t).get(Real()), (*components[1])(t));
    }
    else if (dynamic_cast<types_namespace::TypePairBase*>(&type) != NULL)
    {
        types_namespace::TypePairBase *tp =
            dynamic_cast<types_namespace::TypePairBase*>(&type);
        assert(components[0] && components[1]);
        return tp->create_value((*components[0])(t), (*components[1])(t));
    }

    synfig::error(string("ValueNode_Composite::operator():")+_("Bad type for composite"));
    assert(components[0]);
    return (*components[0])(t);
}
コード例 #3
0
	/*!
	 * @param prev previous withpoint
	 * @param next next withpoint
	 * @param p position to calculate the new width between previous position and next position
	 * @param smoothness [0,1] how much linear (0) or smooth (1) the interpolation is
	 * @return the interpolated width
	*/
Real
synfig::widthpoint_interpolate(const WidthPoint& prev, const WidthPoint& next, const Real p, const Real smoothness)
{
	// Smoothness gives linear interpolation  between
	// the result of the linear interpolation between the withpoints
	// and the interpolation based on a 5th degree polynomial that matches
	// following rules:
	// q [0,1]
	// p(0)= 0    p(1)= 1
	// p'(0)= 0   p'(1)= 0
	// p''(0)= 0  p''(1)= 0
	// It is: p(q) = 6*q^5-15*q^4+10*q^3 = q*q*q*(10+q*(6*q-15)
	WidthPoint::SideType side_int(WidthPoint::TYPE_INTERPOLATE);
	int nsb, nsa, psb, psa;
	Real pp, np;
	Real nw, pw, rw(0.0);
	const Real epsilon(0.0000001f);
	np=next.get_position();
	pp=prev.get_position();
	nw=next.get_width();
	pw=prev.get_width();
	nsb=next.get_side_type_before();
	nsa=next.get_side_type_after();
	psb=prev.get_side_type_before();
	psa=prev.get_side_type_after();

	if(p==np)
		return nw;
	if(p==pp)
		return pw;
	// Normal case: previous position is lower than next position
	if(np > pp)
	{
		if(np > p && p > pp )
		{
			Real q;
			if(nsb != side_int)
				nw=0.0;
			if(psa != side_int)
				pw=0.0;
			if(np-pp < epsilon)
				q=0.5;
			else
				q=(p-pp)/(np-pp);
			rw=pw+(nw-pw)*(q*(1.0-smoothness)+q*q*q*(10+q*(6*q-15))*smoothness);
		}
		else if(p < pp)
		{
			if(psb != side_int)
				pw=0.0;
			rw=pw;
		}
		else if(p > np)
		{
			if(nsa != side_int)
				nw=0.0;
			rw=nw;
		}
	}
	// particular case: previous position is higher than next position
	else
	if(p > pp || np > p)
	{
		Real q(0);
		if(nsb != side_int)
			nw=0.0;
		if(psa != side_int)
			pw=0.0;
		if(np+1.0-pp < epsilon)
			q=0.5;
		else
		{
			if(p > pp)
				q=(p-pp)/(np+1.0-pp);
			if(np > p)
				q=(p+1.0-pp)/(np+1.0-pp);
		}
		rw=pw+(nw-pw)*(q*(1.0-smoothness)+q*q*q*(10+q*(6*q-15))*smoothness);
	}
	else
	if(p > np && p < pp)
	{
		Real q;
		if(nsa != side_int)
			nw=0.0;
		if(psb != side_int)
			pw=0.0;
		if(pp-np < epsilon)
			q=0.5;
		else
			q=(p-np)/(pp-np);
		rw=nw+(pw-nw)*(q*(1.0-smoothness)+q*q*q*(10+q*(6*q-15))*smoothness);
	}
	return rw;
}