historical/toontown-classic.git/panda/include/shaderTerrainMesh.I
2024-01-16 11:20:27 -06:00

192 lines
6 KiB
Text

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file shaderTerrainMesh.I
* @author tobspr
* @date 2016-02-16
*/
/**
* @brief Sets the heightfield texture
* @details This sets the heightfield texture. It should be 16bit
* single channel, and have a power-of-two resolution greater than 32.
* Common sizes are 2048x2048 or 4096x4096.
*
* You should call generate() after setting the heightfield.
*
* @param filename Heightfield texture
*/
INLINE void ShaderTerrainMesh::set_heightfield(Texture* heightfield) {
MutexHolder holder(_lock);
_heightfield_tex = heightfield;
}
/**
* @brief Returns the heightfield
* @details This returns the terrain heightfield, previously set with
* set_heightfield()
*
* @return Path to the heightfield
*/
INLINE Texture* ShaderTerrainMesh::get_heightfield() const {
MutexHolder holder(_lock);
return _heightfield_tex;
}
/**
* @brief Sets the chunk size
* @details This sets the chunk size of the terrain. A chunk is basically the
* smallest unit in LOD. If the chunk size is too small, the terrain will
* perform bad, since there will be way too many chunks. If the chunk size
* is too big, you will not get proper LOD, and might also get bad performance.
*
* For terrains of the size 4096x4096 or 8192x8192, a chunk size of 32 seems
* to produce good results. For smaller resolutions, you should try out a
* size of 16 or even 8 for very small terrains.
*
* The amount of chunks generated for the last level equals to
* (heightfield_size / chunk_size) ** 2. The chunk size has to be a power
* of two.
*
* @param chunk_size Size of the chunks, has to be a power of two
*/
INLINE void ShaderTerrainMesh::set_chunk_size(size_t chunk_size) {
MutexHolder holder(_lock);
_chunk_size = chunk_size;
}
/**
* @brief Returns the chunk size
* @details This returns the chunk size, previously set with set_chunk_size()
* @return Chunk size
*/
INLINE size_t ShaderTerrainMesh::get_chunk_size() const {
MutexHolder holder(_lock);
return _chunk_size;
}
/**
* @brief Sets whether to generate patches
* @details If this option is set to true, GeomPatches will be used instead of
* GeomTriangles. This is required when the terrain is used with tesselation
* shaders, since patches are required for tesselation, whereas triangles
* are required for regular rendering.
*
* If this option is set to true while not using a tesselation shader, the
* terrain will not get rendered, or even produce errors. The same applies
* when this is option is not set, but the terrain is used with tesselation
* shaders.
*
* @param generate_patches [description]
*/
INLINE void ShaderTerrainMesh::set_generate_patches(bool generate_patches) {
MutexHolder holder(_lock);
_generate_patches = generate_patches;
}
/**
* @brief Returns whether to generate patches
* @details This returns whether patches are generated, previously set with
* set_generate_patches()
*
* @return Whether to generate patches
*/
INLINE bool ShaderTerrainMesh::get_generate_patches() const {
MutexHolder holder(_lock);
return _generate_patches;
}
/**
* @brief Sets the desired triangle width
* @details This sets the desired width a triangle should have in pixels.
* A value of 10.0 for example will make the terrain tesselate everything
* in a way that each triangle edge roughly is 10 pixels wide.
* Of course this will not always accurately match, however you can use this
* setting to control the LOD algorithm of the terrain.
*
* @param target_triangle_width Desired triangle width in pixels
*/
INLINE void ShaderTerrainMesh::set_target_triangle_width(PN_stdfloat target_triangle_width) {
MutexHolder holder(_lock);
_target_triangle_width = target_triangle_width;
}
/**
* @brief Returns the target triangle width
* @details This returns the target triangle width, previously set with
* ShaderTerrainMesh::set_target_triangle_width()
*
* @return Target triangle width
*/
INLINE PN_stdfloat ShaderTerrainMesh::get_target_triangle_width() const {
MutexHolder holder(_lock);
return _target_triangle_width;
}
/**
* @brief Sets whether to enable terrain updates
* @details This flag controls whether the terrain should be updated. If this value
* is set to false, no updating of the terrain will happen. This can be useful
* to debug the culling algorithm used by the terrain.
*
* @param update_enabled Whether to update the terrain
*/
INLINE void ShaderTerrainMesh::set_update_enabled(bool update_enabled) {
MutexHolder holder(_lock);
_update_enabled = update_enabled;
}
/**
* @brief Returns whether the terrain is getting updated
* @details This returns whether the terrain is getting updates, previously set with
* set_update_enabled()
*
* @return Whether to update the terrain
*/
INLINE bool ShaderTerrainMesh::get_update_enabled() const {
MutexHolder holder(_lock);
return _update_enabled;
}
/**
* @brief Clears all children
* @details This clears all children on the chunk and sets them to NULL. This will
* effectively free all memory consumed by this chunk and its children.
*/
INLINE void ShaderTerrainMesh::Chunk::clear_children() {
for (size_t i = 0; i < 4; ++i) {
delete children[i];
children[i] = nullptr;
}
}
/**
* @brief Chunk constructor
* @details This constructs a new chunk, and sets all children to NULL.
*/
INLINE ShaderTerrainMesh::Chunk::Chunk() {
for (size_t i = 0; i < 4; ++i)
children[i] = nullptr;
}
/**
* @brief Chunk destructor
* @details This destructs the chunk, freeing all used resources
*/
INLINE ShaderTerrainMesh::Chunk::~Chunk() {
clear_children();
}
/**
* @see ShaderTerrainMesh::uv_to_world(LTexCoord)
*/
INLINE LPoint3 ShaderTerrainMesh::uv_to_world(PN_stdfloat u, PN_stdfloat v) const {
return uv_to_world(LTexCoord(u, v));
}