Beispiel #1
0
bool CCharShape::RotateNode (size_t node_name, int axis, double angle) {
    TCharNode *node = GetNode (node_name);
    if (node == NULL) return false;

    if (axis > 3) return false;

    TMatrix rotMatrix;
    char caxis = '0';
    switch (axis) {
    case 1:
        caxis = 'x';
        break;
    case 2:
        caxis = 'y';
        break;
    case 3:
        caxis = 'z';
        break;
    }

    MakeRotationMatrix (rotMatrix, angle, caxis);
    MultiplyMatrices (node->trans, node->trans, rotMatrix);
    MakeRotationMatrix (rotMatrix, -angle, caxis);
    MultiplyMatrices (node->invtrans, rotMatrix, node->invtrans);

    if (newActions && useActions) AddAction (node_name, axis, NullVec, angle);
    return true;
}
Beispiel #2
0
void MultiplyRotationMatrices (TMatrix mat, TMatrix inv, double angle, char axis) {
  if(mat) {
    TMatrix r;
    MakeRotationMatrix( r, angle, axis );
    MultiplyMatrices( mat, mat, r );
  }
  if(inv) {
    TMatrix ir;
    MakeRotationMatrix( ir, -angle, axis );
    MultiplyMatrices( inv, ir, inv );
  }
}
Beispiel #3
0
void RotateAboutVectorMatrix (TMatrix mat, TVector3 u, double angle) {
    TMatrix rx, irx, ry, iry;
    double a, b, c, d;

    a = u.x;
    b = u.y;
    c = u.z;

    d = sqrt (b*b + c*c);

    if  (d < EPS) {
        if  (a < 0) 
            MakeRotationMatrix (mat, -angle, 'x');
        else
            MakeRotationMatrix (mat, angle, 'x');
        return;
    } 

    MakeIdentityMatrix (rx);
    MakeIdentityMatrix (irx);
    MakeIdentityMatrix (ry);
    MakeIdentityMatrix (iry);

    rx[1][1] = c/d;
    rx[2][1] = -b/d;
    rx[1][2] = b/d;
    rx[2][2] = c/d;

    irx[1][1] = c/d;
    irx[2][1] = b/d;
    irx[1][2] = -b/d;
    irx[2][2] = c/d;

    ry[0][0] = d;
    ry[2][0] = -a;
    ry[0][2] = a;
    ry[2][2] = d;

    iry[0][0] = d;
    iry[2][0] = a;
    iry[0][2] = -a;
    iry[2][2] = d;

    MakeRotationMatrix (mat, angle, 'z');

    MultiplyMatrices (mat, mat, ry);
    MultiplyMatrices (mat, mat, rx);
    MultiplyMatrices (mat, iry, mat);
    MultiplyMatrices (mat, irx, mat);
} 
Beispiel #4
0
void RotateAboutVectorMatrix (TMatrix mat, TVector3 u, double angle) {
    TMatrix rx, irx, ry, iry;
    double a, b, c, d, bd, cd;

    a = u.x;
    b = u.y;
    c = u.z;

    d = sqrt (b*b + c*c);

    if  (d < EPS) {
        angle = (a < 0 ? -angle : angle);
        MakeRotationMatrix (mat, angle, 'x');
        return;
    }

    MakeRotationMatrix (mat, angle, 'z');
    bd = b/d;
    cd = c/d;

    //MakeIdentityMatrix (ry);
    ry[0][0] =   d; ry[0][1] = 0.0; ry[0][2] =   a; ry[0][3] = 0.0;
    ry[1][0] = 0.0; ry[1][1] = 1.0; ry[1][2] = 0.0; ry[1][3] = 0.0;
    ry[2][0] =  -a; ry[2][1] = 0.0; ry[2][2] =   d; ry[2][3] = 0.0;
    ry[3][0] = 0.0; ry[3][1] = 0.0; ry[3][2] = 0.0; ry[3][3] = 1.0;
    MultiplyMatrices (mat, mat, ry);

    //MakeIdentityMatrix (rx);
    rx[0][0] = 1.0; rx[0][1] = 0.0; rx[0][2] = 0.0; rx[0][3] = 0.0;
    rx[1][0] = 0.0; rx[1][1] =  cd; rx[1][2] =  bd; rx[1][3] = 0.0;
    rx[2][0] = 0.0; rx[2][1] = -bd; rx[2][2] =  cd; rx[2][3] = 0.0;
    rx[3][0] = 0.0; rx[3][1] = 0.0; rx[3][2] = 0.0; rx[3][3] = 1.0;
    MultiplyMatrices (mat, mat, rx);

    //MakeIdentityMatrix (iry);
    iry[0][0] =   d; iry[0][1] = 0.0; iry[0][2] =  -a; iry[0][3] = 0.0;
    iry[1][0] = 0.0; iry[1][1] = 1.0; iry[1][2] = 0.0; iry[1][3] = 0.0;
    iry[2][0] =   a; iry[2][1] = 0.0; iry[2][2] =   d; iry[2][3] = 0.0;
    iry[3][0] = 0.0; iry[3][1] = 0.0; iry[3][2] = 0.0; iry[3][3] = 1.0;
    MultiplyMatrices (mat, iry, mat);

    //MakeIdentityMatrix (irx);
    irx[0][0] = 1.0; irx[0][1] = 0.0; irx[0][2] = 0.0; irx[0][3] = 0.0;
    irx[1][0] = 0.0; irx[1][1] =  cd; irx[1][2] = -bd; irx[1][3] = 0.0;
    irx[2][0] = 0.0; irx[2][1] =  bd; irx[2][2] =  cd; irx[2][3] = 0.0;
    irx[3][0] = 0.0; irx[3][1] = 0.0; irx[3][2] = 0.0; irx[3][3] = 1.0;
    MultiplyMatrices (mat, irx, mat);
}
Beispiel #5
0
/*
 * Create direction vector from angles in 3D (ignoring banking).
 */
