Precipitations Tutorial
by Xavier "eXoDuS" Amado · 01/05/2002 (12:33 pm) · 20 comments
Seeing that lots of people have had some problems with putting rain, snow, etc in their games i'm writing this little tutorial that will help you do all the modifications you need.
First of all let's create a new script file called precipitations or something ... (ie. fps/server/scripts/precipitations.cs). In that file we need to declare the precipitation data blocks, like this:
datablock PrecipitationData(Rain)
{
type = 1;
materialList = "~/data/specialfx/raindrops.dml";
sizeX = 0.10;
sizeY = 0.10;
movingBoxPer = 0.35;
divHeightVal = 1.5;
sizeBigBox = 1;
topBoxSpeed = 20;
frontBoxSpeed = 30;
topBoxDrawPer = 0.5;
bottomDrawHeight = 40;
skipIfPer = -0.3;
bottomSpeedPer = 1.0;
frontSpeedPer = 1.5;
frontRadiusPer = 0.5;
};
//-------------------- SNOW -----------------------------------------------------
datablock PrecipitationData(Snow)
{
type = 1;
materialList = "~/data/specialfx/snowflakes.dml";
sizeX = 0.10;
sizeY = 0.10;
movingBoxPer = 0.35;
divHeightVal = 1.5;
sizeBigBox = 1;
topBoxSpeed = 20;
frontBoxSpeed = 30;
topBoxDrawPer = 0.5;
bottomDrawHeight = 40;
skipIfPer = -0.3;
bottomSpeedPer = 1.0;
frontSpeedPer = 1.5;
frontRadiusPer = 0.5;
};
Now we need to load this file, open up game.cs and add the following line where similar lines are (ie, after the exec("./player.cs"); line should be ok):
exec("./precipitations.cs");
That will declare two datablocks for us to use in our missions, rain and snow. Notice the materialList line... its pointing to a .dml file, we have to create this file which is just a simple text file that points to the textures we want to use. For our example we will put the textures in the same dir as the dml file. So go ahead, open up notepad, vim or your editor of choice and make a file that contains the name of the textures you are gonna use, for example if you have only one texture called raindrops.png in the same dir as the .dml file you would put this:
raindrops
If you have several textures you just add the names of the textures, for example:
raindrop1
raindrop2
raindrop3
You should press ENTER after you type raindrops so that you create a blank line below it.. this IS IMPORTANT. Now save that file as ~/data/specialfx/raindrops.dml
Create another file but this time add (i you have a snowflakes.png):
snowflakes
Dont forget the ENTER please! Save this one as ~/data/specialfx/snowflakes.dml
Now open up the mission file (.mis) in which you want to add the rain or snow and add something like this (change the datablock if you want to):
new Precipitation(Precipitation) {
position = "0 0 0";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "Rain";
percentage = "1";
color1 = "1.000000 1.000000 1.000000 1.000000";
color2 = "-1.000000 0.000000 0.000000 1.000000";
color3 = "-1.000000 0.000000 0.000000 1.000000";
offsetSpeed = "0.25";
minVelocity = "1.5";
maxVelocity = "3.5";
maxNumDrops = "2000";
maxRadius = "100";
locked = "true";
};
Now we need to do some engine source code changes...
open up game/fx/precipitation.cc
and find the function "void Precipitation::loadDml()"
just after the opening brace of this function (the very top) add this code:
//Added code
char path[1024], *p;
dStrcpy( path, mDataBlock->mMaterialListName );
if( (p = dStrrchr( path, '/')) != NULL )
*p = 0;
Now a few lines after that you should see a line like this one:
mMaterialList.load();
change it to look like this
mMaterialList.load(path);
Ok now you need to make a decision. You can make your precipitation textures in 2 ways. The first one and default one includes 9 different drops or flakes in 1 texture (only one .png file for 9 drops or flakes). The other way round you need to modify some engine code so that you would be able to have each flake/drop in a different file. Personally i left it as it was and used a texture i got from tribes 2 :)
If you want to use each raindrop or snowflake in a different file do this:
In precipitation.cc look for a line that looks like this: glTexCoord2f(coordX, coordY); and change all the glTexCoord2f lines to look like in the code below (in the code below the old glTexCoord where commented out and the new ones where typed below). The only thing that changes is that instead of being passed a coordX and a coordY the texture coordinates are set to 0 and 0. This way you would use each texture completely for each flake/drop.
// glTexCoord2f(coordX, coordY);
glTexCoord2f(0, 0);
glVertex3f(point[0].x, point[0].y, point[0].z);
// glTexCoord2f(coordX, coordY + 0.25);
glTexCoord2f(0, 1.0);
glVertex3f(point[1].x, point[1].y, point[1].z);
// glTexCoord2f(coordX + 0.25, coordY + 0.25);
glTexCoord2f(1.0, 1.0);
glVertex3f(point[2].x, point[2].y, point[2].z);
// glTexCoord2f(coordX + 0.25, coordY);
glTexCoord2f(1.0, 0);
glVertex3f(point[3].x, point[3].y, point[3].z);
Well now you have to create you snowflake and raindrop texture(s). If you left the code unchanged you'll have to make a texture with 9 flakes in it. I dont have much information on how to create this texture since i used a tribes 2 one. I found it in the special dir in tribes2. If you dont have tribes 2 email me and ill give you a hand with creating this 9x9 textures.
Otherwise you'll have to create each flake or drop in a separate file which is easier. The images should have an alpha channel for the background. Well that's all, hope you enjoy your new weather :)
If there's any bug in this tutorial please e-mail me asap and ill fix it!
Well enjoy, and wait for my character selection tutorial :)
PD: Special thanks go to SnowMan which told me about the needed engine changes :)
Thanks a lot man!
First of all let's create a new script file called precipitations or something ... (ie. fps/server/scripts/precipitations.cs). In that file we need to declare the precipitation data blocks, like this:
datablock PrecipitationData(Rain)
{
type = 1;
materialList = "~/data/specialfx/raindrops.dml";
sizeX = 0.10;
sizeY = 0.10;
movingBoxPer = 0.35;
divHeightVal = 1.5;
sizeBigBox = 1;
topBoxSpeed = 20;
frontBoxSpeed = 30;
topBoxDrawPer = 0.5;
bottomDrawHeight = 40;
skipIfPer = -0.3;
bottomSpeedPer = 1.0;
frontSpeedPer = 1.5;
frontRadiusPer = 0.5;
};
//-------------------- SNOW -----------------------------------------------------
datablock PrecipitationData(Snow)
{
type = 1;
materialList = "~/data/specialfx/snowflakes.dml";
sizeX = 0.10;
sizeY = 0.10;
movingBoxPer = 0.35;
divHeightVal = 1.5;
sizeBigBox = 1;
topBoxSpeed = 20;
frontBoxSpeed = 30;
topBoxDrawPer = 0.5;
bottomDrawHeight = 40;
skipIfPer = -0.3;
bottomSpeedPer = 1.0;
frontSpeedPer = 1.5;
frontRadiusPer = 0.5;
};
Now we need to load this file, open up game.cs and add the following line where similar lines are (ie, after the exec("./player.cs"); line should be ok):
exec("./precipitations.cs");
That will declare two datablocks for us to use in our missions, rain and snow. Notice the materialList line... its pointing to a .dml file, we have to create this file which is just a simple text file that points to the textures we want to use. For our example we will put the textures in the same dir as the dml file. So go ahead, open up notepad, vim or your editor of choice and make a file that contains the name of the textures you are gonna use, for example if you have only one texture called raindrops.png in the same dir as the .dml file you would put this:
raindrops
If you have several textures you just add the names of the textures, for example:
raindrop1
raindrop2
raindrop3
You should press ENTER after you type raindrops so that you create a blank line below it.. this IS IMPORTANT. Now save that file as ~/data/specialfx/raindrops.dml
Create another file but this time add (i you have a snowflakes.png):
snowflakes
Dont forget the ENTER please! Save this one as ~/data/specialfx/snowflakes.dml
Now open up the mission file (.mis) in which you want to add the rain or snow and add something like this (change the datablock if you want to):
new Precipitation(Precipitation) {
position = "0 0 0";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "Rain";
percentage = "1";
color1 = "1.000000 1.000000 1.000000 1.000000";
color2 = "-1.000000 0.000000 0.000000 1.000000";
color3 = "-1.000000 0.000000 0.000000 1.000000";
offsetSpeed = "0.25";
minVelocity = "1.5";
maxVelocity = "3.5";
maxNumDrops = "2000";
maxRadius = "100";
locked = "true";
};
Now we need to do some engine source code changes...
open up game/fx/precipitation.cc
and find the function "void Precipitation::loadDml()"
just after the opening brace of this function (the very top) add this code:
//Added code
char path[1024], *p;
dStrcpy( path, mDataBlock->mMaterialListName );
if( (p = dStrrchr( path, '/')) != NULL )
*p = 0;
Now a few lines after that you should see a line like this one:
mMaterialList.load();
change it to look like this
mMaterialList.load(path);
Ok now you need to make a decision. You can make your precipitation textures in 2 ways. The first one and default one includes 9 different drops or flakes in 1 texture (only one .png file for 9 drops or flakes). The other way round you need to modify some engine code so that you would be able to have each flake/drop in a different file. Personally i left it as it was and used a texture i got from tribes 2 :)
If you want to use each raindrop or snowflake in a different file do this:
In precipitation.cc look for a line that looks like this: glTexCoord2f(coordX, coordY); and change all the glTexCoord2f lines to look like in the code below (in the code below the old glTexCoord where commented out and the new ones where typed below). The only thing that changes is that instead of being passed a coordX and a coordY the texture coordinates are set to 0 and 0. This way you would use each texture completely for each flake/drop.
// glTexCoord2f(coordX, coordY);
glTexCoord2f(0, 0);
glVertex3f(point[0].x, point[0].y, point[0].z);
// glTexCoord2f(coordX, coordY + 0.25);
glTexCoord2f(0, 1.0);
glVertex3f(point[1].x, point[1].y, point[1].z);
// glTexCoord2f(coordX + 0.25, coordY + 0.25);
glTexCoord2f(1.0, 1.0);
glVertex3f(point[2].x, point[2].y, point[2].z);
// glTexCoord2f(coordX + 0.25, coordY);
glTexCoord2f(1.0, 0);
glVertex3f(point[3].x, point[3].y, point[3].z);
Well now you have to create you snowflake and raindrop texture(s). If you left the code unchanged you'll have to make a texture with 9 flakes in it. I dont have much information on how to create this texture since i used a tribes 2 one. I found it in the special dir in tribes2. If you dont have tribes 2 email me and ill give you a hand with creating this 9x9 textures.
Otherwise you'll have to create each flake or drop in a separate file which is easier. The images should have an alpha channel for the background. Well that's all, hope you enjoy your new weather :)
If there's any bug in this tutorial please e-mail me asap and ill fix it!
Well enjoy, and wait for my character selection tutorial :)
PD: Special thanks go to SnowMan which told me about the needed engine changes :)
Thanks a lot man!
#2
It kinda sux...
01/04/2002 (12:52 pm)
yes sorry, it shows inside buildings ... didnt look further into that.... if you notice also the wind affects the interior of buildings...It kinda sux...
#3
01/06/2002 (3:30 am)
I could be totally wrong but doesn't portals separate interior from exterior...maybe thats how you do it?
#4
01/06/2002 (12:13 pm)
i dont know :\
#6
01/08/2002 (4:52 pm)
oh, that's nice :)
#8
01/11/2002 (12:03 pm)
Help! For some reason textures still don't come thru. Can someone assemble a download with all the necessary files? Also, how do I get Lightning to use textures?
#9
01/19/2002 (6:18 am)
anyone found out yet how to let it stop raining inside buildings? Becuase I wont put it in my game as long as I don't have any idea on how to stop that from happening.
#10
If you get rain going on in the water world level it rains through the bridge(hang out underneath it).
It doesnt rain in the inner room of the beach house but outside that room(with the chair and lamp) it rains.
Seems to rain inside and through objects where the engine thinks you have visibility to the outside(use wireframe to see what I mean).
Checking the code the rain only adjusts itself for the height of the water volume, its not checking for anything else so its basically raining through everything. So hang out underneath the house on the water world level it rains completely through it.
But once inside the indoor engine it doesnt rain at all(makes sense), so deep inside the cave on water world it doesnt rain either.
Need a slick solution becaue doing 3d collision checking on each drop is obviously too expensive. need to detect when a drop is below the height of a static object without doing a lot of expensive math.
03/28/2002 (4:33 pm)
it doesnt just rain inside of buildings it rains through static objects as well.If you get rain going on in the water world level it rains through the bridge(hang out underneath it).
It doesnt rain in the inner room of the beach house but outside that room(with the chair and lamp) it rains.
Seems to rain inside and through objects where the engine thinks you have visibility to the outside(use wireframe to see what I mean).
Checking the code the rain only adjusts itself for the height of the water volume, its not checking for anything else so its basically raining through everything. So hang out underneath the house on the water world level it rains completely through it.
But once inside the indoor engine it doesnt rain at all(makes sense), so deep inside the cave on water world it doesnt rain either.
Need a slick solution becaue doing 3d collision checking on each drop is obviously too expensive. need to detect when a drop is below the height of a static object without doing a lot of expensive math.
#11
11/30/2005 (10:26 pm)
I seem to be using a different version of the Torque engine and the precipitation class does not contain member function loadDml(). I also have the same issue with getting texture painted onto the small white boxes. Any ideas?
#12
11/30/2005 (10:30 pm)
OH, I forgot to mention that I am using 9 textures on 1 .png image file for the raindrops. The size is 256x256 .png image.
#13
12/01/2005 (2:35 am)
@Josef: This tutorial is kinda dated, the precipitation code in Torque 1.4 is much better than it was when I did this tutorial, so you might want to check it out.
#14
12/01/2005 (8:06 pm)
how to alter 1.4 to get rid of white boxes...that is the question that is giving me a headache
#15
12/02/2005 (2:44 pm)
What white boxes? Check the demo that comes with 1.4, there's perfectly working rain in the demo with splashes and all the prettiness.
#16
12/03/2005 (2:01 pm)
every thing is working except the rain...and i have switched to the demo png and file
#17
10/06/2006 (11:33 pm)
Regarding white boxes: It seems that 1.4 doesn't use DML files anymore; instead, it wants a drop texture and a splash texture.
#18
Thx.
12/01/2006 (10:17 am)
Is it possible to have precipitation only at a certain position. I would like to have precipitation on my main level. I have a floating .dif high in the sky and would like to have it so there's no precipitation up there. The precipitation is everywhere right now. Am I just missing something or this gonna have to coded in engine? Any ideas?Thx.
#19
Thanks Lucus
01/27/2008 (11:17 pm)
Hello, I can not find the function void Precipitation::loadDml(). Should I just build this function in the game/fx/precipition.cc?? Or is there equivalent function? Thanks Lucus
#20
01/28/2008 (1:07 am)
Lucus: This resource is very old, the precipitation code has changed in recent versiones of Torque. 
Torque Owner Karsten "Clocks" Viese
With all the other trys it showed up inside of building as well, but in Tribes 2 it did not.
So its should be fixable somehow.
// Clocks out