Get Materials of terrain at given position for sound
pietru2004 opened this issue · 2 comments
I was thinking would it be possible to add API for getting material at XYZ position of the terrain so people could adapt it to sound systems - when player goes for ex from grass to sand it would play different sound. Also I am not aware is there any API.
There is currently no ready-made function to tell which "material" is present at a given position. It is possible to obtain the information from the images that make up splatmaps, however there are a few caveats:
- It depends on the shader you are using. If you use
classic4
, there will be just one splatmap, where the RGBA components are the densities of each 4 possible materials. If you usemultisplat16
, there will be 4 splatmaps. To access them, you have to get the images under the terrain data directory and read their pixels. But that leads to the second caveat... - The reason you'd have to load splatmaps manually, is because splatmaps are loaded in graphics card memory only. They are not available to CPU. For stuf like sound, knowing just one material where you are walking is probably all you need. But a splatmap is a lot more data than you need. To give a sense of scale, one pixel of one splatmap is 4 bytes. The amount of sound types you need is 4, which fits in just one byte. So if you keep one splatmap in memory, you will use 4 times more memory than necessary. If you use 4 splatmaps, you will use 16 times more memory than necessary.
So for now, if you don't care much about the extra memory usage, you can load the splatmap images (either using Image.load(path)
or terrain.get_texture(HTerrainData.CHANNEL_SPLAT, index).get_data()
, look up their pixels with a few simple coordinate conversions (see HTerrain.world_to_map
), and pick the highest weight. Also you better cache these images instead of loading them on each call, because they can be big.
If memory usage is a problem, a "material index map" could be generated, allowing to get such information more cheaply. However that's easier to do in games where the terrain isn't changing.
Also I am not aware is there any API.
There is no page with API docs, but scripts have comments describing functions, so you may want to look in there (functions starting with _
are private and are not meant to be called directly).
I care for memory cause my game uses it for building system and it takes bit memory to handle objects so I guess I just gona wait for it. I mean if I gona need it as piority then I just gona do what you described, but still. Each building block has script to store object name + special data if object handles those and save data func - normal blocks are Placable and special blocks extend Placable class.