AutoGrass in LiteC

Posted By: Sputnicker

AutoGrass in LiteC - 07/23/09 23:07

Hello people
I read this forum frequently, but now I have a problem.

I've tried to transcode the Aum's 58 autograss from WDL to LiteC, but it isnt working.

Here is the code I wrote:
Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Special thanks go to Loopix for the grass models and to Nifty for the idea
// 1) Include svegetation.wdl in your project
// 2) Place a terrain entity inside the level and attach it the action named my_terrain. Set its skill1 and skill2 values.
// 3) Export the skin of the terrain and paint the areas where the grass and the trees are supposed to appear in green (R G B = 0 255 0)
// 4) Save the resulting file as colormap.tga and copy it inside your game folder. That's it!
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var skin_size_x; // the size of the skin (and the color map) in pixels
var skin_size_y; // on the x and y axis

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

STRING grass1_mdl = "gramacskins.mdl";
STRING grass2_mdl = "gramacskins.mdl";
STRING tree1_mdl  = "t3.mdl";
STRING colormap_tga = "teste.bmp";

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

BMAP* vegetation_map;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ENTITY* terrain1;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function place_grass();
function place_trees();
function color_map();
function weaving_grass();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define grass_area skill1 // the size of the grassy area that surrounds the player, set it in Wed
#define grass_dist skill2 // the distance between two consecutive grass models, set it in Wed

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// uses grass_area, grass_dist
function generate_grass();
action my_terrain()
{
	if (my.grass_area == 0) {my.grass_area = 500;} // default grass_area value
	if (my.grass_dist == 0) {my.grass_dist = 50;} // default grass_dist value
	terrain1 = my;
	my.push = 3; // don't allow the grass and tree models to penetrate the terrain
	generate_grass();
}

function generate_grass()
{
	max_entities = 10000;
	wait (3); // wait until the level is loaded
	var grass_pos[3] = {0,0,0};
	var grass_id = 1;
	var grass_coords[3] = {0,0,0};
	ent_create (colormap_tga, nullvector, color_map); // create the color map entity
	// wait until the player, the terrain and the color map appear in the level
	while ((player == NULL) || (terrain1 == NULL) || (vegetation_map == NULL)) {wait (1);}
	grass_pos[1] = player.x - terrain1.grass_area; // set the initial position of the grass models
	grass_pos[2] = player.y - terrain1.grass_area; // surround the player with the grass models
	grass_pos[3] = terrain1.max_z + 400; // and place them up high in the sky
	grass_coords[1] = grass_pos[1];	
	grass_coords[2] = grass_pos[2];
	while (grass_coords[1] < player.x + terrain1.grass_area)
	{
		grass_pos[2] = grass_coords[2] + (random(0.2 * terrain1.grass_dist) - 0.4 * terrain1.grass_dist);
		grass_pos[1] = grass_coords[1] + (random(0.2 * terrain1.grass_dist) - 0.4 * terrain1.grass_dist);
		if (random (1) > 0.1)
		{
			you = ent_create (grass1_mdl, grass_pos[1], place_grass);
		}
		else
		{
			you = ent_create (grass2_mdl, grass_pos[1], place_grass);
		}
		// we can spread the cpu load over 10 consecutive frames by giving every 10th model a different id (skill1 value)
		you.skill1 = grass_id; // used for further optimizations (not used in this demo)
		grass_id %= 10;
		grass_id += 1;
		grass_coords[2] += terrain1.grass_dist;
		if (grass_coords[2] > (player.y + terrain1.grass_area))
		{
			grass_coords[1] += terrain1.grass_dist;
			grass_coords[2] = player.y - terrain1.grass_area;
		}
		if (random (1) > 0.99) // play with 0.99 to adjust the number of trees in the level
		{
			grass_pos[1] += 20 - random(40); // don't plant the tree in the same spot with a grass model
			grass_pos[2] += 20 - random(40);
			ent_create (tree1_mdl, grass_pos[1], place_trees);
		}
	}
}

