eugene.litvinov Posted April 26, 2011 Share Posted April 26, 2011 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
ulf.schroeter Posted April 26, 2011 Share Posted April 26, 2011 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
eugene.litvinov Posted May 11, 2011 Author Share Posted May 11, 2011 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
ulf.schroeter Posted May 11, 2011 Share Posted May 11, 2011 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
eugene.litvinov Posted May 12, 2011 Author Share Posted May 12, 2011 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
ilya.tolmachev Posted June 16, 2011 Share Posted June 16, 2011 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
manguste Posted June 16, 2011 Share Posted June 16, 2011 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
Recommended Posts