Exemplo n.º 1
0
void Intermediate ( Quaternion* q0, Quaternion* q1, Quaternion* q2,
   Quaternion* a, Quaternion* b)
{
   /* assert:  q0, q1, q2 are unit quaternions */
   /*Quaternion q0inv = q0.UnitInverse();
   Quaternion q1inv = q1.UnitInverse();
   Quaternion p0 = q0inv*q1;
   Quaternion p1 = q1inv*q2;
   Quaternion arg = 0.25*(p0.Log()-p1.Log());
   Quaternion marg = -arg;
 
   a = q1*arg.Exp();
   b = q1*marg.Exp();
   */

   Quaternion p0, p1;
   UnitInverse(&p0, q0);
   UnitInverse(&p1, q1);
   MulSelf(&p0, q1);
   MulSelf(&p1, q2);
   LogSelf(&p0);
   LogSelf(&p1);
   Sub(a,&p0, &p1);
   MulScalSelf(a, 0.25);
   Neg(b, a);

   ExpSelf(a);
   ExpSelf(b);
   Mul(a, q1, a);
   Mul(b, q1, b);
}
Exemplo n.º 2
0
/*-------------------------------------------------------------------------*/
void* KB_RotInitialize (int numKeys, RotationKey* key)
{
    double omt0, omc0, opc0, omb0, opb0, adj0, out0, out1;
    double omt1, omc1, opc1, omb1, opb1, adj1, in0, in1;
    int i0 = 0, i1 = 1, i2 = 2, i3 = 3;
    Quaternion q0, q1, q2, q3;
    Quaternion prod;
    Quaternion logdq, Tout, Tin, arg0, arg1;

    /* assert:  numKeys >= 4 */

    SplineInfo* info = (SplineInfo*) calloc( 1, sizeof(SplineInfo));
    info->numPolys = numKeys-3;
    info->si = (SquadInfo*) calloc(info->numPolys, sizeof( SquadInfo ) );

    for (/**/; i0 < info->numPolys; i0++, i1++, i2++, i3++)
    {
        FromAngleAxis(&q0, key[i0].Rot.angle,key[i0].Rot.x,key[i0].Rot.y,
            key[i0].Rot.z);
        FromAngleAxis(&q1, key[i1].Rot.angle,key[i1].Rot.x,key[i1].Rot.y,
            key[i1].Rot.z);
        FromAngleAxis(&q2, key[i2].Rot.angle,key[i2].Rot.x,key[i2].Rot.y,
            key[i2].Rot.z);
        FromAngleAxis(&q3, key[i3].Rot.angle,key[i3].Rot.x,key[i3].Rot.y,
            key[i3].Rot.z);

        /* arrange for consecutive quaternions to have acute angle */
        if ( Dot(&q1, &q2) < 0.0 )
        {
	    /*q2 = -q2;*/
	    NegSelf(&q2);
            ToAngleAxis(&q2, &(key[i2].Rot.angle),&(key[i2].Rot.x),&(key[i2].Rot.y),
                &(key[i2].Rot.z));
        }

        /* build log(q[i1]^{-1}*q[i2]) */
	/* prod = q1.UnitInverse()*q2; */
	UnitInverse(&prod, &q1); MulSelf(&prod, &q2);
        /* logdq = prod.Log(); */
	Log(&logdq, &prod);

	/* build multipliers at q[i1] */
        omt0 = 1-key[i1].tension;
        omc0 = 1-key[i1].continuity;
        opc0 = 1+key[i1].continuity;
        omb0 = 1-key[i1].bias;
	opb0 = 1+key[i1].bias;
	adj0 = 2*(key[i2].t-key[i1].t)/(key[i2].t-key[i0].t);
	out0 = 0.5*adj0*omt0*opc0*opb0;
	out1 = 0.5*adj0*omt0*omc0*omb0;

        /* build outgoing tangent at q[i1] */
        /* prod = q0.UnitInverse()*q1; */
	UnitInverse(&prod, &q0); MulSelf(&prod, &q1);
        /* Quaternion Tout = out1*logdq+out0*prod.Log(); */
	MulScal(&Tout, &logdq, out1); LogSelf(&prod); MulScal(&prod, &prod, out0);
	AddSelf(&Tout, &prod);

        /* build multipliers at q[i2] */
	omt1 = 1-key[i2].tension;
	omc1 = 1-key[i2].continuity;
	opc1 = 1+key[i2].continuity;
	omb1 = 1-key[i2].bias;
	opb1 = 1+key[i2].bias;
	adj1 = 2*(key[i2].t-key[i1].t)/(key[i3].t-key[i1].t);
	in0 = 0.5*adj1*omt1*omc1*opb1;
	in1 = 0.5*adj1*omt1*opc1*omb1;

        /* build incoming tangent at q[i2] */
        /* prod = q2.UnitInverse()*q3; */
	UnitInverse(&prod, &q2); MulSelf(&prod, &q3);
	/* Quaternion Tin = in1*prod.Log()+in0*logdq; */
	MulScal(&Tin, &logdq, in0); LogSelf(&prod); MulScal(&prod, &prod, in1);
	AddSelf(&Tin, &prod);

        /*info->si[i0].p = q1;*/
	SetQuat(&(info->si[i0].p), &q1);
	  
        /*info->si[i0].q = q2; */
	SetQuat(&(info->si[i0].q), &q2);


        /* Quaternion arg0 = 0.5*(Tout-logdq); */
	Sub(&arg0, &Tout, &logdq); MulScalSelf(&arg0, 0.5);
	/* Quaternion arg1 = 0.5*(logdq-Tin); */
	Sub(&arg1, &logdq, &Tin); MulScalSelf(&arg1, 0.5);

        /* info->si[i0].a = q1*arg0.Exp(); */	
        /* info->si[i0].b = q2*arg1.Exp(); */
	ExpSelf(&arg0); Mul(&(info->si[i0].a), &q1, &arg0);
	ExpSelf(&arg1); Mul(&(info->si[i0].b), &q2, &arg1);

        info->si[i0].tmin = key[i1].t;
        info->si[i0].tmax = key[i2].t;
        info->si[i0].trange = info->si[i0].tmax-info->si[i0].tmin;
    }

    return info;
}