function color_map()
{
	set (my,PASSABLE);
	reset (my,VISIBLE);
 	vegetation_map = bmap_for_entity (my, 0);
	skin_size_x = bmap_width (vegetation_map); // get the size of the color map (same with the skin of the terrain)
	skin_size_y = bmap_height (vegetation_map); // on the x and y axis
}
 
function place_grass()
{
	var pixel_color[3];
	var format;
	var pixel;
	var coords_x;
	var coords_y;
	var temp[3];
	my.scale_x += 0.1 - random(2) / 10;
	my.scale_y = my.scale_x;
	my.scale_z = my.scale_x;
	reset (my,VISIBLE);
	set (my,PASSABLE);
	set (my,TRANSLUCENT);
	my.push = 2;
	weaving_grass();
	while (player != NULL)
	{
		temp[1] = random(10);
		wait (temp); // spread the cpu load over 10 consecutive frames
		my.alpha = vec_dist(player.x, my.x); // play with 10000
		my.x = cycle(my.x, camera.x - terrain1.grass_area, camera.x + terrain1.grass_area); // wrap the grass around player's position
		my.y = cycle(my.y, camera.y - terrain1.grass_area, camera.y + terrain1.grass_area); // on the x and y axis
		my.z = terrain1.max_z + 400; // and place it up high in the sky
		vec_set(temp[1], my.x);
		temp[3] -= 10000;
		my.skill10 = c_trace (my.x, temp[1], IGNORE_SPRITES | IGNORE_PASSABLE | IGNORE_PUSH);
		// the tracing ray has hit the terrain? (not the surrounding hollowed cube)
		if ((trace_hit != 0) && (you != NULL)) 
		{
			coords_x = (my.x - terrain1.min_x) / ((terrain1.max_x - terrain1.min_x) / skin_size_x); // get the coordinates of the current pixel
			coords_y = (terrain1.max_y - my.y) / ((terrain1.max_y - terrain1.min_y) / skin_size_y); // on x and y
			format = bmap_lock (vegetation_map, 0);
			pixel = pixel_for_bmap(vegetation_map, coords_x, coords_y);
			pixel_to_vec (pixel_color, NULL, format, pixel); // store the color of the pixel in pixel_color 
			bmap_unlock (vegetation_map);
			// detected a green area on the color map bitmap?
			if (pixel_color[2] == 255)
			{
				my.z -= my.skill10 - 1; // then place a grass model on the ground (skill10 was used to store the result of the c_trace operation)
				vec_to_angle (my.pan, normal); // and align it properly
				my.tilt -= 90;
				reset (my,VISIBLE); // make it visible
			}
			else // this isn't a green pixel on the color map?
			{
				set (my,VISIBLE); // then hide the grass model (for now)
			}
		}
		wait (1);
	}
}

