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