If you look at the default wpsc-products_page.php template, it uses
while (wpsc_have_products()) : wpsc_the_product();
instead of have_posts() and the_posts() to setup the loop.
The wpsc_the_product() function sets up a global $wpsc_variations object that the product variation functions use.
I think in order to use wpsc_the_product() you need your query to be the global $wp_query, but you can setup $wpsc_variations yourself after you open your loop:
while ($loop->have_posts()) : $loop->the_post();
global $wpsc_variations;
$wpsc_variations = new wpsc_variations( get_the_ID() );
That hopefully should get all the product variation functions working.
This is the full wpsc_the_product() function. It also sets up global $wpsc_custom_meta, which could potentially have a similar affect on custom meta related functions, so that is something else you might need to consider.
/**
* wpsc the product function, gets the next product,
* @return nothing
*/
function wpsc_the_product() {
global $wpsc_custom_meta, $wpsc_variations;
the_post();
$wpsc_custom_meta = new wpsc_custom_meta( get_the_ID() );
$wpsc_variations = new wpsc_variations( get_the_ID() );
}
Hope this helps.