TGEA Seamless Cubemap Builder
by Lorne McIntosh · 04/24/2008 (8:55 am) · 6 comments
Download Code File
Set Up
To start off, create a new script file in your data/server/scripts folder. We've named ours "buildcubemap.cs". Copy/Paste the code at the bottom of this article into your new script file (or download it from the resource link above).
To make sure the code executes when running the game, also include the following line in your game.cs inside the function onServerCreated().
exec("./buildcubemap.cs");
How to Run the thing
Pick the point at which you want the cubemap to be generated from (most likely the center of your room or environment). An easy way I have found to do it is walk your player to that spot, hit F11 to go into the mission editor mode, hit Alt-C to go into free-cam mode, select your player by clicking on them, hit F3 to view the player properties and then scroll down to get the xyz coordinates of where your player is located. Another way is to create an object and just move it to where you want the camera to be, get the xyz location and then delete it.
Open up your console and type the following code but replacing the stuff in quotes with real data.
buildcubemap("x y z", "texture size");
"X Y Z" is the xyz coordinates that you want the cubemap to be generated from. "texture size" is the size of the texture you want to generate.
example: buildcubemap("0 0 0", "512");
That example code would take 6 pictures starting at the origin of the map, and output them as 512x512 .png files into your games root directory.
Important!: This tool literally takes screenshots of torque so make sure you close the mission editor and don't move the mouse while the application is running. Make sure any models that aren't supposed to be in the scene have been removed or they will appear in your cubemaps. If you are also inspecting the code, you will notice that the first image doesn't come out correct so I've added a little piece of code to take that into consideration.
Manual Work
We couldn't figure out how to get the camera to rotate and take the screenshots with the correct orientation so you will need to re-orient the images manually using Photoshop or a similar graphics tool:
ypos - needs to rotate 180
xneg - needs to rotate 90 clockwise
yneg - perfect
xpos - needs to rotate 90 counter-clockwise
zneg - needs to rotate 180
zpos - perfect
All Done
Hopefully from this you have 6 images that will generate a seamless cubemap.
Set Up
To start off, create a new script file in your data/server/scripts folder. We've named ours "buildcubemap.cs". Copy/Paste the code at the bottom of this article into your new script file (or download it from the resource link above).
To make sure the code executes when running the game, also include the following line in your game.cs inside the function onServerCreated().
exec("./buildcubemap.cs");
How to Run the thing
Pick the point at which you want the cubemap to be generated from (most likely the center of your room or environment). An easy way I have found to do it is walk your player to that spot, hit F11 to go into the mission editor mode, hit Alt-C to go into free-cam mode, select your player by clicking on them, hit F3 to view the player properties and then scroll down to get the xyz coordinates of where your player is located. Another way is to create an object and just move it to where you want the camera to be, get the xyz location and then delete it.
Open up your console and type the following code but replacing the stuff in quotes with real data.
buildcubemap("x y z", "texture size");
"X Y Z" is the xyz coordinates that you want the cubemap to be generated from. "texture size" is the size of the texture you want to generate.
example: buildcubemap("0 0 0", "512");
That example code would take 6 pictures starting at the origin of the map, and output them as 512x512 .png files into your games root directory.
Important!: This tool literally takes screenshots of torque so make sure you close the mission editor and don't move the mouse while the application is running. Make sure any models that aren't supposed to be in the scene have been removed or they will appear in your cubemaps. If you are also inspecting the code, you will notice that the first image doesn't come out correct so I've added a little piece of code to take that into consideration.
Manual Work
We couldn't figure out how to get the camera to rotate and take the screenshots with the correct orientation so you will need to re-orient the images manually using Photoshop or a similar graphics tool:
ypos - needs to rotate 180
xneg - needs to rotate 90 clockwise
yneg - perfect
xpos - needs to rotate 90 counter-clockwise
zneg - needs to rotate 180
zpos - perfect
All Done
Hopefully from this you have 6 images that will generate a seamless cubemap.
//-----------------------------------------
//buildcubemap.cs
//-----------------------------------------
//build a cubemap of the given size rendered from the given position
function buildcubemap(%position, %size)
{
%delay = 1000;
%HalfPI = 3.14159265359 / 2.0;
echo("Building cubemap...");
//save the current settings
%oldControl = LocalClientConnection.getControlObject();
%oldMode = canvas.getVideoMode();
//set camera as control object
LocalClientConnection.setControlObject(LocalClientConnection.camera);
//set resolution
canvas.setVideoMode(%size, %size, Canvas.isFullScreen());
//turn off console & HUD so it's not in the screenshot
Canvas.popDialog(ConsoleDlg);
Canvas.popDialog(MainChatHud);
//the first setTransform doesn't work properly for some reason, let's get it over with now
LocalClientConnection.camera.schedule(%delay*1, "setTransform", %position @ " 0 0 1 0");
//take the 6 screenshots
// ideally cubemaps would come out perfect and ready to use, but torque doesn't support
// rolling the camera so you'll need to apply the specified rotations manually in photoshop
LocalClientConnection.camera.schedule(%delay*2, "setTransform", %position @ " 0 0 1 0"); //rotate 180 in photoshop
schedule(%delay*3, 0, "screenshot", "cubemap_ypos.png", "PNG");
LocalClientConnection.camera.schedule(%delay*4, "setTransform", %position @ " 0 0 1 " @ %HalfPI); //rotate 90 counter-clockwise in photoshop
schedule(%delay*5, 0, "screenshot", "cubemap_xpos.png", "PNG");
LocalClientConnection.camera.schedule(%delay*6, "setTransform", %position @ " 0 0 1 " @ %HalfPI*2);
schedule(%delay*7, 0, "screenshot", "cubemap_yneg.png", "PNG");
LocalClientConnection.camera.schedule(%delay*8, "setTransform", %position @ " 0 0 1 " @ %HalfPI*3); //rotate 90 clockwise in photoshop
schedule(%delay*9, 0, "screenshot", "cubemap_xneg.png", "PNG");
LocalClientConnection.camera.schedule(%delay*10, "setTransform", %position @ " 1 0 0 " @ %HalfPI); //rotate 180 in photoshop
schedule(%delay*11, 0, "screenshot", "cubemap_zneg.png", "PNG");
LocalClientConnection.camera.schedule(%delay*12, "setTransform", %position @ " -1 0 0 " @ %HalfPI);
schedule(%delay*13, 0, "screenshot", "cubemap_zpos.png", "PNG");
//set the video mode back
canvas.schedule(%delay*14, "setVideoMode", getWord(%oldMode, $WORD::RES_X), getWord(%oldMode, $WORD::RES_Y), Canvas.isFullScreen());
//set the control object back
LocalClientConnection.schedule(%delay*14, "setControlObject", %oldControl);
//turn console & HUD back on
canvas.schedule(%delay*14, "pushDialog", ConsoleDlg, 99);
canvas.schedule(%delay*14, "pushDialog", MainChatHud );
//aaaand we're done!
schedule(%delay*15, "echo", "Done!");
}About the author
Ubiq Visuals is a software and creative content developer for the entertainment industry. Our vision is to provide inspiration and the tools for soon-to-be game designers and creative minds of all ages.
#2
[edit]
Nevermind, just browsed the script more thoroughly and I see now that it just generates the images... And then you have to edit them!
Still, good and useful script. Nice work.
[/edit]
04/24/2008 (7:44 pm)
Is this similar in function, to say... The Source engine, where in the Hammer editor you plop down a env_cubemap entity and in game you type "build_cubemaps", and it generates a cubemap for each entity laid down in the level... and then anything that needs a cubemap references those images? Or does it just basically generate the images and you do the rest as needed?[edit]
Nevermind, just browsed the script more thoroughly and I see now that it just generates the images... And then you have to edit them!
Still, good and useful script. Nice work.
[/edit]
#3
04/25/2008 (12:47 am)
I was just busy with Cubemaps. I do have a problem however (not with your script). How would you change the Cubemap from Level-to-Level? Not everyone only has one mission. I've been wondering about this the past day.
#4
04/26/2008 (12:15 am)
@James: What I've done for that is to export all relevant models so that they can accept setskins (make sure they are named base.mytexturename) and then place a setting in the missionfile to specify the missiontype setting. Then when these models load you can do a setskin with that specifier. Have the material for the new skin be the same as before, but with the relevant cubemap, or color settings for that map in the new materials.
#5
Yeah, the way Valve handles cubemaps in Source engine is nearly perfect. I love that system. One day I'd like to combine this resource with J.C. Smith's excellent suggestion above to create something similar. Objects would automatically switch their cubemap based on which "env_cubemap" entity they are currently closest to. It might not even be that hard... but probably won't happen for a long time.
04/27/2008 (7:21 pm)
@NathanYeah, the way Valve handles cubemaps in Source engine is nearly perfect. I love that system. One day I'd like to combine this resource with J.C. Smith's excellent suggestion above to create something similar. Objects would automatically switch their cubemap based on which "env_cubemap" entity they are currently closest to. It might not even be that hard... but probably won't happen for a long time.
#6
02/05/2012 (9:45 pm)
Yes! So glad I came across this, thank you! 
Torque Owner Jason "fireVein" Culwell