void MatrixSkew(Matrix &Result, const Vec3f  &RotationAxis, const Vec3f  &TranslationAxis, Real32 AngleInRadians)
{
	/* 
	 * Implemented in accordance with the RenderMan specification.
	 * See http://www.koders.com/cpp/fidA08C276050F880D11C2E49280DD9997478DC5BA1.aspx for
	 * the implementation that this was copied from.
	 * (If the url is invalid, this implementation was copied from the GNU GMAN project,
	 * in the gmanmatrix4.cpp file.)
	 *
	 */
    Result.setIdentity();

	Real32 an1,an2,rx,ry,alpha;
	Vec3f a1,a2,n1,n2;

	Vec3f a(RotationAxis), b(TranslationAxis);
	b.normalize();
	a1 = b * a.dot(b);
	a2 = a - a1;
	a2.normalize();

	an1 = a.dot(a2);
	an2 = a.dot(b);

	rx = an1*osgCos(AngleInRadians) - an2*osgSin(AngleInRadians);
	ry = an1*osgSin(AngleInRadians) + an2*osgCos(AngleInRadians);

	if(rx <= 0.0f)
	{  // skew AngleInRadians too large, and we can't calculate the skew matrix
		SWARNING << "ColladaNode::handleSkew: Skew Angle too large! ( rx = " << rx << " )" << std::endl;
		return; 
	}

	// are A and B parallel?
	if(OSG::osgAbs(an1) < 0.000001)
    {
		alpha = 0.0f;
    }
	else
    {
		alpha = ry/rx - an2/an1;
    }

	Result[0][0] = a2.x() * b.x() * alpha + 1.0f;
	Result[1][0] = a2.y() * b.x() * alpha;
	Result[2][0] = a2.z() * b.x() * alpha;

	Result[0][1] = a2.x() * b.y() * alpha;
	Result[1][1] = a2.y() * b.y() * alpha + 1.0f;
	Result[2][1] = a2.z() * b.y() * alpha;

	Result[0][2] = a2.x() * b.z() * alpha;
	Result[1][2] = a2.y() * b.z() * alpha;
	Result[2][2] = a2.z() * b.z() * alpha + 1.0f;
}
Pnt2f RotatedComponent::getParentToLocal(const Pnt2f& Location) const
{
    Pnt2f Result(Inherited::getParentToLocal(Location));
    Result = Result - Vec2f(static_cast<Real32>(getSize().x())/2.0,static_cast<Real32>(getSize().y())/2.0);
    Result.setValues( Result[0]*osgCos(getAngle()) - Result[1]*osgSin(getAngle()), Result[0]*osgSin(getAngle()) + Result[1]*osgCos(getAngle()));
    Result = Result + Vec2f(static_cast<Real32>(getInternalComponent()->getSize().x())/2.0,static_cast<Real32>(getInternalComponent()->getSize().y())/2.0);
    return Result;
}
void Graphics3DExtrude::drawArc(const Pnt2f& Center, const Real32& Width, const Real32& Height, const Real32& StartAngleRad, const Real32& EndAngleRad, const Real32& LineWidth, const UInt16& SubDivisions, const Color4f& Color, const Real32& Opacity) const
{
	GLfloat previousLineWidth;
	glGetFloatv(GL_LINE_WIDTH, &previousLineWidth);
	Real32 angleNow = StartAngleRad;
	Real32 angleDiff = (EndAngleRad-StartAngleRad)/(static_cast<Real32>(SubDivisions));
	//If andle difference is bigger to a circle, set it to equal to a circle
	if(EndAngleRad-StartAngleRad > 2*3.1415926535)
		angleDiff = 2*3.1415926535/static_cast<Real32>(SubDivisions);
   Real32 Alpha(Color.alpha() * Opacity * getOpacity());
	if(Alpha < 1.0)
	{
		//Setup the blending equations properly
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);
	}
	glLineWidth(LineWidth);
	glBegin(GL_LINE_STRIP);
      glColor4f(Color.red(), Color.green(), Color.blue(), Alpha );
		//draw vertex lines
      for(UInt16 i = 0 ; i<SubDivisions+1 ; ++i)
      {
			glVertex2f( static_cast<Real32>(Center.x()) + static_cast<Real32>(Width)*osgCos(angleNow ),static_cast<Real32>(Center.y()) +static_cast<Real32>(Height)*osgSin(angleNow));
			//glVertex2f(Center.x() + Width*osgCos(angleNow + angleDiff), Center.y() + Height*osgSin(angleNow+angleDiff));
			angleNow += angleDiff;
		}
	glEnd();

	
	if(Alpha < 1.0)
	{
		glDisable(GL_BLEND);
	}
   glLineWidth(previousLineWidth);
}
void Graphics3DExtrude::drawComplexDisc(const Pnt2f& Center, const Real32& InnerRadius, const Real32& OuterRadius, const Real32& StartAngleRad, const Real32& EndAngleRad, const UInt16& SubDivisions, const Color4f& CenterColor, const Color4f& OuterColor, const Real32& Opacity) const
{	
	Real32 angleNow = StartAngleRad;
	Real32 angleDiff = (EndAngleRad-StartAngleRad)/(static_cast<Real32>(SubDivisions));
	if(EndAngleRad-StartAngleRad > 2*3.1415926535)
		angleDiff = 2*3.1415926535/static_cast<Real32>(SubDivisions);
	if(CenterColor.alpha() < 1.0 ||
       OuterColor.alpha() < 1.0)
	{
		//Setup the blending equations properly
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);
	}
	//Front
	glBegin(GL_QUAD_STRIP);
	   glNormal3f(0.0,0.0,1.0);
		for(UInt16 i = 0 ; i<SubDivisions+1 ; ++i)
		{
			glColor4f(OuterColor.red(), OuterColor.green(), OuterColor.blue(), OuterColor.alpha());
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(OuterRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(OuterRadius)*osgSin(angleNow),0.0);
			glColor4f(CenterColor.red(), CenterColor.green(), CenterColor.blue(), CenterColor.alpha());
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(InnerRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(InnerRadius)*osgSin(angleNow), 0.0);
			angleNow += angleDiff;
		}
	glEnd();
	
	//OuterArc
	angleNow = StartAngleRad;
	glBegin(GL_QUAD_STRIP);
		glColor4f(OuterColor.red(), OuterColor.green(), OuterColor.blue(), OuterColor.alpha());
		for(UInt16 i = 0 ; i<SubDivisions+1 ; ++i)
		{
			glNormal3f(osgCos(angleNow),osgSin(angleNow),0.0);

			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(OuterRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(OuterRadius)*osgSin(angleNow),getExtrudeLength());
			
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(OuterRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(OuterRadius)*osgSin(angleNow),0.0);
			
			
			angleNow += angleDiff;
		}
	glEnd();

	//InnerArc
	angleNow = StartAngleRad;
	glBegin(GL_QUAD_STRIP);
		glColor4f(CenterColor.red(), CenterColor.green(), CenterColor.blue(), CenterColor.alpha());
		for(UInt16 i = 0 ; i<SubDivisions+1 ; ++i)
		{
			glNormal3f(-osgCos(angleNow),-osgSin(angleNow),0.0);
			
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(InnerRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(InnerRadius)*osgSin(angleNow),0.0);
			
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(InnerRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(InnerRadius)*osgSin(angleNow),getExtrudeLength());
			
			angleNow += angleDiff;
		}
	glEnd();

	//Back
	angleNow = StartAngleRad;
	glBegin(GL_QUAD_STRIP);
	   glNormal3f(0.0,0.0,-1.0);
		for(UInt16 i = 0 ; i<SubDivisions+1 ; ++i)
		{
			glColor4f(CenterColor.red(), CenterColor.green(), CenterColor.blue(), CenterColor.alpha());
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(InnerRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(InnerRadius)*osgSin(angleNow), getExtrudeLength());
			glColor4f(OuterColor.red(), OuterColor.green(), OuterColor.blue(), OuterColor.alpha());
			glVertex3f(static_cast<Real32>(Center.x()) + static_cast<Real32>(OuterRadius)*osgCos(angleNow), static_cast<Real32>(Center.y()) + static_cast<Real32>(OuterRadius)*osgSin(angleNow), getExtrudeLength());
			angleNow += angleDiff;
		}
	glEnd();

	if(CenterColor.alpha() < 1.0 ||
       OuterColor.alpha() < 1.0)
    {
        glDisable(GL_BLEND);
    }
}
Vec3f CylinderDistribution3D::generate(void) const
{
    Vec3f Result;

    switch(getSurfaceOrVolume())
    {
    case SURFACE:
        {
            std::vector<Real32> Areas;
            //Min Cap
            Areas.push_back(0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius()));
            //Max Cap
            Areas.push_back(Areas.back() + 0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius()));
            //Inner Tube
            Areas.push_back(Areas.back() + getInnerRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight());
            //Outer Tube
            Areas.push_back(Areas.back() + getOuterRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight());

            bool HasTubeSides(osgAbs(getMaxTheta() - getMinTheta()) - 6.283185 < -0.000001);
            if(HasTubeSides)
            {
                //MinTheta Tube Side
                Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight());

                //MaxTheta Tube Side
                Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight());
            }

            Real32 PickEdge(RandomPoolManager::getRandomReal32(0.0,1.0));
            if(PickEdge < Areas[0]/Areas.back())
            {
                //Max Cap
                Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0)));
                Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius()));
                Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) );
                Result = getCenter().subZero()
                    + (Radius*osgSin(Theta))*getTangent()
                    + (Radius*osgCos(Theta))*getBinormal()
                    + (getHeight()/static_cast<Real32>(2.0))*getNormal();
            }
            else if(PickEdge < Areas[1]/Areas.back())
            {
                //Min Cap
                Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0)));
                Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius()));
                Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) );
                Result = getCenter().subZero()
                    + (Radius*osgSin(Theta))*getTangent()
                    + (Radius*osgCos(Theta))*getBinormal()
                    + (-getHeight()/static_cast<Real32>(2.0))*getNormal();
            }
            else if(PickEdge < Areas[2]/Areas.back())
            {
                //Inner Tube
                Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) );
                Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0));
                Result =  getCenter().subZero()
                    + getInnerRadius()*osgSin(Theta)*getTangent()
                    + getInnerRadius()*osgCos(Theta)*getBinormal()
                    + Height*getNormal();
            }
            else if(PickEdge < Areas[3]/Areas.back())
            {
                //Outer Tube
                Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) );
                Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0));
                Result =  getCenter().subZero()
                    + getOuterRadius()*osgSin(Theta)*getTangent()
                    + getOuterRadius()*osgCos(Theta)*getBinormal()
                    + Height*getNormal();
            }
            else if(HasTubeSides && PickEdge < Areas[4]/Areas.back())
            {
                //MinTheta Tube Side
                Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0)));
                Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius()));
                Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0));
                Result = getCenter().subZero()
                    + (Radius*osgSin(getMinTheta()))*getTangent()
                    + (Radius*osgCos(getMinTheta()))*getBinormal()
                    + Height*getNormal();
            }
            else if(HasTubeSides && PickEdge < Areas[5]/Areas.back())
            {
                //MaxTheta Tube Side
                Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0)));
                Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius()));
                Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0));
                Result = getCenter().subZero()
                    + (Radius*osgSin(getMaxTheta()))*getTangent()
                    + (Radius*osgCos(getMaxTheta()))*getBinormal()
                    + Height*getNormal();
            }
            else
            {
                assert(false && "Should never reach this point");
            }
            break;
        }
    case VOLUME:
    default:
        {
            //To get a uniform distribution across the disc get a uniformly distributed allong 0.0 - 1.0
            //Then Take the square root of that.  This gives a square root distribution from 0.0 - 1.0
            //This square root distribution is used for the random radius because the area of a disc is 
            //dependant on the square of the radius, i.e it is a quadratic function
            Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0)));
            Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius()));
            Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0));
            Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) );
            Result = getCenter().subZero()
                   + (Radius*osgSin(Theta))*getTangent()
                   + (Radius*osgCos(Theta))*getBinormal()
                   + Height*getNormal();
            break;
        }
    }

    return Result;
}
void SkyBackground::clear(DrawEnv *pEnv)
{
#if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
    glPushAttrib(GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT |
                 GL_LIGHTING_BIT);

    glDisable(GL_LIGHTING);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    Matrix m,t;

/*
    action->getCamera()->getViewing(m, viewport->getPixelWidth(),
                                        viewport->getPixelHeight());
    action->getCamera()->getProjectionTranslation(t,
                                        viewport->getPixelWidth(),
                                        viewport->getPixelHeight());
 */

    m = pEnv->getCameraViewing();
    t = pEnv->getCameraProjectionTrans();

    m.multLeft(t);

    if(getBeacon() != NULL)
    {
        getBeacon()->getToWorld(t);
        m.mult(t);
    }

    m[3][0] = m[3][1] = m[3][2] = 0;
    glLoadMatrixf(m.getValues());

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glLoadIdentity();
    glTranslatef(0.f, 0.f, 0.5);
    glScalef(1.f, 1.f, 0.f);

/*
    action->getCamera()->getProjection(m, viewport->getPixelWidth(),
                                           viewport->getPixelHeight());
 */
    m = pEnv->getCameraProjection();

    glMultMatrixf(m.getValues());

    UInt32 i, j;
    UInt32 sr = _sfSphereRes.getValue() + 1;      // sphere resolution

    if(_cosval.size() != sr)
    {
        Real32 da = 2 * Pi / (sr - 1);

        _cosval.resize(sr);
        _sinval.resize(sr);

        for(i = 0; i < sr; ++i)
        {
            _cosval[i] = osgCos(i * da);
            _sinval[i] = osgSin(i * da);
        }
    }

    Real32  vcos1,vsin1,vcos2,vsin2;

    // better always clear and set a defined color...
    glColor3f(1, 1, 1);
	
	if(_mfSkyColor.size() > 0)
	{
		glClearColor(_mfSkyColor[0][0], _mfSkyColor[0][1],
					 _mfSkyColor[0][2], _mfSkyColor[0][2]);
	}
	else
	{
		glClearColor(0, 0, 0, 1);
	}

	glClear(GL_COLOR_BUFFER_BIT);

    if(_mfSkyAngle.size() > 0)
    {
        vcos1 = osgCos(_mfSkyAngle[0]);
        vsin1 = osgSin(_mfSkyAngle[0]);

        glBegin(GL_TRIANGLE_FAN);
        glColor4fv(
            static_cast<const GLfloat *>(_mfSkyColor[0].getValuesRGBA()));
        glVertex3f(0, 1, 0);
        glColor4fv(
            static_cast<const GLfloat *>(_mfSkyColor[1].getValuesRGBA()));

        for(i = 0; i < sr; ++i)
        {
            glVertex3f(vsin1 * _sinval[i], vcos1, vsin1 * _cosval[i]);
        }

        glEnd();


        for(j = 0; j < _mfSkyAngle.size() - 1; ++j)
        {
            Color4f c1, c2;

            c1 = _mfSkyColor[j+1];
            c2 = _mfSkyColor[j+2];

            vcos1 = osgCos(_mfSkyAngle[j  ]);
            vsin1 = osgSin(_mfSkyAngle[j  ]);
            vcos2 = osgCos(_mfSkyAngle[j+1]);
            vsin2 = osgSin(_mfSkyAngle[j+1]);

            glBegin(GL_TRIANGLE_STRIP);

            for(i = 0; i < sr; ++i)
            {
                glColor4fv(static_cast<const GLfloat *>(c1.getValuesRGBA()));
                glVertex3f(vsin1 * _sinval[i], vcos1, vsin1 * _cosval[i]);
                glColor4fv(static_cast<const GLfloat *>(c2.getValuesRGBA()));
                glVertex3f(vsin2 * _sinval[i], vcos2, vsin2 * _cosval[i]);
            }
            glEnd();
        }

        //if(osgAbs(_mfSkyAngle[j] - Pi) > TypeTraits<Real32>::getDefaultEps())
        {
            glBegin(GL_TRIANGLE_FAN);
            glColor4fv(
                static_cast<const GLfloat *>(_mfSkyColor[j+1].getValuesRGBA()));
            glVertex3f(0, -1, 0);
            vcos1 = osgCos(_mfSkyAngle[j]);
            vsin1 = osgSin(_mfSkyAngle[j]);

            for(i = 0; i < sr; ++i)
            {
                glVertex3f(vsin1 * _sinval[i], vcos1, vsin1 * _cosval[i]);
            }

            glEnd();
        }
    }

    // Draw the ground.
    // It's possible to be smarter about this, but for now just overdraw.

    if(_mfGroundAngle.size() > 0)
    {
        vcos1 = -osgCos(_mfGroundAngle[0]);
        vsin1 =  osgSin(_mfGroundAngle[0]);

        glBegin(GL_TRIANGLE_FAN);

        if(_mfGroundColor.size())
        {
            glColor4fv(
                static_cast<const GLfloat* >(
                    _mfGroundColor[0].getValuesRGBA()));
        }

        glVertex3f(0, -1, 0);

        if(_mfGroundColor.size() > 1)
        {
            glColor4fv(
                static_cast<const GLfloat *>(
                    _mfGroundColor[1].getValuesRGBA()));
        }

        for(i = 0; i < sr; ++i)
        {
            glVertex3f(vsin1 * _sinval[i], vcos1, vsin1 * _cosval[i]);
        }

        glEnd();


        for(j = 0; j < _mfGroundAngle.size() - 1; ++j)
        {
            Color4f c1, c2;

            if (_mfGroundColor.size() > j+2)
            {
                c1 = _mfGroundColor[j+1];
                c2 = _mfGroundColor[j+2];
            }

            vcos1 = -osgCos(_mfGroundAngle[j  ]);
            vsin1 =  osgSin(_mfGroundAngle[j  ]);
            vcos2 = -osgCos(_mfGroundAngle[j+1]);
            vsin2 =  osgSin(_mfGroundAngle[j+1]);

            glBegin(GL_TRIANGLE_STRIP);

            for(i = 0; i < sr; ++i)
            {
                glColor4fv(static_cast<const GLfloat *>(c1.getValuesRGBA()));
                glVertex3f(vsin1 * _sinval[i], vcos1, vsin1 * _cosval[i]);
                glColor4fv(static_cast<const GLfloat *>(c2.getValuesRGBA()));
                glVertex3f(vsin2 * _sinval[i], vcos2, vsin2 * _cosval[i]);
            }
            glEnd();
        }
    }

    // now draw the textures, if set
          StateChunk *tchunk = NULL;
    const Vec3f      *pTexCoords;

    pTexCoords = selectTexCoords(
        getMFBackTexCoord()->size() ? &getMFBackTexCoord()->front() : NULL,
        getBackTexture(), 1);

    drawFace(pEnv, getBackTexture(),   tchunk,
                                         Pnt3f( 0.5, -0.5,  0.5),
                                         Pnt3f(-0.5, -0.5,  0.5),
                                         Pnt3f(-0.5,  0.5,  0.5),
                                         Pnt3f( 0.5,  0.5,  0.5),
                                         pTexCoords             );

    pTexCoords = selectTexCoords(
        getMFFrontTexCoord()->size() ? &getMFFrontTexCoord()->front() : NULL,
        getFrontTexture(), 2);

    drawFace(pEnv, getFrontTexture(),  tchunk,
                                         Pnt3f(-0.5, -0.5, -0.5),
                                         Pnt3f( 0.5, -0.5, -0.5),
                                         Pnt3f( 0.5,  0.5, -0.5),
                                         Pnt3f(-0.5,  0.5, -0.5),
                                         pTexCoords              );

    pTexCoords = selectTexCoords(
        getMFBottomTexCoord()->size() ? &getMFBottomTexCoord()->front() : NULL,
        getBottomTexture(), 3);

    drawFace(pEnv, getBottomTexture(), tchunk,
                                         Pnt3f(-0.5, -0.5,  0.5),
                                         Pnt3f( 0.5, -0.5,  0.5),
                                         Pnt3f( 0.5, -0.5, -0.5),
                                         Pnt3f(-0.5, -0.5, -0.5),
                                         pTexCoords              );

    pTexCoords = selectTexCoords(
        getMFTopTexCoord()->size() ? &getMFTopTexCoord()->front() : NULL,
        getTopTexture(), 4);

    drawFace(pEnv, getTopTexture(),    tchunk,
                                         Pnt3f(-0.5,  0.5, -0.5),
                                         Pnt3f( 0.5,  0.5, -0.5),
                                         Pnt3f( 0.5,  0.5,  0.5),
                                         Pnt3f(-0.5,  0.5,  0.5),
                                         pTexCoords              );

    pTexCoords = selectTexCoords(
        getMFLeftTexCoord()->size() ? &getMFLeftTexCoord()->front() : NULL,
        getLeftTexture(), 5);

    drawFace(pEnv, getLeftTexture(),   tchunk,
                                         Pnt3f(-0.5, -0.5,  0.5),
                                         Pnt3f(-0.5, -0.5, -0.5),
                                         Pnt3f(-0.5,  0.5, -0.5),
                                         Pnt3f(-0.5,  0.5,  0.5),
                                         pTexCoords              );

    pTexCoords = selectTexCoords(
        getMFRightTexCoord()->size() ? &getMFRightTexCoord()->front() : NULL,
        getRightTexture(), 6);

    drawFace(pEnv, getRightTexture(),  tchunk,
                                         Pnt3f( 0.5, -0.5, -0.5),
                                         Pnt3f( 0.5, -0.5,  0.5),
                                         Pnt3f( 0.5,  0.5,  0.5),
                                         Pnt3f( 0.5,  0.5, -0.5),
                                         pTexCoords              );
    if(tchunk != NULL)
        tchunk->deactivate(pEnv);

    Int32 bit = getClearStencilBit();

	glClearDepth(1.f);

    if(bit >= 0)
    {
        glClearStencil(bit);
        glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    }
    else
    {
        glClear(GL_DEPTH_BUFFER_BIT);
    }

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glPopAttrib();

    glColor3f(1.0, 1.0, 1.0);
#endif
}