bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from) { KernelGlobals *kg = kernel_globals; if (from == u_ndc) { Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.screentoworld); COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); COPY_MATRIX44(&result, &tfm); return true; } return false; }
static bool ObtainCacheParticleData( Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) { int curvenum = 0; int keyno = 0; if (!(mesh && b_mesh && b_ob && CData)) return false; Transform tfm = get_transform(b_ob->matrix_world()); Transform itfm = transform_quick_inverse(tfm); BL::Object::modifiers_iterator b_mod; for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) { BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) { int shader = clamp(b_part.material() - 1, 0, mesh->used_shaders.size() - 1); int display_step = background ? b_part.render_step() : b_part.display_step(); int totparts = b_psys.particles.length(); int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f); int totcurves = totchild; if (b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if (totcurves == 0) continue; int ren_step = (1 << display_step) + 1; if (b_part.kink() == BL::ParticleSettings::kink_SPIRAL) ren_step += b_part.kink_extra_steps(); CData->psys_firstcurve.push_back_slow(curvenum); CData->psys_curvenum.push_back_slow(totcurves); CData->psys_shader.push_back_slow(shader); float radius = b_part.radius_scale() * 0.5f; CData->psys_rootradius.push_back_slow(radius * b_part.root_radius()); CData->psys_tipradius.push_back_slow(radius * b_part.tip_radius()); CData->psys_shape.push_back_slow(b_part.shape()); CData->psys_closetip.push_back_slow(b_part.use_close_tip()); int pa_no = 0; if (!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts + totchild - pa_no); CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add); CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add); CData->curve_length.reserve(CData->curve_length.size() + num_add); CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add * ren_step); CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add * ren_step); for (; pa_no < totparts + totchild; pa_no++) { int keynum = 0; CData->curve_firstkey.push_back_slow(keyno); float curve_length = 0.0f; float3 pcKey; for (int step_no = 0; step_no < ren_step; step_no++) { float nco[3]; b_psys.co_hair(*b_ob, pa_no, step_no, nco); float3 cKey = make_float3(nco[0], nco[1], nco[2]); cKey = transform_point(&itfm, cKey); if (step_no > 0) { const float step_length = len(cKey - pcKey); curve_length += step_length; } CData->curvekey_co.push_back_slow(cKey); CData->curvekey_time.push_back_slow(curve_length); pcKey = cKey; keynum++; } keyno += keynum; CData->curve_keynum.push_back_slow(keynum); CData->curve_length.push_back_slow(curve_length); curvenum++; } } } } return true; }
void BlenderSync::sync_curves( Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { if (!motion) { /* Clear stored curve data */ mesh->curve_keys.clear(); mesh->curve_radius.clear(); mesh->curve_first_key.clear(); mesh->curve_shader.clear(); mesh->curve_attributes.clear(); } /* obtain general settings */ const bool use_curves = scene->curve_system_manager->use_curves; if (!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT && b_ob.mode() != b_ob.mode_EDIT)) { if (!motion) mesh->compute_bounds(); 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*/ ParticleCurveData CData; ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); /* 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) ExportCurveSegmentsMotion(mesh, &CData, motion_step); else ExportCurveSegments(scene, mesh, &CData); } /* generated coordinates from first key. we should ideally get this from * blender to handle deforming objects */ if (!motion) { if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) { float3 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); float3 *generated = attr_generated->data_float3(); for (size_t i = 0; i < mesh->num_curves(); i++) { float3 co = mesh->curve_keys[mesh->get_curve(i).first_key]; generated[i] = co * size - loc; } } } } /* create vertex color attributes */ if (!motion) { BL::Mesh::vertex_colors_iterator l; int vcol_num = 0; 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()))) continue; 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( ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); float3 *fdata = attr_vcol->data_float3(); if (fdata) { size_t i = 0; /* Encode vertex color using the sRGB curve. */ for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); } } } } } /* create UV attributes */ if (!motion) { BL::Mesh::uv_layers_iterator l; int uv_num = 0; for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) { bool active_render = l->active_render(); AttributeStandard std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE; ustring name = ustring(l->name().c_str()); /* UV map */ if (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { Attribute *attr_uv; 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, TypeFloat2, ATTR_ELEMENT_CORNER); float2 *uv = attr_uv->data_float2(); ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv); } else { if (active_render) attr_uv = mesh->curve_attributes.add(std, name); else attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); float2 *uv = attr_uv->data_float2(); if (uv) { size_t i = 0; for (size_t curve = 0; curve < CData.curve_uv.size(); curve++) { uv[i++] = CData.curve_uv[curve]; } } } } } } mesh->compute_bounds(); }
bool BlenderSync::fill_mesh_hair_data(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, int uv_num, int vcol_num) { if(!mesh || !b_mesh || !b_ob) return false; int cur_hair_idx = 0; int cur_vertex_idx = 0; Transform tfm = get_transform(b_ob->matrix_world()); Transform itfm = transform_quick_inverse(tfm); BL::Object::modifiers_iterator b_mod; size_t hair_points_size = 0, hair_thickness_size = 0, vert_per_hair_size = 0, hair_mat_indices_size = 0, hair_uvs_size = 0; for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { if(b_mod->type() == b_mod->type_PARTICLE_SYSTEM && (interactive ? b_mod->show_viewport() : b_mod->show_render())) { BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if(b_part.render_type() == BL::ParticleSettings::render_type_PATH && b_part.type() == BL::ParticleSettings::type_HAIR) { int draw_step = interactive ? b_part.draw_step() : b_part.render_step(); int ren_step = (int)powf(2.0f, (float)draw_step); int totparts = b_psys.particles.length(); int totchild = interactive ? (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f) : b_psys.child_particles.length(); int totcurves = totchild; if(b_part.child_type() == 0) totcurves += totparts; if(totcurves == 0) continue; hair_points_size += totcurves * (ren_step + 1); hair_thickness_size += totcurves * (ren_step + 1); vert_per_hair_size += totcurves; hair_mat_indices_size += totcurves; hair_uvs_size += totcurves; } } } if(hair_points_size == 0 || hair_thickness_size == 0 || vert_per_hair_size == 0 || hair_mat_indices_size == 0 || hair_uvs_size == 0) return true; mesh->hair_points.resize(hair_points_size); float3 *hair_points = &mesh->hair_points[0]; mesh->hair_thickness.resize(hair_thickness_size); float *hair_thickness = &mesh->hair_thickness[0]; mesh->vert_per_hair.resize(vert_per_hair_size); int *vert_per_hair = &mesh->vert_per_hair[0]; mesh->hair_mat_indices.resize(hair_mat_indices_size); int *hair_mat_indices = &mesh->hair_mat_indices[0]; mesh->hair_uvs.resize(hair_uvs_size); float2 *hair_uvs = &mesh->hair_uvs[0]; for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { if(b_mod->type() == b_mod->type_PARTICLE_SYSTEM && (interactive ? b_mod->show_viewport() : b_mod->show_render())) { BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if(b_part.render_type() == BL::ParticleSettings::render_type_PATH && b_part.type() == BL::ParticleSettings::type_HAIR) { int shader_idx = clamp(b_part.material() - 1, 0, mesh->used_shaders.size() - 1); int draw_step = interactive ? b_part.draw_step() : b_part.render_step(); int ren_step = (int)powf(2.0f, (float)draw_step); int totparts = b_psys.particles.length(); int totchild = interactive ? (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f) : b_psys.child_particles.length(); int totcurves = totchild; if(b_part.child_type() == 0) totcurves += totparts; if(totcurves == 0) continue; PointerRNA oct_settings = RNA_pointer_get(&b_part.ptr, "octane"); float root_width = get_float(oct_settings, "root_width"); float tip_width = get_float(oct_settings, "tip_width"); float width_step = (tip_width - root_width) / ren_step; int pa_no = 0; if(b_part.child_type() != 0) pa_no = totparts; BL::ParticleSystem::particles_iterator b_pa; b_psys.particles.begin(b_pa); for(; pa_no < (totparts + totchild); ++pa_no) { float3 prev_point; int vert_cnt = 0; float cur_width = root_width; for(int step_no = 0; step_no <= ren_step; step_no++) { float nco[3]; b_psys.co_hair(*b_ob, pa_no, step_no, nco); float3 cur_point = make_float3(nco[0], nco[1], nco[2]); cur_point = transform_point(&itfm, cur_point); if(step_no > 0) { float step_length = len(cur_point - prev_point); if(step_length == 0.0f) continue; } hair_points[cur_vertex_idx] = cur_point; hair_thickness[cur_vertex_idx] = cur_width; cur_width += width_step; prev_point = cur_point; ++cur_vertex_idx; ++vert_cnt; } vert_per_hair[cur_hair_idx] = vert_cnt; hair_mat_indices[cur_hair_idx] = shader_idx; // Add UVs BL::Mesh::tessface_uv_textures_iterator l; b_mesh->tessface_uv_textures.begin(l); float3 uv = make_float3(0.0f, 0.0f, 0.0f); if(b_mesh->tessface_uv_textures.length()) b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x); hair_uvs[cur_hair_idx].x = uv.x; hair_uvs[cur_hair_idx].y = uv.y; // Add vertex colors //BL::Mesh::tessface_vertex_colors_iterator l; //b_mesh->tessface_vertex_colors.begin(l); //float3 vcol = make_float3(0.0f, 0.0f, 0.0f); //if(b_mesh->tessface_vertex_colors.length()) // b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x); //hair_colors[cur_hair_idx] = vcol; if(pa_no < totparts && b_pa != b_psys.particles.end()) ++b_pa; ++cur_hair_idx; } } } } return true; } //fill_mesh_hair_data()