/* adds a subdiv cube to the scene */
unsigned int addQuadSubdivCube (RTCScene scene_i, const Vec3fa& pos)
{
  RTCGeometry geom = rtcNewGeometry(g_device, RTC_GEOMETRY_TYPE_SUBDIVISION);

  //rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, cube_vertices, 0, sizeof(Vec3fa  ), NUM_VERTICES);
  Vec3fa* vtx = (Vec3fa*) rtcSetNewGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vec3fa), NUM_VERTICES);
  for (unsigned int i=0; i<NUM_VERTICES; i++) vtx[i] = Vec3fa(cube_vertices[i][0]+pos.x,cube_vertices[i][1]+pos.y,cube_vertices[i][2]+pos.z);

  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, cube_quad_indices, 0, sizeof(unsigned int), NUM_QUAD_INDICES);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_FACE,  0, RTC_FORMAT_UINT, cube_quad_faces,   0, sizeof(unsigned int), NUM_QUAD_FACES);

  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_EDGE_CREASE_INDEX,  0, RTC_FORMAT_UINT2, cube_edge_crease_indices, 0, 2*sizeof(unsigned int), 0);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT, 0, RTC_FORMAT_FLOAT, cube_edge_crease_weights, 0, sizeof(float),          0);

  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX,  0, RTC_FORMAT_UINT,  cube_vertex_crease_indices, 0, sizeof(unsigned int), 0);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT, 0, RTC_FORMAT_FLOAT, cube_vertex_crease_weights, 0, sizeof(float),        0);

  rtcSetGeometryVertexAttributeCount(geom,1);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, RTC_FORMAT_FLOAT3, cube_vertex_colors, 0, sizeof(Vec3fa), NUM_VERTICES);

  float* level = (float*) rtcSetNewGeometryBuffer(geom, RTC_BUFFER_TYPE_LEVEL, 0, RTC_FORMAT_FLOAT, sizeof(float), NUM_QUAD_INDICES);
  for (unsigned int i=0; i<NUM_QUAD_INDICES; i++) level[i] = FIXED_EDGE_TESSELLATION_VALUE;

  rtcCommitGeometry(geom);
  unsigned int geomID = rtcAttachGeometry(scene_i, geom);
  rtcReleaseGeometry(geom);
  return geomID;
}
/* adds a sphere to the scene */
unsigned int createSphere (RTCBuildQuality quality, const Vec3fa& pos, const float r)
{
  /* create a triangulated sphere */
  RTCGeometry geom = rtcNewGeometry (g_device, RTC_GEOMETRY_TYPE_TRIANGLE);
  rtcSetGeometryBuildQuality(geom, quality);

  /* map triangle and vertex buffer */
  Vertex*   vertices  = (Vertex*  ) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_VERTEX,0,RTC_FORMAT_FLOAT3,sizeof(Vertex),numTheta*(numPhi+1));
  Triangle* triangles = (Triangle*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_INDEX,0,RTC_FORMAT_UINT3,sizeof(Triangle),2*numTheta*(numPhi-1));

  /* create sphere geometry */
  int tri = 0;
  const float rcpNumTheta = rcp((float)numTheta);
  const float rcpNumPhi   = rcp((float)numPhi);
  for (int phi=0; phi<=numPhi; phi++)
  {
    for (int theta=0; theta<numTheta; theta++)
    {
      const float phif   = phi*float(pi)*rcpNumPhi;
      const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
      Vertex& v = vertices[phi*numTheta+theta];
      v.x = pos.x + r*sin(phif)*sin(thetaf);
      v.y = pos.y + r*cos(phif);
      v.z = pos.z + r*sin(phif)*cos(thetaf);
    }
    if (phi == 0) continue;

    for (int theta=1; theta<=numTheta; theta++)
    {
      int p00 = (phi-1)*numTheta+theta-1;
      int p01 = (phi-1)*numTheta+theta%numTheta;
      int p10 = phi*numTheta+theta-1;
      int p11 = phi*numTheta+theta%numTheta;

      if (phi > 1) {
        triangles[tri].v0 = p10;
        triangles[tri].v1 = p01;
        triangles[tri].v2 = p00;
        tri++;
      }

      if (phi < numPhi) {
        triangles[tri].v0 = p11;
        triangles[tri].v1 = p01;
        triangles[tri].v2 = p10;
        tri++;
      }
    }
  }

  rtcCommitGeometry(geom);
  unsigned int geomID = rtcAttachGeometry(g_scene,geom);
  rtcReleaseGeometry(geom);
  return geomID;
}
/* adds a quad cube to the scene */
unsigned int addQuadCube (RTCScene scene_i, const Vec3fa& pos)
{
  RTCGeometry geom = rtcNewGeometry(g_device, RTC_GEOMETRY_TYPE_QUAD);

  //rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, cube_vertices, 0, sizeof(Vec3fa  ), NUM_VERTICES);
  Vec3fa* vtx = (Vec3fa*) rtcSetNewGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vec3fa), NUM_VERTICES);
  for (unsigned int i=0; i<NUM_VERTICES; i++) vtx[i] = Vec3fa(cube_vertices[i][0]+pos.x,cube_vertices[i][1]+pos.y,cube_vertices[i][2]+pos.z);

  rtcSetGeometryVertexAttributeCount(geom,1);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_INDEX,            0, RTC_FORMAT_UINT4,  cube_quad_indices,  0, 4*sizeof(unsigned int), NUM_QUAD_INDICES/4);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, RTC_FORMAT_FLOAT3, cube_vertex_colors, 0, sizeof(Vec3fa),         NUM_VERTICES);

  rtcCommitGeometry(geom);
  unsigned int geomID = rtcAttachGeometry(scene_i, geom);
  rtcReleaseGeometry(geom);
  return geomID;
}
/* adds a cube to the scene */
unsigned int addCube (RTCScene scene_i)
{
  /* create a triangulated cube with 6 quads and 8 vertices */
  RTCGeometry geom = rtcNewGeometry(g_device, RTC_GEOMETRY_TYPE_SUBDIVISION);

  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, cube_vertices, 0, sizeof(Vec3fa),       8);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_INDEX,  0, RTC_FORMAT_UINT,   cube_indices,  0, sizeof(unsigned int), NUM_INDICES);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_FACE,   0, RTC_FORMAT_UINT,   cube_faces,    0, sizeof(unsigned int), NUM_FACES);

  float* level = (float*) rtcSetNewGeometryBuffer(geom, RTC_BUFFER_TYPE_LEVEL, 0, RTC_FORMAT_FLOAT, sizeof(float), NUM_INDICES);
  for (size_t i=0; i<NUM_INDICES; i++) level[i] = EDGE_LEVEL;

  rtcSetGeometryDisplacementFunction(geom,displacementFunction);

  rtcCommitGeometry(geom);
  unsigned int geomID = rtcAttachGeometry(scene_i,geom);
  rtcReleaseGeometry(geom);
  return geomID;
}
/* adds a ground plane to the scene */
unsigned int addGroundPlane (RTCScene scene_i)
{
  /* create a triangulated plane with 2 triangles and 4 vertices */
  RTCGeometry geom = rtcNewGeometry (g_device, RTC_GEOMETRY_TYPE_TRIANGLE);

  /* set vertices */
  Vertex* vertices = (Vertex*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_VERTEX,0,RTC_FORMAT_FLOAT3,sizeof(Vertex),4);
  vertices[0].x = -10; vertices[0].y = -2; vertices[0].z = -10;
  vertices[1].x = -10; vertices[1].y = -2; vertices[1].z = +10;
  vertices[2].x = +10; vertices[2].y = -2; vertices[2].z = -10;
  vertices[3].x = +10; vertices[3].y = -2; vertices[3].z = +10;

  /* set triangles */
  Triangle* triangles = (Triangle*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_INDEX,0,RTC_FORMAT_UINT3,sizeof(Triangle),2);
  triangles[0].v0 = 0; triangles[0].v1 = 1; triangles[0].v2 = 2;
  triangles[1].v0 = 1; triangles[1].v1 = 3; triangles[1].v2 = 2;

  rtcCommitGeometry(geom);
  unsigned int geomID = rtcAttachGeometry(scene_i,geom);
  rtcReleaseGeometry(geom);
  return geomID;
}
/* add curve geometry */
unsigned int addCurve (RTCScene scene, const Vec3fa& pos)
{
  RTCGeometry geom = rtcNewGeometry (g_device, RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE);

  //rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, hair_vertices, 0, sizeof(Vec3fa), NUM_HAIR_VERTICES);
  Vec3fa* vtx = (Vec3fa*) rtcSetNewGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT4, sizeof(Vec3fa), NUM_HAIR_VERTICES);
  for (unsigned int i=0; i<NUM_HAIR_VERTICES; i++) {
    vtx[i].x = hair_vertices[i][0]+pos.x;
    vtx[i].y = hair_vertices[i][1]+pos.y;
    vtx[i].z = hair_vertices[i][2]+pos.z;
    vtx[i].w = hair_vertices[i][3];
  }

  rtcSetGeometryVertexAttributeCount(geom,1);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_INDEX,            0, RTC_FORMAT_UINT,   hair_indices,       0, sizeof(unsigned int), 1);
  rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, RTC_FORMAT_FLOAT3, hair_vertex_colors, 0, sizeof(Vec3fa),       NUM_HAIR_VERTICES);

  rtcCommitGeometry(geom);
  unsigned int geomID = rtcAttachGeometry(scene, geom);
  rtcReleaseGeometry(geom);
  return geomID;
}
Esempio n. 7
0
EmbreeScene::EmbreeScene(const EmbreeScene::Arguments& arguments)
{
    // Start stopwatch.
    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    Statistics statistics;

    m_device = arguments.m_device.m_device;
    m_scene = rtcNewScene(m_device);

    rtcSetSceneBuildQuality(
        m_scene,
        RTCBuildQuality::RTC_BUILD_QUALITY_HIGH);

    const ObjectInstanceContainer& instance_container = arguments.m_assembly.object_instances();

    const size_t instance_count = instance_container.size();

    m_geometry_container.reserve(instance_count);

    for (size_t instance_idx = 0; instance_idx < instance_count; ++instance_idx)
    {
        const ObjectInstance* object_instance = instance_container.get_by_index(instance_idx);
        assert(object_instance);

        RTCGeometry geometry_handle;

        // Set per instance data.
        unique_ptr<EmbreeGeometryData> geometry_data(new EmbreeGeometryData());
        geometry_data->m_object_instance_idx = instance_idx;
        geometry_data->m_vis_flags = object_instance->get_vis_flags();

        //
        // Collect geometry data for the instance.
        //
        const char* object_model = object_instance->get_object().get_model();

        if (strcmp(object_model, MeshObjectFactory().get_model()) == 0)
        {
            geometry_data->m_geometry_type = RTC_GEOMETRY_TYPE_TRIANGLE;

            // Retrieve triangle data.
            collect_triangle_data(*object_instance, *geometry_data);

            geometry_handle = rtcNewGeometry(
                m_device,
                RTC_GEOMETRY_TYPE_TRIANGLE);

            rtcSetGeometryBuildQuality(
                geometry_handle,
                RTCBuildQuality::RTC_BUILD_QUALITY_HIGH);

            rtcSetGeometryTimeStepCount(
                geometry_handle,
                geometry_data->m_motion_steps_count);

            geometry_data->m_geometry_handle = geometry_handle;

            const unsigned int vertices_count = geometry_data->m_vertices_count;
            const unsigned int vertices_stride = geometry_data->m_vertices_stride;

            for (unsigned int m = 0; m < geometry_data->m_motion_steps_count; ++m)
            {
                // Byte offset for the current motion segment.
                const unsigned int vertices_offset = m * vertices_count * vertices_stride;

                // Set vertices.
                rtcSetSharedGeometryBuffer(
                    geometry_handle,                            // geometry
                    RTC_BUFFER_TYPE_VERTEX,                     // buffer type
                    m,                                          // slot
                    RTC_FORMAT_FLOAT3,                          // format
                    geometry_data->m_vertices,                  // buffer
                    vertices_offset,                            // byte offset
                    vertices_stride,                            // byte stride
                    vertices_count);                            // item count
            }

            // Set vertex indices.
            rtcSetSharedGeometryBuffer(
                geometry_handle,                                // geometry
                RTC_BUFFER_TYPE_INDEX,                          // buffer type
                0,                                              // slot
                RTC_FORMAT_UINT3,                               // format
                geometry_data->m_primitives,                    // buffer
                0,                                              // byte offset
                geometry_data->m_primitives_stride,             // byte stride
                geometry_data->m_primitives_count);             // item count

            rtcSetGeometryMask(
                geometry_handle,
                geometry_data->m_vis_flags);

            rtcCommitGeometry(geometry_handle);
        }
        else if (strcmp(object_model, CurveObjectFactory().get_model()) == 0)
        {
            geometry_data->m_geometry_type = RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE;

            // Retrieve curve data.
            collect_curve_data(*object_instance, *geometry_data);

            geometry_handle = rtcNewGeometry(
                m_device,
                RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE);

            rtcSetGeometryBuildQuality(
                geometry_handle,
                RTCBuildQuality::RTC_BUILD_QUALITY_HIGH);

            // Set vertices. (x_pos, y_pos, z_pos, radii)
            rtcSetSharedGeometryBuffer(
                geometry_handle,                                // geometry
                RTC_BUFFER_TYPE_INDEX,                          // buffer type
                0,                                              // slot
                RTC_FORMAT_FLOAT4,                              // format
                geometry_data->m_vertices,                      // buffer
                0,                                              // byte offset
                geometry_data->m_vertices_stride,               // byte stride
                geometry_data->m_vertices_count);               // item count

            // Set vertex indices.
            rtcSetSharedGeometryBuffer(
                geometry_handle,                                // geometry
                RTC_BUFFER_TYPE_INDEX,                          // buffer type
                0,                                              // slot
                RTC_FORMAT_UINT4,                               // format
                geometry_data->m_primitives,                    // buffer
                0,                                              // byte offset
                geometry_data->m_primitives_stride,             // byte stride
                geometry_data->m_primitives_count);             // item count

        }
        else
        {
            // Unsupported object type.
            continue;
        }

        rtcAttachGeometryByID(m_scene, geometry_handle, static_cast<unsigned int>(instance_idx));
        m_geometry_container.push_back(std::move(geometry_data));
    }

    rtcCommitScene(m_scene);

    statistics.insert_time("total build time", stopwatch.measure().get_seconds());

    RENDERER_LOG_DEBUG("%s",
        StatisticsVector::make(
            "Embree scene #" + to_string(arguments.m_assembly.get_uid()) + " statistics",
            statistics).to_string().c_str());
}
Esempio n. 8
0
  void Instance::finalize(Model *model)
  {
    xfm.l.vx = getParam3f("xfm.l.vx",vec3f(1.f,0.f,0.f));
    xfm.l.vy = getParam3f("xfm.l.vy",vec3f(0.f,1.f,0.f));
    xfm.l.vz = getParam3f("xfm.l.vz",vec3f(0.f,0.f,1.f));
    xfm.p   = getParam3f("xfm.p",vec3f(0.f,0.f,0.f));

    instancedScene = (Model *)getParamObject("model", nullptr);
    assert(instancedScene);

    if (!instancedScene->embreeSceneHandle) {
      instancedScene->commit();
    }

    RTCGeometry embreeGeom   = rtcNewGeometry(ispc_embreeDevice(),RTC_GEOMETRY_TYPE_INSTANCE);
    embreeGeomID = rtcAttachGeometry(model->embreeSceneHandle,embreeGeom);
    rtcSetGeometryInstancedScene(embreeGeom,instancedScene->embreeSceneHandle);

    const box3f b = instancedScene->bounds;
    if (b.empty()) {
      // for now, let's just issue a warning since not all ospray
      // geometries do properly set the boudning box yet. as soon as
      // this gets fixed we will actually switch to reporting an error
      static WarnOnce warning("creating an instance to a model that does not"
                              " have a valid bounding box. epsilons for"
                              " ray offsets may be wrong");
    }
    const vec3f v000(b.lower.x,b.lower.y,b.lower.z);
    const vec3f v001(b.upper.x,b.lower.y,b.lower.z);
    const vec3f v010(b.lower.x,b.upper.y,b.lower.z);
    const vec3f v011(b.upper.x,b.upper.y,b.lower.z);
    const vec3f v100(b.lower.x,b.lower.y,b.upper.z);
    const vec3f v101(b.upper.x,b.lower.y,b.upper.z);
    const vec3f v110(b.lower.x,b.upper.y,b.upper.z);
    const vec3f v111(b.upper.x,b.upper.y,b.upper.z);

    bounds = empty;
    bounds.extend(xfmPoint(xfm,v000));
    bounds.extend(xfmPoint(xfm,v001));
    bounds.extend(xfmPoint(xfm,v010));
    bounds.extend(xfmPoint(xfm,v011));
    bounds.extend(xfmPoint(xfm,v100));
    bounds.extend(xfmPoint(xfm,v101));
    bounds.extend(xfmPoint(xfm,v110));
    bounds.extend(xfmPoint(xfm,v111));

    rtcSetGeometryTransform(embreeGeom,0,RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR,&xfm);
    rtcCommitGeometry(embreeGeom);
    rtcReleaseGeometry(embreeGeom);

    AffineSpace3f rcp_xfm = rcp(xfm);
    areaPDF.resize(instancedScene->geometry.size());
    ispc::InstanceGeometry_set(getIE(),
                               (ispc::AffineSpace3f&)xfm,
                               (ispc::AffineSpace3f&)rcp_xfm,
                               instancedScene->getIE(),
                               &areaPDF[0]);
    for (auto volume : instancedScene->volume) {
      ospSet3f((OSPObject)volume.ptr, "xfm.l.vx", xfm.l.vx.x, xfm.l.vx.y, xfm.l.vx.z);
      ospSet3f((OSPObject)volume.ptr, "xfm.l.vy", xfm.l.vy.x, xfm.l.vy.y, xfm.l.vy.z);
      ospSet3f((OSPObject)volume.ptr, "xfm.l.vz", xfm.l.vz.x, xfm.l.vz.y, xfm.l.vz.z);
      ospSet3f((OSPObject)volume.ptr, "xfm.p", xfm.p.x, xfm.p.y, xfm.p.z);
    }
  }