void AnglesToDirectionVector(const ANGLE3D &a3dAngles, FLOAT3D &vDirection)
{
  // find the rotation matrix from the angles
  FLOATmatrix3D mDirection;
  MakeRotationMatrix(mDirection, a3dAngles);
  // rotate a front oriented vector by the matrix
  vDirection = FLOAT3D(0.0f, 0.0f, -1.0f)*mDirection;
}
// mirror a placement of one entity
static void MirrorAndStretchPlacement(CPlacement3D &pl)
{
  ASSERT(_wmtMirror==WMT_X||_wmtMirror==WMT_Y||_wmtMirror==WMT_Z||_wmtMirror==WMT_NONE);

  // if there should be mirror
  if (_wmtMirror!=WMT_NONE) {
    // make rotation matrix for the placement
    FLOATmatrix3D m;
    MakeRotationMatrix(m, pl.pl_OrientationAngle);
    // get row vectors, with object x flipped
    FLOAT3D vX(-m(1,1),m(1,2),m(1,3));
    FLOAT3D vY(-m(2,1),m(2,2),m(2,3));
    FLOAT3D vZ(-m(3,1),m(3,2),m(3,3));

    // flip needed axis
    switch(_wmtMirror) {
    case WMT_X: 
      pl.pl_PositionVector(1) = -pl.pl_PositionVector(1);
      vX = -vX; 
      break;
    case WMT_Y: 
      pl.pl_PositionVector(2) = -pl.pl_PositionVector(2);
      vY = -vY; 
      break;
    case WMT_Z: 
      pl.pl_PositionVector(3) = -pl.pl_PositionVector(3);
      vZ = -vZ; 
      break;
    default: ASSERT(FALSE);
    }

    // compose matrix back from the vectors
    m(1,1) = vX(1); m(2,1) = vY(1); m(3,1) = vZ(1);
    m(1,2) = vX(2); m(2,2) = vY(2); m(3,2) = vZ(2);
    m(1,3) = vX(3); m(2,3) = vY(3); m(3,3) = vZ(3);
    // decompose matrix into angles
    DecomposeRotationMatrix(pl.pl_OrientationAngle, m);
  }

  pl.pl_PositionVector*=_fStretch;
}
Beispiel #7
0
/***********************************************************************

  ComputeInitLink() - this function computes the initial end points, 
		u,v,n vectors, and rotation matrix for the specified link.

  for the given link
	set visible end to origin + vislen
	set actual end to origin + totlen
	rotate both points by theta about z axis
	translate both points to actual end of previous link
	compute u,v,n vectors
	map end points to screen coordinates

***********************************************************************/
int 
ComputeInitLink(int link, MyProgram *data)
{
   vectorType	o2, o2prime, o3, o3prime;
   vectorType	p1, p2, p3;
   vectorType	u, v, vprime, n;

   double	world[4];
   double	screen[4];

   matrixType 	translation;
   matrixType	rotation;
   matrixType	screen_map;

   pointType MapWPointToScreen(wpointType *p, matrixType *map);


   /*  set actual end to origin + totlen
    */
   o3.x = data->links[link].total_length;
   o3.y = 0.0;
   o3.z = 0.0;

   /* set visible end to origin + vislen
    */
   o2.x = data->links[link].visible_length;
   o2.y = 0.0;
   o2.z = 0.0;

   /*  make rotation matrix
    */
   rotation = MakeRotationMatrix('z', data->links[link].zrot_deg);

   MatrixCopy(&rotation, &data->links[link].rot_mat);

   /*  rotate actual and visible end points around z axis
    */
   o3prime = TransformVector(&o3, &rotation);    /* o3prime = o3 * Rz(theta) */
   o2prime = TransformVector(&o2, &rotation);    /* o2prime = o2 * Rz(theta) */

   /*  set start of link to actual end of previous link if not root link 
    */
   if (data->links[link].type == LINK_ROOT) {	/* root link */
      p1.x = data->links[link].w_start.x;
      p1.y = data->links[link].w_start.y;
      p1.z = data->links[link].w_start.z;
   }
   else {					/* normal link */
      p1.x = data->links[link - 1].w_end.x;
      p1.y = data->links[link - 1].w_end.y;
      p1.z = data->links[link - 1].w_end.z;
   }

   /*  make translation matrix
    */
   translation = MakeTranslationMatrix(p1.x, p1.y, p1.z);

   /*  translate actual end and visible end to final locations
    */
   p3 = TransformVector(&o3prime, &translation); /* p3 = o3prime * T(ox,oy,oz) */
   p2 = TransformVector(&o2prime, &translation); /* p2 = o2prime * T(ox,oy,oz) */

   /*  copy final end locations to link data
    */
   data->links[link].w_end.x = p3.x;		/* actual end */
   data->links[link].w_end.y = p3.y;
   data->links[link].w_end.z = p3.z;
   data->links[link].w_visend.x = p2.x;		/* visible end */
   data->links[link].w_visend.y = p2.y;
   data->links[link].w_visend.z = p2.z;
   data->links[link].w_start.x = p1.x;		/* start point */
   data->links[link].w_start.y = p1.y;
   data->links[link].w_start.z = p1.z;

   /*  compute u vector
    */
   u = VecSub(&p1, &p3);		/* u = p3 - p1 */
   VecNormalize(&u);			/* u = u / mag(u) */

   /*  compute n vector 
    */
   vprime.x = 0.0;
   vprime.y = 1.0;
   vprime.z = 0.0;
   n = VecCrossproduct(&u, &vprime);	/* n = u X vprime */

   /*  compute v vector
    */
   v = VecCrossproduct(&n, &u);		/* v = n X u */

   /*  copy u,v,n vectors to link data
    */
   data->links[link].u_vec.x = u.x;
   data->links[link].u_vec.y = u.y;
   data->links[link].u_vec.z = u.z;

   data->links[link].v_vec.x = v.x;
   data->links[link].v_vec.y = v.y;
   data->links[link].v_vec.z = v.z;

   data->links[link].n_vec.x = n.x;
   data->links[link].n_vec.y = n.y;
   data->links[link].n_vec.z = n.z;

   /*  map start and end points to screen coordinates
    */
   world[0] = WB_MINX;
   world[1] = WB_MINY;
   world[2] = WB_MAXX;
   world[3] = WB_MAXY;
   screen[0] = 0.0;
   screen[1] = 0.0;
   screen[2] = SCREEN_X_SIZE;
   screen[3] = SCREEN_Y_SIZE;
   screen_map = MakeMappingMatrix(world, screen);

   data->links[link].start = MapWPointToScreen( &data->links[link].w_start, &screen_map);
   data->links[link].end = MapWPointToScreen( &data->links[link].w_end, &screen_map);
   data->links[link].visend = MapWPointToScreen( &data->links[link].w_visend, &screen_map);


#ifdef INVKINE_DEBUG
   OutputLink(stdout, data, link);
#endif

   return(0);
} /* end of ComputeInitLink() */
/*
 * Prepare for projecting.
 */
