[Bf-blender-cvs] [5abae51] master: Support multiple tangents for BI render & viewport
Alexander Romanov
noreply at git.blender.org
Tue Apr 26 12:41:36 CEST 2016
Commit: 5abae51a6ef5b0f1b817ef5ce4bff34fef5001cd
Author: Alexander Romanov
Date: Tue Apr 26 18:43:02 2016 +1000
Branches: master
https://developer.blender.org/rB5abae51a6ef5b0f1b817ef5ce4bff34fef5001cd
Support multiple tangents for BI render & viewport
Normal Map node support for GLSL mode and the internal render (multiple tangents support).
The Normal Map node is a useful node which is present in the Cycles render.
It makes it possible to use normal mapping without additional material node in a node tree.
This patch implements Normal Map node for GLSL mode and the internal render.
Previously only the active UV layer was used to calculate tangents.
===================================================================
M release/scripts/startup/nodeitems_builtins.py
M source/blender/blenkernel/BKE_DerivedMesh.h
M source/blender/blenkernel/BKE_mesh.h
M source/blender/blenkernel/intern/DerivedMesh.c
M source/blender/blenkernel/intern/cdderivedmesh.c
M source/blender/blenkernel/intern/customdata.c
M source/blender/blenkernel/intern/editderivedmesh.c
M source/blender/blenkernel/intern/material.c
M source/blender/blenkernel/intern/mesh_evaluate.c
M source/blender/blenkernel/intern/subsurf_ccg.c
M source/blender/gpu/shaders/gpu_shader_material.glsl
M source/blender/makesdna/DNA_material_types.h
M source/blender/nodes/shader/nodes/node_shader_normal_map.c
M source/blender/render/extern/include/RE_shader_ext.h
M source/blender/render/intern/include/render_types.h
M source/blender/render/intern/include/renderdatabase.h
M source/blender/render/intern/source/bake_api.c
M source/blender/render/intern/source/convertblender.c
M source/blender/render/intern/source/multires_bake.c
M source/blender/render/intern/source/renderdatabase.c
M source/blender/render/intern/source/shadeinput.c
M source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 7806621..9dca55e 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -160,6 +160,7 @@ shader_node_categories = [
NodeItem("ShaderNodeMapping"),
NodeItem("ShaderNodeVectorCurve"),
NodeItem("ShaderNodeVectorTransform"),
+ NodeItem("ShaderNodeNormalMap"),
]),
ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[
NodeItem("ShaderNodeValToRGB"),
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index d7d6daa..7419b18 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -71,6 +71,7 @@
* as it is and stick with using BMesh and CDDM.
*/
+#include "DNA_defs.h"
#include "DNA_customdata_types.h"
#include "DNA_meshdata_types.h"
@@ -200,6 +201,8 @@ struct DerivedMesh {
/* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
char cd_flag;
+ char tangent_mask; /* which tangent layers are calculated */
+
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
@@ -210,7 +213,9 @@ struct DerivedMesh {
void (*calcLoopNormalsSpaceArray)(DerivedMesh *dm, const bool use_split_normals, const float split_angle,
struct MLoopNorSpaceArray *r_lnors_spacearr);
- void (*calcLoopTangents)(DerivedMesh *dm);
+ void (*calcLoopTangents)(
+ DerivedMesh *dm, bool calc_active_tangent,
+ const char (*tangent_names)[MAX_NAME], int tangent_names_count);
/** Recalculates mesh tessellation */
void (*recalcTessellation)(DerivedMesh *dm);
@@ -763,7 +768,7 @@ typedef struct DMVertexAttribs {
struct {
float (*array)[4];
int em_offset, gl_index;
- } tang;
+ } tang[MAX_MTFACE];
struct {
float (*array)[3];
@@ -779,7 +784,20 @@ void DM_vertex_attributes_from_gpu(
void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop);
-void DM_calc_loop_tangents(DerivedMesh *dm);
+void DM_calc_tangents_names_from_gpu(
+ const struct GPUVertexAttribs *gattribs,
+ char (*tangent_names)[MAX_NAME], int *tangent_names_count);
+void DM_add_named_tangent_layer_for_uv(
+ CustomData *uv_data, CustomData *tan_data, int numLoopData,
+ const char *layer_name);
+void DM_calc_loop_tangents_step_0(
+ const CustomData *loopData, bool calc_active_tangent,
+ const char (*tangent_names)[MAX_NAME], int tangent_names_count,
+ bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
+ char *ract_uv_name, char *rren_uv_name, char *rtangent_mask);
+void DM_calc_loop_tangents(
+ DerivedMesh *dm, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME],
+ int tangent_names_count);
void DM_calc_auto_bump_scale(DerivedMesh *dm);
/** Set object's bounding box based on DerivedMesh min/max data */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index a8f20a4..ac1f157 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -293,8 +293,9 @@ void BKE_mesh_loops_to_mface_corners(
void BKE_mesh_loops_to_tessdata(
struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, struct MFace *mface,
int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
-void BKE_mesh_tangent_loops_to_tessdata(struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
- int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
+void BKE_mesh_tangent_loops_to_tessdata(
+ struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
+ int *polyindices, unsigned int (*loopindices)[4], const int num_faces, const char *layer_name);
int BKE_mesh_recalc_tessellation(
struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata,
struct MVert *mvert,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d120678..57926e6 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -49,6 +49,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
+#include "BLI_task.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_editmesh.h"
@@ -595,50 +596,49 @@ void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate)
int mf_idx;
int *polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX);
- unsigned int (*loopindex)[4];
+ unsigned int (*loopindex)[4] = NULL;
/* Should never occure, but better abort than segfault! */
if (!polyindex)
return;
if (generate) {
- for (int i = 0; i < ldata->totlayer; i++) {
- if (ldata->layers[i].type == CD_TANGENT) {
- CustomData_add_layer_named(fdata, CD_TANGENT, CD_CALLOC, NULL, totface, ldata->layers[i].name);
- }
- }
- CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
- }
-
- BLI_assert(CustomData_from_bmeshpoly_test(fdata, pdata, ldata, true));
-
- loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
-
- for (mf_idx = 0, mf = mface; mf_idx < totface; mf_idx++, mf++) {
- const int mf_len = mf->v4 ? 4 : 3;
- unsigned int *ml_idx = loopindex[mf_idx];
- int i, not_done;
+ for (int j = 0; j < ldata->totlayer; j++) {
+ if (ldata->layers[j].type == CD_TANGENT) {
+ CustomData_add_layer_named(fdata, CD_TANGENT, CD_CALLOC, NULL, totface, ldata->layers[j].name);
+ CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
+
+ if (!loopindex) {
+ loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
+ for (mf_idx = 0, mf = mface; mf_idx < totface; mf_idx++, mf++) {
+ const int mf_len = mf->v4 ? 4 : 3;
+ unsigned int *ml_idx = loopindex[mf_idx];
+
+ /* Find out loop indices. */
+ /* NOTE: This assumes tessface are valid and in sync with loop/poly... Else, most likely, segfault! */
+ for (int i = mp[polyindex[mf_idx]].loopstart, not_done = mf_len; not_done; i++) {
+ const int tf_v = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, ml[i].v);
+ if (tf_v != -1) {
+ ml_idx[tf_v] = i;
+ not_done--;
+ }
+ }
+ }
+ }
- /* Find out loop indices. */
- /* NOTE: This assumes tessface are valid and in sync with loop/poly... Else, most likely, segfault! */
- for (i = mp[polyindex[mf_idx]].loopstart, not_done = mf_len; not_done; i++) {
- const int tf_v = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, ml[i].v);
- if (tf_v != -1) {
- ml_idx[tf_v] = i;
- not_done--;
+ /* NOTE: quad detection issue - fourth vertidx vs fourth loopidx:
+ * Here, our tfaces' fourth vertex index is never 0 for a quad. However, we know our fourth loop index may be
+ * 0 for quads (because our quads may have been rotated compared to their org poly, see tessellation code).
+ * So we pass the MFace's, and BKE_mesh_loops_to_tessdata will use MFace->v4 index as quad test.
+ */
+ BKE_mesh_tangent_loops_to_tessdata(fdata, ldata, mface, polyindex, loopindex, totface, ldata->layers[j].name);
}
}
+ if (loopindex)
+ MEM_freeN(loopindex);
+ BLI_assert(CustomData_from_bmeshpoly_test(fdata, pdata, ldata, true));
}
- /* NOTE: quad detection issue - fourth vertidx vs fourth loopidx:
- * Here, our tfaces' fourth vertex index is never 0 for a quad. However, we know our fourth loop index may be
- * 0 for quads (because our quads may have been rotated compared to their org poly, see tessellation code).
- * So we pass the MFace's, and BKE_mesh_loops_to_tessdata will use MFace->v4 index as quad test.
- */
- BKE_mesh_tangent_loops_to_tessdata(fdata, ldata, mface, polyindex, loopindex, totface);
-
- MEM_freeN(loopindex);
-
if (G.debug & G_DEBUG)
printf("%s: Updated tessellated tangents of dm %p\n", __func__, dm);
}
@@ -3207,96 +3207,28 @@ finally:
pRes[3] = fSign;
}
-void DM_calc_loop_tangents(DerivedMesh *dm)
+void DM_calc_tangents_names_from_gpu(
+ const GPUVertexAttribs *gattribs,
+ char (*tangent_names)[MAX_NAME], int *r_tangent_names_count)
{
- /* mesh vars */
- const MLoopTri *looptri;
- MVert *mvert;
- MLoopUV *mloopuv;
- MPoly *mpoly;
- MLoop *mloop;
- float (*orco)[3] = NULL, (*tangent)[4];
- int /* totvert, */ totface;
- float (*fnors)[3];
- float (*tlnors)[3];
-
- if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) != -1)
- return;
-
- fnors = dm->getPolyDataArray(dm, CD_NORMAL);
- /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
- * have to check this is valid...
- */
- tlnors = dm->getLoopDataArray(dm, CD_NORMAL);
-
- /* check we have all the needed layers */
- /* totvert = dm->getNumVerts(dm); */ /* UNUSED */
- looptri = dm->getLoopTriArray(dm);
- totface = dm->getNumLoopTri(dm);
-
- mvert = dm->getVertArray(dm);
- mpoly = dm->getPolyArray(dm);
- mloop = dm->getLoopArray(dm);
- mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
-
- if (!mloopuv) {
- orco = dm->getVertDataArray(dm, CD_ORCO);
- if (!orco)
- return;
- }
-
- /* create tangent layer */
- DM_add_loop_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
- tangent = DM_get_loop_data_layer(dm, CD_TANGENT);
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- int num_face_as_quad_map;
- int *face_as_quad_map = NULL;
-
- /* map faces to quads */
- if (totface != dm->getNumPolys(dm)) {
- /* over alloc, since we dont know how many ngon or quads we have */
-
- /* map fake face index to looptri */
- face_as_quad_map = MEM_mallocN(sizeof(int) * totface, __func__);
- int i, j;
- for (i = 0, j = 0; j < totface; i++, j++) {
- face_as_quad_map[i] = j;
- /* step over all quads */
- if (mpoly[looptri[j].poly].totloop == 4) {
- j++; /* skips the nest looptri */
- }
+ int count = 0;
+ for (int b = 0; b < gattribs->totlayer; b++) {
+ if (gattribs->layer[b].type == CD_TANGENT) {
+ strcpy(tangent_names[count++], gattribs->layer[b].name);
}
- num_face_as_quad_map = i;
- }
- el
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list