Gamestudio Links
Zorro Links
Newest Posts
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
4 registered members (degenerate_762, AbrahamR, AndrewAMD, ozgur), 667 guests, and 8 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 6 of 11 1 2 4 5 6 7 8 10 11
Re: Dumb terrain question.. Cannot get it to move... [Re: EvilSOB] #386404
11/02/11 13:19
11/02/11 13:19
Joined: Oct 2008
Posts: 513
Carlos3DGS Offline
User
Carlos3DGS  Offline
User

Joined: Oct 2008
Posts: 513
I was also having problems with ent_fixnormals when I started using it for runtime edited models (even terrains).

ent_fixnormals(entity*,frame);

I also had no idea what to put in the frame parameter for un-animated entities. i tried with NULL, tried with 0, and tried with 1... always getting no result.

So I started using an entity propety: ".frame"
i dont set .frame anywhere, it sets itself.
so now whenever I use something like ent_fixnormals i always do:
ent_fixnormals(entity,entity.frame);

I am also a noob when it comes to normals, this is the first time I do anything with them.
Quote:
Which frame? Its an un-animated entity pretending to be a terrain.. so where the hell does a frame number come from?

I don't use .frame because I know what I'm doing. I actually use .frame because I have abolutely no idea what I am doing and don't know what value to put in there for un-animated entities, so I let engine decide for me.
Even when using real terrains that cannot be animated i have to use this entity.frame thing, but I honestly have no idea why...

As Socrates said: "the more you learn the more you realize how little you know" wink
(this frase is becoming more and more evident to me when learning to program new stuff for videogames. I might even set it as my signature, lol!)


"The more you know, the more you realize how little you know..."

I <3 HORUS
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=401929&page=1
Re: Dumb terrain question.. Cannot get it to move... [Re: MrGuest] #386409
11/02/11 14:14
11/02/11 14:14
Joined: Oct 2008
Posts: 513
Carlos3DGS Offline
User
Carlos3DGS  Offline
User

Joined: Oct 2008
Posts: 513
Originally Posted By: MrGuest
have a look at vec_lerp for its height and vec_dot for its angle

I have been reading both functions and am trying to come up with a clever way to implement it but I have to admit I have absolutely no idea what to do...

lets say this is a 16x16 square with these vectors:
D=(0,0,-1)
A=(0,15,6)
B=(15,0,7)
C=(15,15,0)

the coords are (x,y,height)
How would I calculate which triangle H1 or H2 are on?
How would I get the height of H1?
How would I get the height of H2?

H1 inside triangle ACD or BCD?
H2 inside triangle ACD or BCD?
H1=(3,11,?)
H2=(13,3,?)




"The more you know, the more you realize how little you know..."

I <3 HORUS
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=401929&page=1
Re: Dumb terrain question.. Cannot get it to move... [Re: Carlos3DGS] #386412
11/02/11 14:38
11/02/11 14:38
Joined: Feb 2008
Posts: 3,232
Australia
EvilSOB Offline OP
Expert
EvilSOB  Offline OP
Expert

Joined: Feb 2008
Posts: 3,232
Australia
Thanks Carlos... You've reminded me...

I was just using 'ent.frame' blindly too...

As for how to use lerp to get what you want ... NFI


"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial
Re: Dumb terrain question.. Cannot get it to move... [Re: EvilSOB] #386413
11/02/11 14:51
11/02/11 14:51
Joined: Oct 2008
Posts: 513
Carlos3DGS Offline
User
Carlos3DGS  Offline
User

Joined: Oct 2008
Posts: 513
Originally Posted By: EvilSOB
I was just using 'ent.frame' blindly too...

