Jump to content

Plane to hug terrain


Rick
 Share

Recommended Posts

So I'm getting an access violation on UpdateMesh(). The mesh is a valid pointer so now sure what I'm missing. I've went over what klepto posted and it looks like I converted it correctly from what I can tell. The only difference I see is he has mesh.AddSurface() where I have CreateSurface(mesh,...) because I couldn't find the AddSurface() method.

 

#include "TerrainPlane.h"

TerrainPlane::TerrainPlane(TTerrain terrain, TEntity parent, float scale)
{
_terrain = terrain;
_plane = CreatePatch(32, 32, parent);
ScaleMesh(_plane, Vec3(scale, 1.0, scale));
MoveEntity(_plane, Vec3(scale / 2.0, 0.0, -scale / 2.0));
}

TerrainPlane::~TerrainPlane(void)
{
}

TMesh TerrainPlane::CreatePatch(int xsegs, int zsegs, TEntity parent)
{
TMesh mesh;
int x, z, count;
TSurface surf;

mesh = CreateMesh(parent);
surf = CreateSurface(mesh);
for(z = 0; z < zsegs; z++)
{
	for(x = 0; x < xsegs; x++)
	{
		count = AddVertex(surf, Vec3((float)x / (float)xsegs, 0.0, (float)z / (float)zsegs), Vec3(0.0,1.0,0.0), Vec2((float)x / (float)xsegs, 1.0 - (float)z / (float)zsegs));

		if(x > 0 && z > 0)
		{
			AddTriangle(surf, count - 1, count, count - xsegs - 1);
			AddTriangle(surf, count - 1, count - xsegs - 1, count - xsegs - 2);
		}
	}
}

UpdateMesh(mesh);                   // THIS IS GIVING ME ACCESS VIOLATION!

return mesh;
}

void TerrainPlane::Update()
{
int Si, Vi;

for(Si = 1; Si < CountSurfaces(_plane); Si++)
{
	TSurface surf = GetSurface(_plane, Si);
	for(Vi = 0; Vi < CountVertices(surf) - 1; Vi++)
	{
		TVec3 vertex = TFormPoint(GetVertexPosition(surf, Vi), _plane, 0);
		TVec3 newpos = Vec3(vertex.X, TerrainElevation(_terrain, vertex.X, vertex.Z) + 0.01, vertex.Z);
		SetVertexPosition(surf, Vi, TFormPoint(newpos, 0, _plane));
	}
}
}

Link to comment
Share on other sites

Do you know how far off it is? You could just start adding 0.01 until you see it show up on top of the terrain. I wonder because maybe if you add 0.02 or 0.03 if it would work and if it does then I assume you could just use that value to add. If the value is small enough I doubt it would be noticeable and would still look like it's morphing to the terrain.

 

 

BTW wh1sp3r, how did you do yours? I assume you used C++ so mind sharing your code? If you did it the same way klepto did it might help me see what I went wrong with my C++ version.

Link to comment
Share on other sites

Rick:

 

	TMesh mesh = LoadMesh("abstract::decalplane4.gmf");
PositionEntity(mesh, Vec3(1.5,0,3.5));

TSurface surf = GetSurface(mesh);


for( int i = 0; i < 33*33; i++)
{
	TVec3 posL = GetVertexPosition( surf, i );
	TVec3 pos = TFormPoint( posL, mesh, 0);
	posL = Vec3( pos.X, TerrainElevation(GetChild(scene,2), pos.X, pos.Z), pos.Z );
	pos = TFormPoint( posL, 0, mesh );
	pos.Y+=0.01;
	SetVertexPosition( surf, i, pos );		
}

 

There is another problem :) you have to load different file for another decal, because decal is instanced ....

I can move with decal over terrain .. on flat or smooth parts of terrain, it's absolutely ok, but in some places, terrain is different visualy, than returned values from HeightEvelation .... and That's a big problem

-= Phenom II X4 965 3.4Ghz - ATI HD5870 - 6 GB DDR3 RAM - Windows 8 Pro 64x=-

Website: http://www.flamewarestudios.com

Link to comment
Share on other sites

Ah, you load a model in instead of creating it in code. I think my issue I'm having is the creation of the plane.

 

 

I understand the issue you are seeing. I was just curious if adding 0.02 or 0.03 instead of 0.01 would solve the issue for those troubled spots and if it does, would it make a difference for the spots that worked already. 0.02 or 0.03 is such a small difference that if it worked for the troubled spots and yet still looked ok for the spots that didn't have troubles then the problem would be solved. For some of those troubled spots there might be rounding errors or something going on, so maybe try a value higher than 0.01 to see what seems to make it work for the troubled spots.

Link to comment
Share on other sites

No it's not, your plane just has a lower resolution (from the picture, I'd say you have one square for 8 terrain squares) than the terrain and your vertices aren't perfectly aligned to the terrain vertices.

 

A patch that should perfectly align to the terrain must have AT LEAST the res of the terrain.

Link to comment
Share on other sites

and your vertices aren't perfectly aligned to the terrain vertices.

 

