Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_curves.cpp
| Show All 32 Lines | |||||
| ParticleCurveData::ParticleCurveData() | ParticleCurveData::ParticleCurveData() | ||||
| { | { | ||||
| } | } | ||||
| ParticleCurveData::~ParticleCurveData() | ParticleCurveData::~ParticleCurveData() | ||||
| { | { | ||||
| } | } | ||||
| static void interp_weights(float t, float data[4]) | |||||
| { | |||||
| /* Cardinal curve interpolation */ | |||||
| float t2 = t * t; | |||||
| float t3 = t2 * t; | |||||
| float fc = 0.71f; | |||||
| data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t; | |||||
| data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f; | |||||
| data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t; | |||||
| data[3] = fc * t3 - fc * t2; | |||||
| } | |||||
| static void curveinterp_v3_v3v3v3v3(float3 *p, | |||||
| float3 *v1, float3 *v2, float3 *v3, float3 *v4, | |||||
| const float w[4]) | |||||
| { | |||||
| p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3]; | |||||
| p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3]; | |||||
| p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3]; | |||||
| } | |||||
| static float shaperadius(float shape, float root, float tip, float time) | static float shaperadius(float shape, float root, float tip, float time) | ||||
| { | { | ||||
| assert(time >= 0.0f); | assert(time >= 0.0f); | ||||
| assert(time <= 1.0f); | assert(time <= 1.0f); | ||||
| float radius = 1.0f - time; | float radius = 1.0f - time; | ||||
| if(shape != 0.0f) { | if(shape != 0.0f) { | ||||
| if(shape < 0.0f) | if(shape < 0.0f) | ||||
| radius = powf(radius, 1.0f + shape); | radius = powf(radius, 1.0f + shape); | ||||
| else | else | ||||
| radius = powf(radius, 1.0f / (1.0f - shape)); | radius = powf(radius, 1.0f / (1.0f - shape)); | ||||
| } | } | ||||
| return (radius * (root - tip)) + tip; | return (radius * (root - tip)) + tip; | ||||
| } | } | ||||
| /* curve functions */ | /* curve functions */ | ||||
| static void InterpolateKeySegments(int seg, | |||||
| int segno, | |||||
| int key, | |||||
| int curve, | |||||
| float3 *keyloc, | |||||
| float *time, | |||||
| ParticleCurveData *CData) | |||||
| { | |||||
| float3 ckey_loc1 = CData->curvekey_co[key]; | |||||
| float3 ckey_loc2 = ckey_loc1; | |||||
| float3 ckey_loc3 = CData->curvekey_co[key+1]; | |||||
| float3 ckey_loc4 = ckey_loc3; | |||||
| if(key > CData->curve_firstkey[curve]) | |||||
| ckey_loc1 = CData->curvekey_co[key - 1]; | |||||
| if(key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) | |||||
| ckey_loc4 = CData->curvekey_co[key + 2]; | |||||
| float time1 = CData->curvekey_time[key]/CData->curve_length[curve]; | |||||
| float time2 = CData->curvekey_time[key + 1]/CData->curve_length[curve]; | |||||
| float dfra = (time2 - time1) / (float)segno; | |||||
| if(time) | |||||
| *time = (dfra * seg) + time1; | |||||
| float t[4]; | |||||
| interp_weights((float)seg / (float)segno, t); | |||||
| if(keyloc) | |||||
| curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t); | |||||
| } | |||||
| static bool ObtainCacheParticleData(Mesh *mesh, | static bool ObtainCacheParticleData(Mesh *mesh, | ||||
| BL::Mesh *b_mesh, | BL::Mesh *b_mesh, | ||||
| BL::Object *b_ob, | BL::Object *b_ob, | ||||
| ParticleCurveData *CData, | ParticleCurveData *CData, | ||||
| bool background) | bool background) | ||||
| { | { | ||||
| int curvenum = 0; | int curvenum = 0; | ||||
| int keyno = 0; | int keyno = 0; | ||||
| ▲ Show 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, | |||||
| float3 RotCam, bool is_ortho) | |||||
| { | |||||
| int vertexno = mesh->verts.size(); | |||||
| int vertexindex = vertexno; | |||||
| int numverts = 0, numtris = 0; | |||||
| /* compute and reserve size of arrays */ | |||||
| for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { | |||||
| for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { | |||||
| numverts += 2 + (CData->curve_keynum[curve] - 1)*2; | |||||
| numtris += (CData->curve_keynum[curve] - 1)*2; | |||||
| } | |||||
| } | |||||
| mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris); | |||||
| /* actually export */ | |||||
| for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { | |||||
| for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { | |||||
| float3 xbasis; | |||||
| float3 v1; | |||||
| float time = 0.0f; | |||||
| float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]]; | |||||
| float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f); | |||||
| v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] - CData->curvekey_co[CData->curve_firstkey[curve]]; | |||||
| if(is_ortho) | |||||
| xbasis = normalize(cross(RotCam, v1)); | |||||
| else | |||||
| xbasis = normalize(cross(RotCam - ickey_loc, v1)); | |||||
| float3 ickey_loc_shfl = ickey_loc - radius * xbasis; | |||||
| float3 ickey_loc_shfr = ickey_loc + radius * xbasis; | |||||
| mesh->add_vertex(ickey_loc_shfl); | |||||
| mesh->add_vertex(ickey_loc_shfr); | |||||
| vertexindex += 2; | |||||
| for(int curvekey = CData->curve_firstkey[curve] + 1; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { | |||||
| ickey_loc = CData->curvekey_co[curvekey]; | |||||
| if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) | |||||
| v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])]; | |||||
| else | |||||
| v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1]; | |||||
| time = CData->curvekey_time[curvekey]/CData->curve_length[curve]; | |||||
| radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); | |||||
| if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) | |||||
| radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); | |||||
| if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) | |||||
| radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); | |||||
| if(is_ortho) | |||||
| xbasis = normalize(cross(RotCam, v1)); | |||||
| else | |||||
| xbasis = normalize(cross(RotCam - ickey_loc, v1)); | |||||
| float3 ickey_loc_shfl = ickey_loc - radius * xbasis; | |||||
| float3 ickey_loc_shfr = ickey_loc + radius * xbasis; | |||||
| mesh->add_vertex(ickey_loc_shfl); | |||||
| mesh->add_vertex(ickey_loc_shfr); | |||||
| mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], true); | |||||
| mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], true); | |||||
| vertexindex += 2; | |||||
| } | |||||
| } | |||||
| } | |||||
| mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); | |||||
| mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); | |||||
| mesh->attributes.remove(ATTR_STD_FACE_NORMAL); | |||||
| mesh->add_face_normals(); | |||||
| mesh->add_vertex_normals(); | |||||
| mesh->attributes.remove(ATTR_STD_FACE_NORMAL); | |||||
| /* texture coords still needed */ | |||||
| } | |||||
| static void ExportCurveTriangleGeometry(Mesh *mesh, | |||||
| ParticleCurveData *CData, | |||||
| int resolution) | |||||
| { | |||||
| int vertexno = mesh->verts.size(); | |||||
| int vertexindex = vertexno; | |||||
| int numverts = 0, numtris = 0; | |||||
| /* compute and reserve size of arrays */ | |||||
| for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { | |||||
| for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { | |||||
| numverts += (CData->curve_keynum[curve] - 1)*resolution + resolution; | |||||
| numtris += (CData->curve_keynum[curve] - 1)*2*resolution; | |||||
| } | |||||
| } | |||||
| mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris); | |||||
| /* actually export */ | |||||
| for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { | |||||
| for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { | |||||
| float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]); | |||||
| if(!is_zero(firstxbasis)) | |||||
| firstxbasis = normalize(firstxbasis); | |||||
| else | |||||
| firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]])); | |||||
| for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { | |||||
| float3 xbasis = firstxbasis; | |||||
| float3 v1; | |||||
| float3 v2; | |||||
| if(curvekey == CData->curve_firstkey[curve]) { | |||||
| v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; | |||||
| v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; | |||||
| } | |||||
| else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { | |||||
| v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; | |||||
| v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; | |||||
| } | |||||
| else { | |||||
| v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; | |||||
| v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; | |||||
| } | |||||
| xbasis = cross(v1, v2); | |||||
| if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) { | |||||
| firstxbasis = normalize(xbasis); | |||||
| break; | |||||
| } | |||||
| } | |||||
| for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { | |||||
| int subv = 1; | |||||
| float3 xbasis; | |||||
| float3 ybasis; | |||||
| float3 v1; | |||||
| float3 v2; | |||||
| if(curvekey == CData->curve_firstkey[curve]) { | |||||
| subv = 0; | |||||
| v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; | |||||
| v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; | |||||
| } | |||||
| else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { | |||||
| v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; | |||||
| v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; | |||||
| } | |||||
| else { | |||||
| v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; | |||||
| v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; | |||||
| } | |||||
| xbasis = cross(v1, v2); | |||||
| if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) { | |||||
| xbasis = normalize(xbasis); | |||||
| firstxbasis = xbasis; | |||||
| } | |||||
| else | |||||
| xbasis = firstxbasis; | |||||
| ybasis = normalize(cross(xbasis, v2)); | |||||
| for(; subv <= 1; subv++) { | |||||
| float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); | |||||
| float time = 0.0f; | |||||
| InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData); | |||||
| float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); | |||||
| if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == 1)) | |||||
| radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); | |||||
| if(CData->psys_closetip[sys] && (subv == 1) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) | |||||
| radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); | |||||
| float angle = M_2PI_F / (float)resolution; | |||||
| for(int section = 0; section < resolution; section++) { | |||||
| float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + sinf(angle * section) * ybasis); | |||||
| mesh->add_vertex(ickey_loc_shf); | |||||
| } | |||||
| if(subv != 0) { | |||||
| for(int section = 0; section < resolution - 1; section++) { | |||||
| mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], true); | |||||
| mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], true); | |||||
| } | |||||
| mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], true); | |||||
| mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], true); | |||||
| } | |||||
| vertexindex += resolution; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); | |||||
| mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); | |||||
| mesh->attributes.remove(ATTR_STD_FACE_NORMAL); | |||||
| mesh->add_face_normals(); | |||||
| mesh->add_vertex_normals(); | |||||
| mesh->attributes.remove(ATTR_STD_FACE_NORMAL); | |||||
| /* texture coords still needed */ | |||||
| } | |||||
| static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) | static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) | ||||
| { | { | ||||
| int num_keys = 0; | int num_keys = 0; | ||||
| int num_curves = 0; | int num_curves = 0; | ||||
| if(mesh->num_curves()) | if(mesh->num_curves()) | ||||
| return; | return; | ||||
| ▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | else if(motion_step > 0) { | ||||
| mP[key] = float3_to_float4(mesh->curve_keys[key]); | mP[key] = float3_to_float4(mesh->curve_keys[key]); | ||||
| mP[key].w = mesh->curve_radius[key]; | mP[key].w = mesh->curve_radius[key]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void ExportCurveTriangleUV(ParticleCurveData *CData, | |||||
| int vert_offset, | |||||
| int resol, | |||||
| float3 *uvdata) | |||||
| { | |||||
| if(uvdata == NULL) | |||||
| return; | |||||
| float time = 0.0f; | |||||
| float prevtime = 0.0f; | |||||
| int vertexindex = vert_offset; | |||||
| for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { | |||||
| for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { | |||||
| for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { | |||||
| const float curve_time = CData->curvekey_time[curvekey]; | |||||
| const float curve_length = CData->curve_length[curve]; | |||||
| time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f; | |||||
| for(int section = 0; section < resol; section++) { | |||||
| uvdata[vertexindex] = CData->curve_uv[curve]; | |||||
| uvdata[vertexindex].z = prevtime; | |||||
| vertexindex++; | |||||
| uvdata[vertexindex] = CData->curve_uv[curve]; | |||||
| uvdata[vertexindex].z = time; | |||||
| vertexindex++; | |||||
| uvdata[vertexindex] = CData->curve_uv[curve]; | |||||
| uvdata[vertexindex].z = prevtime; | |||||
| vertexindex++; | |||||
| uvdata[vertexindex] = CData->curve_uv[curve]; | |||||
| uvdata[vertexindex].z = time; | |||||
| vertexindex++; | |||||
| uvdata[vertexindex] = CData->curve_uv[curve]; | |||||
| uvdata[vertexindex].z = prevtime; | |||||
| vertexindex++; | |||||
| uvdata[vertexindex] = CData->curve_uv[curve]; | |||||
| uvdata[vertexindex].z = time; | |||||
| vertexindex++; | |||||
| } | |||||
| prevtime = time; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static void ExportCurveTriangleVcol(ParticleCurveData *CData, | |||||
| int vert_offset, | |||||
| int resol, | |||||
| uchar4 *cdata) | |||||
| { | |||||
| if(cdata == NULL) | |||||
| return; | |||||
| int vertexindex = vert_offset; | |||||
| for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { | |||||
| for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { | |||||
| for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { | |||||
| for(int section = 0; section < resol; section++) { | |||||
| /* Encode vertex color using the sRGB curve. */ | |||||
| cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve])); | |||||
| vertexindex++; | |||||
| cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve])); | |||||
| vertexindex++; | |||||
| cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve])); | |||||
| vertexindex++; | |||||
| cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve])); | |||||
| vertexindex++; | |||||
| cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve])); | |||||
| vertexindex++; | |||||
| cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve])); | |||||
| vertexindex++; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Hair Curve Sync */ | /* Hair Curve Sync */ | ||||
| void BlenderSync::sync_curve_settings() | void BlenderSync::sync_curve_settings() | ||||
| { | { | ||||
| PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); | PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); | ||||
| CurveSystemManager *curve_system_manager = scene->curve_system_manager; | CurveSystemManager *curve_system_manager = scene->curve_system_manager; | ||||
| CurveSystemManager prev_curve_system_manager = *curve_system_manager; | CurveSystemManager prev_curve_system_manager = *curve_system_manager; | ||||
| curve_system_manager->use_curves = get_boolean(csscene, "use_curves"); | curve_system_manager->use_curves = get_boolean(csscene, "use_curves"); | ||||
| curve_system_manager->minimum_width = get_float(csscene, "minimum_width"); | curve_system_manager->minimum_width = get_float(csscene, "minimum_width"); | ||||
| curve_system_manager->maximum_width = get_float(csscene, "maximum_width"); | curve_system_manager->maximum_width = get_float(csscene, "maximum_width"); | ||||
| curve_system_manager->primitive = | curve_system_manager->primitive = | ||||
| (CurvePrimitiveType)get_enum(csscene, | (CurvePrimitiveType)get_enum(csscene, | ||||
| "primitive", | "primitive", | ||||
| CURVE_NUM_PRIMITIVE_TYPES, | CURVE_NUM_PRIMITIVE_TYPES, | ||||
| CURVE_LINE_SEGMENTS); | CURVE_LINE_SEGMENTS); | ||||
| curve_system_manager->curve_shape = | curve_system_manager->curve_shape = | ||||
| (CurveShapeType)get_enum(csscene, | (CurveShapeType)get_enum(csscene, | ||||
| "shape", | "shape", | ||||
| CURVE_NUM_SHAPE_TYPES, | CURVE_NUM_SHAPE_TYPES, | ||||
| CURVE_THICK); | CURVE_THICK); | ||||
| curve_system_manager->resolution = get_int(csscene, "resolution"); | |||||
| curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); | curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); | ||||
| curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing"); | curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing"); | ||||
| /* Triangles */ | |||||
| if(curve_system_manager->primitive == CURVE_TRIANGLES) { | |||||
| /* camera facing planes */ | |||||
| if(curve_system_manager->curve_shape == CURVE_RIBBON) { | |||||
| curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES; | |||||
| curve_system_manager->resolution = 1; | |||||
| } | |||||
| else if(curve_system_manager->curve_shape == CURVE_THICK) { | |||||
| curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES; | |||||
| } | |||||
| } | |||||
| /* Line Segments */ | /* Line Segments */ | ||||
| else if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS) { | if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS) { | ||||
| if(curve_system_manager->curve_shape == CURVE_RIBBON) { | if(curve_system_manager->curve_shape == CURVE_RIBBON) { | ||||
| /* tangent shading */ | /* tangent shading */ | ||||
| curve_system_manager->line_method = CURVE_UNCORRECTED; | curve_system_manager->line_method = CURVE_UNCORRECTED; | ||||
| curve_system_manager->use_encasing = true; | curve_system_manager->use_encasing = true; | ||||
| curve_system_manager->use_backfacing = false; | curve_system_manager->use_backfacing = false; | ||||
| curve_system_manager->use_tangent_normal_geometry = true; | curve_system_manager->use_tangent_normal_geometry = true; | ||||
| } | } | ||||
| else if(curve_system_manager->curve_shape == CURVE_THICK) { | else if(curve_system_manager->curve_shape == CURVE_THICK) { | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | void BlenderSync::sync_curves(Mesh *mesh, | ||||
| const bool use_curves = scene->curve_system_manager->use_curves; | const bool use_curves = scene->curve_system_manager->use_curves; | ||||
| if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) { | if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) { | ||||
| if(!motion) | if(!motion) | ||||
| mesh->compute_bounds(); | mesh->compute_bounds(); | ||||
| return; | return; | ||||
| } | } | ||||
| const int primitive = scene->curve_system_manager->primitive; | |||||
| const int triangle_method = scene->curve_system_manager->triangle_method; | |||||
| const int resolution = scene->curve_system_manager->resolution; | |||||
| const size_t vert_num = mesh->verts.size(); | |||||
| const size_t tri_num = mesh->num_triangles(); | |||||
| int used_res = 1; | |||||
| /* extract particle hair data - should be combined with connecting to mesh later*/ | /* extract particle hair data - should be combined with connecting to mesh later*/ | ||||
| ParticleCurveData CData; | ParticleCurveData CData; | ||||
| ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); | ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); | ||||
| /* add hair geometry to mesh */ | /* add hair geometry to mesh */ | ||||
| if(primitive == CURVE_TRIANGLES) { | |||||
| if(triangle_method == CURVE_CAMERA_TRIANGLES) { | |||||
| /* obtain camera parameters */ | |||||
| float3 RotCam; | |||||
| Camera *camera = scene->camera; | |||||
| Transform &ctfm = camera->matrix; | |||||
| if(camera->type == CAMERA_ORTHOGRAPHIC) { | |||||
| RotCam = -make_float3(ctfm.x.z, ctfm.y.z, ctfm.z.z); | |||||
| } | |||||
| else { | |||||
| Transform tfm = get_transform(b_ob.matrix_world()); | |||||
| Transform itfm = transform_quick_inverse(tfm); | |||||
| RotCam = transform_point(&itfm, make_float3(ctfm.x.w, | |||||
| ctfm.y.w, | |||||
| ctfm.z.w)); | |||||
| } | |||||
| bool is_ortho = camera->type == CAMERA_ORTHOGRAPHIC; | |||||
| ExportCurveTrianglePlanes(mesh, &CData, RotCam, is_ortho); | |||||
| } | |||||
| else { | |||||
| ExportCurveTriangleGeometry(mesh, &CData, resolution); | |||||
| used_res = resolution; | |||||
| } | |||||
| } | |||||
| else { | |||||
| if(motion) | if(motion) | ||||
| ExportCurveSegmentsMotion(mesh, &CData, motion_step); | ExportCurveSegmentsMotion(mesh, &CData, motion_step); | ||||
| else | else | ||||
| ExportCurveSegments(scene, mesh, &CData); | ExportCurveSegments(scene, mesh, &CData); | ||||
| } | |||||
| /* generated coordinates from first key. we should ideally get this from | /* generated coordinates from first key. we should ideally get this from | ||||
| * blender to handle deforming objects */ | * blender to handle deforming objects */ | ||||
| if(!motion) { | if(!motion) { | ||||
| if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { | if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { | ||||
| float3 loc, size; | float3 loc, size; | ||||
| mesh_texture_space(b_mesh, loc, size); | mesh_texture_space(b_mesh, loc, size); | ||||
| if(primitive == CURVE_TRIANGLES) { | |||||
| Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED); | |||||
| float3 *generated = attr_generated->data_float3(); | |||||
| for(size_t i = vert_num; i < mesh->verts.size(); i++) | |||||
| generated[i] = mesh->verts[i]*size - loc; | |||||
| } | |||||
| else { | |||||
| Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED); | Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED); | ||||
| float3 *generated = attr_generated->data_float3(); | float3 *generated = attr_generated->data_float3(); | ||||
| for(size_t i = 0; i < mesh->num_curves(); i++) { | for(size_t i = 0; i < mesh->num_curves(); i++) { | ||||
| float3 co = mesh->curve_keys[mesh->get_curve(i).first_key]; | float3 co = mesh->curve_keys[mesh->get_curve(i).first_key]; | ||||
| generated[i] = co*size - loc; | generated[i] = co*size - loc; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| /* create vertex color attributes */ | /* create vertex color attributes */ | ||||
| if(!motion) { | if(!motion) { | ||||
| BL::Mesh::vertex_colors_iterator l; | BL::Mesh::vertex_colors_iterator l; | ||||
| int vcol_num = 0; | int vcol_num = 0; | ||||
| for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) { | for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) { | ||||
| if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) | if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) | ||||
| continue; | continue; | ||||
| ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num); | ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num); | ||||
| if(primitive == CURVE_TRIANGLES) { | |||||
| Attribute *attr_vcol = mesh->attributes.add( | |||||
| ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE); | |||||
| uchar4 *cdata = attr_vcol->data_uchar4(); | |||||
| ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata); | |||||
| } | |||||
| else { | |||||
| Attribute *attr_vcol = mesh->curve_attributes.add( | Attribute *attr_vcol = mesh->curve_attributes.add( | ||||
| ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); | ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); | ||||
| float3 *fdata = attr_vcol->data_float3(); | float3 *fdata = attr_vcol->data_float3(); | ||||
| if(fdata) { | if(fdata) { | ||||
| size_t i = 0; | size_t i = 0; | ||||
| /* Encode vertex color using the sRGB curve. */ | /* Encode vertex color using the sRGB curve. */ | ||||
| for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { | for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { | ||||
| fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); | fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| /* create UV attributes */ | /* create UV attributes */ | ||||
| if(!motion) { | if(!motion) { | ||||
| BL::Mesh::uv_layers_iterator l; | BL::Mesh::uv_layers_iterator l; | ||||
| int uv_num = 0; | int uv_num = 0; | ||||
| for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) { | for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) { | ||||
| bool active_render = l->active_render(); | bool active_render = l->active_render(); | ||||
| AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE; | AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE; | ||||
| ustring name = ustring(l->name().c_str()); | ustring name = ustring(l->name().c_str()); | ||||
| /* UV map */ | /* UV map */ | ||||
| if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { | if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { | ||||
| Attribute *attr_uv; | Attribute *attr_uv; | ||||
| ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num); | ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num); | ||||
| if(primitive == CURVE_TRIANGLES) { | |||||
| if(active_render) | |||||
| attr_uv = mesh->attributes.add(std, name); | |||||
| else | |||||
| attr_uv = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER); | |||||
| float3 *uv = attr_uv->data_float3(); | |||||
| ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv); | |||||
| } | |||||
| else { | |||||
| if(active_render) | if(active_render) | ||||
| attr_uv = mesh->curve_attributes.add(std, name); | attr_uv = mesh->curve_attributes.add(std, name); | ||||
| else | else | ||||
| attr_uv = mesh->curve_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE); | attr_uv = mesh->curve_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE); | ||||
| float3 *uv = attr_uv->data_float3(); | float3 *uv = attr_uv->data_float3(); | ||||
| if(uv) { | if(uv) { | ||||
| size_t i = 0; | size_t i = 0; | ||||
| for(size_t curve = 0; curve < CData.curve_uv.size(); curve++) { | for(size_t curve = 0; curve < CData.curve_uv.size(); curve++) { | ||||
| uv[i++] = CData.curve_uv[curve]; | uv[i++] = CData.curve_uv[curve]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| mesh->compute_bounds(); | mesh->compute_bounds(); | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||