void CParallelProjection3D::Prepare(void)
{
  FLOATmatrix3D t3dObjectStretch;   // matrix for object stretch
  FLOATmatrix3D t3dObjectRotation;  // matrix for object angles

  // calc. matrices for viewer and object angles and stretch
  MakeRotationMatrix(t3dObjectRotation, pr_ObjectPlacement.pl_OrientationAngle);  // object normally
  MakeInverseRotationMatrix(pr_ViewerRotationMatrix, pr_ViewerPlacement.pl_OrientationAngle);  // viewer inverse
  t3dObjectStretch.Diagonal(pr_ObjectStretch);
  pr_vViewerPosition = pr_ViewerPlacement.pl_PositionVector;
  BOOL bXInverted = pr_ObjectStretch(1)<0;
  BOOL bYInverted = pr_ObjectStretch(2)<0;
  BOOL bZInverted = pr_ObjectStretch(3)<0;

  pr_bInverted = (bXInverted != bYInverted) != bZInverted;

  // if the projection is mirrored
  if (pr_bMirror) {
    // reflect viewer
    ReflectPositionVectorByPlane(pr_plMirror, pr_vViewerPosition);
    ReflectRotationMatrixByPlane_rows(pr_plMirror, pr_ViewerRotationMatrix);
    // invert inversion
    pr_bInverted = !pr_bInverted;
  }

  // calculate screen center
  pr_ScreenCenter = pr_ScreenBBox.Center();

  // if the object is face-forward
  if (pr_bFaceForward) {
    // apply object stretch only
    pr_RotationMatrix = t3dObjectStretch;
  } else {
    // first apply object stretch then object rotation and then viewer rotation
    pr_mDirectionRotation = pr_ViewerRotationMatrix*t3dObjectRotation;
    pr_RotationMatrix = pr_mDirectionRotation*t3dObjectStretch;
  }

  // calc. offset of object from viewer
  pr_TranslationVector = pr_ObjectPlacement.pl_PositionVector - pr_vViewerPosition;
  // rotate offset only by viewer angles
  pr_TranslationVector = pr_TranslationVector*pr_ViewerRotationMatrix;
  // transform handle from object space to viewer space and add it to the offset
  pr_TranslationVector -= pr_vObjectHandle*pr_RotationMatrix;

  // calculate constant value used for calculating z-buffer k-value from vertex's z coordinate
  pr_fDepthBufferFactor = -pr_NearClipDistance;
  pr_fDepthBufferMul = (pr_fDepthBufferFar-pr_fDepthBufferNear);
  pr_fDepthBufferAdd = pr_fDepthBufferNear;

  // make clip planes
  MakeClipPlane(FLOAT3D(+pr_vZoomFactors(1),0,+pr_vStepFactors(1)), pr_ScreenBBox.Min()(1)-pr_ScreenCenter(1), pr_plClipL);
  MakeClipPlane(FLOAT3D(-pr_vZoomFactors(1),0,-pr_vStepFactors(1)), pr_ScreenCenter(1)-pr_ScreenBBox.Max()(1), pr_plClipR);
  MakeClipPlane(FLOAT3D(0,-pr_vZoomFactors(2),-pr_vStepFactors(2)), pr_ScreenBBox.Min()(2)-pr_ScreenCenter(2), pr_plClipU);
  MakeClipPlane(FLOAT3D(0,+pr_vZoomFactors(2),+pr_vStepFactors(2)), pr_ScreenCenter(2)-pr_ScreenBBox.Max()(2), pr_plClipD);

  // find vector in direction of viewing
  pr_vViewDirection = FLOAT3D(
    pr_vStepFactors(1)/pr_vZoomFactors(1),
    pr_vStepFactors(2)/pr_vZoomFactors(2),
    -1.0f);

  // mark as prepared
  pr_Prepared = TRUE;
}
Beispiel #9
0
void CCharShape::RefreshNode (size_t idx) {
    if (idx >= numNodes) return;
    TMatrix TempMatrix;
    char caxis;
    double angle;

    TCharNode *node = Nodes[idx];
    TCharAction *act = node->action;
    if (act == NULL) return;
    if (act->num < 1) return;

    MakeIdentityMatrix (node->trans);
    MakeIdentityMatrix (node->invtrans);

    for (size_t i=0; i<act->num; i++) {
        int type = act->type[i];
        const TVector3& vec = act->vec[i];
        double dval = act->dval[i];

        switch (type) {
        case 0:
            MakeTranslationMatrix (TempMatrix, vec.x, vec.y, vec.z);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeTranslationMatrix (TempMatrix, -vec.x, -vec.y, -vec.z);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);
            break;
        case 1:
            caxis = 'x';
            angle = dval;
            MakeRotationMatrix (TempMatrix, angle, caxis);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeRotationMatrix (TempMatrix, -angle, caxis);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);
            break;
        case 2:
            caxis = 'y';
            angle = dval;
            MakeRotationMatrix (TempMatrix, angle, caxis);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeRotationMatrix (TempMatrix, -angle, caxis);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);
            break;
        case 3:
            caxis = 'z';
            angle = dval;
            MakeRotationMatrix (TempMatrix, angle, caxis);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeRotationMatrix (TempMatrix, -angle, caxis);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);
            break;
        case 4:
            MakeIdentityMatrix (TempMatrix);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeIdentityMatrix (TempMatrix);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);

            MakeScalingMatrix (TempMatrix, vec.x, vec.y, vec.z);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeScalingMatrix (TempMatrix, 1.0 / vec.x, 1.0 / vec.y, 1.0 / vec.z);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);

            MakeIdentityMatrix (TempMatrix);
            MultiplyMatrices (node->trans, node->trans, TempMatrix);
            MakeIdentityMatrix (TempMatrix);
            MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans);
            break;
        case 5:
            VisibleNode (node->node_name, dval);
            break;
        default:
            break;
        }
    }
}