function place_trees()
{
	var pixel_color[3];
	var format;
	var pixel;
	var coords_x;
	var coords_y;
	var temp[3];
	my.pan = random(360);
	my.scale_x += 0.2 - random(4) / 10;
	my.scale_y = my.scale_x;
	my.scale_z = my.scale_x;
	reset (my,VISIBLE);
	set (my,TRANSLUCENT);
	set (my,PASSABLE);
	my.push = 1;
	var player1_pos[3];
	var player2_pos[3];
	while (player != NULL)
	{
		// update the trees only at game start of if the player has moved
		if ((total_frames < 20) || (vec_dist (player1_pos[1], player2_pos[1]) != 0)) 
		{
			my.alpha = (vec_dist(player.x, my.x)); // play with 20000
			my.x = cycle(my.x, camera.x - terrain1.grass_area, camera.x + terrain1.grass_area);
			my.y = cycle(my.y, camera.y - terrain1.grass_area, camera.y + terrain1.grass_area);
			my.z = terrain1.max_z + 400;
			vec_set(temp[1], my.x);
			temp[3] -= 10000;
			my.skill10 = c_trace (my.x, temp[1], IGNORE_ME | IGNORE_SPRITES | IGNORE_PASSABLE | IGNORE_PUSH);
			// the tracing ray has hit the terrain? (not the surrounding hollowed cube)
			if ((trace_hit != 0) && (you != NULL)) 
			{
				coords_x = (my.x - terrain1.min_x) / ((terrain1.max_x - terrain1.min_x) / skin_size_x);
				coords_y = (terrain1.max_y - my.y) / ((terrain1.max_y - terrain1.min_y) / skin_size_y);
				format = bmap_lock (vegetation_map, 0);
				pixel = pixel_for_bmap(vegetation_map, coords_x, coords_y);
				pixel_to_vec (pixel_color, NULL, format, pixel); // store the color of the pixel in pixel_color  
				bmap_unlock (vegetation_map);
				if (pixel_color[2] == 255) // got a green pixel here?
				{
					my.z -= my.skill10 - 1; // place a grass model on the ground (skill10 was used to store the result of the c_trace operation)
					reset (my,VISIBLE);
					reset (my,PASSABLE); // comment this line if you want to make the trees passable
				}
				else
				{
					set (my,VISIBLE);
				}
			}
		}
		vec_set (player1_pos[1], player.x); // use these 2 vars to detect if the player has moved or not
		wait (1);
		vec_set (player2_pos[1], player.x); // in the last frame
	}
}

function weaving_grass()
{
	var grass_angles;
	var grass_speed;
	grass_speed = 2 + random(5);
	while (1)
	{
		grass_angles += grass_speed * time_step; // allow the grass to weave
		my.roll += 0.02 * sin(grass_angles);
		wait (1);
	}
}



The error that it gives me is that: Malfunction W1301: <>: Can't open file

After I click OK, all the level is loaded corretly, except for the grass.

Can you help me people?
Thanks!!
Sputnicker.
Posted By: Claus_N

Re: AutoGrass in LiteC - 07/23/09 23:13

Maybe you need to use "STRING*" instead of just "STRING"? Thus making it a pointer smile

I didn't look through the other code though
Posted By: Cowabanga

Re: AutoGrass in LiteC - 07/23/09 23:16

Originally Posted By: Claus_N
Maybe you need to use "STRING*" instead of just "STRING"? Thus making it a pointer smile
A good point. And better using a shader for waving grass.
Posted By: Sputnicker

Re: AutoGrass in LiteC - 07/23/09 23:21

Thanks for the answers! You are fast! =D

Hey people, it doesnt gimme error anymore, but still not working.

Probably is this:
Code:
my.alpha = min (100, (20000 / ((vec_dist(player.x, my.x) + 1)))); // play with 20000


How can I translate into LiteC?
Posted By: Cowabanga

Re: AutoGrass in LiteC - 07/23/09 23:30

Yes, it should be:
Code:
my.alpha = minv (100, (20000 / ((vec_dist(player.x, my.x) + 1)))); // play with 20000


Posted By: Sputnicker

Re: AutoGrass in LiteC - 07/24/09 00:06

Uhm... still dont working... =(
Do you have any code of grass generation by colormap? I think this code will not work...lol
Posted By: Cowabanga

Re: AutoGrass in LiteC - 07/24/09 11:49

Well, if you have Gamestudio Commercial or Pro, i can give you a shader for waving grass. laugh
Posted By: Sputnicker

Re: AutoGrass in LiteC - 07/24/09 12:33

Thanks dude! But I have it =)
Its on the wiki... but my graphic card is a Intel GMA 950, that is not that shader-friendly...

The major problem is to generate the grass by a colormap... =/
Posted By: Razoron

Re: AutoGrass in LiteC - 07/24/09 13:46

could you give me the shader for the grass? I'm having com edition.
Posted By: Sputnicker

Re: AutoGrass in LiteC - 07/24/09 14:39

Waving Grass 2
asm, v.s. 1.1 / p.s. 1.3
Source: The Wiki
http://www.coniserver.net/wiki/index.php
http://www.coniserver.net/wiki/index.php/Waving_Grass_2
Code:
texture entSkin1;
		
