diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-04-13 14:29:21 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-04-13 14:34:45 +0400 |
commit | 41b8f8873284dc9a2b0df2151b5d384a4ea212d9 (patch) | |
tree | 60f43347ea0bad4e297357666ec643ea5050f043 | |
parent | 0b7f5813973c515b84cd7c18ef6d7d1e59374237 (diff) |
Split Normals I (3/5): Add 3Dview shading support of split normals.
Mostly monkey coding in gpu ("modern" VBO drawing) and DM variants ("legacy" drawing) code...
Reviewers: brecht
Reviewed By: brecht
CC: campbellbarton
Differential Revision: https://developer.blender.org/D367
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 145 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedmesh.c | 76 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 205 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 16 |
4 files changed, 360 insertions, 82 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 9af6220e4b2..176ef505a9a 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -537,16 +537,9 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, MVert *mvert = cddm->mvert; MFace *mface = cddm->mface; float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1; -#define PASSVERT(index) { \ - if (shademodel == GL_SMOOTH) { \ - short *no = mvert[index].no; \ - glNormal3sv(no); \ - } \ - glVertex3fv(mvert[index].co); \ -} (void)0 - if (cddm->pbvh && cddm->pbvh_draw) { if (dm->numTessFaceData) { float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL); @@ -567,7 +560,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES; new_matnr = mface->mat_nr + 1; - new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT; + new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) { glEnd(); @@ -579,7 +572,20 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, } if (drawCurrentMat) { - if (shademodel == GL_FLAT) { + if (lnors) { + glNormal3sv((const GLshort *)lnors[0][0]); + glVertex3fv(mvert[mface->v1].co); + glNormal3sv((const GLshort *)lnors[0][1]); + glVertex3fv(mvert[mface->v2].co); + glNormal3sv((const GLshort *)lnors[0][2]); + glVertex3fv(mvert[mface->v3].co); + if (mface->v4) { + glNormal3sv((const GLshort *)lnors[0][3]); + glVertex3fv(mvert[mface->v4].co); + } + lnors++; + } + else if (shademodel == GL_FLAT) { if (nors) { glNormal3fv(nors); } @@ -594,13 +600,24 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, } glNormal3fv(nor); } + glVertex3fv(mvert[mface->v1].co); + glVertex3fv(mvert[mface->v2].co); + glVertex3fv(mvert[mface->v3].co); + if (mface->v4) { + glVertex3fv(mvert[mface->v4].co); + } } - - PASSVERT(mface->v1); - PASSVERT(mface->v2); - PASSVERT(mface->v3); - if (mface->v4) { - PASSVERT(mface->v4); + else { /* shademodel == GL_SMOOTH */ + glNormal3sv(mvert[mface->v1].no); + glVertex3fv(mvert[mface->v1].co); + glNormal3sv(mvert[mface->v2].no); + glVertex3fv(mvert[mface->v2].co); + glNormal3sv(mvert[mface->v3].no); + glVertex3fv(mvert[mface->v3].co); + if (mface->v4) { + glNormal3sv(mvert[mface->v4].no); + glVertex3fv(mvert[mface->v4].co); + } } } @@ -623,7 +640,6 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, GPU_buffer_unbind(); } -#undef PASSVERT glShadeModel(GL_FLAT); } @@ -637,6 +653,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, MVert *mv = cddm->mvert; MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); MCol *mcol; int i, orig; @@ -722,7 +739,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol) cp = (unsigned char *) &mcol[i * 4]; - if (!(mf->flag & ME_SMOOTH)) { + if (!(lnors || (mf->flag & ME_SMOOTH))) { if (nors) { glNormal3fv(nors); } @@ -742,28 +759,33 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (tf) glTexCoord2fv(tf[i].uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); mvert = &mv[mf->v1]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][0]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); - + if (tf) glTexCoord2fv(tf[i].uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); mvert = &mv[mf->v2]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][1]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); if (tf) glTexCoord2fv(tf[i].uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); mvert = &mv[mf->v3]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][2]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); if (mf->v4) { if (tf) glTexCoord2fv(tf[i].uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); mvert = &mv[mf->v4]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][3]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); } + if (lnors) lnors++; glEnd(); } @@ -865,6 +887,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, MFace *mf = cddm->mface; MCol *mcol; float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int colType, useColors = flag & DM_DRAW_USE_COLORS; int i, orig; @@ -895,7 +918,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) { DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); for (i = 0; i < dm->numTessFaceData; i++, mf++) { - int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH); + int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH); DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; @@ -921,7 +944,24 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, glShadeModel(GL_SMOOTH); glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); - if (!drawSmooth) { + if (lnors) { + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3sv((const GLshort *)lnors[0][0]); + glVertex3fv(mv[mf->v1].co); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3sv((const GLshort *)lnors[0][1]); + glVertex3fv(mv[mf->v2].co); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3sv((const GLshort *)lnors[0][2]); + glVertex3fv(mv[mf->v3].co); + if (mf->v4) { + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3sv((const GLshort *)lnors[0][3]); + glVertex3fv(mv[mf->v4].co); + } + lnors++; + } + else if (!drawSmooth) { if (nors) { glNormal3fv(nors); } @@ -1062,7 +1102,8 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData); } -static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal) +static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, + short (*lnor)[3], int smoothnormal) { const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; int b; @@ -1119,9 +1160,13 @@ static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int } /* vertex normal */ - if (smoothnormal) + if (lnor) { + glNormal3sv((const GLshort *)lnor); + } + else if (smoothnormal) { glNormal3sv(mvert[index].no); - + } + /* vertex coordinate */ glVertex3fv(mvert[index].co); } @@ -1138,6 +1183,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, MFace *mface = cddm->mface; /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, b, matnr, new_matnr; bool do_draw; int orig; @@ -1176,7 +1222,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, glBegin(GL_QUADS); for (a = 0; a < dm->numTessFaceData; a++, mface++) { - const int smoothnormal = (mface->flag & ME_SMOOTH); + const int smoothnormal = lnors || (mface->flag & ME_SMOOTH); + short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL; new_matnr = mface->mat_nr + 1; if (new_matnr != matnr) { @@ -1222,14 +1269,22 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, } } - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal); + if (lnors) { + ln1 = &lnors[0][0]; + ln2 = &lnors[0][1]; + ln3 = &lnors[0][2]; + ln4 = &lnors[0][3]; + lnors++; + } + + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); if (mface->v4) - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal); else - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); } glEnd(); } @@ -1465,6 +1520,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, MVert *mvert = cddm->mvert; MFace *mf = cddm->mface; float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, matnr, new_matnr; int orig; @@ -1499,7 +1555,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, glBegin(GL_QUADS); for (a = 0; a < dm->numTessFaceData; a++, mf++) { - const int smoothnormal = (mf->flag & ME_SMOOTH); + const int smoothnormal = lnors || (mf->flag & ME_SMOOTH); + short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL; /* material */ new_matnr = mf->mat_nr + 1; @@ -1539,15 +1596,23 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, } } + if (lnors) { + ln1 = &lnors[0][0]; + ln2 = &lnors[0][1]; + ln3 = &lnors[0][2]; + ln4 = &lnors[0][3]; + lnors++; + } + /* vertices */ - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, ln1, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, ln2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal); if (mf->v4) - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, ln4, smoothnormal); else - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal); } glEnd(); diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 5862c5358c4..19a621ad8d4 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -434,6 +434,7 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int i, flush; const int skip_normals = !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */ + const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; unsigned char(*color_vert_array)[4] = em->derivedVertColor; unsigned char(*color_face_array)[4] = em->derivedFaceColor; @@ -479,14 +480,14 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, polyNos = bmdm->polyNos; } - BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); + BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE); for (i = 0; i < tottri; i++) { BMLoop **ltri = looptris[i]; int drawSmooth; efa = ltri[0]->f; - drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH); + drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH)); draw_option = (!setDrawOptions ? DM_DRAW_OPTION_NORMAL : @@ -539,13 +540,16 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, } else { if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]); + else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]); + else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]); + else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); } } @@ -564,14 +568,14 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, } } else { - BM_mesh_elem_index_ensure(bm, BM_FACE); + BM_mesh_elem_index_ensure(bm, lnors ? BM_FACE | BM_LOOP : BM_FACE); for (i = 0; i < tottri; i++) { BMLoop **ltri = looptris[i]; int drawSmooth; efa = ltri[0]->f; - drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH); + drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH)); draw_option = (!setDrawOptions ? DM_DRAW_OPTION_NORMAL : @@ -625,13 +629,16 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, } else { if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glNormal3fv(ltri[0]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]); + else glNormal3fv(ltri[0]->v->no); glVertex3fv(ltri[0]->v->co); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glNormal3fv(ltri[1]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]); + else glNormal3fv(ltri[1]->v->no); glVertex3fv(ltri[1]->v->co); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glNormal3fv(ltri[2]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]); + else glNormal3fv(ltri[2]->v->no); glVertex3fv(ltri[2]->v->co); } } @@ -687,6 +694,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; BMFace *efa; + const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); MLoopUV *luv[3], dummyluv = {{0}}; MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); @@ -726,14 +734,14 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, vertexNos = bmdm->vertexNos; polyNos = bmdm->polyNos; - BM_mesh_elem_index_ensure(bm, BM_VERT); + BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT); for (i = 0; i < em->tottri; i++) { BMLoop **ltri = looptris[i]; MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL; MTFace mtf = {{{0}}}; /*unsigned char *cp = NULL;*/ /*UNUSED*/ - int drawSmooth = BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH); + int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH); DMDrawOption draw_option; efa = ltri[0]->f; @@ -774,17 +782,20 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, else { glTexCoord2fv(luv[0]->uv); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]); + else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); glTexCoord2fv(luv[1]->uv); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]); + else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); glTexCoord2fv(luv[2]->uv); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]); + else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); } glEnd(); @@ -792,14 +803,14 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, } } else { - BM_mesh_elem_index_ensure(bm, BM_VERT); + BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT); for (i = 0; i < em->tottri; i++) { BMLoop **ltri = looptris[i]; MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL; MTFace mtf = {{{0}}}; /*unsigned char *cp = NULL;*/ /*UNUSED*/ - int drawSmooth = BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH); + int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH); DMDrawOption draw_option; efa = ltri[0]->f; @@ -840,17 +851,20 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, else { glTexCoord2fv(luv[0]->uv); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r)); - glNormal3fv(ltri[0]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]); + else glNormal3fv(ltri[0]->v->no); glVertex3fv(ltri[0]->v->co); glTexCoord2fv(luv[1]->uv); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r)); - glNormal3fv(ltri[1]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]); + else glNormal3fv(ltri[1]->v->no); glVertex3fv(ltri[1]->v->co); glTexCoord2fv(luv[2]->uv); if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r)); - glNormal3fv(ltri[2]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]); + else glNormal3fv(ltri[2]->v->no); glVertex3fv(ltri[2]->v->co); } glEnd(); @@ -951,6 +965,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, const float (*vertexCos)[3] = bmdm->vertexCos; const float (*vertexNos)[3]; const float (*polyNos)[3]; + const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); BMFace *efa; DMVertexAttribs attribs; @@ -971,7 +986,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); - BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); + BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE); for (i = 0; i < em->tottri; i++) { BMLoop **ltri = looptris[i]; @@ -997,7 +1012,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, if (do_draw) { /* draw face */ - drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH); + drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH); if (!drawSmooth) { if (vertexCos) { @@ -1020,14 +1035,16 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, for (fi = 0; fi < 3; fi++) { const int j = BM_elem_index_get(ltri[fi]->v); emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi); - glNormal3fv(vertexNos[j]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); + else glNormal3fv(vertexNos[j]); glVertex3fv(vertexCos[j]); } } else { for (fi = 0; fi < 3; fi++) { emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi); - glNormal3fv(ltri[fi]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); + else glNormal3fv(ltri[fi]->v->no); glVertex3fv(ltri[fi]->v->co); } } @@ -1057,6 +1074,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, const float (*vertexCos)[3] = bmdm->vertexCos; const float (*vertexNos)[3]; const float (*polyNos)[3]; + const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); BMFace *efa; DMVertexAttribs attribs = {{{NULL}}}; GPUVertexAttribs gattribs; @@ -1073,7 +1091,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); - BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); + BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE); for (i = 0; i < em->tottri; i++) { BMLoop **ltri = looptris[i]; @@ -1098,7 +1116,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, } /* draw face */ - drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH); + drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH); if (!drawSmooth) { if (vertexCos) { @@ -1121,14 +1139,16 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, for (fi = 0; fi < 3; fi++) { const int j = BM_elem_index_get(ltri[fi]->v); emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi); - glNormal3fv(vertexNos[j]); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); + else glNormal3fv(vertexNos[j]); glVertex3fv(vertexCos[j]); } } else { for (fi = 0; fi < 3; fi++) { emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi); - glNormal3fv(ltri[fi]->v->no); + if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]); + else glNormal3fv(ltri[fi]->v->no); glVertex3fv(ltri[fi]->v->co); } } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 0b2d772978d..6a3b060ce36 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1730,7 +1730,9 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGKey key; + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int gridSize = ccgSubSurf_getGridSize(ss); + int gridFaces = gridSize - 1; DMFlagMat *faceFlags = ccgdm->faceFlags; int step = (fast) ? gridSize - 1 : 1; int i, totface = ccgSubSurf_getNumFaces(ss); @@ -1754,9 +1756,10 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); int new_matnr, new_shademodel; + short (*ln)[4][3] = NULL; if (faceFlags) { - new_shademodel = (faceFlags[index].flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT; + new_shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; new_matnr = faceFlags[index].mat_nr; } else { @@ -1764,6 +1767,11 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) new_matnr = 0; } + if (lnors) { + ln = lnors; + lnors += gridFaces * gridFaces * numVerts; + } + if (shademodel != new_shademodel || matnr != new_matnr) { matnr = new_matnr; shademodel = new_shademodel; @@ -1782,8 +1790,31 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) for (S = 0; S < numVerts; S++) { CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (shademodel == GL_SMOOTH) { - for (y = 0; y < gridSize - 1; y += step) { + if (ln) { + /* Can't use quad strips here... */ + glBegin(GL_QUADS); + for (y = 0; y < gridFaces; y += step) { + for (x = 0; x < gridFaces; x += step) { + float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0); + float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step); + float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step); + + glNormal3sv(ln[0][1]); + glVertex3fv(d); + glNormal3sv(ln[0][2]); + glVertex3fv(c); + glNormal3sv(ln[0][3]); + glVertex3fv(b); + glNormal3sv(ln[0][0]); + glVertex3fv(a); + ln += step; + } + } + glEnd(); + } + else if (shademodel == GL_SMOOTH) { + for (y = 0; y < gridFaces; y += step) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridSize; x += step) { CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y + 0); @@ -1799,8 +1830,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) } else { glBegin(GL_QUADS); - for (y = 0; y < gridSize - 1; y += step) { - for (x = 0; x < gridSize - 1; x += step) { + for (y = 0; y < gridFaces; y += step) { + for (x = 0; x < gridFaces; x += step) { float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0); float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step); @@ -1894,6 +1925,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int gridFaces = gridSize - 1; int edgeSize = ccgSubSurf_getEdgeSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, i, do_draw, numVerts, matnr, new_matnr, totface; CCG_key_top_level(&key, ss); @@ -1913,6 +1945,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, totface = ccgSubSurf_getNumFaces(ss); for (a = 0, i = 0; i < totface; i++) { CCGFace *f = ccgdm->faceMap[i].face; + short (*ln)[4][3] = NULL; int S, x, y, drawSmooth; int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); int origIndex = ccgDM_getFaceMapIndex(ss, f); @@ -1920,7 +1953,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, numVerts = ccgSubSurf_getFaceNumVerts(f); if (faceFlags) { - drawSmooth = (faceFlags[index].flag & ME_SMOOTH); + drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); new_matnr = faceFlags[index].mat_nr + 1; } else { @@ -1928,6 +1961,11 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, new_matnr = 1; } + if (lnors) { + ln = lnors; + lnors += gridFaces * gridFaces * numVerts; + } + if (new_matnr != matnr) { do_draw = setMaterial(matnr = new_matnr, &gattribs); if (do_draw) @@ -1946,7 +1984,35 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); CCGElem *vda, *vdb; - if (drawSmooth) { + if (ln) { + glBegin(GL_QUADS); + for (y = 0; y < gridFaces; y++) { + for (x = 0; x < gridFaces; x++) { + float *aco = CCG_grid_elem_co(&key, faceGridData, x, y); + float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y); + float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); + + PASSATTRIB(0, 1, 1); + glNormal3sv(ln[0][1]); + glVertex3fv(dco); + PASSATTRIB(1, 1, 2); + glNormal3sv(ln[0][2]); + glVertex3fv(cco); + PASSATTRIB(1, 0, 3); + glNormal3sv(ln[0][3]); + glVertex3fv(bco); + PASSATTRIB(0, 0, 0); + glNormal3sv(ln[0][0]); + glVertex3fv(aco); + + ln++; + a++; + } + } + glEnd(); + } + else if (drawSmooth) { for (y = 0; y < gridFaces; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridFaces; x++) { @@ -2031,6 +2097,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, int gridFaces = gridSize - 1; int edgeSize = ccgSubSurf_getEdgeSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, i, numVerts, matnr, new_matnr, totface; CCG_key_top_level(&key, ss); @@ -2049,6 +2116,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, totface = ccgSubSurf_getNumFaces(ss); for (a = 0, i = 0; i < totface; i++) { CCGFace *f = ccgdm->faceMap[i].face; + short (*ln)[4][3] = NULL; int S, x, y, drawSmooth; int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); int origIndex = ccgDM_getFaceMapIndex(ss, f); @@ -2057,7 +2125,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, /* get flags */ if (faceFlags) { - drawSmooth = (faceFlags[index].flag & ME_SMOOTH); + drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); new_matnr = faceFlags[index].mat_nr + 1; } else { @@ -2065,6 +2133,11 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, new_matnr = 1; } + if (lnors) { + ln = lnors; + lnors += gridFaces * gridFaces * numVerts; + } + /* material */ if (new_matnr != matnr) { setMaterial(userData, matnr = new_matnr, &gattribs); @@ -2083,7 +2156,35 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); CCGElem *vda, *vdb; - if (drawSmooth) { + if (ln) { + glBegin(GL_QUADS); + for (y = 0; y < gridFaces; y++) { + for (x = 0; x < gridFaces; x++) { + float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); + float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); + + PASSATTRIB(0, 1, 1); + glNormal3sv(ln[0][1]); + glVertex3fv(dco); + PASSATTRIB(1, 1, 2); + glNormal3sv(ln[0][2]); + glVertex3fv(cco); + PASSATTRIB(1, 0, 3); + glNormal3sv(ln[0][3]); + glVertex3fv(bco); + PASSATTRIB(0, 0, 0); + glNormal3sv(ln[0][0]); + glVertex3fv(aco); + + ln++; + a++; + } + } + glEnd(); + } + else if (drawSmooth) { for (y = 0; y < gridFaces; y++) { glBegin(GL_QUAD_STRIP); for (x = 0; x < gridFaces; x++) { @@ -2160,6 +2261,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, CCGKey key; MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); DMFlagMat *faceFlags = ccgdm->faceFlags; DMDrawOption draw_option; int i, totface, gridSize = ccgSubSurf_getGridSize(ss); @@ -2183,10 +2285,11 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); unsigned char *cp = NULL; + short (*ln)[4][3] = NULL; int mat_nr; if (faceFlags) { - drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH); + drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH)); mat_nr = faceFlags[origIndex].mat_nr; } else { @@ -2201,6 +2304,10 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, else draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; + if (lnors) { + ln = lnors; + lnors += gridFaces * gridFaces * numVerts; + } if (draw_option == DM_DRAW_OPTION_SKIP) { if (tf) tf += gridFaces * gridFaces * numVerts; @@ -2219,7 +2326,44 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); CCGElem *a, *b; - if (drawSmooth) { + if (ln) { + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + for (y = 0; y < gridFaces; y++) { + for (x = 0; x < gridFaces; x++) { + float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); + float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1); + + if (tf) glTexCoord2fv(tf->uv[1]); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3sv(ln[0][1]); + glVertex3fv(d_co); + + if (tf) glTexCoord2fv(tf->uv[2]); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3sv(ln[0][2]); + glVertex3fv(c_co); + + if (tf) glTexCoord2fv(tf->uv[3]); + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3sv(ln[0][3]); + glVertex3fv(b_co); + + if (tf) glTexCoord2fv(tf->uv[0]); + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3sv(ln[0][0]); + glVertex3fv(a_co); + + if (tf) tf++; + if (cp) cp += 16; + ln++; + } + } + glEnd(); + } + else if (drawSmooth) { glShadeModel(GL_SMOOTH); for (y = 0; y < gridFaces; y++) { glBegin(GL_QUAD_STRIP); @@ -2360,6 +2504,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, CCGSubSurf *ss = ccgdm->ss; CCGKey key; MCol *mcol = NULL; + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int i, gridSize = ccgSubSurf_getGridSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; int useColors = flag & DM_DRAW_USE_COLORS; @@ -2383,11 +2528,12 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); int origIndex; unsigned char *cp = NULL; + short (*ln)[4][3] = NULL; origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1; - else if (faceFlags) drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH); + else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH)); else drawSmooth = 1; if (mcol) { @@ -2395,6 +2541,11 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, mcol += gridFaces * gridFaces * numVerts * 4; } + if (lnors) { + ln = lnors; + lnors += gridFaces * gridFaces * numVerts; + } + { DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; @@ -2415,7 +2566,35 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, for (S = 0; S < numVerts; S++) { CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (drawSmooth) { + if (ln) { + glBegin(GL_QUADS); + for (y = 0; y < gridFaces; y++) { + for (x = 0; x < gridFaces; x++) { + float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); + float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); + float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); + float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); + + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3sv(ln[0][1]); + glVertex3fv(d); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3sv(ln[0][2]); + glVertex3fv(c); + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3sv(ln[0][3]); + glVertex3fv(b); + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3sv(ln[0][0]); + glVertex3fv(a); + + if (cp) cp += 16; + ln++; + } + } + glEnd(); + } + else if (drawSmooth) { for (y = 0; y < gridFaces; y++) { CCGElem *a, *b; glBegin(GL_QUAD_STRIP); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 177ffd071fd..e2588c251fb 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -737,6 +737,7 @@ static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, i float f_no[3]; float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); MVert *mvert = dm->getVertArray(dm); MFace *f = dm->getTessFaceArray(dm); @@ -747,7 +748,20 @@ static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, i start = index[mat_orig_to_new[f->mat_nr]]; index[mat_orig_to_new[f->mat_nr]] += f->v4 ? 18 : 9; - if (smoothnormal) { + if (tlnors) { + short (*tlnor)[3] = tlnors[i]; + /* Copy loop normals */ + normal_short_to_float_v3(&varray[start], tlnor[0]); + normal_short_to_float_v3(&varray[start + 3], tlnor[1]); + normal_short_to_float_v3(&varray[start + 6], tlnor[2]); + + if (f->v4) { + normal_short_to_float_v3(&varray[start + 9], tlnor[2]); + normal_short_to_float_v3(&varray[start + 12], tlnor[3]); + normal_short_to_float_v3(&varray[start + 15], tlnor[0]); + } + } + else if (smoothnormal) { /* copy vertex normal */ normal_short_to_float_v3(&varray[start], mvert[f->v1].no); normal_short_to_float_v3(&varray[start + 3], mvert[f->v2].no); |