/* 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; }
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()); }
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); } }