matrix matWorldViewProj;
matrix matWorldView;
		
vector vecFog;
vector vecTime;
		
technique Grass
{
	pass p0
	{
		texture[0]=<entSkin1>;
		zWriteEnable=true;
		alphaTestEnable=true;
		cullMode=none;
		
		vertexShaderConstant[0]=<matWorldViewProj>;
		vertexShaderConstant[8]=<matWorldView>;
		vertexShaderConstant[16]=<vecFog>;
		vertexShaderConstant[32]=<vecTime>;
		vertexShaderConstant[33]={0.0f,0.5f,1.0f,2.0f};										// common constants
		vertexShaderConstant[34]={-0.16161616f,0.0083333f,-0.00019841f,0.000002755731f};	// {-1/3!,1/5!,-1/7!,1/9!}
		vertexShaderConstant[35]={4.0f,1.57079632f,3.14159265f,6.28318530f};				// {4.0,pi/2,pi,pi*2}
		vertexShaderConstant[36]={1.07f,0.0f,0.0f,0.0f};									// fixup factor
		
		vertexShaderConstant[40]={3.5f,1.2f,0.8f,0.1f};										// wave distort x
		vertexShaderConstant[41]={1.0f,2.0f,1.6f,0.1f};									// wave distort y
		vertexShaderConstant[42]={-0.4f,-0.9f,-0.9f,-0.01f};								// wave distort z
		vertexShaderConstant[43]={-0.1f,-0.2f,0.1f,0.05f};									// wave dir x
		vertexShaderConstant[44]={-0.005f,-0.01f,-0.005f,-0.0025f};							// wave dir y
				//vertexShaderConstant[45]={0.02f,0.04f,0.05f,0.1f};									// wave speed
		vertexShaderConstant[45]={0.005f,0.01f,0.01f,0.1f};									// wave speed
		vertexShaderConstant[46]={0.35f,0.1f,0.1f,0.04f};									// lighting wave scale
		vertexShaderConstant[47]={0.6f,0.8f,0.3f,0.0f};										// lighting scale bias
		
		vertexShader=
		asm
		{
			vs.1.1
		
			dcl_position  v0
			dcl_normal    v3
			dcl_texcoord0 v7
			dcl_texcoord1 v8
		
			mov r1.w,c16.w                  // r1.w=1
			dp4 r0,v0,c10                   // distance to camera position (v0 is the position without sinusodial warping!)
			add r0,r0,-c16.x                // distance-fog_start
			mad r0.x,-r0.x,c16.z,r1.w       // 1-(distance-fog_start)*(1/(fog_end-fog_start))
			max oFog,r0.x,c33.x           // clamp with custom max value
		
			mul r0,c43,v0.x                 // use vertex pos x as inputs to sinusoidal warp
			mad r0,c44,v0.y,r0              // use vertex pos y as inputs to sinusoidal warp
		
			mov r1,c32.w                    // get current time
			mad r0,r1,c45,r0                // add scaled time
			frc r0.xy,r0                    // take fraction of all 4 components
			frc r1.xy,r0.zwzw
			mov r0.zw,r1.xyxy
		
			mul r0,r0,c36.x                 // multiply by fixup factor (due to inaccuracy of taylor series)
			sub r0,r0,c33.y                 // subtract 0.5
			mul r1,r0,c35.w                 // range -pi to pi
		
			mul r2,r1,r1                    // wave_vec^2
			mul r3,r2,r1                    // wave_vec^3
			mul r5,r3,r2                    // wave_vec^5
			mul r7,r5,r2                    // wave_vec^7
			mul r9,r7,r2                    // wave_vec^9
		
			mad r0,r3,c34.x,r1              // wave_vec-(wave_vec^3)/3!
			mad r0,r5,c34.y,r0              // +(wave_vec^5)/5!
			mad r0,r7,c34.z,r0              // -(wave_vec^7)/7!
			mad r0,r9,c34.w,r0              // +(wave_vec^9)/9!
		
			dp4 r3.x,r0,c40
			dp4 r3.y,r0,c41
			dp4 r3.zw,r0,c42
		
			sub r4,c33.z,v7.y               // attenuate sinusoidal warping by (1-uv.y)^2
			mul r4,r4,r4
			mul r3,r3,r4
		
			mov r2.w,v0
			add r2.xyz,r3,v0                // add sinusoidal warping to grass position
			m4x4 oPos,r2,c0                 // transform position to clip space
		
			dp4 r1.x,r0,c46                 // scale and add sin waves together
			mad oD0,c47.xzxz,-r1.x,c47.y    // scale and bias color values (green is scaled more than red and blue)
			mov oT0.xy,v7.xy                // output uvs
		};
		
		pixelShader=
		asm
		{
			ps.1.3
			def c0,1,1,1,1
			def c1,0,0,0,0
			tex t0                  // sample t0
			mov r0,t0
			cnd r0.a,r0.a,c0,c1     // if(r0.a>0.5){r0.a=1;}else{r0.a=0;}
			//mul_x2 r0.rgb,r0,v0     // modulate with lighting
		};
	}
}