But that's what we are trying to do with getting the terrain height at a given point on the terrain. I think the issue is a given point on the terrain is retrieved from an interpolation calculation by the near vertices, which won't make it always exact, which is what I thin whisper is seeing.

 

So whisper, I wouldn't say it's a bug by any means, I'd say there doesn't seem to be a way to get the exact point height for any possible point on the terrain using those terrain functions.

 

This is why I still think a raycast would produce more accurate results than this method. The raycast should give the exact x, Y, & z point of collision on the terrain. Or at least a constant value could be used to add or substract the y value to get the exact point on the terrain, instead of having the terrain method interpolate a point.

Link to comment
Share on other sites

No, I meant if your terrain has one grid/vertice per meter, the mesh patch needs to have that too.

 

Did the patch in your first shot also have that much polygons (then I saw that wrong)?

Do you this still have problems with this high res patch?

 

Masterxilo: yes, IT's same plain with same resolution :D

-= Phenom II X4 965 3.4Ghz - ATI HD5870 - 6 GB DDR3 RAM - Windows 8 Pro 64x=-

Website: http://www.flamewarestudios.com

Link to comment
Share on other sites

I'd be interested to see the y value difference returned from a raycast colliding with the terrain vs TerrainElevation for a given vertex on your decal.

 

Can you try that whisper? You should be able to do that in that same loop you have. After you load your gmf position it below the terrain and raycast up to the terrain and see what the collision y value is.

Link to comment
Share on other sites

I'm sure the TerrainElevation function is just not taking into account the actual layout of the triangles but just performing a linear interpolation between the closest 4 terrain vertices.

It should be easy to use TerrainHeight on the 4 closest grid points and calculating the interpolation yourself. I'll try to write a TerrainElevation command replacement that way.

 

Because a raycast would still be many times slower I guess.

Link to comment
Share on other sites

lol,Rick, i made a test ...

 

LinePick returns X=1.5 Y=5.751125 Z = -2.5

Ter.Elev returns X=1.5 Y=5.803769 Z = -2.5

 

So, LinePick is right, Terrain Elevation NOT. That's reason, why i get this ****.

So, another problem here .. if i want to use LinePick :D how to tell, i want to pick only terrain ?

 

ftp://78.102.70.147/Images/decal5.jpg

 

Measured place = white ball :) ( of course, i have hidden all object, which can affect measuring...)

 

EDIT: but .. It'S strange, if Ter.Elev returns higher value, decal should be higher too, lol ? I am very confused now

-= Phenom II X4 965 3.4Ghz - ATI HD5870 - 6 GB DDR3 RAM - Windows 8 Pro 64x=-

Website: http://www.flamewarestudios.com

Link to comment
Share on other sites

Forget the linepicking if you want it to update in realtime. I don't know whats going wrong with the terrainElevation function but it looks much less accurate as it should be. For a single patch it linepicking slows down to 2 - 5 fps, so no option. I will look a bit deeper in it as i need this function myself.

  • Windows 10 Pro 64-Bit-Version
  • NVIDIA Geforce 1080 TI
Link to comment
Share on other sites

Correct TerrainElevation command (tested):

This takes into account the traingle layout of the terrain.

flt WorkingTerrainElevation(TTerrain terrain, const int resolution, flt x, flt y)
{
   TVec3 s = EntityScale(terrain); x /= s.X; y /= s.Z;
   x += resolution/2; y += resolution/2;

   int _x = int(x), _y = int(y);
   flt ox = x - _x; flt oy = y - _y;

   flt z0 = TerrainHeight(terrain, _x, _y);
   flt z1 = TerrainHeight(terrain, _x+1, _y);
   flt z2 = TerrainHeight(terrain, _x+1, _y+1);
   flt z3 = TerrainHeight(terrain, _x, _y+1);

   float resultingz;
   if(ox > oy) // in which triangle are we? 
   {
       resultingz = z0 - ox*(z0-z1) - oy*(z1-z2); // the first
   }
   else
   {
       resultingz = z0 - ox*(z3-z2) - oy*(z0-z3); // the second
   }

   return resultingz  * s.Y;
}

Unfortunately, there's no command to get the terrain's resolution so you'll have to pass that as an argument.

Link to comment
Share on other sites

Very nice.

 

For a single patch it linepicking slows down to 2 - 5 fps, so no option. I will look a bit deeper in it as i need this function myself.

 

That's actually acceptable in my eyes (as in the game I'm working on) as you would only have to do it when it moves, although I'll use Max's version since it'll be faster.

 

Thanks Masterxilo, Josh should know about this I would think.

 

Also what is meant by terrain resolution?

Link to comment
Share on other sites

Very nice.

 

 

 

That's actually acceptable in my eyes (as in the game I'm working on) as you would only have to do it when it moves, although I'll use Max's version since it'll be faster.

 

Thanks Masterxilo, Josh should know about this I would think.

 

Also what is meant by terrain resolution?

 

terrain 128x128 = 128 resolution

 

Rick: It'S working very well, no zfighting or something :D

-= Phenom II X4 965 3.4Ghz - ATI HD5870 - 6 GB DDR3 RAM - Windows 8 Pro 64x=-

Website: http://www.flamewarestudios.com

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...