Getting something to work withought fully understanding how all the elements involved in the solution work. This is the pro way of getting stuff done (I do it all the time, and I'm not only talking about programming hahaha)


"The more you know, the more you realize how little you know..."

I <3 HORUS
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=401929&page=1
Re: Dumb terrain question.. Cannot get it to move... [Re: Carlos3DGS] #386414
11/02/11 14:56
11/02/11 14:56
Joined: Feb 2008
Posts: 3,232
Australia
EvilSOB Offline OP
Expert
EvilSOB  Offline OP
Expert

Joined: Feb 2008
Posts: 3,232
Australia
If it aint broke, dont fix it...

If it works this way, stop playing around with it...


"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial
Re: Dumb terrain question.. Cannot get it to move... [Re: EvilSOB] #386444
11/03/11 03:46
11/03/11 03:46
Joined: Oct 2008
Posts: 513
Carlos3DGS Offline
User
Carlos3DGS  Offline
User

Joined: Oct 2008
Posts: 513
I finally achieved it! (I think)

Code:
var get_height(VECTOR P, int SW, ENTITY* Terrain)
{
	//P = point that we want the height of (x,y,0)
	//SW = vertex number of terrain ent closest towards the lower left corner of the square
	//Terrain we are calculating for
	
	CONTACT* c1;
	VECTOR Triangle[3];
	VECTOR temp_vec;
	ANGLE temp_ang;
	VECTOR Director[2];
	
	VECTOR formula;
	var ind_term;
	
	//retrieve first point of containing triangle (base corner)
	c1= ent_getvertex(Terrain,NULL,SW);
	Triangle[0].x=c1.v.x;
	Triangle[0].y=c1.v.z;
	Triangle[0].z=c1.v.y;
	
	//retrieve second point of containing triangle (diagonal to base)
	c1= ent_getvertex(Terrain,NULL,SW-32);
	Triangle[1].x=c1.v.x;
	Triangle[1].y=c1.v.z;
	Triangle[1].z=c1.v.y;
	
	//determine third point of containing triangle (varying point)
	vec_set (temp_vec, P);
	vec_sub (temp_vec,Triangle[0].x);
	vec_to_angle (temp_ang.pan,temp_vec);
   
   //retrieve third point of containing triangle (varying point)
	if(temp_ang.pan>45)
	{
		c1= ent_getvertex(Terrain,NULL,SW-33);
	}
	else
	{
		c1= ent_getvertex(Terrain,NULL,SW+1);
	}
	Triangle[2].x=c1.v.x;
	Triangle[2].y=c1.v.z;
	Triangle[2].z=c1.v.y;
	
	//calculate the triangle's plane normal for the formula coeficients
	vec_set(Director[0],Triangle[1]);
	vec_sub(Director[0],Triangle[0]);
	vec_set(Director[1],Triangle[2]);
	vec_sub(Director[1],Triangle[0]);
	vec_cross(formula,Director[0],Director[1]);
	//set the independant term of the formula
	ind_term=(-1*formula.x*Triangle[0].x)+(-1*formula.y*Triangle[0].y)+(-1*formula.z*Triangle[0].z);
	//calculate our point's height plugging our values into the formula
	P.z=(-1*((formula.x*P.x)+(formula.y*P.y)+ind_term))/formula.z;
	return(P.z);
}



A short summary:
Planes can be expressed in two ways, either by three points, or by one point and a normal vector to the plane's surface.
(we have the first way of expressing a plane but need the second)

First I determine which of the two triangles (that form our square) our point is on. Then I retrieve the vertex positions that form that triangle. With those three points we have a plane, now I translate that way of expressing a plane to the point and normal version. Then I store the coeficients of the formula we are building. I multiply all the coeficients with the independant terms and store it all together to have those parts pre-calculated and solved. Now we have to use another formula for the line, and plug it into our unfinished formula or the plane to find out where the line and plane intersect eachother. I plug in to the formula the rest of our known data and multiply by the formula coeficients we calculated before. We need to isolate the variable we are searching for using basic algebra, that was automatically done re-arranging the formula in the previous step taking into account what needed to go to where and how to solve for z.

And finished! OMG I HATE calculus! Finally I can sleep!

It surprizes me how short and simple the function looks after spending most of the the afternoon and night (it's 4:30 in the morning here) learning calculus.

Untested but it should work, I am too tired to test it now and risk feeling pulled into the code for god knows how many more hours... When I program hours fly and I lose track of time...

This was a nightmare for me to figure out, hope it saves you some sleep hours in the future.
tired sleep


"The more you know, the more you realize how little you know..."

I <3 HORUS
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=401929&page=1
Re: Dumb terrain question.. Cannot get it to move... [Re: Carlos3DGS] #386445
11/03/11 04:02
11/03/11 04:02
Joined: Feb 2008
Posts: 3,232
Australia
EvilSOB Offline OP
Expert
EvilSOB  Offline OP
Expert

Joined: Feb 2008
Posts: 3,232
Australia
Whoa! I aint going NEAR this code.

Just reading your 'short summary' is giving me a headache.

I hope it does work for you, and I hope I never need it.

Well done all the same. Enjoy your sleep, you earned it!


"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial
Re: Dumb terrain question.. Cannot get it to move... [Re: EvilSOB] #386497
11/03/11 21:40
11/03/11 21:40
Joined: Oct 2008
Posts: 513
Carlos3DGS Offline
User
Carlos3DGS  Offline
User

Joined: Oct 2008
Posts: 513
Had to make some modifications to get it working, but finally it is done!

Video working on 100 terrains:
http://www.youtube.com/watch?v=CnODODp4feg

around one second for all of the following:
-generating random height data (diamond-square algorithym) for 100 terrains.
-splicing 100 terrains
-ent_updtatehull x100
-ent_fixnormals x100
-4 corner normal fix for shadows 4x100 = 400 function calls
-4 edge normal fix for shadows 4x100 function calls

around 32 seconds just for this:
painting 100 512x512 textures...

Painting was incredibly slow, I heavily modified my painting function to optimize as much as I could. I don't think I can make it faster than it is now though (32 secs for 100 512x512 textures). Any suggestions are welcome to help me speed things up.
Click to reveal..
HEIGHT FUNCTION:
Code:
var get_height(var Px, var Py, int SW, ENTITY* Terrain)
{
	//P = point that we want the height of (x,y,0)
	//SW = vertex number of terrain ent closest towards the lower left corner of the square
	//Terrain we are calculating for
	
	
	VECTOR P;
	//TRANSFORM SKIN PIXEL COORDS TO LOCAL ENT COORD SYSTEM
	vec_set(P,vector(Px,Py,0));
	P.x-= 256;
	P.y = 256-P.y;
	
	
	CONTACT* c1;
	VECTOR Triangle[3];
	VECTOR temp_vec;
	ANGLE temp_ang;
	VECTOR Director[2];
	
	VECTOR formula;
	var ind_term;
	
	//retrieve first point of containing triangle (base corner)
	c1= ent_getvertex(Terrain,NULL,SW);
	Triangle[0].x=c1.v.x;
	Triangle[0].y=c1.v.z;
	Triangle[0].z=c1.v.y;
	
	//retrieve second point of containing triangle (diagonal to base)
	c1= ent_getvertex(Terrain,NULL,SW-32);
	Triangle[1].x=c1.v.x;
	Triangle[1].y=c1.v.z;
	Triangle[1].z=c1.v.y;
	
	//determine third point of containing triangle (varying point)
	vec_set (temp_vec, P);
	vec_sub (temp_vec,Triangle[0].x);
	vec_to_angle (temp_ang.pan,temp_vec);
	
	//retrieve third point of containing triangle (varying point)
	if(temp_ang.pan>45)
	{
		c1= ent_getvertex(Terrain,NULL,SW-33);
	}
	else
	{
		c1= ent_getvertex(Terrain,NULL,SW+1);
	}
	Triangle[2].x=c1.v.x;
	Triangle[2].y=c1.v.z;
	Triangle[2].z=c1.v.y;
	
	//calculate the triangle's plane normal for the formula coeficients
	vec_set(Director[0],Triangle[1]);
	vec_sub(Director[0],Triangle[0]);
	vec_set(Director[1],Triangle[2]);
	vec_sub(Director[1],Triangle[0]);
	vec_cross(formula,Director[0],Director[1]);
	//set the independant term of the formula
	ind_term=(-1*formula.x*Triangle[0].x)+(-1*formula.y*Triangle[0].y)+(-1*formula.z*Triangle[0].z);
	//calculate our point's height plugging our values into the formula
	P.z=(-1*((formula.x*P.x)+(formula.y*P.y)+ind_term))/formula.z;
	return(P.z);
}



TERRAIN PAINTING FUNCTION:
Code:
void Terrain_Paint(int x, int y)
{
	//wait(1);
	
	ENTITY* Terr = Terrain[x][y];
	int i; //vertex info for terrain
	
	BMAP* Source_BM;
	//BMAP* NewSkin = bmap_createblack(512,512,24);
	BMAP* NewSkin = bmap_create("Terrain_Sand.tga");
	BMAP* OldSkin;
	//bmap_for_entity (Terr,Terr.frame);
	VECTOR Pixel_pos; //pixel coordinates for skin bmap
	
	var height;
	var slope;
	
	var pixel_source; var pixel_dest;
	//var t_format1; var t_format2;
	COLOR* t_color; var t_alpha; 
	
	t_format1=bmap_lock(NewSkin,0);
	
	//	t_format2=bmap_lock(Sand_BM,0);
	//	t_format2=bmap_lock(Grass_BM,0);
	//	t_format2=bmap_lock(Rock_BM,0);
	//	t_format2=bmap_lock(Snow_BM,0);

	for(Pixel_pos.y=0;Pixel_pos.y<512;Pixel_pos.y++)
	{
		for(Pixel_pos.x=0;Pixel_pos.x<512;Pixel_pos.x++)
		{
			//              (0to31)+1          (((0to31)+1)*33)+1
			
			i = (integer((Pixel_pos.x)/16)+1) + (((integer((Pixel_pos.y)/16)+1)*33));
			height = get_height(Pixel_pos.x,Pixel_pos.y,i,Terr);
			//slope = get_slope(Pixel_pos.x,Pixel_pos.y,i,Terr);
			
			if(height>16)
			{
				if(height<=16)//sand
				{
					Source_BM=Sand_BM;
				}
				else if(height<75)//grass
				{
					Source_BM=Grass_BM;
				}
				else if(height<150)//stone
				{
					Source_BM=Rock_BM;
				}
				else//snow
				{
					Source_BM=Snow_BM;
				}
			pixel_source = pixel_for_bmap(Source_BM,Pixel_pos.x,Pixel_pos.y);
			t_color = pixel_to_vec(NULL, t_alpha ,t_format2,pixel_source);
			
			//paint pixel on selected terrain's texture
			pixel_dest=pixel_for_vec(t_color,t_alpha,t_format1);
			pixel_to_bmap(NewSkin,Pixel_pos.x,Pixel_pos.y,pixel_dest);
		}
		
		//bmap_unlock(Source_BM);
	}
	
}

//	bmap_unlock(Sand_BM);
//	bmap_unlock(Grass_BM);
//	bmap_unlock(Rock_BM);
//	bmap_unlock(Snow_BM);

bmap_unlock(NewSkin);
OldSkin=ent_getskin(Terr,1);
ptr_remove(OldSkin);
ent_setskin(Terr,NewSkin,1);
}



Call Example:
Code:
var t_format1; var t_format2;


t_format2=bmap_lock(Sand_BM,0);
t_format2=bmap_lock(Grass_BM,0);
t_format2=bmap_lock(Rock_BM,0);
t_format2=bmap_lock(Snow_BM,0);
for(x=0;x<TERRAIN_COUNT;x++)
{
	for(y=0;y<TERRAIN_COUNT;y++)
	{			
		Terrain_Paint(x,y);
		wait(1);
	}
}
wait_for(Terrain_Paint);
bmap_unlock(Sand_BM);
bmap_unlock(Grass_BM);
bmap_unlock(Rock_BM);
bmap_unlock(Snow_BM);



Turns out bmap_lock & bmap_unlock calls were making my paint function extremely slow. I don't have an exact number, but believe me, EXTREMELY slow.
I used to lock a bmap when i draw a pixel, then unlock (per pixel) since i might not need that same texture for the next pixel, so I would only lock each texture while I'm using it. With that version I never saw the completion of a terrain (waited several minutes) before closing realizing something was terribly wrong or terribly slow...
After that I moved the bmap_lock in my painter function before the loops and just locked all of them before hand, and moved the bmap_unlock after the loops, so they were locked and unlocked only once per terrain function. (lock*4 + unlock*4)*100 terrains = 1600 lock/unlock calls. This time I did manage to see the terrains painted after several minutes, but these times were still unacceptable.
So I decided to move the lock/unlock calls out of my painter function. they are called once before painting ALL terrains consecutively, and called the unlocks after ALL terrains have painted.

There have been more tweaks for speed, but lock/unlock seem to be what had the most impact on speed.

hope this experience is a usefull warning for anyone using these functions when they attempt to paint several large textures. An example of the calls and the paint function are in the spoiler above.

Also the height detection function was not working correctly, an updated version is also in the spoiler.

I had also programmed separate cliff textures to be drawn on steep angles, but they didn't blend well with the rest no matter what textures I used. The overall look was terrible so I removed that code.

@EvilSOB: even though you don't like calculating height between vertex, i hope this will help you out when you get to painting. The problem with random terains is that you can't have a pre-made texture looking good on it due to its randomness. And infinite worlds benefit greatly from randomized terrains. In my first attempt at painting I coloured each polygon entirely based on the average height of it's vertexs, and believe me it looks horrible. At least if you decide to take this route you have a head start wink


I have another question regarding this memory problem we are working around... Does this also include textures? I mean, if I remove textures with ptr_remove(BMAP) and create new ones with bmpa_create will that also leave behind unused texture memory and end up growing till the system is saturated like with models?



"The more you know, the more you realize how little you know..."

I <3 HORUS
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=401929&page=1
Re: Dumb terrain question.. Cannot get it to move... [Re: Carlos3DGS] #386509
11/04/11 00:29
11/04/11 00:29
Joined: Jul 2008
Posts: 1,178
England
M
MrGuest Offline
Serious User
MrGuest  Offline
Serious User
M

Joined: Jul 2008
Posts: 1,178
England
I've not encountered these problems through testing for bmap_remove though obviously can't say concisely due to the way you're creating / editing the bmaps

Great video btw, you should look at using interpolation to allow strength of paints rather than anything over a certain point

Re: Dumb terrain question.. Cannot get it to move... [Re: MrGuest] #386514
11/04/11 05:07
11/04/11 05:07
Joined: Feb 2008
Posts: 3,232
Australia
EvilSOB Offline OP
Expert
EvilSOB  Offline OP
Expert

Joined: Feb 2008
Posts: 3,232
Australia
Video looks good.

So lets look at the slow painting problem. Do some horsepower tests for me IF you can.
We will slowly disable segments of your painting to see where all the horsepower
is going by doing a speed-test on each of the below steps.

0> I cant see any, but if there are any wait commands WITHIN a single terrain
calculations, disable them. Waits between terrains is OK. Dont speed test this step.

1> Disable ONLY the pixel_for_bmap and pixel_to_bmap COMMANDS.
Just the individual LINES, not chunks of code.
We still want all the height and color CALCULATIONS to take place.

2> Now disable ALL the COLOR/PIXEL calculations as well, leaving the height calcs in.

3> Next disable all the HEIGHT calculations as well.
All that should be left is the bmap_lock and bmap_unlock's, and bmp_create's.

4> Next disable all the BMAP_CREATEs if you can find a way. Maybe create a
single global 512x512 bmap and just keep re-using it in place of the bmap_creates.
All that should be left is the bmap_lock and bmap_unlock's.

5> Finally, disable all the bmap_locks and bmap_unlocks.

Post the approximate results (in seconds) that you can measure for each step.
Until we know which PART is eating CPU, it going to be hard to optimise.
Also please do all the steps if you can. Dont stop just because it appears
that you've found 'the one', later-step results may be important too.
If you need to skip a step because it is just not possible code-wise, then so be it...

Also ... can you use shaders? Do you own a 'high' enough version of gamestudio?



Any of this is "unlikely" to help me, as I wont be doing any REAL painting.
My map isnt random. It comes from a monster height-map. (16384*12288 ATM and may grow)
So I plan on storing a simple color mask for using with a multi-tex shader in it too.
The simple color mask (128x128) get loaded at the same time I load my vertex heights(128x28),
and "blurred" into a 512x512 texture that the multi-tex shader will use.
At LOD-change time those heights will get lerped up into a 256x256 terrain
if it is LOD_0 or down to 32x32 for an LOD_3 terrain.



And I can say concisely that the textures WILL completely free their memory when
you use BOTH bmap_purge then bmap_remove. (dunno about ptr_remove though)


"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial
Page 6 of 11 1 2 4 5 6 7 8 10 11

Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1