diff options
-rw-r--r-- | source/blender/blenkernel/BKE_dynamicpaint.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/dynamicpaint.c | 632 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_render_ext.h | 6 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_texture.c | 63 | ||||
-rw-r--r-- | source/blenderplayer/bad_level_call_stubs/stubs.c | 6 |
6 files changed, 338 insertions, 379 deletions
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h index e7384fb1a9c..00256176d98 100644 --- a/source/blender/blenkernel/BKE_dynamicpaint.h +++ b/source/blender/blenkernel/BKE_dynamicpaint.h @@ -45,12 +45,10 @@ typedef struct PaintPoint { /* Wet paint is handled at effect layer only * and mixed to surface when drying */ - float e_color[3]; - float e_alpha; + float e_color[4]; float wetness; short state; - float color[3]; - float alpha; + float color[4]; } PaintPoint; /* heigh field waves */ diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 4372f9635c7..6f510d846f6 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -200,12 +200,11 @@ typedef struct PaintBakeData { /* UV Image sequence format point */ typedef struct PaintUVPoint { /* Pixel / mesh data */ - unsigned int face_index, pixel_index; /* face index on domain derived mesh */ + unsigned int tri_index, pixel_index; /* tri index on domain derived mesh */ unsigned int v1, v2, v3; /* vertex indexes */ unsigned int neighbour_pixel; /* If this pixel isn't uv mapped to any face, * but it's neighboring pixel is */ - short quad; } PaintUVPoint; typedef struct ImgSeqFormatData { @@ -457,7 +456,7 @@ static void blendColors(const float t_color[3], float t_alpha, const float s_col } /* Mix two alpha weighed colors by a defined ratio. output is saved at a_color */ -static float mixColors(float a_color[3], float a_weight, float b_color[3], float b_weight, float ratio) +static float mixColors(float a_color[3], float a_weight, const float b_color[3], float b_weight, float ratio) { float weight_ratio, factor; if (b_weight) { @@ -1465,24 +1464,26 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* apply color to every surface point */ #pragma omp parallel for schedule(static) for (i = 0; i < sData->total_points; i++) { - copy_v3_v3(pPoint[i].color, surface->init_color); - pPoint[i].alpha = surface->init_color[3]; + copy_v4_v4(pPoint[i].color, surface->init_color); } } /* UV mapped texture */ else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { Tex *tex = surface->init_texture; - MTFace *tface; - MFace *mface = dm->getTessFaceArray(dm); - int numOfFaces = dm->getNumTessFaces(dm); + + const MLoop *mloop = dm->getLoopArray(dm); + const MLoopTri *mlooptri = dm->getLoopTriArray(dm); + const int tottri = dm->getNumLoopTri(dm); + const MLoopUV *mloopuv = NULL; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; if (!tex) return; /* get uv map */ - CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, surface->init_layername, uvname); - tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); - if (!tface) return; + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, surface->init_layername, uvname); + mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname); + if (!mloopuv) return; /* for vertex surface loop through tfaces and find uv color * that provides highest alpha */ @@ -1490,23 +1491,22 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface struct ImagePool *pool = BKE_image_pool_new(); #pragma omp parallel for schedule(static) shared(pool) - for (i = 0; i < numOfFaces; i++) { - int numOfVert = (mface[i].v4) ? 4 : 3; + for (i = 0; i < tottri; i++) { float uv[3] = {0.0f}; int j; - for (j = 0; j < numOfVert; j++) { + for (j = 0; j < 3; j++) { TexResult texres = {0}; - unsigned int *vert = (&mface[i].v1) + j; + unsigned int vert = mloop[mlooptri[i].tri[j]].v; /* remap to -1.0 to 1.0 */ - uv[0] = tface[i].uv[j][0] * 2.0f - 1.0f; - uv[1] = tface[i].uv[j][1] * 2.0f - 1.0f; + uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f; + uv[1] = mloopuv[mlooptri[i].tri[j]].uv[1] * 2.0f - 1.0f; multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false); - if (texres.tin > pPoint[*vert].alpha) { - copy_v3_v3(pPoint[*vert].color, &texres.tr); - pPoint[*vert].alpha = texres.tin; + if (texres.tin > pPoint[vert].color[3]) { + copy_v3_v3(pPoint[vert].color, &texres.tr); + pPoint[vert].color[3] = texres.tin; } } } @@ -1525,8 +1525,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* collect all uvs */ for (j = 0; j < 3; j++) { - int v = (f_data->uv_p[i].quad && j > 0) ? j + 1 : j; - copy_v2_v2(&uv[j * 3], tface[f_data->uv_p[i].face_index].uv[v]); + copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]].uv); } /* interpolate final uv pos */ @@ -1540,7 +1539,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* apply color */ copy_v3_v3(pPoint[i].color, &texres.tr); - pPoint[i].alpha = texres.tin; + pPoint[i].color[3] = texres.tin; } } } @@ -1549,46 +1548,40 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* for vertex surface, just copy colors from mcol */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { - MLoop *mloop = dm->getLoopArray(dm); - int numOfLoops = dm->getNumLoops(dm); - MCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername); + const MLoop *mloop = dm->getLoopArray(dm); + const int totloop = dm->getNumLoops(dm); + const MLoopCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername); if (!col) return; #pragma omp parallel for schedule(static) - for (i = 0; i < numOfLoops; i++) { - pPoint[mloop[i].v].color[0] = 1.0f / 255.f * (float)col[i].b; - pPoint[mloop[i].v].color[1] = 1.0f / 255.f * (float)col[i].g; - pPoint[mloop[i].v].color[2] = 1.0f / 255.f * (float)col[i].r; - pPoint[mloop[i].v].alpha = 1.0f / 255.f * (float)col[i].a; + for (i = 0; i < totloop; i++) { + rgba_uchar_to_float(pPoint[mloop[i].v].color, (const unsigned char *)&col[mloop[i].v].r); } } else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { + const MLoopTri *mlooptri = dm->getLoopTriArray(dm); ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data; int samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; - MCol *col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->init_layername); + // should this be replaced by CD_MLOOPCOL? + MLoopCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername); if (!col) return; #pragma omp parallel for schedule(static) for (i = 0; i < sData->total_points; i++) { - int face_ind = f_data->uv_p[i].face_index; - float colors[3][4] = {{0.0f, 0.0f, 0.0f, 0.0f}}; + int tri_ind = f_data->uv_p[i].tri_index; + float colors[3][4]; float final_color[4]; int j; + /* collect color values */ for (j = 0; j < 3; j++) { - int v = (f_data->uv_p[i].quad && j > 0) ? j + 1 : j; - colors[j][0] = 1.0f / 255.f * (float)col[face_ind * 4 + v].b; - colors[j][1] = 1.0f / 255.f * (float)col[face_ind * 4 + v].g; - colors[j][2] = 1.0f / 255.f * (float)col[face_ind * 4 + v].r; - colors[j][3] = 1.0f / 255.f * (float)col[face_ind * 4 + v].a; + rgba_uchar_to_float(colors[j], (const unsigned char *)&col[mlooptri[tri_ind].tri[j]].r); } - + /* interpolate final color */ - interp_v4_v4v4v4(final_color, colors[0], colors[1], colors[2], - f_data->barycentricWeights[i * samples].v); + interp_v4_v4v4v4(final_color, UNPACK3(colors), f_data->barycentricWeights[i * samples].v); - copy_v3_v3(pPoint[i].color, final_color); - pPoint[i].alpha = final_color[3]; + copy_v4_v4(pPoint[i].color, final_color); } } } @@ -1724,7 +1717,7 @@ static DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, #pragma omp parallel for schedule(static) for (i = 0; i < sData->total_points; i++) { /* blend dry and wet layer */ - blendColors(pPoint[i].color, pPoint[i].alpha, pPoint[i].e_color, pPoint[i].e_alpha, &fcolor[i * 4]); + blendColors(pPoint[i].color, pPoint[i].color[3], pPoint[i].e_color, pPoint[i].e_color[3], &fcolor[i * 4]); } /* viewport preview */ @@ -2051,7 +2044,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh * Check if shifted point is on same face -> it's a correct neighbor * (and if it isn't marked as an "edge pixel") */ - if ((tPoint->face_index == cPoint->face_index) && (tPoint->neighbour_pixel == -1)) + if ((tPoint->tri_index == cPoint->tri_index) && (tPoint->neighbour_pixel == -1)) return (x + w * y); /* @@ -2062,7 +2055,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh * This should work fine as long as uv island * margin is > 1 pixel. */ - if ((tPoint->face_index != -1) && (tPoint->neighbour_pixel == -1)) { + if ((tPoint->tri_index != -1) && (tPoint->neighbour_pixel == -1)) { return (x + w * y); } @@ -2080,9 +2073,10 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh * TODO: Implement something more accurate / optimized? */ { - int numOfFaces = dm->getNumTessFaces(dm); - MFace *mface = dm->getTessFaceArray(dm); - MTFace *tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); + const MLoop *mloop = dm->getLoopArray(dm); + const MLoopTri *mlooptri = dm->getLoopTriArray(dm); + const int tottri = dm->getNumLoopTri(dm); + const MLoopUV *mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname); /* Get closest edge to that subpixel on UV map */ { @@ -2090,8 +2084,8 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh /* distances only used for comparison */ float dist_squared, t_dist_squared; - int i, uindex[3], edge1_index, edge2_index, - e1_index, e2_index, target_face; + int i, edge1_index, edge2_index, + e1_index, e2_index, target_tri; float closest_point[2], lambda, dir_vec[2]; int target_uv1, target_uv2, final_pixel[2], final_index; @@ -2100,75 +2094,88 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)w; pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)h; - /* Get uv indexes for current face part */ - if (cPoint->quad) { - uindex[0] = 0; uindex[1] = 2; uindex[2] = 3; - } - else { - uindex[0] = 0; uindex[1] = 1; uindex[2] = 2; - } - /* * Find closest edge to that pixel */ + /* Dist to first edge */ - e1_index = cPoint->v1; e2_index = cPoint->v2; edge1_index = uindex[0]; edge2_index = uindex[1]; - dist_squared = dist_squared_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[edge1_index], tface[cPoint->face_index].uv[edge2_index]); + e1_index = cPoint->v1; + e2_index = cPoint->v2; + edge1_index = 0; + edge2_index = 1; + dist_squared = dist_squared_to_line_segment_v2( + pixel, + mloopuv[mlooptri[cPoint->tri_index].tri[0]].uv, + mloopuv[mlooptri[cPoint->tri_index].tri[1]].uv); /* Dist to second edge */ - t_dist_squared = dist_squared_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[uindex[1]], tface[cPoint->face_index].uv[uindex[2]]); - if (t_dist_squared < dist_squared) { e1_index = cPoint->v2; e2_index = cPoint->v3; edge1_index = uindex[1]; edge2_index = uindex[2]; dist_squared = t_dist_squared; } + t_dist_squared = dist_squared_to_line_segment_v2( + pixel, + mloopuv[mlooptri[cPoint->tri_index].tri[1]].uv, + mloopuv[mlooptri[cPoint->tri_index].tri[2]].uv); + if (t_dist_squared < dist_squared) { + e1_index = cPoint->v2; + e2_index = cPoint->v3; + edge1_index = 1; + edge2_index = 2; + dist_squared = t_dist_squared; + } /* Dist to third edge */ - t_dist_squared = dist_squared_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[uindex[2]], tface[cPoint->face_index].uv[uindex[0]]); - if (t_dist_squared < dist_squared) { e1_index = cPoint->v3; e2_index = cPoint->v1; edge1_index = uindex[2]; edge2_index = uindex[0]; dist_squared = t_dist_squared; } + t_dist_squared = dist_squared_to_line_segment_v2( + pixel, + mloopuv[mlooptri[cPoint->tri_index].tri[2]].uv, + mloopuv[mlooptri[cPoint->tri_index].tri[0]].uv); + if (t_dist_squared < dist_squared) { + e1_index = cPoint->v3; + e2_index = cPoint->v1; + edge1_index = 2; + edge2_index = 0; + dist_squared = t_dist_squared; + } /* * Now find another face that is linked to that edge */ - target_face = -1; + target_tri = -1; - for (i = 0; i < numOfFaces; i++) { + for (i = 0; i < tottri; i++) { /* * Check if both edge vertices share this face */ - int v4 = (mface[i].v4) ? mface[i].v4 : -1; - - if ((e1_index == mface[i].v1 || e1_index == mface[i].v2 || e1_index == mface[i].v3 || e1_index == v4) && - (e2_index == mface[i].v1 || e2_index == mface[i].v2 || e2_index == mface[i].v3 || e2_index == v4)) + if ((e1_index == mloop[mlooptri[i].tri[0]].v || e1_index == mloop[mlooptri[i].tri[1]].v || e1_index == mloop[mlooptri[i].tri[2]].v) && + (e2_index == mloop[mlooptri[i].tri[0]].v || e2_index == mloop[mlooptri[i].tri[1]].v || e2_index == mloop[mlooptri[i].tri[2]].v)) { - if (i == cPoint->face_index) continue; + if (i == cPoint->tri_index) continue; - target_face = i; + target_tri = i; /* * Get edge UV index */ - if (e1_index == mface[i].v1) target_uv1 = 0; - else if (e1_index == mface[i].v2) target_uv1 = 1; - else if (e1_index == mface[i].v3) target_uv1 = 2; - else target_uv1 = 3; + if (e1_index == mloop[mlooptri[i].tri[0]].v) target_uv1 = 0; + else if (e1_index == mloop[mlooptri[i].tri[1]].v) target_uv1 = 1; + else if (e1_index == mloop[mlooptri[i].tri[2]].v) target_uv1 = 2; - if (e2_index == mface[i].v1) target_uv2 = 0; - else if (e2_index == mface[i].v2) target_uv2 = 1; - else if (e2_index == mface[i].v3) target_uv2 = 2; - else target_uv2 = 3; + if (e2_index == mloop[mlooptri[i].tri[0]].v) target_uv2 = 0; + else if (e2_index == mloop[mlooptri[i].tri[1]].v) target_uv2 = 1; + else if (e2_index == mloop[mlooptri[i].tri[2]].v) target_uv2 = 2; break; } } /* If none found pixel is on mesh edge */ - if (target_face == -1) return ON_MESH_EDGE; + if (target_tri == -1) return ON_MESH_EDGE; /* * If target face is connected in UV space as well, just use original index */ - s_uv1 = (float *)tface[cPoint->face_index].uv[edge1_index]; - s_uv2 = (float *)tface[cPoint->face_index].uv[edge2_index]; - t_uv1 = (float *)tface[target_face].uv[target_uv1]; - t_uv2 = (float *)tface[target_face].uv[target_uv2]; + s_uv1 = mloopuv[mlooptri[cPoint->tri_index].tri[edge1_index]].uv; + s_uv2 = mloopuv[mlooptri[cPoint->tri_index].tri[edge2_index]].uv; + t_uv1 = mloopuv[mlooptri[target_tri].tri[target_uv1]].uv; + t_uv2 = mloopuv[mlooptri[target_tri].tri[target_uv2]].uv; //printf("connected UV : %f,%f & %f,%f - %f,%f & %f,%f\n", s_uv1[0], s_uv1[1], s_uv2[0], s_uv2[1], t_uv1[0], t_uv1[1], t_uv2[0], t_uv2[1]); @@ -2184,15 +2191,21 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh * Find a point that is relatively at same edge position * on this other face UV */ - lambda = closest_to_line_v2(closest_point, pixel, tface[cPoint->face_index].uv[edge1_index], tface[cPoint->face_index].uv[edge2_index]); + lambda = closest_to_line_v2( + closest_point, pixel, + mloopuv[mlooptri[cPoint->tri_index].tri[edge1_index]].uv, + mloopuv[mlooptri[cPoint->tri_index].tri[edge2_index]].uv); if (lambda < 0.0f) lambda = 0.0f; if (lambda > 1.0f) lambda = 1.0f; - sub_v2_v2v2(dir_vec, tface[target_face].uv[target_uv2], tface[target_face].uv[target_uv1]); + sub_v2_v2v2( + dir_vec, + mloopuv[mlooptri[target_tri].tri[target_uv2]].uv, + mloopuv[mlooptri[target_tri].tri[target_uv1]].uv); mul_v2_fl(dir_vec, lambda); - copy_v2_v2(pixel, tface[target_face].uv[target_uv1]); + copy_v2_v2(pixel, mloopuv[mlooptri[target_tri].tri[target_uv1]].uv); add_v2_v2(pixel, dir_vec); pixel[0] = (pixel[0] * (float)w) - 0.5f; pixel[1] = (pixel[1] * (float)h) - 0.5f; @@ -2209,7 +2222,9 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh /* If we ended up to our origin point ( mesh has smaller than pixel sized faces) */ if (final_index == (px + w * py)) return NOT_FOUND; /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */ - if (tempPoints[final_index].face_index != target_face) return NOT_FOUND; + if (tempPoints[final_index].tri_index != target_tri) { + return NOT_FOUND; + } /* * If final point is an "edge pixel", use it's "real" neighbor instead @@ -2236,7 +2251,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) }; int ty; int w, h; - int numOfFaces; + int tottri; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; int active_points = 0; int error = 0; @@ -2247,8 +2262,10 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) PaintUVPoint *tempPoints = NULL; Vec3f *tempWeights = NULL; - MFace *mface = NULL; - MTFace *tface = NULL; + const MLoopTri *mlooptri = NULL; + const MLoopUV *mloopuv = NULL; + const MLoop *mloop = NULL; + Bounds2D *faceBB = NULL; int *final_index; int aa_samples; @@ -2258,15 +2275,16 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) return setError(canvas, N_("Cannot bake non-'image sequence' formats")); - numOfFaces = dm->getNumTessFaces(dm); - mface = dm->getTessFaceArray(dm); + mloop = dm->getLoopArray(dm); + mlooptri = dm->getLoopTriArray(dm); + tottri = dm->getNumLoopTri(dm); /* get uv map */ - CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, surface->uvlayer_name, uvname); - tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, surface->uvlayer_name, uvname); + mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname); /* Check for validity */ - if (!tface) + if (!mloopuv) return setError(canvas, N_("No UV data on canvas")); if (surface->image_resolution < 16 || surface->image_resolution > 8192) return setError(canvas, N_("Invalid resolution")); @@ -2276,7 +2294,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) /* * Start generating the surface */ - printf("DynamicPaint: Preparing UV surface of %ix%i pixels and %i faces.\n", w, h, numOfFaces); + printf("DynamicPaint: Preparing UV surface of %ix%i pixels and %i tris.\n", w, h, tottri); /* Init data struct */ if (surface->data) dynamicPaint_freeSurfaceData(surface); @@ -2299,24 +2317,22 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) * the pixel-inside-a-face search. */ if (!error) { - faceBB = (struct Bounds2D *) MEM_mallocN(numOfFaces * sizeof(struct Bounds2D), "MPCanvasFaceBB"); + faceBB = (struct Bounds2D *) MEM_mallocN(tottri * sizeof(struct Bounds2D), "MPCanvasFaceBB"); if (!faceBB) error = 1; } if (!error) - for (ty = 0; ty < numOfFaces; ty++) { - int numOfVert = (mface[ty].v4) ? 4 : 3; + for (ty = 0; ty < tottri; ty++) { int i; - copy_v2_v2(faceBB[ty].min, tface[ty].uv[0]); - copy_v2_v2(faceBB[ty].max, tface[ty].uv[0]); - - for (i = 1; i < numOfVert; i++) { - if (tface[ty].uv[i][0] < faceBB[ty].min[0]) faceBB[ty].min[0] = tface[ty].uv[i][0]; - if (tface[ty].uv[i][1] < faceBB[ty].min[1]) faceBB[ty].min[1] = tface[ty].uv[i][1]; - if (tface[ty].uv[i][0] > faceBB[ty].max[0]) faceBB[ty].max[0] = tface[ty].uv[i][0]; - if (tface[ty].uv[i][1] > faceBB[ty].max[1]) faceBB[ty].max[1] = tface[ty].uv[i][1]; + copy_v2_v2(faceBB[ty].min, mloopuv[mlooptri[ty].tri[0]].uv); + copy_v2_v2(faceBB[ty].max, mloopuv[mlooptri[ty].tri[0]].uv); + for (i = 1; i < 3; i++) { + CLAMP_MAX(faceBB[ty].min[0], mloopuv[mlooptri[ty].tri[i]].uv[0]); + CLAMP_MAX(faceBB[ty].min[1], mloopuv[mlooptri[ty].tri[i]].uv[1]); + CLAMP_MIN(faceBB[ty].max[0], mloopuv[mlooptri[ty].tri[i]].uv[0]); + CLAMP_MIN(faceBB[ty].max[1], mloopuv[mlooptri[ty].tri[i]].uv[1]); } } @@ -2333,13 +2349,13 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) int index = tx + w * ty; PaintUVPoint *tPoint = (&tempPoints[index]); - short isInside = 0; /* if point is inside a uv face */ + bool isInside = false; /* if point is inside a uv face */ float d1[2], d2[2], d3[2], point[5][2]; float dot00, dot01, dot02, dot11, dot12, invDenom, u, v; /* Init per pixel settings */ - tPoint->face_index = -1; + tPoint->tri_index = -1; tPoint->neighbour_pixel = -1; tPoint->pixel_index = index; @@ -2366,9 +2382,9 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) /* Loop through samples, starting from middle point */ for (sample = 0; sample < 5; sample++) { - + /* Loop through every face in the mesh */ - for (i = 0; i < numOfFaces; i++) { + for (i = 0; i < tottri; i++) { /* Check uv bb */ if (faceBB[i].min[0] > (point[sample][0])) continue; @@ -2378,9 +2394,9 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) /* Calculate point inside a triangle check * for uv0, 1, 2 */ - sub_v2_v2v2(d1, tface[i].uv[2], tface[i].uv[0]); // uv2 - uv0 - sub_v2_v2v2(d2, tface[i].uv[1], tface[i].uv[0]); // uv1 - uv0 - sub_v2_v2v2(d3, point[sample], tface[i].uv[0]); // point - uv0 + sub_v2_v2v2(d1, mloopuv[mlooptri[i].tri[2]].uv, mloopuv[mlooptri[i].tri[0]].uv); /* uv2 - uv0 */ + sub_v2_v2v2(d2, mloopuv[mlooptri[i].tri[1]].uv, mloopuv[mlooptri[i].tri[0]].uv); /* uv1 - uv0 */ + sub_v2_v2v2(d3, point[sample], mloopuv[mlooptri[i].tri[0]].uv); /* point - uv0 */ dot00 = d1[0] * d1[0] + d1[1] * d1[1]; dot01 = d1[0] * d2[0] + d1[1] * d2[1]; @@ -2393,50 +2409,20 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; - if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = 1; } /* is inside a triangle */ - - /* If collision wasn't found but the face is a quad - * do another check for the second half */ - if ((!isInside) && mface[i].v4) { - - /* change d2 to test the other half */ - sub_v2_v2v2(d2, tface[i].uv[3], tface[i].uv[0]); // uv3 - uv0 - - /* test again */ - dot00 = d1[0] * d1[0] + d1[1] * d1[1]; - dot01 = d1[0] * d2[0] + d1[1] * d2[1]; - dot02 = d1[0] * d3[0] + d1[1] * d3[1]; - dot11 = d2[0] * d2[0] + d2[1] * d2[1]; - dot12 = d2[0] * d3[0] + d2[1] * d3[1]; - - invDenom = (dot00 * dot11 - dot01 * dot01); - invDenom = invDenom ? 1.0f / invDenom : 1.0f; - u = (dot11 * dot02 - dot01 * dot12) * invDenom; - v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = 2; } /* is inside the second half of the quad */ - - } + if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = true; } /* is inside a triangle */ /* * If point was inside the face */ - if (isInside != 0) { + if (isInside) { float uv1co[2], uv2co[2], uv3co[2], uv[2]; int j; /* Get triagnle uvs */ - if (isInside == 1) { - copy_v2_v2(uv1co, tface[i].uv[0]); - copy_v2_v2(uv2co, tface[i].uv[1]); - copy_v2_v2(uv3co, tface[i].uv[2]); - } - else { - copy_v2_v2(uv1co, tface[i].uv[0]); - copy_v2_v2(uv2co, tface[i].uv[2]); - copy_v2_v2(uv3co, tface[i].uv[3]); - } + copy_v2_v2(uv1co, mloopuv[mlooptri[i].tri[0]].uv); + copy_v2_v2(uv2co, mloopuv[mlooptri[i].tri[1]].uv); + copy_v2_v2(uv3co, mloopuv[mlooptri[i].tri[2]].uv); /* Add b-weights per anti-aliasing sample */ for (j = 0; j < aa_samples; j++) { @@ -2447,13 +2433,12 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) } /* Set surface point face values */ - tPoint->face_index = i; /* face index */ - tPoint->quad = (isInside == 2) ? 1 : 0; /* quad or tri part*/ + tPoint->tri_index = i; /* save vertex indexes */ - tPoint->v1 = mface[i].v1; - tPoint->v2 = (isInside == 2) ? mface[i].v3 : mface[i].v2; - tPoint->v3 = (isInside == 2) ? mface[i].v4 : mface[i].v3; + tPoint->v1 = mloop[mlooptri[i].tri[0]].v; + tPoint->v2 = mloop[mlooptri[i].tri[1]].v; + tPoint->v3 = mloop[mlooptri[i].tri[2]].v; sample = 5; /* make sure we exit sample loop as well */ break; @@ -2477,7 +2462,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) PaintUVPoint *tPoint = (&tempPoints[index]); /* If point isn't't on canvas mesh */ - if (tPoint->face_index == -1) { + if (tPoint->tri_index == -1) { int u_min, u_max, v_min, v_max; int u, v, ind; float point[2]; @@ -2499,22 +2484,15 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) ind = (tx + u) + w * (ty + v); /* if neighbor has index */ - if (tempPoints[ind].face_index != -1) { + if (tempPoints[ind].tri_index != -1) { float uv1co[2], uv2co[2], uv3co[2], uv[2]; - int i = tempPoints[ind].face_index, j; + int i = tempPoints[ind].tri_index, j; /* Now calculate pixel data for this pixel as it was on polygon surface */ - if (!tempPoints[ind].quad) { - copy_v2_v2(uv1co, tface[i].uv[0]); - copy_v2_v2(uv2co, tface[i].uv[1]); - copy_v2_v2(uv3co, tface[i].uv[2]); - } - else { - copy_v2_v2(uv1co, tface[i].uv[0]); - copy_v2_v2(uv2co, tface[i].uv[2]); - copy_v2_v2(uv3co, tface[i].uv[3]); - } + copy_v2_v2(uv1co, mloopuv[mlooptri[i].tri[0]].uv); + copy_v2_v2(uv2co, mloopuv[mlooptri[i].tri[1]].uv); + copy_v2_v2(uv3co, mloopuv[mlooptri[i].tri[2]].uv); /* Add b-weights per anti-aliasing sample */ for (j = 0; j < aa_samples; j++) { @@ -2525,13 +2503,12 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) } /* Set values */ - tPoint->neighbour_pixel = ind; // face index - tPoint->quad = tempPoints[ind].quad; // quad or tri + tPoint->neighbour_pixel = ind; /* tri index */ /* save vertex indexes */ - tPoint->v1 = mface[i].v1; - tPoint->v2 = (tPoint->quad) ? mface[i].v3 : mface[i].v2; - tPoint->v3 = (tPoint->quad) ? mface[i].v4 : mface[i].v3; + tPoint->v1 = mloop[mlooptri[i].tri[0]].v; + tPoint->v2 = mloop[mlooptri[i].tri[1]].v; + tPoint->v3 = mloop[mlooptri[i].tri[2]].v; u = u_max + 1; /* make sure we exit outer loop as well */ break; @@ -2550,10 +2527,12 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) int tx; for (tx = 0; tx < w; tx++) { int index = tx + w * ty; - PaintUVPoint *tPoint = (&tempPoints[index]); + PaintUVPoint *tPoint = &tempPoints[index]; - if (tPoint->face_index == -1 && tPoint->neighbour_pixel != -1) tPoint->face_index = tempPoints[tPoint->neighbour_pixel].face_index; - if (tPoint->face_index != -1) active_points++; + if (tPoint->tri_index == -1 && tPoint->neighbour_pixel != -1) + tPoint->tri_index = tempPoints[tPoint->neighbour_pixel].tri_index; + if (tPoint->tri_index != -1) + active_points++; } } @@ -2564,7 +2543,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) /* Create a temporary array of final indexes (before unassigned * pixels have been dropped) */ for (i = 0; i < w * h; i++) { - if (tempPoints[i].face_index != -1) { + if (tempPoints[i].tri_index != -1) { final_index[i] = cursor; cursor++; } @@ -2581,7 +2560,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) for (tx = 0; tx < w; tx++) { int i, index = tx + w * ty; - if (tempPoints[index].face_index != -1) { + if (tempPoints[index].tri_index != -1) { ed->n_index[final_index[index]] = n_pos; ed->n_num[final_index[index]] = 0; @@ -2635,7 +2614,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) sData->format_data = f_data; for (index = 0; index < (w * h); index++) { - if (tempPoints[index].face_index != -1) { + if (tempPoints[index].tri_index != -1) { memcpy(&f_data->uv_p[cursor], &tempPoints[index], sizeof(PaintUVPoint)); memcpy(&f_data->barycentricWeights[cursor * aa_samples], &tempWeights[index * aa_samples], sizeof(Vec3f) * aa_samples); cursor++; @@ -2671,9 +2650,9 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface) /* Every pixel that is assigned as "edge pixel" gets blue color */ if (uvPoint->neighbour_pixel != -1) pPoint->color[2] = 1.0f; /* and every pixel that finally got an polygon gets red color */ - if (uvPoint->face_index != -1) pPoint->color[0] = 1.0f; + if (uvPoint->tri_index != -1) pPoint->color[0] = 1.0f; /* green color shows pixel face index hash */ - if (uvPoint->face_index != -1) pPoint->color[1] = (float)(uvPoint->face_index % 255) / 256.0f; + if (uvPoint->tri_index != -1) pPoint->color[1] = (float)(uvPoint->tri_index % 255) / 256.0f; } #endif @@ -2741,7 +2720,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam PaintPoint *point = &((PaintPoint *)sData->type_data)[index]; /* blend wet and dry layers */ - blendColors(point->color, point->alpha, point->e_color, point->e_alpha, &ibuf->rect_float[pos]); + blendColors(point->color, point->color[3], point->e_color, point->e_color[3], &ibuf->rect_float[pos]); /* Multiply color by alpha if enabled */ if (surface->flags & MOD_DPAINT_MULALPHA) { @@ -2858,17 +2837,20 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats) /* * Get material diffuse color and alpha (including linked textures) in given coordinates */ -static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, - const float volume_co[3], const float surface_co[3], - int faceIndex, short isQuad, DerivedMesh *orcoDm) +static void dynamicPaint_doMaterialTex( + BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, + const float volume_co[3], const float surface_co[3], + int triIndex, DerivedMesh *orcoDm) { Material *mat = bMats->mat; - MFace *mface = orcoDm->getTessFaceArray(orcoDm); + + const MLoopTri *mlooptri = orcoDm->getLoopTriArray(orcoDm); + const MPoly *mpoly = orcoDm->getPolyArray(orcoDm); /* If no material defined, use the one assigned to the mesh face */ if (mat == NULL) { if (bMats->ob_mats) { - int mat_nr = mface[faceIndex].mat_nr; + int mat_nr = mpoly[mlooptri[triIndex].poly].mat_nr; if (mat_nr >= (*give_totcolp(brushOb))) return; mat = bMats->ob_mats[mat_nr]; if (mat == NULL) return; /* No material assigned */ @@ -2877,88 +2859,69 @@ static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], fl return; } } - - RE_sample_material_color(mat, color, alpha, volume_co, surface_co, faceIndex, isQuad, orcoDm, brushOb); + RE_sample_material_color(mat, color, alpha, volume_co, surface_co, triIndex, orcoDm, brushOb); } /***************************** Ray / Nearest Point Utils ******************************/ -/* A modified callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces. +/* A modified callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_looptri. * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. * * To optimize brush detection speed this doesn't calculate hit coordinates or normal. - * If ray hit the second half of a quad, no[0] is set to 1.0f. */ -static void mesh_faces_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +static void mesh_tris_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; const MVert *vert = data->vert; - const MFace *face = data->face + index; - short quad = 0; - - const float *t0, *t1, *t2, *t3; - t0 = vert[face->v1].co; - t1 = vert[face->v2].co; - t2 = vert[face->v3].co; - t3 = face->v4 ? vert[face->v4].co : NULL; - - do { - float dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); - - if (dist >= 0 && dist < hit->dist) { - hit->index = index; - hit->dist = dist; - hit->no[0] = (quad) ? 1.0f : 0.0f; - } + const MLoopTri *mlooptri = data->looptri; + const MLoop *mloop = data->loop; + + const float *t0, *t1, *t2; + float dist; - t1 = t2; - t2 = t3; - t3 = NULL; - quad = 1; + t0 = vert[mloop[mlooptri[index].tri[0]].v].co; + t1 = vert[mloop[mlooptri[index].tri[1]].v].co; + t2 = vert[mloop[mlooptri[index].tri[2]].v].co; + + dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); + + if (dist >= 0 && dist < hit->dist) { + hit->index = index; + hit->dist = dist; + hit->no[0] = 0.0f; + } - } while (t2); } -/* A modified callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces. +/* A modified callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_looptri. * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. * * To optimize brush detection speed this doesn't calculate hit normal. - * If ray hit the second half of a quad, no[0] is set to 1.0f, else 0.0f */ -static void mesh_faces_nearest_point_dp(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) +static void mesh_tris_nearest_point_dp(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; const MVert *vert = data->vert; - const MFace *face = data->face + index; - short quad = 0; - - const float *t0, *t1, *t2, *t3; - t0 = vert[face->v1].co; - t1 = vert[face->v2].co; - t2 = vert[face->v3].co; - t3 = face->v4 ? vert[face->v4].co : NULL; - - do { - float nearest_tmp[3], dist_sq; - - closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); - dist_sq = len_squared_v3v3(co, nearest_tmp); - - if (dist_sq < nearest->dist_sq) { - nearest->index = index; - nearest->dist_sq = dist_sq; - copy_v3_v3(nearest->co, nearest_tmp); - nearest->no[0] = (quad) ? 1.0f : 0.0f; - } - - t1 = t2; - t2 = t3; - t3 = NULL; - quad = 1; - - } while (t2); + const MLoopTri *mlooptri = data->looptri; + const MLoop *mloop = data->loop; + float nearest_tmp[3], dist_sq; + + const float *t0, *t1, *t2; + t0 = vert[mloop[mlooptri[index].tri[0]].v].co; + t1 = vert[mloop[mlooptri[index].tri[1]].v].co; + t2 = vert[mloop[mlooptri[index].tri[2]].v].co; + + closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); + dist_sq = len_squared_v3v3(co, nearest_tmp); + + if (dist_sq < nearest->dist_sq) { + nearest->index = index; + nearest->dist_sq = dist_sq; + copy_v3_v3(nearest->co, nearest_tmp); + nearest->no[0] = 0.0f; + } } @@ -2986,23 +2949,23 @@ static void dynamicPaint_mixPaintColors( float temp_alpha = (*paintAlpha) * ((paintFlags & MOD_DPAINT_ABS_ALPHA) ? 1.0f : (*timescale)); /* mix brush color with wet layer color */ - blendColors(pPoint->e_color, pPoint->e_alpha, paintColor, temp_alpha, mix); + blendColors(pPoint->e_color, pPoint->e_color[3], paintColor, temp_alpha, mix); copy_v3_v3(pPoint->e_color, mix); /* mix wetness and alpha depending on selected alpha mode */ if (paintFlags & MOD_DPAINT_ABS_ALPHA) { /* update values to the brush level unless theyre higher already */ - if (pPoint->e_alpha < (*paintAlpha)) pPoint->e_alpha = (*paintAlpha); - if (pPoint->wetness < (*paintWetness)) pPoint->wetness = (*paintWetness); + CLAMP_MIN(pPoint->e_color[3], *paintAlpha); + CLAMP_MIN(pPoint->wetness, *paintWetness); } else { float wetness = (*paintWetness); CLAMP(wetness, 0.0f, 1.0f); - pPoint->e_alpha = mix[3]; + pPoint->e_color[3] = mix[3]; pPoint->wetness = pPoint->wetness * (1.0f - wetness) + wetness; } - if (pPoint->wetness < MIN_WETNESS) pPoint->wetness = MIN_WETNESS; + CLAMP_MIN(pPoint->wetness, MIN_WETNESS); pPoint->state = DPAINT_PAINT_NEW; } @@ -3017,23 +2980,23 @@ static void dynamicPaint_mixPaintColors( * but maintain alpha ratio */ if (paintFlags & MOD_DPAINT_ABS_ALPHA) { - a_highest = (pPoint->e_alpha > pPoint->alpha) ? pPoint->e_alpha : pPoint->alpha; + a_highest = max_ff(pPoint->color[3], pPoint->e_color[3]); if (a_highest > invFact) { a_ratio = invFact / a_highest; - pPoint->e_alpha *= a_ratio; - pPoint->alpha *= a_ratio; + pPoint->e_color[3] *= a_ratio; + pPoint->color[3] *= a_ratio; } } else { - pPoint->e_alpha -= (*paintAlpha) * (*timescale); - if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f; - pPoint->alpha -= (*paintAlpha) * (*timescale); - if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f; + pPoint->e_color[3] -= (*paintAlpha) * (*timescale); + CLAMP_MIN(pPoint->e_color[3], 0.0f); + pPoint->color[3] -= (*paintAlpha) * (*timescale); + CLAMP_MIN(pPoint->color[3], 0.0f); } - wetness = (1.0f - (*paintWetness)) * pPoint->e_alpha; - if (pPoint->wetness > wetness) pPoint->wetness = wetness; + wetness = (1.0f - (*paintWetness)) * pPoint->e_color[3]; + CLAMP_MAX(pPoint->wetness, wetness); } } @@ -3286,7 +3249,8 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, DerivedMesh *dm = NULL; Vec3f *brushVelocity = NULL; MVert *mvert = NULL; - MFace *mface = NULL; + const MLoopTri *mlooptri = NULL; + const MLoop *mloop = NULL; if (brush->flags & MOD_DPAINT_USES_VELOCITY) dynamicPaint_brushMeshCalculateVelocity(scene, brushOb, brush, &brushVelocity, timescale); @@ -3303,7 +3267,8 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, dm = CDDM_copy(brush->dm); mvert = dm->getVertArray(dm); - mface = dm->getTessFaceArray(dm); + mlooptri = dm->getLoopTriArray(dm); + mloop = dm->getLoopArray(dm); numOfVerts = dm->getNumVerts(dm); /* Transform collider vertices to global space @@ -3336,7 +3301,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, /* check bounding box collision */ if (grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush, brush_radius)) { /* Build a bvh tree from transformed vertices */ - if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 8)) { + if (bvhtree_from_mesh_looptri(&treeData, dm, 0.0f, 4, 8)) { int c_index; int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2]; @@ -3385,8 +3350,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, /* hit data */ float hitCoord[3]; - int hitFace = -1; - short hitQuad = 0; + int hitTri = -1; /* Supersampling factor */ if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) @@ -3408,16 +3372,19 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, /* Check volume collision */ if (brush->collision == MOD_DPAINT_COL_VOLUME || brush->collision == MOD_DPAINT_COL_VOLDIST) - if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_tris_spherecast_dp, &treeData) != -1) { /* We hit a triangle, now check if collision point normal is facing the point */ /* For optimization sake, hit point normal isn't calculated in ray cast loop */ - int v1 = mface[hit.index].v1, v2 = mface[hit.index].v2, v3 = mface[hit.index].v3, quad = (hit.no[0] == 1.0f); + const int vtri[3] = { + mloop[mlooptri[hit.index].tri[0]].v, + mloop[mlooptri[hit.index].tri[1]].v, + mloop[mlooptri[hit.index].tri[2]].v, + }; float dot; - if (quad) { v2 = mface[hit.index].v3; v3 = mface[hit.index].v4; } - normal_tri_v3(hit.no, mvert[v1].co, mvert[v2].co, mvert[v3].co); - dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; + normal_tri_v3(hit.no, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); + dot = dot_v3v3(ray_dir, hit.no); /* If ray and hit face normal are facing same direction * hit point is inside a closed mesh. */ @@ -3431,7 +3398,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, hit.index = -1; hit.dist = 9999; - BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData); + BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_tris_spherecast_dp, &treeData); if (hit.index != -1) { /* Add factor on supersample filter */ @@ -3441,8 +3408,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, /* Mark hit info */ madd_v3_v3v3fl(hitCoord, ray_start, ray_dir, hit.dist); /* Calculate final hit coordinates */ depth += dist * sample_factor; - hitFace = f_index; - hitQuad = quad; + hitTri = f_index; } } } @@ -3453,19 +3419,17 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, { float proxDist = -1.0f; float hitCo[3] = {0.0f, 0.0f, 0.0f}; - short hQuad; - int face; + int tri; /* if inverse prox and no hit found, skip this sample */ if (inner_proximity && !hit_found) continue; /* If pure distance proximity, find the nearest point on the mesh */ if (!(brush->flags & MOD_DPAINT_PROX_PROJECT)) { - if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_faces_nearest_point_dp, &treeData) != -1) { + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_tris_nearest_point_dp, &treeData) != -1) { proxDist = sqrtf(nearest.dist_sq); copy_v3_v3(hitCo, nearest.co); - hQuad = (nearest.no[0] == 1.0f); - face = nearest.index; + tri = nearest.index; } } else { /* else cast a ray in defined projection direction */ @@ -3485,11 +3449,10 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, hit.dist = brush_radius; /* Do a face normal directional raycast, and use that distance */ - if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, proj_ray, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, proj_ray, 0.0f, &hit, mesh_tris_spherecast_dp, &treeData) != -1) { proxDist = hit.dist; madd_v3_v3v3fl(hitCo, ray_start, proj_ray, hit.dist); /* Calculate final hit coordinates */ - hQuad = (hit.no[0] == 1.0f); - face = hit.index; + tri = hit.index; } } @@ -3503,10 +3466,9 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, hit_found = HIT_PROXIMITY; /* if no volume hit, use prox point face info */ - if (hitFace == -1) { + if (hitTri == -1) { copy_v3_v3(hitCoord, hitCo); - hitQuad = hQuad; - hitFace = face; + hitTri = tri; } } } @@ -3547,16 +3509,10 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, float brushPointVelocity[3]; float velocity[3]; - if (!hitQuad) { - v1 = mface[hitFace].v1; - v2 = mface[hitFace].v2; - v3 = mface[hitFace].v3; - } - else { - v1 = mface[hitFace].v2; - v2 = mface[hitFace].v3; - v3 = mface[hitFace].v4; - } + v1 = mloop[mlooptri[hitTri].tri[0]].v; + v2 = mloop[mlooptri[hitTri].tri[1]].v; + v3 = mloop[mlooptri[hitTri].tri[2]].v; + /* calculate barycentric weights for hit point */ interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, hitCoord); @@ -3601,7 +3557,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, /* Get material+textures color on hit point if required */ if (brush_usesMaterial(brush, scene)) - dynamicPaint_doMaterialTex(bMats, sampleColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index] + ss].v, hitCoord, hitFace, hitQuad, brush->dm); + dynamicPaint_doMaterialTex(bMats, sampleColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index] + ss].v, hitCoord, hitTri, brush->dm); /* Sample proximity colorband if required */ if ((hit_found == HIT_PROXIMITY) && (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP)) { @@ -3961,7 +3917,7 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po copy_v3_v3(hit_coord, mvert[0].co); mul_m4_v3(brushOb->obmat, hit_coord); - dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, 0, brush->dm); + dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, brush->dm); } /* color ramp */ @@ -4190,15 +4146,15 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrus if (dir_dot <= 0.0f) continue; dir_factor = dir_dot * speed_scale; - if (dir_factor > brush->smudge_strength) dir_factor = brush->smudge_strength; + CLAMP_MAX(dir_factor, brush->smudge_strength); /* mix new color and alpha */ - mixColors(ePoint->color, ePoint->alpha, pPoint->color, pPoint->alpha, dir_factor); - ePoint->alpha = ePoint->alpha * (1.0f - dir_factor) + pPoint->alpha * dir_factor; + mixColors(ePoint->color, ePoint->color[3], pPoint->color, pPoint->color[3], dir_factor); + ePoint->color[3] = ePoint->color[3] * (1.0f - dir_factor) + pPoint->color[3] * dir_factor; /* smudge "wet layer" */ - mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, pPoint->e_alpha, dir_factor); - ePoint->e_alpha = ePoint->e_alpha * (1.0f - dir_factor) + pPoint->e_alpha * dir_factor; + mixColors(ePoint->e_color, ePoint->e_color[3], pPoint->e_color, pPoint->e_color[3], dir_factor); + ePoint->e_color[3] = ePoint->e_color[3] * (1.0f - dir_factor) + pPoint->e_color[3] * dir_factor; pPoint->wetness *= (1.0f - dir_factor); } } @@ -4337,7 +4293,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force float color_mix = (MIN3(ePoint->wetness, pPoint->wetness, 1.0f)) * 0.25f * surface->color_spread_speed; /* do color mixing */ - if (color_mix) mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, color_mix); + if (color_mix) mixColors(pPoint->e_color, pPoint->e_color[3], ePoint->e_color, ePoint->e_color[3], color_mix); /* Only continue if surrounding point has higher wetness */ if (ePoint->wetness < pPoint->wetness || ePoint->wetness < MIN_WETNESS) continue; @@ -4347,7 +4303,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force /* mix new wetness and color */ pPoint->wetness = (1.0f - w_factor) * pPoint->wetness + w_factor * ePoint->wetness; - pPoint->e_alpha = mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, w_factor); + pPoint->e_color[3] = mixColors(pPoint->e_color, pPoint->e_color[3], ePoint->e_color, ePoint->e_color[3], w_factor); } } } @@ -4374,28 +4330,28 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force PaintPoint *ePoint = &prevPoint[sData->adj_data->n_target[n_index]]; float a_factor, ea_factor, w_factor; - totalAlpha += ePoint->e_alpha; + totalAlpha += ePoint->e_color[3]; /* Check if neighboring point has lower alpha, * if so, decrease this point's alpha as well*/ - if (pPoint->alpha <= 0.0f && pPoint->e_alpha <= 0.0f && pPoint->wetness <= 0.0f) continue; + if (pPoint->color[3] <= 0.0f && pPoint->e_color[3] <= 0.0f && pPoint->wetness <= 0.0f) continue; /* decrease factor for dry paint alpha */ - a_factor = (1.0f - ePoint->alpha) / numOfNeighs * (pPoint->alpha - ePoint->alpha) * speed_scale; - if (a_factor < 0.0f) a_factor = 0.0f; + a_factor = (1.0f - ePoint->color[3]) / numOfNeighs * (pPoint->color[3] - ePoint->color[3]) * speed_scale; + CLAMP_MIN(a_factor, 0.0f); /* decrease factor for wet paint alpha */ - ea_factor = (1.0f - ePoint->e_alpha) / 8 * (pPoint->e_alpha - ePoint->e_alpha) * speed_scale; - if (ea_factor < 0.0f) ea_factor = 0.0f; + ea_factor = (1.0f - ePoint->e_color[3]) / 8 * (pPoint->e_color[3] - ePoint->e_color[3]) * speed_scale; + CLAMP_MIN(ea_factor, 0.0f); /* decrease factor for paint wetness */ w_factor = (1.0f - ePoint->wetness) / 8 * (pPoint->wetness - ePoint->wetness) * speed_scale; - if (w_factor < 0.0f) w_factor = 0.0f; + CLAMP_MIN(w_factor, 0.0f); - pPoint->alpha -= a_factor; - if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f; - pPoint->e_alpha -= ea_factor; - if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f; + pPoint->color[3] -= a_factor; + CLAMP_MIN(pPoint->color[3], 0.0f); + pPoint->e_color[3] -= ea_factor; + CLAMP_MIN(pPoint->e_color[3], 0.0f); pPoint->wetness -= w_factor; - if (pPoint->wetness < 0.0f) pPoint->wetness = 0.0f; + CLAMP_MIN(pPoint->wetness, 0.0f); } } } @@ -4437,7 +4393,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force if (dir_dot <= 0.0f) continue; dir_factor = dir_dot * MIN2(speed_scale, 1.0f) * w_factor; - if (dir_factor > 0.5f) dir_factor = 0.5f; + CLAMP_MAX(dir_factor, 0.5f); /* mix new wetness */ ePoint->wetness += dir_factor; @@ -4446,12 +4402,11 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force /* mix new color */ a_factor = dir_factor / pPoint_prev->wetness; CLAMP(a_factor, 0.0f, 1.0f); - mixColors(ePoint->e_color, ePoint->e_alpha, pPoint_prev->e_color, pPoint_prev->e_alpha, a_factor); + mixColors(ePoint->e_color, ePoint->e_color[3], pPoint_prev->e_color, pPoint_prev->e_color[3], a_factor); /* dripping is supposed to preserve alpha level */ - if (pPoint_prev->e_alpha > ePoint->e_alpha) { - ePoint->e_alpha += a_factor * pPoint_prev->e_alpha; - if (ePoint->e_alpha > pPoint_prev->e_alpha) - ePoint->e_alpha = pPoint_prev->e_alpha; + if (pPoint_prev->e_color[3] > ePoint->e_color[3]) { + ePoint->e_color[3] += a_factor * pPoint_prev->e_color[3]; + CLAMP_MAX(ePoint->e_color[3], pPoint_prev->e_color[3]); } /* decrease paint wetness on current point */ @@ -4610,21 +4565,21 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time * Slowly "shift" paint from wet layer to dry layer as it drys: */ /* make sure alpha values are within proper range */ - CLAMP(pPoint->alpha, 0.0f, 1.0f); - CLAMP(pPoint->e_alpha, 0.0f, 1.0f); + CLAMP(pPoint->color[3], 0.0f, 1.0f); + CLAMP(pPoint->e_color[3], 0.0f, 1.0f); /* get current final blended color of these layers */ - blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color); + blendColors(pPoint->color, pPoint->color[3], pPoint->e_color, pPoint->e_color[3], f_color); /* reduce wet layer alpha by dry factor */ - pPoint->e_alpha *= dry_ratio; + pPoint->e_color[3] *= dry_ratio; /* now calculate new alpha for dry layer that keeps final blended color unchanged */ - pPoint->alpha = (f_color[3] - pPoint->e_alpha) / (1.0f - pPoint->e_alpha); + pPoint->color[3] = (f_color[3] - pPoint->e_color[3]) / (1.0f - pPoint->e_color[3]); /* for each rgb component, calculate a new dry layer color that keeps the final blend color * with these new alpha values. (wet layer color doesnt change)*/ - if (pPoint->alpha) { + if (pPoint->color[3]) { for (i = 0; i < 3; i++) { - pPoint->color[i] = (f_color[i] * f_color[3] - pPoint->e_color[i] * pPoint->e_alpha) / (pPoint->alpha * (1.0f - pPoint->e_alpha)); + pPoint->color[i] = (f_color[i] * f_color[3] - pPoint->e_color[i] * pPoint->e_color[3]) / (pPoint->color[3] * (1.0f - pPoint->e_color[3])); } } } @@ -4634,22 +4589,21 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time /* in case of just dryed paint, just mix it to the dry layer and mark it empty */ else if (pPoint->state > 0) { float f_color[4]; - blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color); - copy_v3_v3(pPoint->color, f_color); - pPoint->alpha = f_color[3]; + blendColors(pPoint->color, pPoint->color[3], pPoint->e_color, pPoint->e_color[3], f_color); + copy_v4_v4(pPoint->color, f_color); /* clear wet layer */ pPoint->wetness = 0.0f; - pPoint->e_alpha = 0.0f; + pPoint->e_color[3] = 0.0f; pPoint->state = DPAINT_PAINT_DRY; } } if (surface->flags & MOD_DPAINT_DISSOLVE) { - value_dissolve(&pPoint->alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); - if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f; + value_dissolve(&pPoint->color[3], surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); + CLAMP_MIN(pPoint->color[3], 0.0f); - value_dissolve(&pPoint->e_alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); - if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f; + value_dissolve(&pPoint->e_color[3], surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); + CLAMP_MIN(pPoint->e_color[3], 0.0f); } } /* dissolve for float types */ @@ -4661,7 +4615,7 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time float *point = &((float *)sData->type_data)[index]; /* log or linear */ value_dissolve(point, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); - if (*point < 0.0f) *point = 0.0f; + CLAMP_MIN(*point, 0.0f); } } } diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 9d8a1a66771..6e1f128b7a5 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -56,9 +56,9 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove); /* dynamicpaint.c */ struct Material *RE_init_sample_material(struct Material *orig_mat, struct Scene *scene); void RE_free_sample_material(struct Material *mat); -void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], - int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob); - +void RE_sample_material_color( + struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], + int tri_index, struct DerivedMesh *orcoDm, struct Object *ob); /* pointdensity.c */ struct PointDensity; diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index c53fb7d1153..f78c0aa8cb2 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -86,12 +86,12 @@ struct ShadeInputCopy { typedef struct ShadeInputUV { float dxuv[3], dyuv[3], uv[3]; - char *name; + const char *name; } ShadeInputUV; typedef struct ShadeInputCol { float col[4]; - char *name; + const char *name; } ShadeInputCol; /* localized renderloop data */ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 6acdde6af9c..fc95cf8c275 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -3526,7 +3526,9 @@ void render_realtime_texture(ShadeInput *shi, Image *ima) /* A modified part of shadeinput.c -> shade_input_set_uv() * Used for sampling UV mapped texture color */ -static void textured_face_generate_uv(float *uv, const float normal[3], float *hit, float *v1, float *v2, float *v3) +static void textured_face_generate_uv( + float r_uv[2], const float normal[3], const float hit[3], + const float v1[3], const float v2[3], const float v3[3]) { float detsh, t00, t10, t01, t11; @@ -3543,12 +3545,12 @@ static void textured_face_generate_uv(float *uv, const float normal[3], float *h t00*= detsh; t01*=detsh; t10*=detsh; t11*=detsh; - uv[0] = (hit[axis1]-v3[axis1])*t11-(hit[axis2]-v3[axis2])*t10; - uv[1] = (hit[axis2]-v3[axis2])*t00-(hit[axis1]-v3[axis1])*t01; + r_uv[0] = (hit[axis1] - v3[axis1]) * t11 - (hit[axis2] - v3[axis2]) * t10; + r_uv[1] = (hit[axis2] - v3[axis2]) * t00 - (hit[axis1] - v3[axis1]) * t01; /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */ - CLAMP(uv[0], -2.0f, 1.0f); - CLAMP(uv[1], -2.0f, 1.0f); + CLAMP(r_uv[0], -2.0f, 1.0f); + CLAMP(r_uv[1], -2.0f, 1.0f); } /* Generate an updated copy of material to use for color sampling. */ @@ -3664,34 +3666,37 @@ void RE_free_sample_material(Material *mat) MEM_freeN(mat); } - - /* * Get material diffuse color and alpha (including linked textures) in given coordinates * * color,alpha : input/output color values * volume_co : sample coordinate in global space. used by volumetric materials * surface_co : sample surface coordinate in global space. used by "surface" materials - * face_index : surface face index - * hit_quad : whether point is on second "half" of a quad + * tri_index : surface tri index * orcoDm : orco state derived mesh */ -void RE_sample_material_color(Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], int face_index, short hit_quad, DerivedMesh *orcoDm, Object *ob) +void RE_sample_material_color( + Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], + int tri_index, DerivedMesh *orcoDm, Object *ob) { - MFace *mface; int v1, v2, v3; MVert *mvert; + MLoop *mloop; + const MLoopTri *mlooptri; float uv[3], normal[3]; ShadeInput shi = {NULL}; Render re = {NULL}; /* Get face data */ mvert = orcoDm->getVertArray(orcoDm); - mface = orcoDm->getTessFaceArray(orcoDm); + mloop = orcoDm->getLoopArray(orcoDm); + mlooptri = orcoDm->getLoopTriArray(orcoDm); + + if (!mvert || !mlooptri || !mat) { + return; + } - if (!mvert || !mface || !mat) return; - v1=mface[face_index].v1, v2=mface[face_index].v2, v3=mface[face_index].v3; - if (hit_quad) { v2 = mface[face_index].v3; v3 = mface[face_index].v4; } + v1=mloop[mlooptri[tri_index].tri[0]].v, v2=mloop[mlooptri[tri_index].tri[1]].v, v3=mloop[mlooptri[tri_index].tri[2]].v; normal_tri_v3(normal, mvert[v1].co, mvert[v2].co, mvert[v3].co); /* generate shadeinput with data required */ @@ -3708,7 +3713,7 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const { float l; /* Get generated UV */ - textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co); + textured_face_generate_uv(normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co, uv); l= 1.0f+uv[0]+uv[1]; /* calculate generated coordinate */ @@ -3718,35 +3723,37 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const } /* uv coordinates */ { - int i, layers = CustomData_number_of_layers(&orcoDm->faceData, CD_MTFACE); - int layer_index = CustomData_get_layer_index(&orcoDm->faceData, CD_MTFACE); + const int layers = CustomData_number_of_layers(&orcoDm->loopData, CD_MLOOPUV); + const int layer_index = CustomData_get_layer_index(&orcoDm->loopData, CD_MLOOPUV); + int i; /* for every uv map set coords and name */ for (i=0; i<layers; i++) { if (layer_index >= 0) { const float *uv1, *uv2, *uv3; + const CustomData *data = &orcoDm->loopData; + const MLoopUV *mloopuv = data->layers[layer_index + i].data; + const float uv[2]; float l; - CustomData *data = &orcoDm->faceData; - MTFace *tface = (MTFace *) data->layers[layer_index+i].data; - float uv[3]; + /* point layer name from actual layer data */ shi.uv[i].name = data->layers[i].name; /* Get generated coordinates to calculate UV from */ - textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co); + textured_face_generate_uv(normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co, uv); /* Get UV mapping coordinate */ l= 1.0f+uv[0]+uv[1]; - - uv1= tface[face_index].uv[0]; - uv2= (hit_quad) ? tface[face_index].uv[2] : tface[face_index].uv[1]; - uv3= (hit_quad) ? tface[face_index].uv[3] : tface[face_index].uv[2]; - + + uv1 = mloopuv[mlooptri[tri_index].tri[0]].uv; + uv2 = mloopuv[mlooptri[tri_index].tri[1]].uv; + uv3 = mloopuv[mlooptri[tri_index].tri[2]].uv; + shi.uv[i].uv[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]); shi.uv[i].uv[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]); shi.uv[i].uv[2]= 0.0f; /* texture.c assumes there are 3 coords */ } } /* active uv map */ - shi.actuv = CustomData_get_active_layer_index(&orcoDm->faceData, CD_MTFACE) - layer_index; + shi.actuv = CustomData_get_active_layer_index(&orcoDm->loopData, CD_MLOOPUV) - layer_index; shi.totuv = layers; } diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index a94d9200a74..952ec08b5d5 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -255,9 +255,9 @@ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], struct Material *RE_init_sample_material(struct Material *orig_mat, struct Scene *scene) RET_NULL void RE_free_sample_material(struct Material *mat) RET_NONE -void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], - int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob) RET_NONE - +void RE_sample_material_color( + struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], + int tri_index, struct DerivedMesh *orcoDm, struct Object *ob) RET_NONE /* nodes */ struct Render *RE_GetRender(const char *name) RET_NULL struct Object *RE_GetCamera(struct Render *re) RET_NULL |