2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* surface_tool.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# ifndef SURFACE_TOOL_H
# define SURFACE_TOOL_H
2020-12-12 13:06:59 +01:00
# include "core/templates/local_vector.h"
2017-03-05 16:44:50 +01:00
# include "scene/resources/mesh.h"
2017-04-28 19:28:21 +02:00
# include "thirdparty/misc/mikktspace.h"
2021-06-04 18:03:15 +02:00
class SurfaceTool : public RefCounted {
GDCLASS ( SurfaceTool , RefCounted ) ;
2017-03-05 16:44:50 +01:00
2014-02-10 02:10:30 +01:00
public :
struct Vertex {
2017-03-05 16:44:50 +01:00
Vector3 vertex ;
Color color ;
Vector3 normal ; // normal, binormal, tangent
Vector3 binormal ;
Vector3 tangent ;
Vector2 uv ;
Vector2 uv2 ;
Vector < int > bones ;
Vector < float > weights ;
2020-12-02 02:40:47 +01:00
Color custom [ RS : : ARRAY_CUSTOM_COUNT ] ;
2020-12-12 13:06:59 +01:00
uint32_t smooth_group = 0 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool operator = = ( const Vertex & p_vertex ) const ;
2014-05-14 06:22:15 +02:00
2017-03-05 16:44:50 +01:00
Vertex ( ) { }
2014-02-10 02:10:30 +01:00
} ;
2020-12-02 02:40:47 +01:00
enum CustomFormat {
CUSTOM_RGBA8_UNORM = RS : : ARRAY_CUSTOM_RGBA8_UNORM ,
CUSTOM_RGBA8_SNORM = RS : : ARRAY_CUSTOM_RGBA8_SNORM ,
CUSTOM_RG_HALF = RS : : ARRAY_CUSTOM_RG_HALF ,
CUSTOM_RGBA_HALF = RS : : ARRAY_CUSTOM_RGBA_HALF ,
CUSTOM_R_FLOAT = RS : : ARRAY_CUSTOM_R_FLOAT ,
CUSTOM_RG_FLOAT = RS : : ARRAY_CUSTOM_RG_FLOAT ,
CUSTOM_RGB_FLOAT = RS : : ARRAY_CUSTOM_RGB_FLOAT ,
CUSTOM_RGBA_FLOAT = RS : : ARRAY_CUSTOM_RGBA_FLOAT ,
CUSTOM_MAX = RS : : ARRAY_CUSTOM_MAX
} ;
enum SkinWeightCount {
SKIN_4_WEIGHTS ,
SKIN_8_WEIGHTS
} ;
2022-12-22 16:22:33 +01:00
enum {
/* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */
SIMPLIFY_LOCK_BORDER = 1 < < 0 , // From meshopt_SimplifyLockBorder
} ;
2020-12-12 13:06:59 +01:00
typedef void ( * OptimizeVertexCacheFunc ) ( unsigned int * destination , const unsigned int * indices , size_t index_count , size_t vertex_count ) ;
static OptimizeVertexCacheFunc optimize_vertex_cache_func ;
2022-12-22 16:22:33 +01:00
typedef size_t ( * SimplifyFunc ) ( unsigned int * destination , const unsigned int * indices , size_t index_count , const float * vertex_positions , size_t vertex_count , size_t vertex_positions_stride , size_t target_index_count , float target_error , unsigned int options , float * r_error ) ;
2020-12-12 13:06:59 +01:00
static SimplifyFunc simplify_func ;
2022-12-22 16:22:33 +01:00
typedef size_t ( * SimplifyWithAttribFunc ) ( unsigned int * destination , const unsigned int * indices , size_t index_count , const float * vertex_data , size_t vertex_count , size_t vertex_stride , size_t target_index_count , float target_error , unsigned int options , float * result_error , const float * attributes , const float * attribute_weights , size_t attribute_count ) ;
2021-04-10 07:44:36 +02:00
static SimplifyWithAttribFunc simplify_with_attrib_func ;
2021-01-09 19:04:09 +01:00
typedef float ( * SimplifyScaleFunc ) ( const float * vertex_positions , size_t vertex_count , size_t vertex_positions_stride ) ;
static SimplifyScaleFunc simplify_scale_func ;
typedef size_t ( * SimplifySloppyFunc ) ( unsigned int * destination , const unsigned int * indices , size_t index_count , const float * vertex_positions_data , size_t vertex_count , size_t vertex_positions_stride , size_t target_index_count , float target_error , float * out_result_error ) ;
static SimplifySloppyFunc simplify_sloppy_func ;
2022-02-04 16:28:18 +01:00
typedef size_t ( * GenerateRemapFunc ) ( unsigned int * destination , const unsigned int * indices , size_t index_count , const void * vertices , size_t vertex_count , size_t vertex_size ) ;
static GenerateRemapFunc generate_remap_func ;
typedef void ( * RemapVertexFunc ) ( void * destination , const void * vertices , size_t vertex_count , size_t vertex_size , const unsigned int * remap ) ;
static RemapVertexFunc remap_vertex_func ;
typedef void ( * RemapIndexFunc ) ( unsigned int * destination , const unsigned int * indices , size_t index_count , const unsigned int * remap ) ;
static RemapIndexFunc remap_index_func ;
static void strip_mesh_arrays ( PackedVector3Array & r_vertices , PackedInt32Array & r_indices ) ;
2020-12-12 13:06:59 +01:00
2014-02-10 02:10:30 +01:00
private :
2014-05-14 06:22:15 +02:00
struct VertexHasher {
static _FORCE_INLINE_ uint32_t hash ( const Vertex & p_vtx ) ;
} ;
2014-02-10 02:10:30 +01:00
2022-10-29 22:37:09 +02:00
struct SmoothGroupVertex {
Vector3 vertex ;
uint32_t smooth_group = 0 ;
bool operator = = ( const SmoothGroupVertex & p_vertex ) const ;
SmoothGroupVertex ( const Vertex & p_vertex ) {
vertex = p_vertex . vertex ;
smooth_group = p_vertex . smooth_group ;
} ;
} ;
struct SmoothGroupVertexHasher {
static _FORCE_INLINE_ uint32_t hash ( const SmoothGroupVertex & p_vtx ) ;
} ;
2022-02-04 16:28:18 +01:00
struct TriangleHasher {
static _FORCE_INLINE_ uint32_t hash ( const int * p_triangle ) ;
static _FORCE_INLINE_ bool compare ( const int * p_lhs , const int * p_rhs ) ;
} ;
2019-04-13 20:19:26 +02:00
struct WeightSort {
2021-02-09 18:24:36 +01:00
int index = 0 ;
float weight = 0.0 ;
2019-04-13 20:19:26 +02:00
bool operator < ( const WeightSort & p_right ) const {
return weight < p_right . weight ;
}
} ;
2021-02-09 18:24:36 +01:00
bool begun = false ;
bool first = false ;
Mesh : : PrimitiveType primitive = Mesh : : PRIMITIVE_LINES ;
uint32_t format = 0 ;
2014-02-10 02:10:30 +01:00
Ref < Material > material ;
//arrays
2020-12-12 13:06:59 +01:00
LocalVector < Vertex > vertex_array ;
LocalVector < int > index_array ;
2014-02-10 02:10:30 +01:00
//memory
Color last_color ;
Vector3 last_normal ;
Vector2 last_uv ;
Vector2 last_uv2 ;
Vector < int > last_bones ;
Vector < float > last_weights ;
Plane last_tangent ;
2020-12-12 13:06:59 +01:00
uint32_t last_smooth_group = 0 ;
2014-02-10 02:10:30 +01:00
2021-02-09 18:24:36 +01:00
SkinWeightCount skin_weights = SKIN_4_WEIGHTS ;
2020-12-02 02:40:47 +01:00
Color last_custom [ RS : : ARRAY_CUSTOM_COUNT ] ;
CustomFormat last_custom_format [ RS : : ARRAY_CUSTOM_COUNT ] ;
2020-12-12 13:06:59 +01:00
void _create_list_from_arrays ( Array arr , LocalVector < Vertex > * r_vertex , LocalVector < int > * r_index , uint32_t & lformat ) ;
void _create_list ( const Ref < Mesh > & p_existing , int p_surface , LocalVector < Vertex > * r_vertex , LocalVector < int > * r_index , uint32_t & lformat ) ;
2014-10-14 06:01:25 +02:00
//mikktspace callbacks
2017-03-05 16:44:50 +01:00
static int mikktGetNumFaces ( const SMikkTSpaceContext * pContext ) ;
static int mikktGetNumVerticesOfFace ( const SMikkTSpaceContext * pContext , const int iFace ) ;
static void mikktGetPosition ( const SMikkTSpaceContext * pContext , float fvPosOut [ ] , const int iFace , const int iVert ) ;
static void mikktGetNormal ( const SMikkTSpaceContext * pContext , float fvNormOut [ ] , const int iFace , const int iVert ) ;
static void mikktGetTexCoord ( const SMikkTSpaceContext * pContext , float fvTexcOut [ ] , const int iFace , const int iVert ) ;
2017-08-29 13:47:29 +02:00
static void mikktSetTSpaceDefault ( const SMikkTSpaceContext * pContext , const float fvTangent [ ] , const float fvBiTangent [ ] , const float fMagS , const float fMagT ,
const tbool bIsOrientationPreserving , const int iFace , const int iVert ) ;
2014-02-10 02:10:30 +01:00
2023-04-25 00:21:32 +02:00
void _add_triangle_fan ( const Vector < Vector3 > & p_vertices , const Vector < Vector2 > & p_uvs = Vector < Vector2 > ( ) , const Vector < Color > & p_colors = Vector < Color > ( ) , const Vector < Vector2 > & p_uv2s = Vector < Vector2 > ( ) , const Vector < Vector3 > & p_normals = Vector < Vector3 > ( ) , const TypedArray < Plane > & p_tangents = TypedArray < Plane > ( ) ) ;
2017-03-05 16:44:50 +01:00
protected :
2014-02-10 02:10:30 +01:00
static void _bind_methods ( ) ;
public :
2020-12-02 02:40:47 +01:00
void set_skin_weight_count ( SkinWeightCount p_weights ) ;
SkinWeightCount get_skin_weight_count ( ) const ;
2022-06-12 01:15:44 +02:00
void set_custom_format ( int p_channel_index , CustomFormat p_format ) ;
CustomFormat get_custom_format ( int p_channel_index ) const ;
2020-12-02 02:40:47 +01:00
2022-06-12 01:15:44 +02:00
Mesh : : PrimitiveType get_primitive_type ( ) const ;
2021-03-19 13:57:52 +01:00
2014-02-10 02:10:30 +01:00
void begin ( Mesh : : PrimitiveType p_primitive ) ;
2020-12-02 02:40:47 +01:00
void set_color ( Color p_color ) ;
void set_normal ( const Vector3 & p_normal ) ;
void set_tangent ( const Plane & p_tangent ) ;
void set_uv ( const Vector2 & p_uv ) ;
void set_uv2 ( const Vector2 & p_uv2 ) ;
2022-06-12 01:15:44 +02:00
void set_custom ( int p_channel_index , const Color & p_custom ) ;
2020-12-02 02:40:47 +01:00
void set_bones ( const Vector < int > & p_bones ) ;
void set_weights ( const Vector < float > & p_weights ) ;
2020-12-12 13:06:59 +01:00
void set_smooth_group ( uint32_t p_group ) ;
2020-12-02 02:40:47 +01:00
2017-03-05 16:44:50 +01:00
void add_vertex ( const Vector3 & p_vertex ) ;
2014-02-10 02:10:30 +01:00
2019-02-13 09:23:29 +01:00
void add_triangle_fan ( const Vector < Vector3 > & p_vertices , const Vector < Vector2 > & p_uvs = Vector < Vector2 > ( ) , const Vector < Color > & p_colors = Vector < Color > ( ) , const Vector < Vector2 > & p_uv2s = Vector < Vector2 > ( ) , const Vector < Vector3 > & p_normals = Vector < Vector3 > ( ) , const Vector < Plane > & p_tangents = Vector < Plane > ( ) ) ;
2016-04-18 19:33:54 +02:00
2017-03-05 16:44:50 +01:00
void add_index ( int p_index ) ;
2014-02-10 02:10:30 +01:00
void index ( ) ;
void deindex ( ) ;
2018-02-14 20:14:23 +01:00
void generate_normals ( bool p_flip = false ) ;
2014-02-10 02:10:30 +01:00
void generate_tangents ( ) ;
2020-12-12 13:06:59 +01:00
void optimize_indices_for_cache ( ) ;
2022-06-12 01:15:44 +02:00
AABB get_aabb ( ) const ;
2020-12-12 13:06:59 +01:00
Vector < int > generate_lod ( float p_threshold , int p_target_index_count = 3 ) ;
2017-03-05 16:44:50 +01:00
void set_material ( const Ref < Material > & p_material ) ;
2021-03-19 13:57:52 +01:00
Ref < Material > get_material ( ) const ;
2014-02-10 02:10:30 +01:00
void clear ( ) ;
2020-12-12 13:06:59 +01:00
LocalVector < Vertex > & get_vertex_array ( ) { return vertex_array ; }
2014-02-10 02:10:30 +01:00
2017-08-02 20:34:55 +02:00
void create_from_triangle_arrays ( const Array & p_arrays ) ;
2020-12-12 13:06:59 +01:00
static void create_vertex_array_from_triangle_arrays ( const Array & p_arrays , LocalVector < Vertex > & ret , uint32_t * r_format = nullptr ) ;
2017-08-02 20:34:55 +02:00
Array commit_to_arrays ( ) ;
2017-03-05 16:44:50 +01:00
void create_from ( const Ref < Mesh > & p_existing , int p_surface ) ;
2019-07-10 11:54:12 +02:00
void create_from_blend_shape ( const Ref < Mesh > & p_existing , int p_surface , const String & p_blend_shape_name ) ;
2020-10-17 07:08:21 +02:00
void append_from ( const Ref < Mesh > & p_existing , int p_surface , const Transform3D & p_xform ) ;
2022-06-12 01:15:44 +02:00
Ref < ArrayMesh > commit ( const Ref < ArrayMesh > & p_existing = Ref < ArrayMesh > ( ) , uint32_t p_compress_flags = 0 ) ;
2014-02-10 02:10:30 +01:00
SurfaceTool ( ) ;
} ;
2020-12-02 02:40:47 +01:00
VARIANT_ENUM_CAST ( SurfaceTool : : CustomFormat )
VARIANT_ENUM_CAST ( SurfaceTool : : SkinWeightCount )
2022-07-23 23:41:51 +02:00
# endif // SURFACE_TOOL_H