Posted By: Ayumi

Re: AutoGrass in LiteC - 07/27/09 03:00

_______
English
#######

I thought, search for the "place gras on terrain code", cause i want
create the same like Sputnicker.

My problem:
The definition of COLOR to create the colormap with green channel.(function place_grass())
If i want define this line, my menue wont work-.-and i can t press anyone
to start my game.
What to do?
Help pls.
(place_tree function cleared)

______
German
######

Ich dacht mir, ich kram den Thread mal raus...da ich das selbe erreichen
moechte wie der Threadersteller.

Mein problem ist die definition COLOR damit RGB code der
farbkarte funktioniert.(function place_grass())
Definiere ich das allerdings, funktioniet mein menue code nicht mehr.
(z.B. kann ich keine panels mehr anklicken).
und ohne COLOR definition gehts nicht-.-
(Place_tree function entfernt...)

Bin natuerlich nicht weiter mit dem uebersetzen
gekommen.Aber bis dahin scheint alles zu funktionieren.
Viell. mal die _startup definition entfernen?!





Code:
function generate_grass_startup();
function color_map();
function place_grass();
function weaving_grass();

var skin_size_x; // Skin groesse an der -
var skin_size_y; // x,y achse

STRING* grass1_mdl = "grass1.mdl";
STRING* grass2_mdl = "grass2.mdl";
STRING* colormap_tga = "Colormap.tga";

BMAP* vegetation_map;

ENTITY* terrain1 = "test_terrain_unreal1.hmp";

#define grass_area skill1 // Gras um den Player 
#define grass_dist skill2 // Distance zwischen 2 Grasmodellen

// uses grass_area, grass_dist
action my_terrain()
{
	if (my.grass_area == 0) {my.grass_area = 500;} // default grass um den Player
	if (my.grass_dist == 0) {my.grass_dist = 50;} // default gras distanz zw. 2 modellen
	terrain1 = my;
	my.push = 3; // Terrain nicht durchdringen
}


