i32 CreateRect2D(Resources::CMesh* pMesh, const IInputLayout* pIL, const SRect2DOptions& Opts)
    {
        Vec3 vecScale( 100 ); 
        Vec2 vecWidth( 0, 100 );
        Vec2 vecHeight( 0, 100 );

        IndexBufferPtr pIB = pMesh->CreateIndexBuffer();
        VertexBufferPtr pVB = pMesh->CreateVertexBuffer();

        pVB->SetVertexCount( 4 );
        pVB->SetInputLayout( pIL );
        pVB->SetTopologyType( TopologyTypes::TRIANGLE_LIST );
        pVB->SetUsage( Opts.eUsage );

        pIB->SetIndexCount( 6 );
        pIB->SetUsage( BufferUsages::STATIC );

        pVB->Lock();
        CVertexData& VData = pVB->GetVertexData();

        if( pIL->IsPosition() )
        {
            VData.SetPosition( 0, Vec3( 0,			0,				0 ) );
            VData.SetPosition( 1, Vec3( vecScale.x, 0,				0 ) );
            VData.SetPosition( 2, Vec3( vecScale.x, -vecScale.y,	0 ) );
            VData.SetPosition( 3, Vec3( 0,			-vecScale.y,	0) );
        }

        if( pIL->IsColor() )
        {
            VData.SetColor( 0, Vec4( 1, 1, 1, 1 ) );
            VData.SetColor( 1, Vec4( 1, 1, 1, 1 ) );
            VData.SetColor( 2, Vec4( 1, 1, 1, 1 ) );
            VData.SetColor( 3, Vec4( 1, 1, 1, 1 ) );
        }

        if( pIL->IsTexCoord0() )
        {
            VData.SetTexCoord( 0, 0, Vec2( 0, 1 ) );
            VData.SetTexCoord( 1, 0, Vec2( 1, 1 ) );
            VData.SetTexCoord( 2, 0, Vec2( 0, 1 ) );
            VData.SetTexCoord( 3, 0, Vec2( 0, 0 ) );
        }

        pVB->Unlock();
        pVB->Create();

        pIB->Lock();
        CIndexData& IData = pIB->GetIndexData();

        IData.SetTriangle( 0, 0, 2, 3 );
        IData.SetTriangle( 1, 1, 2, 0 );

        return XST_OK;
    }
    i32 CreateBox(Resources::CMesh* pMesh, const IInputLayout* pIL, const SLineBoxOptions& Options)
    {

        ul32 ulVertCount = 8; 
        ul32 ulIndexCount = 24; //8 * 2 + 2 * 4; 8 per front/back, 4 per left, right
        VertexBufferPtr pVB = pMesh->CreateVertexBuffer();
        
        pVB->SetTopologyType( TopologyTypes::LINE_LIST );
        pVB->SetUsage( BufferUsages::DEFAULT );
        pVB->SetVertexCount( ulVertCount );
        pVB->SetInputLayout( pIL );

        if( XST_FAILED( pVB->Lock() ) )
        {
            return XST_FAIL;
        }

        CVertexData& Data = pVB->GetVertexData();

        cf32 fUnit = 1.0f;
        ul32 vs = pIL->GetVertexSize();
        const Vec3 vecSize( Options.vecSize * 0.5f );
        const Vec3 vecPos( vecSize + Options.vecPos );

        Vec3 aCorners[ Resources::BoxCorners::_ENUM_COUNT ];
        aCorners[ Resources::BoxCorners::LEFT_BOTTOM_BACK ]	= Vec3( -vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::LEFT_BOTTOM_FRONT ]	= Vec3( -vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::LEFT_TOP_BACK ]		= Vec3( -vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::LEFT_TOP_FRONT ]		= Vec3( -vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::RIGHT_BOTTOM_BACK ]	= Vec3( vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::RIGHT_BOTTOM_FRONT ]	= Vec3( vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::RIGHT_TOP_FRONT ]		= Vec3( vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos;
        aCorners[ Resources::BoxCorners::RIGHT_TOP_BACK ]		= Vec3( vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos;

        /*for(i32 i = 0; i < BoxCorners::_ENUM_COUNT; ++i)
        {
            XST::CDebug::PrintDebugLN( XST::ToStr() << XST_GET_DBG_NAME( pMesh ) << (BOX_CORNER)i << aCorners[ i ] );
        }*/

        if( pIL->IsPosition() )
        {
            for(u32 i = 0; i < Resources::BoxCorners::_ENUM_COUNT; ++i)
            {
                Data.SetPosition( i, aCorners[ i ] );
            }
        }

        if( pIL->IsColor() )
        {
            f32 fc = 0.05f;
            for(ul32 i = 0; i < ulVertCount; ++i)
            {
                Data.SetColor( i, Options.colColor.ToVector4() ); 
            }
        }

        if( XST_FAILED( pVB->Unlock() ) )
        {
            return XST_FAIL;
        }

        IndexBufferPtr pIB = pMesh->CreateIndexBuffer();
        pIB->SetUsage( BufferUsages::DEFAULT );
        pIB->SetIndexCount( ulIndexCount );
        
        if( XST_FAILED( pIB->Lock() ) )
        {
            return XST_FAIL;
        }

        CIndexData& IData = pIB->GetIndexData();

        //Front
        IData.SetIndex( 0, Resources::BoxCorners::LEFT_BOTTOM_FRONT );
        IData.SetIndex( 1, Resources::BoxCorners::LEFT_TOP_FRONT );

        IData.SetIndex( 2, Resources::BoxCorners::LEFT_TOP_FRONT );
        IData.SetIndex( 3, Resources::BoxCorners::RIGHT_TOP_FRONT );

        IData.SetIndex( 4, Resources::BoxCorners::RIGHT_TOP_FRONT );
        IData.SetIndex( 5, Resources::BoxCorners::RIGHT_BOTTOM_FRONT );

        IData.SetIndex( 6, Resources::BoxCorners::RIGHT_BOTTOM_FRONT );
        IData.SetIndex( 7, Resources::BoxCorners::LEFT_BOTTOM_FRONT );
        
        //Back
        IData.SetIndex( 8, Resources::BoxCorners::LEFT_BOTTOM_BACK );
        IData.SetIndex( 9, Resources::BoxCorners::LEFT_TOP_BACK );

        IData.SetIndex( 10, Resources::BoxCorners::LEFT_TOP_BACK );
        IData.SetIndex( 11, Resources::BoxCorners::RIGHT_TOP_BACK );

        IData.SetIndex( 12, Resources::BoxCorners::RIGHT_TOP_BACK );
        IData.SetIndex( 13, Resources::BoxCorners::RIGHT_BOTTOM_BACK );

        IData.SetIndex( 14, Resources::BoxCorners::RIGHT_BOTTOM_BACK );
        IData.SetIndex( 15, Resources::BoxCorners::LEFT_BOTTOM_BACK );

        //Left
        IData.SetIndex( 16, Resources::BoxCorners::LEFT_BOTTOM_FRONT );
        IData.SetIndex( 17, Resources::BoxCorners::LEFT_BOTTOM_BACK );

        IData.SetIndex( 18, Resources::BoxCorners::LEFT_TOP_FRONT );
        IData.SetIndex( 19, Resources::BoxCorners::LEFT_TOP_BACK );

        //Right
        IData.SetIndex( 20, Resources::BoxCorners::RIGHT_BOTTOM_FRONT );
        IData.SetIndex( 21, Resources::BoxCorners::RIGHT_BOTTOM_BACK );

        IData.SetIndex( 22, Resources::BoxCorners::RIGHT_TOP_FRONT );
        IData.SetIndex( 23, Resources::BoxCorners::RIGHT_TOP_BACK );

        if( XST_FAILED( pIB->Unlock() ) )
        {
            return XST_FAIL;
        }

        CBoundingVolume Vol;
        Vol.BuildFromMinMax( aCorners[ Resources::BoxCorners::LEFT_BOTTOM_BACK ], aCorners[ Resources::BoxCorners::RIGHT_TOP_FRONT ] );
        pMesh->SetBoundingVolume( Vol );

        return XST_OK;
    }
    i32 CreatePlane(Resources::CMesh* pMesh, const IInputLayout* pIL, const SPlaneOptions& Opts)
    {
        bool bIsNormal = pIL->IsNormal();
        u16 ulVVertCount = (u16)Opts.vecVertexCount.x;
        u16 ulHVertCount = (u16)Opts.vecVertexCount.y;
        ul32 ulVertCount = ulVVertCount * ulHVertCount;
        //ul32 ulIndexCount = 36;
        VertexBufferPtr pVB = pMesh->CreateVertexBuffer();
        pVB->SetInputLayout( pIL );
        
        pVB->SetTopologyType( TopologyTypes::TRIANGLE_STRIP );
        pVB->SetUsage( BufferUsages::DEFAULT );
        pVB->SetVertexCount( ulVertCount );
        pVB->SetInputLayout( pIL );

        pVB->Lock();

        CVertexData& Data = pVB->GetVertexData();

        cf32 fUnit = 1.0f;
        ul32 vs = pIL->GetVertexSize();
        Vec2 vecTC( Vec2::ZERO );
        Vec3 vecTmpPos;

        if( pIL->IsPosition() )
        {
            ul32 ulVertId = 0;
            Vec2 vecVertDist( Opts.vecSize.x / ( Opts.vecVertexCount.x - 1 ), Opts.vecSize.y / ( Opts.vecVertexCount.y - 1 ) );
            Vec2 vecPos( Vec2::ZERO );

            for(ul32 y = 0; y < ulVVertCount; ++y, vecPos.y += vecVertDist.y)
            {
                for(ul32 x = 0; x < ulHVertCount; ++x, vecPos.x += vecVertDist.x)
                {
                    vecTmpPos = Vec3( vecPos.x, 0, vecPos.y );
                    Data.SetPosition( ulVertId, vecTmpPos );
                    if( pIL->IsTexCoord0() )
                    {
                        vecTC.x = vecTmpPos.x / Opts.vecSize.x;
                        vecTC.y = vecTmpPos.z / Opts.vecSize.y;
                        Data.SetTexCoord0( ulVertId, vecTC );
                    }

                    ++ulVertId;
                }

                vecPos.x = 0.0f;
            }
        }

        if( pIL->IsColor() )
        {
            f32 fc = 0.05f;
            for(ul32 i = 0; i < ulVertCount; ++i)
            {
                Data.SetColor( i, XST::CColor::Random().ToVector4() + Vec4( 0.2f, 0.2f, 0.2f, 0.0f ) ); 
            }
        }

        if( bIsNormal )
        {
            for(u32 i = 0; i < ulVertCount; ++i)
            {
                Data.SetNormal( i, Opts.vecNormal );
            }
        }

        pVB->Unlock();
        pVB->Create();


        IndexBufferPtr pIB = pMesh->CreateIndexBuffer();
        pIB->SetUsage( BufferUsages::DEFAULT );
        u16 ulIndexCount = ( ulHVertCount * 2 ) * ( ulVVertCount - 1 ) + ( ulVVertCount - 2 );
        pIB->SetIndexCount( ulIndexCount );
        pIB->Lock();

        CIndexData& IndexData = pIB->GetIndexData();

        ul32 ulIndex = 0;
        for(u16 z = 0; z < ulVVertCount - 1; ++z)
        {
            if( z % 2 == 0 )
            {
                i16 x;
                for(x = 0; x < ulHVertCount; ++x )
                {
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) );
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) + ulHVertCount );
                }

                if( z != ulVVertCount - 2 )
                {
                    IndexData.SetIndex( ulIndex++, --x + ( z * ulHVertCount ) );
                }
            }
            else
            {
                i16 x;
                for(x = ulHVertCount - 1; x >= 0; --x )
                {
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) );
                    IndexData.SetIndex( ulIndex++, x + ( z * ulHVertCount ) + ulHVertCount );
                }

                if( z != ulVVertCount - 2 )
                {
                    IndexData.SetIndex( ulIndex++, ++x + ( z * ulHVertCount ) );
                }
            }
        }

        pIB->Unlock();
        pIB->Create();

        return XST_OK;
    }
    i32 CreateBox(Resources::CMesh* pMesh, const IInputLayout* pIL, const SBoxOptions& Options)
    {
        bool bIsNormal = pIL->IsNormal();
        ul32 ulVertCount = ( bIsNormal )? 24 : 8; //if there are normals use more vertices
        ul32 ulIndexCount = 36;
        VertexBufferPtr pVB = pMesh->CreateVertexBuffer();
        
        pVB->SetTopologyType( TopologyTypes::TRIANGLE_LIST );
        pVB->SetUsage( BufferUsages::DEFAULT );
        pVB->SetVertexCount( ulVertCount );
        pVB->SetInputLayout( pIL );

        pVB->Lock();

        CVertexData& Data = pVB->GetVertexData();

        cf32 fUnit = 1.0f;
        ul32 vs = pIL->GetVertexSize();
        const Vec3 vecSize( Options.vecSize * 0.5f );
        const Vec3 vecPos( vecSize + Options.vecPos );

        if( pIL->IsPosition() )
        {
            if( bIsNormal )
            {
                Data.SetPosition( 0, Vec3( -vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos );
                Data.SetPosition( 1, Vec3( vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 2, Vec3( vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos  ); 
                Data.SetPosition( 3, Vec3( -vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos );

                Data.SetPosition( 4, Vec3( -vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos );
                Data.SetPosition( 5, Vec3( -vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 6, Vec3( -vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 7, Vec3( -vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos );

                Data.SetPosition( 8, Vec3( vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 9, Vec3( vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 10, Vec3( vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 11, Vec3( vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos ); 

                Data.SetPosition( 12, Vec3( -vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 13, Vec3( vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos );
                Data.SetPosition( 14, Vec3( vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 15, Vec3( -vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos );

                Data.SetPosition( 16, Vec3( -vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos );
                Data.SetPosition( 17, Vec3( vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos );
                Data.SetPosition( 18, Vec3( vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos  ); 
                Data.SetPosition( 19, Vec3( -vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos ); 

                Data.SetPosition( 20, Vec3( -vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 21, Vec3( vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 22, Vec3( vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 23, Vec3( -vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos ); 
                
            }
            else
            {
                Data.SetPosition( 0, Vec3( -vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 1, Vec3( vecSize.x, vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 2, Vec3( vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 3, Vec3( -vecSize.x, vecSize.y, vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 4, Vec3( -vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 5, Vec3( vecSize.x, -vecSize.y, -vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 6, Vec3( vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos ); 
                Data.SetPosition( 7, Vec3( -vecSize.x, -vecSize.y, vecSize.z ) + Options.vecPos ); 
            }
        }

        if( pIL->IsColor() )
        {
            f32 fc = 0.05f;
            for(ul32 i = 0; i < ulVertCount; ++i)
            {
                /*Data.SetColor( 0, Vec4( 1, 0, 0, 1 ) ); 
                Data.SetColor( 1, Vec4( 1, 1, 1, 1 ) ); 
                Data.SetColor( 2, Vec4( 0, 1, 0, 1 ) ); 
                Data.SetColor( 3, Vec4( 0.5, 0.3, 1, 1 ) ); */
                Data.SetColor( i, Options.colColor.ToVector4() ); 
            }
        }

        if( bIsNormal )
        {
            Data.SetNormal( 0, Vec3( -1, 1, -1 ) ); 
            Data.SetNormal( 1, Vec3( 1, 1, -1 ) ); 
            Data.SetNormal( 2, Vec3( 1, 1, 1 ) ); 
            Data.SetNormal( 3, Vec3( -1, 1, 1 ) ); 
            Data.SetNormal( 4, Vec3( -1, -1, -1 ) ); 
            Data.SetNormal( 5, Vec3( 1, -1, -1 ) ); 
            Data.SetNormal( 6, Vec3( 1, -1, 1 ) ); 
            Data.SetNormal( 7, Vec3( -1, -1, 1 ) ); 
        }

        pVB->Unlock();
        pVB->Create();

        IndexBufferPtr pIB = pMesh->CreateIndexBuffer();
        pIB->SetUsage( BufferUsages::DEFAULT );
        pIB->SetIndexCount( ulIndexCount );
        pIB->Lock();

        CIndexData& IndexData = pIB->GetIndexData();

        if( bIsNormal )
        {
            //Front
            IndexData.AddTriangle( 3, 1, 0 );
            IndexData.AddTriangle( 2, 1, 3 );
            //Back
            IndexData.AddTriangle( 6, 4, 5 );
            IndexData.AddTriangle( 7, 4, 6 );
            //Top
            IndexData.AddTriangle( 11,9,8 );
            IndexData.AddTriangle( 10,9,11 );
            //Bottom
            IndexData.AddTriangle( 14,12,13 );
            IndexData.AddTriangle( 15,12,14 );
            //Left
            IndexData.AddTriangle( 19,17,16 );
            IndexData.AddTriangle( 18,17,19 );
            //Right
            IndexData.AddTriangle( 22,20,21 );
            IndexData.AddTriangle( 23,20,22 );
        }
        else
        {
            IndexData.AddTriangle( 3, 1, 0 );
            IndexData.AddTriangle( 2, 1, 3 );

            IndexData.AddTriangle( 0, 5, 4 );
            IndexData.AddTriangle( 1, 5, 0 );

            IndexData.AddTriangle( 3, 4, 7 );
            IndexData.AddTriangle( 0, 4, 3 );

            IndexData.AddTriangle( 1, 6, 5 );
            IndexData.AddTriangle( 2, 6, 1 );

            IndexData.AddTriangle( 2, 7, 6 );
            IndexData.AddTriangle( 3, 7, 2 );

            IndexData.AddTriangle( 6, 4, 5 );
            IndexData.AddTriangle( 7, 4, 6 );

        }

        XST_RET_FAIL( pIB->Unlock() );
        XST_RET_FAIL( pIB->Create() );

        CBoundingVolume Vol;
        Vol.BuildFromMinMax( -vecSize + Options.vecPos, vecSize + Options.vecPos );
        pMesh->SetBoundingVolume( Vol );

        return XST_OK;
    }