Jump to content

Determining terrain type in specific point


photo

Recommended Posts

We have terrain with different material types: grass, sand, ground, stone, etc. They mix via terrain masks. We need play player's step sounds taking into account prevail material type under player's foot's position. In which direction we should research? Thanks.

Link to comment

We have terrain with different material types: grass, sand, ground, stone, etc. They mix via terrain masks. We need play player's step sounds taking into account prevail material type under player's foot's position. In which direction we should research? Thanks.

 

General approach: ObjectTerrain::getSurfaceMaskTextureImage(x,y,image) -> mask image pixel-lookup based on players position -> predominat material type via RGBA-pixel-component weight analysis and ObjectTerrain::get(Num)SurfaceMaterial().

 

Most probably some mask image caching required for performance and memory reasons: check image cache for already cached mask image for surface tile x/y, if available use it for pixel lookup, if not available than get it from ObjectTerrain and add it to image cache, if players surface tile x/y indices change due to tile border crossing purge all mask images with surfes tiles indices not within x last +/- 1, y last +/- 1 to just keep images cached around players last position.

Link to comment
  • 3 weeks later...

Thanks for idea.

I trying implement this pattern, and get some error:

vec3 pos; // I set position of player here

int step = (terrain.getSizeX() - 1) / terrain.getSurfacesX(); // calculate step, it is 256

// calculate surface index under playte
int x = Math::floor(pos.x / step);
int y = Math::floor(pos.y / step);

LOG("x = " + x + ", y = " + y + ", step = " + step);

Image image = new Image();

int result = terrain.getSurfaceMaskTextureImage(x, y, image); // fill image
int sum = terrain.getNumSurfaceMaterials(x, y); // get sum materials

LOG("result = " + result);
LOG("sum = " + sum);

 

Sum have correct result, but getSurfaceMaskTextureImage throw an error:

13:38:23 Direct3D9 error: invalid call

13:38:23 D3D9Texture::getImage(): can't update R8 256x256 2D surface

and result is 0

 

We use standard mechanism: we export terrain mask from editor, and get multichannel psd-file, then we modify layers, and import terrain mask to editor. What we doing incorrect? Thanks

Link to comment

Not the fix for the problem, but for propper surface index calculation you should account for ObjectTerrain position not at (0,0,0)

 

vec3 posTerrain = terrain.getWorldPosition();

int x = Math::floor( (posPlayer.x - posTerrain.x) / step);
int y = Math::floor( (posPlayer.y - posTerrain.y) / step);

 

 

D3D9Texture::getImage(): can't update R8 256x256 2D surface

 

D3D9 UpdateSurface call for downloading texture to system memory fails. There are several possible reasons according to D3D9 docs

 

This function has the following restrictions.

 


  • * The source surface must have been created with D3DPOOL_SYSTEMMEM.
    * The destination surface must have been created with D3DPOOL_DEFAULT.
    * Neither surface can be locked or holding an outstanding device context.
    * Neither surface can be created with multisampling. The only valid flag for both surfaces is D3DMULTISAMPLE_NONE.
    * The surface format cannot be a depth stencil format.
    * The source and dest rects must fit within the surface.
    * No stretching or shrinking is allowed (the rects must be the same size).
    * The source format must match the dest format.

 

Problem might be related to possible violation of first 2 items as getImage() source surface has been created with D3DPOOL_DEFAULT and target surface uses D3DPOOL_SYSTEMMEM. Not sure, based on documentation it sounds like UpdateSurface() can be used for texture upload, but not for texture download to CPU memory.

 

Reproducable also for OpenGL in case of compressed texture, so most probably a more general Texture::getImage() issue based on source texture / dest image format constellations.

Link to comment

Not the fix for the problem, but for propper surface index calculation you should account for ObjectTerrain position not at (0,0,0)

 

vec3 posTerrain = terrain.getWorldPosition();

int x = Math::floor( (posPlayer.x - posTerrain.x) / step);
int y = Math::floor( (posPlayer.y - posTerrain.y) / step);

 

Yes, I do it, my pos variable present player's position in local terrain coordinate system.

 

Reproducable also for OpenGL in case of compressed texture, so most probably a more general Texture::getImage() bug

 

Yes, for OpenGL all works, and we can use surface mask texture image.

Link to comment
  • 1 month later...

Hi.

We would like to know when you plan to fix this bug - it is connected to important milestones in our development. Please answer.

Thank you.

Link to comment

Do not use getSurfaceMaskTextureImage(). This function is intended for internal usage by the Editor. Right now you are trying to download the texture back to CPU memory, which can interfere with streaming of terrain textures and causes the problem.

 

There is a much easier workaround. Simply create an image that contains your mask texture for the whole terrain and check the player's position relative to it.

Link to comment
×
×
  • Create New...