diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-01-11 14:31:44 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-01-11 14:51:19 +0400 |
commit | 8952f58375385a6e8a636aa1e86763e88fc68fc0 (patch) | |
tree | e0f82a77ed1e969b155517dd427505776dc6f2c1 /source/blender/makesrna/intern | |
parent | 274b2590fb0eedaadbd5e588f629df7cb69ba0d8 (diff) |
Add tangent space computation/access from RNA (i.e. python).
This simply mimics code used for loopnormals, to enable py scripts to generate and access (temporary)
a tangent 3D vector and bitangent sign for each loop. Together with the split normals, this allow
to recreate a complete tangent space for normal mapping (bitangent = bitangent_sign * cross(normal, tangent)).
Expects all faces to be tri or quads.
Reviewed By: Brecht, campbellbarton
Differential Revision: https://developer.blender.org/D185
Diffstat (limited to 'source/blender/makesrna/intern')
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 43 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh_api.c | 40 |
2 files changed, 81 insertions, 2 deletions
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index fe6f33abc8c..cf634f9c7d4 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -338,6 +338,29 @@ static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values) } } +static void rna_MeshLoop_tangent_get(PointerRNA *ptr, float *values) +{ + Mesh *me = rna_mesh(ptr); + MLoop *ml = (MLoop *)ptr->data; + const float (*vec)[4] = CustomData_get(&me->ldata, (int)(ml - me->mloop), CD_MLOOPTANGENT); + + if (!vec) { + zero_v3(values); + } + else { + copy_v3_v3(values, (const float *)vec); + } +} + +static float rna_MeshLoop_bitangent_sign_get(PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + MLoop *ml = (MLoop *)ptr->data; + const float (*vec)[4] = CustomData_get(&me->ldata, (int)(ml - me->mloop), CD_MLOOPTANGENT); + + return (vec) ? (*vec)[3] : 0.0f; +} + static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); @@ -1870,10 +1893,26 @@ static void rna_def_mloop(BlenderRNA *brna) RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_funcs(prop, "rna_MeshLoop_normal_get", NULL, NULL); - RNA_def_property_ui_text(prop, "Loop Normal", + RNA_def_property_ui_text(prop, "Normal", "Local space unit length split normal vector of this vertex for this polygon " - "(only computed on demand!)"); + "(must be computed beforehand using calc_normals_split or calc_tangents)"); + prop = RNA_def_property(srna, "tangent", PROP_FLOAT, PROP_DIRECTION); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, -1.0f, 1.0f); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_MeshLoop_tangent_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Tangent", + "Local space unit length tangent vector of this vertex for this polygon " + "(must be computed beforehand using calc_tangents)"); + + prop = RNA_def_property(srna, "bitangent_sign", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, -1.0f, 1.0f); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_MeshLoop_bitangent_sign_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Bitangent Sign", + "Sign of the bitangent vector of this vertex for this polygon (must be computed " + "beforehand using calc_tangents, bitangent = bitangent_sign * cross(normal, tangent))"); } static void rna_def_mpolygon(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 34f21046a92..76097b04c99 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -34,6 +34,8 @@ #include "RNA_define.h" +#include "DNA_customdata_types.h" + #include "BLI_sys_types.h" #include "BLI_utildefines.h" @@ -100,6 +102,32 @@ static void rna_Mesh_free_normals_split(Mesh *mesh) CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop); } +static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *uvmap) +{ + float (*r_looptangents)[4]; + + if (CustomData_has_layer(&mesh->ldata, CD_MLOOPTANGENT)) { + r_looptangents = CustomData_get_layer(&mesh->ldata, CD_MLOOPTANGENT); + memset(r_looptangents, 0, sizeof(float[4]) * mesh->totloop); + } + else { + r_looptangents = CustomData_add_layer(&mesh->ldata, CD_MLOOPTANGENT, CD_CALLOC, NULL, mesh->totloop); + CustomData_set_layer_flag(&mesh->ldata, CD_MLOOPTANGENT, CD_FLAG_TEMPORARY); + } + + /* Compute loop normals if needed. */ + if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) { + rna_Mesh_calc_normals_split(mesh, (float)M_PI); + } + + BKE_mesh_loop_tangents(mesh, uvmap, r_looptangents, reports); +} + +static void rna_Mesh_free_tangents(Mesh *mesh) +{ + CustomData_free_layers(&mesh->ldata, CD_MLOOPTANGENT, mesh->totloop); +} + static void rna_Mesh_calc_smooth_groups(Mesh *mesh, int use_bitflags, int *r_poly_group_len, int **r_poly_group, int *r_group_total) { @@ -141,6 +169,18 @@ void RNA_api_mesh(StructRNA *srna) func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split"); RNA_def_function_ui_description(func, "Free split vertex normals"); + func = RNA_def_function(srna, "calc_tangents", "rna_Mesh_calc_tangents"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, + "Compute tangents and bitangent signs, to be used together with the split normals " + "to get a complete tangent space for normal mapping " + "(split normals are also computed if not yet present)"); + parm = RNA_def_string(func, "uvmap", "", MAX_CUSTOMDATA_LAYER_NAME, "", + "Name of the UV map to use for tangent space computation"); + + func = RNA_def_function(srna, "free_tangents", "rna_Mesh_free_tangents"); + RNA_def_function_ui_description(func, "Free tangents"); + func = RNA_def_function(srna, "calc_tessface", "ED_mesh_calc_tessface"); RNA_def_function_ui_description(func, "Calculate face tessellation (supports editmode too)"); |