Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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();
}
Пример #4
0
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()