void drawSkewedCoordinateSystem(CGContextRef context)
{
    // alpha is 22.5 degrees and beta is 15 degrees.
    float alpha = M_PI/8, beta = M_PI/12;
    CGAffineTransform skew;
    // Create a rectangle that is 72 units on a side
    // with its origin at (0,0).
    CGRect r = CGRectMake(0, 0, 72, 72);
    
    CGContextTranslateCTM(context, 144, 144);
    // Draw the coordinate axes untransformed.
    drawCoordinateAxes(context);
    // Fill the rectangle.
    CGContextFillRect(context, r);

    // Create an affine transform that skews the coordinate system,
    // skewing the x-axis by alpha radians and the y-axis by beta radians. 
    skew = CGAffineTransformMake(1, tan(alpha), tan(beta), 1, 0, 0);
    // Apply that transform to the context coordinate system.
    CGContextConcatCTM(context, skew);

    // Set the fill and stroke color to a dark blue.
    CGContextSetRGBStrokeColor(context, 0.11, 0.208, 0.451, 1);
    CGContextSetRGBFillColor(context, 0.11, 0.208, 0.451, 1);
    
    // Draw the coordinate axes again, now transformed.
    drawCoordinateAxes(context);
    // Set the fill color again but with a partially transparent alpha.
    CGContextSetRGBFillColor(context, 0.11, 0.208, 0.451, 0.7);
    // Fill the rectangle in the transformed coordinate system.
    CGContextFillRect(context, r);
}
void Virtual3dCharacterViewer::drawMarkCube ( int i, int Group )
{
    MarkCube *group ;
    Vector3D color ;

    switch(Group)
    {
    case 0:
        group = MarkCubePOT ;
        break;
    case 1:
        group = MarkCubeFK ;
        break;
    case 2:
        group = MarkCubeFKResult ;
        break;
    case 3:
        group = MarkCubeDebugLeftArm ;
        break;
    default:
        return ;
    }


    color = group[i].Color ;
    if ( group[i].show )
    {
        glPushMatrix();

        glTranslatef(  group[i].Pos.getX(),  group[i].Pos.getY(), group[i].Pos.getZ()  ) ;
        glRotatef( group[i].Ori.getYaw() , 0.0, 1.0 , 0.0 ) ;
        glRotatef( group[i].Ori.getPitch() , 1.0, 0.0 , 0.0 ) ;
        glRotatef( group[i].Ori.getRoll() , 0.0, 0.0 , 1.0 ) ;

        xLength = 0.04f ;
        yLength = 0.04f ;
        zLength = 0.04f ;
        leftBottomX = - xLength / 2.0f ;
        leftBottomY = - yLength / 2.0f ;
        leftBottomZ = - zLength / 2.0f ;
        drawSingleColorCube(color);
        drawCoordinateAxes(0.15);

        glPopMatrix();
    }
}
void Virtual3dCharacterViewer::paintGL()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glBindTexture( GL_TEXTURE_2D, texture[filter] );


    // switch to camera sight .
    glTranslatef(  WorldInCamera.Pos.getX(),  WorldInCamera.Pos.getY(), WorldInCamera.Pos.getZ() );
    glRotatef( WorldInCamera.Ori.getYaw() , 0.0, 1.0 , 0.0 ) ;
    glRotatef( WorldInCamera.Ori.getPitch() , 1.0, 0.0 , 0.0 ) ;
    glRotatef( WorldInCamera.Ori.getRoll() , 0.0, 0.0 , 1.0 ) ;


    glGetFloatv(GL_MODELVIEW_MATRIX,  (GLfloat*)WorldMat);
    InvTransformation ( WorldMat, WorldMatInv ) ;
    drawCoordinateAxes () ;

    if ( ShowIK )
        glDrawBody(IKResult);
    if ( ShowFK )
        glDrawBody(FKResult);

    int i ;
    for ( i=0; i<sizeof(MarkCubePOT)/sizeof(MarkCubePOT[0]); i++ )
    {
        drawMarkCube(i);
    }
    for ( i=0; i<sizeof(MarkCubeFK)/sizeof(MarkCubeFK[0]); i++ )
    {
        drawMarkCube(i,1);
    }
    for ( i=0; i<sizeof(MarkCubeFKResult)/sizeof(MarkCubeFK[0]); i++ )
    {
        drawMarkCube(i,2);
    }
    for ( i=0; i<sizeof(MarkCubeDebugLeftArm)/sizeof(MarkCubeDebugLeftArm[0]); i++ )
    {
        drawMarkCube(i,3);
    }
}