function generate_grass_startup()
{
	max_entities = 1000;
	wait (3); // wait until the level is loaded
	VECTOR grass_pos;
	var grass_id = 1;
	VECTOR grass_coords;
	
	ent_create (colormap_tga, nullvector, color_map); // erstelle colormap
	
	while ((player == NULL) || (terrain1 == NULL) || (vegetation_map == NULL)) {wait (1);}
	grass_pos.x = player.x - terrain1.grass_area; // setzte Grass position
	grass_pos.y = player.y - terrain1.grass_area; // um den Spieler
	grass_pos.z = terrain1.z + 400; // richtung Himmel
	grass_coords.x = grass_pos.x;	
	grass_coords.y = grass_pos.y;
	while (grass_coords.x < player.x + terrain1.grass_area)
	{
		grass_pos.y = grass_coords.y + (random(0.2 * terrain1.grass_dist) - 0.4 * terrain1.grass_dist);
		grass_pos.x = grass_coords.x + (random(0.2 * terrain1.grass_dist) - 0.4 * terrain1.grass_dist);
		if (random (1) > 0.1)
		{
			you = ent_create (grass1_mdl, grass_pos.x, place_grass);
		}
		else
		{
			you = ent_create (grass2_mdl, grass_pos.x, place_grass);
		}

		you.skill1 = grass_id; 
		grass_id %= 10;
		grass_id += 1;
		grass_coords.y += terrain1.grass_dist;
		if (grass_coords.y > (player.y + terrain1.grass_area))
		{
			grass_coords.x += terrain1.grass_dist;
			grass_coords.y = player.y - terrain1.grass_area;
		}
	}
}
function color_map()
{
	set(my, PASSABLE | INVISIBLE);
 	vegetation_map = bmap_for_entity (my, 0);
	skin_size_x = bmap_width (vegetation_map); // get the size of the color map (same with the skin of the terrain)
	skin_size_y = bmap_height (vegetation_map); // on the x and y axis
}
 
function place_grass()
{
	COLOR pixel_color;
	var format;
	var pixel;
	var coords_x;
	var coords_y;
	VECTOR temp5;
	
	
	
	my.scale_x += 0.1 - random(2) / 10;
	my.scale_y = my.scale_x;
	my.scale_z = my.scale_x;
	set( my, INVISIBLE | PASSABLE | TRANSLUCENT);
	my.push = 2;
	weaving_grass();
	while (player != NULL)
	{
		//temp = random(10);
		//wait (temp); // spread the cpu load over 10 consecutive frames
		wait(1);
		my.alpha = minv (100, (10000 / ((vec_dist(player.x, my.x) + 1)))); // play with 10000
		my.x = cycle(my.x, camera.x - terrain1.grass_area, camera.x + terrain1.grass_area); // wrap the grass around player's position
		my.y = cycle(my.y, camera.y - terrain1.grass_area, camera.y + terrain1.grass_area); // on the x and y axis
		my.z = terrain1.z + 400; // and place it up high in the sky
	
		vec_set(temp5.x, my.x);
		temp5.z -= 10000;
		my.skill10 = c_trace (my.x, temp.x, IGNORE_SPRITES | IGNORE_PASSABLE | IGNORE_PUSH);
		// the tracing ray has hit the terrain? (not the surrounding hollowed cube)
		if ((trace_hit != 0) && (you != NULL)) 
		{
			coords_x = (my.x - terrain1.min_x) / ((terrain1.max_x - terrain1.min_x) / skin_size_x); // get the coordinates of the current pixel
			coords_y = (terrain1.max_y - my.y) / ((terrain1.max_y - terrain1.min_y) / skin_size_y); // on x and y
			format = bmap_lock (vegetation_map, 0);
			pixel = pixel_for_bmap(vegetation_map, coords_x, coords_y);
			pixel_to_vec (pixel_color, NULL, format, pixel); // store the color of the pixel in pixel_color 
			bmap_unlock (vegetation_map);
			// detected a green area on the color map bitmap?
			if (pixel_color.green == 255)
			{
				my.z -= my.skill10 - 1; // then place a grass model on the ground (skill10 was used to store the result of the c_trace operation)
				vec_to_angle (my.pan, normal); // and align it properly
				my.tilt -= 90;
				reset(my, INVISIBLE);
			}
			else // this isn't a green pixel on the color map?
			{
				set(my, INVISIBLE);
			}
		}
		wait (1);
	}
}


function weaving_grass()
{
	var grass_angles;
	var grass_speed;
	grass_speed = 2 + random(5);
	while (1)
	{
		grass_angles += grass_speed * time_step; // allow the grass to weave
		my.roll += 0.02 * sin(grass_angles);
		wait (1);
	}
}




© 2024 lite-C Forums