int TriangleMeshWithNormals::extract(RTCScene scene, size_t id) const { unsigned mesh = rtcNewTriangleMesh (scene, RTC_GEOMETRY_STATIC, triangles.size(), vertices.size()); //if (mesh != id) throw std::runtime_error("ID does not match"); Vec3fa* vertices_o = (Vec3fa*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER); RTCTriangle* triangles_o = (RTCTriangle*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); for (size_t j=0; j<triangles.size(); j++) { const TriangleMeshWithNormals::Triangle& tri = triangles[j]; triangles_o[j].v0 = tri.v0; triangles_o[j].v1 = tri.v1; triangles_o[j].v2 = tri.v2; } BBox3f bounds = empty; for (size_t j=0; j<vertices.size(); j++) { const Vector3f p = vertices[j].p; vertices_o[j].x = p.x; vertices_o[j].y = p.y; vertices_o[j].z = p.z; bounds.grow(p); } rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER); rtcUnmapBuffer(scene,mesh,RTC_INDEX_BUFFER); return mesh; }
/* creates a ground plane */ unsigned int createGroundPlane (RTCScene scene) { /* create a triangulated plane with 2 triangles and 4 vertices */ unsigned int mesh = rtcNewTriangleMesh (scene, RTC_GEOMETRY_STATIC, 2, 4); /* set vertices */ Vertex* vertices = (Vertex*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER); 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; rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER); /* set triangles */ Triangle* triangles = (Triangle*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); triangles[0].v0 = 0; triangles[0].v1 = 2; triangles[0].v2 = 1; triangles[1].v0 = 1; triangles[1].v1 = 2; triangles[1].v2 = 3; rtcUnmapBuffer(scene,mesh,RTC_INDEX_BUFFER); return mesh; }
int TriangleMesh::toEmbreeObj ( RTCScene scene_i ) { unsigned int mesh = rtcNewTriangleMesh( scene_i, RTC_GEOMETRY_STATIC, num_of_triangle, num_of_vertex ); Vertex * vertices = ( Vertex * ) rtcMapBuffer( scene_i, mesh, RTC_VERTEX_BUFFER ); for ( int i = 0; i < num_of_vertex; i++ ) { vertices[ i ] = ver_array[ i ]; } rtcUnmapBuffer( scene_i, mesh, RTC_VERTEX_BUFFER ); Triangle_index_bre * triangles = ( Triangle_index_bre * ) rtcMapBuffer( scene_i, mesh, RTC_INDEX_BUFFER ); for ( int i = 0; i < num_of_triangle; i++ ) { triangles[ i ] = tri_array[ i ]; } rtcUnmapBuffer( scene_i, mesh, RTC_INDEX_BUFFER ); embreeID = mesh; return mesh; }
EmbreeScene *embree_init(OzyScene ozy_scene) { RTCDevice dev = rtcNewDevice(NULL); RTCScene scene = rtcDeviceNewScene(dev,RTC_SCENE_STATIC, RTC_INTERSECT1); for(unsigned i=0;i<ozy_scene.objects.count;i++){ Object *obj = ozy_scene.objects.data + i; unsigned geomID = rtcNewTriangleMesh(scene, RTC_GEOMETRY_STATIC , obj->num_tris, obj->num_verts); float* vertices = static_cast<float*>(rtcMapBuffer(scene, geomID, RTC_VERTEX_BUFFER)); for(u32 ii=0;ii<obj->num_verts;ii++){ vertices[ii * 4 + 0] = obj->verts[ii].x; vertices[ii * 4 + 1] = obj->verts[ii].y; vertices[ii * 4 + 2] = obj->verts[ii].z; } rtcUnmapBuffer(scene, geomID, RTC_VERTEX_BUFFER); u32* triangles = static_cast<u32*>( rtcMapBuffer(scene, geomID, RTC_INDEX_BUFFER)); for(u32 ii=0;ii<obj->num_tris*3;ii++){ triangles[ii] = obj->tris[ii]; } rtcUnmapBuffer(scene, geomID, RTC_INDEX_BUFFER); } rtcCommit(scene); EmbreeScene *embree_scene = new EmbreeScene; embree_scene->dev = dev; embree_scene->scene = scene; return embree_scene; }
void Raytracer::buildScene() { SceneVisitor visitor(_meshes); _rootNode->accept(visitor); for (int meshId = 0; meshId < _meshes.size();++meshId) { unsigned int geoId = rtcNewTriangleMesh (_scene, RTC_GEOMETRY_STATIC, _meshes[meshId].getNumTriangles(), _meshes[meshId].getNumVertices()); osg::Vec4f* vertices = ( osg::Vec4f*) rtcMapBuffer(_scene,geoId,RTC_VERTEX_BUFFER); for (int i =0; i < _meshes[meshId].getNumVertices();++i) { Vertex tri = _meshes[meshId].getVertices()[i]; vertices[i].x() =tri.pos.x(); vertices[i].y() =tri.pos.y(); vertices[i].z() =tri.pos.z(); } rtcUnmapBuffer(_scene,geoId,RTC_VERTEX_BUFFER); osg::Vec3i* triangles = (osg::Vec3i*) rtcMapBuffer(_scene,geoId,RTC_INDEX_BUFFER); for (int i =0; i < _meshes[meshId].getNumTriangles();++i) { Triangle tri = _meshes[meshId].getTriangles()[i]; triangles[i].x() =tri.v0; triangles[i].y() =tri.v1; triangles[i].z() =tri.v2; } rtcUnmapBuffer(_scene,geoId,RTC_INDEX_BUFFER); _geoToMesh[geoId] = meshId; _meshToGeo[meshId] = geoId; } rtcCommit(_scene); }
/* adds a cube to the scene */ unsigned int addCube (RTCScene scene_i) { /* create a triangulated cube with 12 triangles and 8 vertices */ unsigned int mesh = rtcNewTriangleMesh (scene_i, RTC_GEOMETRY_STATIC, 12, 8); /* set vertices */ Vertex* vertices = (Vertex*) rtcMapBuffer(scene_i,mesh,RTC_VERTEX_BUFFER); vertices[0].x = -1; vertices[0].y = -1; vertices[0].z = -1; vertices[1].x = -1; vertices[1].y = -1; vertices[1].z = +1; vertices[2].x = -1; vertices[2].y = +1; vertices[2].z = -1; vertices[3].x = -1; vertices[3].y = +1; vertices[3].z = +1; vertices[4].x = +1; vertices[4].y = -1; vertices[4].z = -1; vertices[5].x = +1; vertices[5].y = -1; vertices[5].z = +1; vertices[6].x = +1; vertices[6].y = +1; vertices[6].z = -1; vertices[7].x = +1; vertices[7].y = +1; vertices[7].z = +1; rtcUnmapBuffer(scene_i,mesh,RTC_VERTEX_BUFFER); /* create triangle color array */ colors = new Vec3f[12]; /* set triangles and colors */ int tri = 0; Triangle* triangles = (Triangle*) rtcMapBuffer(scene_i,mesh,RTC_INDEX_BUFFER); // left side colors[tri] = Vec3f(1,0,0); triangles[tri].v0 = 0; triangles[tri].v1 = 2; triangles[tri].v2 = 1; tri++; colors[tri] = Vec3f(1,0,0); triangles[tri].v0 = 1; triangles[tri].v1 = 2; triangles[tri].v2 = 3; tri++; // right side colors[tri] = Vec3f(0,1,0); triangles[tri].v0 = 4; triangles[tri].v1 = 5; triangles[tri].v2 = 6; tri++; colors[tri] = Vec3f(0,1,0); triangles[tri].v0 = 5; triangles[tri].v1 = 7; triangles[tri].v2 = 6; tri++; // bottom side colors[tri] = Vec3f(0.5f); triangles[tri].v0 = 0; triangles[tri].v1 = 1; triangles[tri].v2 = 4; tri++; colors[tri] = Vec3f(0.5f); triangles[tri].v0 = 1; triangles[tri].v1 = 5; triangles[tri].v2 = 4; tri++; // top side colors[tri] = Vec3f(1.0f); triangles[tri].v0 = 2; triangles[tri].v1 = 6; triangles[tri].v2 = 3; tri++; colors[tri] = Vec3f(1.0f); triangles[tri].v0 = 3; triangles[tri].v1 = 6; triangles[tri].v2 = 7; tri++; // front side colors[tri] = Vec3f(0,0,1); triangles[tri].v0 = 0; triangles[tri].v1 = 4; triangles[tri].v2 = 2; tri++; colors[tri] = Vec3f(0,0,1); triangles[tri].v0 = 2; triangles[tri].v1 = 4; triangles[tri].v2 = 6; tri++; // back side colors[tri] = Vec3f(1,1,0); triangles[tri].v0 = 1; triangles[tri].v1 = 3; triangles[tri].v2 = 5; tri++; colors[tri] = Vec3f(1,1,0); triangles[tri].v0 = 3; triangles[tri].v1 = 7; triangles[tri].v2 = 5; tri++; rtcUnmapBuffer(scene_i,mesh,RTC_INDEX_BUFFER); /* set intersection filter for the cube */ rtcSetIntersectionFilterFunction(scene_i,mesh,(RTCFilterFunc)&intersectionFilter); rtcSetOcclusionFilterFunction (scene_i,mesh,(RTCFilterFunc)&occlusionFilter); return mesh; }
unsigned int createTriangulatedSphere (RTCScene scene, Vec3f p, float r) { /* create triangle mesh */ unsigned int mesh = rtcNewTriangleMesh (scene, RTC_GEOMETRY_STATIC, 2*numTheta*(numPhi-1), numTheta*(numPhi+1)); /* map triangle and vertex buffers */ Vertex* vertices = (Vertex*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER); Triangle* triangles = (Triangle*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); /* create sphere */ 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 = p.x + r*sin(phif)*sin(thetaf); v.y = p.y + r*cos(phif); v.z = p.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 = p00; triangles[tri].v2 = p01; tri++; } if (phi < numPhi) { triangles[tri].v0 = p11; triangles[tri].v1 = p10; triangles[tri].v2 = p01; tri++; } } } rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER); rtcUnmapBuffer(scene,mesh,RTC_INDEX_BUFFER); return mesh; }
void TriangleMesh::Register(RTCScene rtcScene, unsigned int geomID) { unsigned int obtainedGeomID = rtcNewTriangleMesh(rtcScene, RTC_GEOMETRY_STATIC, m_Triangles.size(), m_Vertices.size(), 1); if(obtainedGeomID != geomID) throw std::runtime_error("Wrong geomID provided when registering a TriangleMesh"); PointA* rtcVertices = (PointA*) rtcMapBuffer(rtcScene, geomID, RTC_VERTEX_BUFFER); std::copy(m_Vertices.begin(), m_Vertices.end(), rtcVertices); rtcUnmapBuffer(rtcScene, geomID, RTC_VERTEX_BUFFER); Triangle* rtcTriangles = (Triangle*) rtcMapBuffer(rtcScene, geomID, RTC_INDEX_BUFFER); std::copy(m_Triangles.begin(), m_Triangles.end(), rtcTriangles); rtcUnmapBuffer(rtcScene, geomID, RTC_INDEX_BUFFER); }
/* adds a cube to the scene */ unsigned int addCube (RTCScene scene_i, const Vec3fa& pos) { /* create a triangulated cube with 12 triangles and 8 vertices */ unsigned int mesh = rtcNewTriangleMesh (scene_i, RTC_GEOMETRY_STATIC, 12, 8); /* set vertices */ Vec3fa* vertices = (Vec3fa*) rtcMapBuffer(scene_i,mesh,RTC_VERTEX_BUFFER); vertices[0].x = pos.x + -1; vertices[0].y = pos.y + -1; vertices[0].z = pos.z + -1; vertices[1].x = pos.x + -1; vertices[1].y = pos.y + -1; vertices[1].z = pos.z + +1; vertices[2].x = pos.x + -1; vertices[2].y = pos.y + +1; vertices[2].z = pos.z + -1; vertices[3].x = pos.x + -1; vertices[3].y = pos.y + +1; vertices[3].z = pos.z + +1; vertices[4].x = pos.x + +1; vertices[4].y = pos.y + -1; vertices[4].z = pos.z + -1; vertices[5].x = pos.x + +1; vertices[5].y = pos.y + -1; vertices[5].z = pos.z + +1; vertices[6].x = pos.x + +1; vertices[6].y = pos.y + +1; vertices[6].z = pos.z + -1; vertices[7].x = pos.x + +1; vertices[7].y = pos.y + +1; vertices[7].z = pos.z + +1; rtcUnmapBuffer(scene_i,mesh,RTC_VERTEX_BUFFER); /* set triangles */ int tri = 0; Triangle* triangles = (Triangle*) rtcMapBuffer(scene_i,mesh,RTC_INDEX_BUFFER); // left side triangles[tri].v0 = 0; triangles[tri].v1 = 2; triangles[tri].v2 = 1; tri++; triangles[tri].v0 = 1; triangles[tri].v1 = 2; triangles[tri].v2 = 3; tri++; // right side triangles[tri].v0 = 4; triangles[tri].v1 = 5; triangles[tri].v2 = 6; tri++; triangles[tri].v0 = 5; triangles[tri].v1 = 7; triangles[tri].v2 = 6; tri++; // bottom side triangles[tri].v0 = 0; triangles[tri].v1 = 1; triangles[tri].v2 = 4; tri++; triangles[tri].v0 = 1; triangles[tri].v1 = 5; triangles[tri].v2 = 4; tri++; // top side triangles[tri].v0 = 2; triangles[tri].v1 = 6; triangles[tri].v2 = 3; tri++; triangles[tri].v0 = 3; triangles[tri].v1 = 6; triangles[tri].v2 = 7; tri++; // front side triangles[tri].v0 = 0; triangles[tri].v1 = 4; triangles[tri].v2 = 2; tri++; triangles[tri].v0 = 2; triangles[tri].v1 = 4; triangles[tri].v2 = 6; tri++; // back side triangles[tri].v0 = 1; triangles[tri].v1 = 3; triangles[tri].v2 = 5; tri++; triangles[tri].v0 = 3; triangles[tri].v1 = 7; triangles[tri].v2 = 5; tri++; rtcUnmapBuffer(scene_i,mesh,RTC_INDEX_BUFFER); return mesh; }
/* adds a cube to the scene */ unsigned int addCube (RTCScene scene_i) { /* create a triangulated cube with 6 quads and 8 vertices */ //unsigned int geomID = rtcNewTriangleMesh(scene_i, RTC_GEOMETRY_STATIC, NUM_FACES, NUM_INDICES/3); unsigned int geomID = rtcNewSubdivisionMesh(scene_i, RTC_GEOMETRY_STATIC, NUM_FACES, NUM_INDICES, 8, 0, 0, 0); //unsigned int geomID = rtcNewSubdivisionMesh(scene_i, RTC_GEOMETRY_STATIC, NUM_FACES, NUM_INDICES, 8, 12, 8, 0); rtcSetBuffer(scene_i, geomID, RTC_VERTEX_BUFFER, cube_vertices, 0, sizeof(Vec3fa )); rtcSetBuffer(scene_i, geomID, RTC_INDEX_BUFFER, cube_indices , 0, sizeof(unsigned int)); //rtcSetBuffer(scene_i, geomID, RTC_INDEX_BUFFER, cube_indices , 0, 3*sizeof(unsigned int)); rtcSetBuffer(scene_i, geomID, RTC_FACE_BUFFER, cube_faces, 0, sizeof(unsigned int)); rtcSetBuffer(scene_i, geomID, RTC_EDGE_CREASE_INDEX_BUFFER, cube_edge_crease_indices, 0, 2*sizeof(unsigned int)); rtcSetBuffer(scene_i, geomID, RTC_EDGE_CREASE_WEIGHT_BUFFER, cube_edge_crease_weights, 0, sizeof(float)); rtcSetBuffer(scene_i, geomID, RTC_VERTEX_CREASE_INDEX_BUFFER, cube_vertex_crease_indices,0, sizeof(unsigned int)); rtcSetBuffer(scene_i, geomID, RTC_VERTEX_CREASE_WEIGHT_BUFFER,cube_vertex_crease_weights,0, sizeof(float)); rtcSetBuffer(scene_i, geomID, RTC_USER_VERTEX_BUFFER0, cube_colors, 0, sizeof(Vec3fa)); float* level = (float*) rtcMapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); for (size_t i=0; i<NUM_INDICES; i++) level[i] = EDGE_LEVEL; rtcUnmapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); return geomID; }
unsigned int convertSubdivMesh(ISPCSubdivMesh* mesh, RTCScene scene_out) { /* if more than a single timestep, mark object as dynamic */ RTCGeometryFlags object_flags = mesh->numTimeSteps > 1 ? RTC_GEOMETRY_DYNAMIC : RTC_GEOMETRY_STATIC; /* create object */ unsigned int geomID = rtcNewSubdivisionMesh(scene_out, object_flags, mesh->numFaces, mesh->numEdges, mesh->numVertices, mesh->numEdgeCreases, mesh->numVertexCreases, mesh->numHoles, mesh->numTimeSteps); mesh->geom.geomID = geomID; for (size_t i=0; i<mesh->numEdges; i++) mesh->subdivlevel[i] = 4.0f; /* generate vertex buffer */ Vec3fa* vertices = (Vec3fa*) rtcMapBuffer(scene_out,geomID,RTC_VERTEX_BUFFER); for (size_t i=0;i<mesh->numVertices;i++) vertices[i] = mesh->positions[0][i]; rtcUnmapBuffer(scene_out, geomID, RTC_VERTEX_BUFFER); /* set all other buffers */ rtcSetBuffer(scene_out, geomID, RTC_LEVEL_BUFFER, mesh->subdivlevel, 0, sizeof(float)); rtcSetBuffer(scene_out, geomID, RTC_INDEX_BUFFER, mesh->position_indices , 0, sizeof(unsigned int)); rtcSetBuffer(scene_out, geomID, RTC_FACE_BUFFER, mesh->verticesPerFace, 0, sizeof(unsigned int)); rtcSetBuffer(scene_out, geomID, RTC_HOLE_BUFFER, mesh->holes, 0, sizeof(unsigned int)); rtcSetBuffer(scene_out, geomID, RTC_EDGE_CREASE_INDEX_BUFFER, mesh->edge_creases, 0, 2*sizeof(unsigned int)); rtcSetBuffer(scene_out, geomID, RTC_EDGE_CREASE_WEIGHT_BUFFER, mesh->edge_crease_weights, 0, sizeof(float)); rtcSetBuffer(scene_out, geomID, RTC_VERTEX_CREASE_INDEX_BUFFER, mesh->vertex_creases, 0, sizeof(unsigned int)); rtcSetBuffer(scene_out, geomID, RTC_VERTEX_CREASE_WEIGHT_BUFFER, mesh->vertex_crease_weights, 0, sizeof(float)); rtcSetSubdivisionMode(scene_out, geomID, 0, mesh->position_subdiv_mode); return geomID; }
/* adds a cube to the scene */ unsigned int addSubdivCube (RTCScene scene_i) { unsigned int geomID = rtcNewSubdivisionMesh(scene_i, RTC_GEOMETRY_STATIC, NUM_QUAD_FACES, NUM_QUAD_INDICES, NUM_VERTICES, 0, 0, 0); rtcSetBuffer(scene_i, geomID, RTC_VERTEX_BUFFER, cube_vertices, 0, sizeof(Vec3fa )); rtcSetBuffer(scene_i, geomID, RTC_INDEX_BUFFER, cube_quad_indices , 0, sizeof(unsigned int)); rtcSetBuffer(scene_i, geomID, RTC_FACE_BUFFER, cube_quad_faces, 0, sizeof(unsigned int)); float* level = (float*) rtcMapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); for (size_t i=0; i<NUM_QUAD_INDICES; i++) level[i] = 4; rtcUnmapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); /* create face color array */ colors = (Vec3fa*) alignedMalloc(6*sizeof(Vec3fa)); colors[0] = Vec3fa(1,0,0); // left side colors[1] = Vec3fa(0,1,0); // right side colors[2] = Vec3fa(0.5f); // bottom side colors[3] = Vec3fa(1.0f); // top side colors[4] = Vec3fa(0,0,1); // front side colors[5] = Vec3fa(1,1,0); // back side /* set intersection filter for the cube */ if (g_mode != MODE_NORMAL) { rtcSetIntersectionFilterFunctionN(scene_i,geomID,intersectionFilterN); rtcSetOcclusionFilterFunctionN (scene_i,geomID,occlusionFilterN); } else { rtcSetIntersectionFilterFunction(scene_i,geomID,intersectionFilter); rtcSetOcclusionFilterFunction (scene_i,geomID,occlusionFilter); } return geomID; }
/* animates a sphere */ void animateSphere (int id, float time) { /* animate vertices */ Vertex* vertices = (Vertex*) rtcMapBuffer(g_scene,id,RTC_VERTEX_BUFFER); const float rcpNumTheta = rcp((float)numTheta); const float rcpNumPhi = rcp((float)numPhi); const Vec3fa pos = position[id]; const float r = radius[id]; const float f = 2.0f*(1.0f+0.5f*sin(time)); /* loop over all vertices */ #if 1 // enables parallel execution launch_animateSphere(animateSphere,numPhi+1,vertices,rcpNumTheta,rcpNumPhi,pos,r,f); #else for (int phi = 0; phi <numPhi+1; phi++) for (int theta = 0; theta<numTheta; theta++) { Vertex* v = &vertices[phi*numTheta+theta]; const float phif = phi*float(pi)*rcpNumPhi; const float thetaf = theta*2.0f*float(pi)*rcpNumTheta; v->x = pos.x+r*sin(f*phif)*sin(thetaf); v->y = pos.y+r*cos(phif); v->z = pos.z+r*sin(f*phif)*cos(thetaf); } #endif rtcUnmapBuffer(g_scene,id,RTC_VERTEX_BUFFER); /* update mesh */ rtcUpdate (g_scene,id); }
/* adds a hair to the scene */ unsigned int addHair(RTCScene scene_i) { unsigned int geomID = rtcNewHairGeometry (scene_i, RTC_GEOMETRY_STATIC, 1, 4, 1); float4* pos = (float4*) rtcMapBuffer(scene_i,geomID,RTC_VERTEX_BUFFER); pos[0] = float4(0.0f,0.0f,0.0f,0.1f); pos[1] = float4(0.0f,1.0f,0.0f,0.1f); pos[2] = float4(0.0f,2.0f,0.0f,0.1f); pos[3] = float4(0.0f,3.0f,0.0f,0.1f); rtcUnmapBuffer(scene_i,geomID,RTC_VERTEX_BUFFER); int* index = (int*) rtcMapBuffer(scene_i,geomID,RTC_INDEX_BUFFER); index[0] = 0; rtcUnmapBuffer(scene_i,geomID,RTC_INDEX_BUFFER); return geomID; }
/* add hair geometry */ unsigned int addCurve (RTCScene scene, const Vec3fa& pos) { unsigned int geomID = rtcNewCurveGeometry (scene, RTC_GEOMETRY_STATIC, NUM_CURVES, 4*NUM_CURVES); /* converts b-spline to bezier basis */ Vec3fa* vtx = (Vec3fa*) rtcMapBuffer(scene, geomID, RTC_VERTEX_BUFFER); for (size_t i=0; i<NUM_CURVES; i++) { Vec3fa P = Vec3fa(pos.x,pos.y,pos.z,0.0f); const Vec3fa v0 = Vec3fa(hair_vertices[i+0][0],hair_vertices[i+0][1],hair_vertices[i+0][2],hair_vertices[i+0][3]); const Vec3fa v1 = Vec3fa(hair_vertices[i+1][0],hair_vertices[i+1][1],hair_vertices[i+1][2],hair_vertices[i+1][3]); const Vec3fa v2 = Vec3fa(hair_vertices[i+2][0],hair_vertices[i+2][1],hair_vertices[i+2][2],hair_vertices[i+2][3]); const Vec3fa v3 = Vec3fa(hair_vertices[i+3][0],hair_vertices[i+3][1],hair_vertices[i+3][2],hair_vertices[i+3][3]); vtx[4*i+0] = P + (1.0f/6.0f)*v0 + (2.0f/3.0f)*v1 + (1.0f/6.0f)*v2; vtx[4*i+1] = P + (2.0f/3.0f)*v1 + (1.0f/3.0f)*v2; vtx[4*i+2] = P + (1.0f/3.0f)*v1 + (2.0f/3.0f)*v2; vtx[4*i+3] = P + (1.0f/6.0f)*v1 + (2.0f/3.0f)*v2 + (1.0f/6.0f)*v3; } rtcUnmapBuffer(scene, geomID, RTC_VERTEX_BUFFER); Vec3fa* colors = (Vec3fa*) alignedMalloc(4*NUM_CURVES*sizeof(Vec3fa)); for (size_t i=0; i<NUM_CURVES; i++) { const Vec3fa v0 = Vec3fa(hair_vertex_colors[i+0][0],hair_vertex_colors[i+0][1],hair_vertex_colors[i+0][2],hair_vertex_colors[i+0][3]); const Vec3fa v1 = Vec3fa(hair_vertex_colors[i+1][0],hair_vertex_colors[i+1][1],hair_vertex_colors[i+1][2],hair_vertex_colors[i+1][3]); const Vec3fa v2 = Vec3fa(hair_vertex_colors[i+2][0],hair_vertex_colors[i+2][1],hair_vertex_colors[i+2][2],hair_vertex_colors[i+2][3]); const Vec3fa v3 = Vec3fa(hair_vertex_colors[i+3][0],hair_vertex_colors[i+3][1],hair_vertex_colors[i+3][2],hair_vertex_colors[i+3][3]); colors[4*i+0] = (1.0f/6.0f)*v0 + (2.0f/3.0f)*v1 + (1.0f/6.0f)*v2; colors[4*i+1] = (2.0f/3.0f)*v1 + (1.0f/3.0f)*v2; colors[4*i+2] = (1.0f/3.0f)*v1 + (2.0f/3.0f)*v2; colors[4*i+3] = (1.0f/6.0f)*v1 + (2.0f/3.0f)*v2 + (1.0f/6.0f)*v3; } int* index = (int*) rtcMapBuffer(scene, geomID, RTC_INDEX_BUFFER); for (int i=0; i<NUM_CURVES; i++) { index[i] = 4*i; } rtcUnmapBuffer(scene,geomID,RTC_INDEX_BUFFER); rtcSetBuffer(scene, geomID, RTC_USER_VERTEX_BUFFER0, colors, 0, sizeof(Vec3fa)); return geomID; }
/*! updates the tessellation level for each edge */ void updateEdgeLevelBuffer( RTCScene scene_i, unsigned geomID, const Vec3fa& cam_pos ) { float* level = (float* ) rtcMapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); int* faces = (int* ) rtcMapBuffer(scene_i, geomID, RTC_INDEX_BUFFER); Vec3fa* vertices = (Vec3fa*) rtcMapBuffer(scene_i, geomID, RTC_VERTEX_BUFFER); for (size_t f=0; f<NUM_FACES; f++) { for (size_t i=0; i<FACE_SIZE; i++) { const Vec3fa v0 = Vec3fa(vertices[faces[FACE_SIZE*f+(i+0)%FACE_SIZE]]); const Vec3fa v1 = Vec3fa(vertices[faces[FACE_SIZE*f+(i+1)%FACE_SIZE]]); const float l = LEVEL_FACTOR*length(v1-v0)/length(cam_pos-0.5f*(v1+v0)); level[FACE_SIZE*f+i] = max(min(l,MAX_EDGE_LEVEL),MIN_EDGE_LEVEL); } } rtcUnmapBuffer(scene_i, geomID, RTC_VERTEX_BUFFER); rtcUnmapBuffer(scene_i, geomID, RTC_INDEX_BUFFER); rtcUnmapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); rtcUpdateBuffer(scene_i,geomID,RTC_LEVEL_BUFFER); }
void triangulateMesh(RTCScene sceneID, unsigned int meshID, SubdivisionMesh &mesh) { /*! Map the triangle mesh vertex buffer from Embree space into user space. */ Vertex *vertices = (Vertex *) rtcMapBuffer(sceneID, meshID, RTC_VERTEX_BUFFER); /*! Copy vertex data from the subdivision mesh into the triangle mesh buffer. */ for (size_t i=0 ; i < mesh.vertexCount() ; i++) { Vec3f p = mesh.getCoordinates(i); vertices[i].x = p.x; vertices[i].y = p.y; vertices[i].z = p.z; } /*! Unmap the triangle mesh buffer. */ rtcUnmapBuffer(sceneID, meshID, RTC_VERTEX_BUFFER); /*! Map the triangle mesh index buffer from Embree space into user space. */ Triangle *triangles = (Triangle *) rtcMapBuffer(sceneID, meshID, RTC_INDEX_BUFFER); /* Copy vertex indices into the triangle mesh buffer. */ for (size_t i=0, j=0 ; i < mesh.faceCount() ; j += mesh.getFace(i).vertexCount() - 2, i++) triangulateFace(mesh.getFace(i), &triangles[j]); /*! Unmap the triangle mesh buffer. */ rtcUnmapBuffer(sceneID, meshID, RTC_INDEX_BUFFER); }
unsigned int convertLineSegments(ISPCLineSegments* mesh, RTCScene scene_out) { /* if more than a single timestep, mark object as dynamic */ RTCGeometryFlags object_flags = mesh->numTimeSteps > 1 ? RTC_GEOMETRY_DYNAMIC : RTC_GEOMETRY_STATIC; /* create object */ unsigned int geomID = rtcNewLineSegments (scene_out, object_flags, mesh->numSegments, mesh->numVertices, mesh->numTimeSteps); /* generate vertex buffer */ Vec3fa* vertices = (Vec3fa*) rtcMapBuffer(scene_out,geomID,RTC_VERTEX_BUFFER); for (size_t i=0;i<mesh->numVertices;i++) vertices[i] = mesh->positions[0][i]; rtcUnmapBuffer(scene_out, geomID, RTC_VERTEX_BUFFER); /* set index buffer */ rtcSetBuffer(scene_out,geomID,RTC_INDEX_BUFFER,mesh->indices,0,sizeof(int)); return geomID; }
/* adds a cube to the scene */ unsigned int addCube (RTCScene scene_i) { /* create a triangulated cube with 6 quads and 8 vertices */ unsigned int geomID = rtcNewSubdivisionMesh(scene_i, RTC_GEOMETRY_STATIC, NUM_FACES, NUM_INDICES, 8, 0, 0, 0); rtcSetBuffer(scene_i, geomID, RTC_VERTEX_BUFFER, cube_vertices, 0, sizeof(Vec3fa )); rtcSetBuffer(scene_i, geomID, RTC_INDEX_BUFFER, cube_indices , 0, sizeof(unsigned int)); rtcSetBuffer(scene_i, geomID, RTC_FACE_BUFFER, cube_faces, 0, sizeof(unsigned int)); float* level = (float*) rtcMapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); for (size_t i=0; i<NUM_INDICES; i++) level[i] = EDGE_LEVEL; rtcUnmapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); rtcSetDisplacementFunction(scene_i,geomID,(RTCDisplacementFunc)&displacementFunction,NULL); return geomID; }
/* adds a cube to the scene */ unsigned int addCube (RTCScene scene_i, const Vec3fa& offset, const Vec3fa& scale, float rotation) { /* create a triangulated cube with 12 triangles and 8 vertices */ unsigned int geomID = rtcNewTriangleMesh (scene_i, RTC_GEOMETRY_STATIC, NUM_TRI_FACES, NUM_VERTICES); //rtcSetBuffer(scene_i, geomID, RTC_VERTEX_BUFFER, cube_vertices, 0, sizeof(Vec3fa )); Vec3fa* ptr = (Vec3fa*) rtcMapBuffer(scene_i, geomID, RTC_VERTEX_BUFFER); for (size_t i=0; i<NUM_VERTICES; i++) { float x = cube_vertices[i][0]; float y = cube_vertices[i][1]; float z = cube_vertices[i][2]; Vec3fa vtx = Vec3fa(x,y,z); ptr[i] = Vec3fa(offset+LinearSpace3fa::rotate(Vec3fa(0,1,0),rotation)*LinearSpace3fa::scale(scale)*vtx); } rtcUnmapBuffer(scene_i,geomID,RTC_VERTEX_BUFFER); rtcSetBuffer(scene_i, geomID, RTC_INDEX_BUFFER, cube_tri_indices , 0, 3*sizeof(unsigned int)); /* create per-triangle color array */ colors = (Vec3fa*) alignedMalloc(12*sizeof(Vec3fa)); colors[0] = Vec3fa(1,0,0); // left side colors[1] = Vec3fa(1,0,0); colors[2] = Vec3fa(0,1,0); // right side colors[3] = Vec3fa(0,1,0); colors[4] = Vec3fa(0.5f); // bottom side colors[5] = Vec3fa(0.5f); colors[6] = Vec3fa(1.0f); // top side colors[7] = Vec3fa(1.0f); colors[8] = Vec3fa(0,0,1); // front side colors[9] = Vec3fa(0,0,1); colors[10] = Vec3fa(1,1,0); // back side colors[11] = Vec3fa(1,1,0); /* set intersection filter for the cube */ if (g_mode != MODE_NORMAL) { rtcSetIntersectionFilterFunctionN(scene_i,geomID,intersectionFilterN); rtcSetOcclusionFilterFunctionN (scene_i,geomID,occlusionFilterN); } else { rtcSetIntersectionFilterFunction(scene_i,geomID,intersectionFilter); rtcSetOcclusionFilterFunction (scene_i,geomID,occlusionFilter); } return geomID; }
unsigned int convertCurveGeometry(ISPCHairSet* hair, RTCScene scene_out) { /* if more than a single timestep, mark object as dynamic */ RTCGeometryFlags object_flags = hair->numTimeSteps > 1 ? RTC_GEOMETRY_DYNAMIC : RTC_GEOMETRY_STATIC; /* create object */ unsigned int geomID = 0; switch (hair->basis) { case BEZIER_BASIS : geomID = rtcNewBezierCurveGeometry (scene_out, object_flags, hair->numHairs, hair->numVertices, hair->numTimeSteps); break; case BSPLINE_BASIS: geomID = rtcNewBSplineCurveGeometry (scene_out, object_flags, hair->numHairs, hair->numVertices, hair->numTimeSteps); break; default: assert(false); } /* generate vertex buffer */ Vec3fa* vertices = (Vec3fa*) rtcMapBuffer(scene_out,geomID,RTC_VERTEX_BUFFER); for (size_t i=0;i<hair->numVertices;i++) vertices[i] = hair->positions[0][i]; rtcUnmapBuffer(scene_out, geomID, RTC_VERTEX_BUFFER); /* set index buffer */ rtcSetBuffer(scene_out,geomID,RTC_INDEX_BUFFER,hair->hairs,0,sizeof(ISPCHair)); return geomID; }
extern "C" void ispcUnmapBuffer(RTCScene scene, unsigned geomID, RTCBufferType type) { rtcUnmapBuffer(scene,geomID,type); }
RTCScene convertScene(ISPCScene* scene_in) { //scene_in->numHairSets = 0; //scene_in->numMeshes = 0; /* create scene */ RTCScene scene_out = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_INCOHERENT, RTC_INTERSECT1); /* add all hair sets to the scene */ for (int i=0; i<scene_in->numHairSets; i++) { ISPCHairSet* hair = scene_in->hairs[i]; unsigned int geomID = rtcNewHairGeometry (scene_out, RTC_GEOMETRY_STATIC, hair->numHairs, hair->numVertices, hair->v2 ? 2 : 1); rtcSetBuffer(scene_out,geomID,RTC_VERTEX_BUFFER,hair->v,0,sizeof(Vertex)); if (hair->v2) rtcSetBuffer(scene_out,geomID,RTC_VERTEX_BUFFER1,hair->v2,0,sizeof(Vertex)); rtcSetBuffer(scene_out,geomID,RTC_INDEX_BUFFER,hair->hairs,0,sizeof(ISPCHair)); rtcSetOcclusionFilterFunction(scene_out,geomID,(RTCFilterFunc)&filterDispatch); } /* add all triangle meshes to the scene */ for (int i=0; i<scene_in->numMeshes; i++) { ISPCMesh* mesh = scene_in->meshes[i]; if (mesh->numQuads) { g_subdiv_mode = true; size_t numPrimitives = mesh->numQuads; size_t numEdges = mesh->numQuads*4; mesh->edge_level = new float[numEdges]; int *index_buffer = new int[numEdges]; for (size_t i=0; i<numEdges; i++) mesh->edge_level[i] = FIXED_EDGE_TESSELLATION_VALUE; /* create a triangle mesh */ unsigned int geomID = rtcNewSubdivisionMesh (scene_out, RTC_GEOMETRY_STATIC, numPrimitives, numEdges, mesh->numVertices, 0, 0, 0); mesh->geomID = geomID; unsigned int* faces = (unsigned int*) rtcMapBuffer(scene_out, geomID, RTC_FACE_BUFFER); for (size_t i=0; i<mesh->numQuads ; i++) faces[i] = 4; rtcUnmapBuffer(scene_out,geomID,RTC_FACE_BUFFER); for (size_t i=0; i<mesh->numQuads; i++) { index_buffer[4*i+0] = mesh->quads[i].v0; index_buffer[4*i+1] = mesh->quads[i].v1; index_buffer[4*i+2] = mesh->quads[i].v2; index_buffer[4*i+3] = mesh->quads[i].v3; } rtcSetBuffer(scene_out, geomID, RTC_VERTEX_BUFFER, mesh->positions , 0, sizeof(Vec3fa )); rtcSetBuffer(scene_out, geomID, RTC_INDEX_BUFFER, index_buffer , 0, sizeof(unsigned int)); rtcSetBuffer(scene_out, geomID, RTC_LEVEL_BUFFER, mesh->edge_level, 0, sizeof(float)); #if ENABLE_DISPLACEMENTS == 1 rtcSetDisplacementFunction(scene_out,geomID,(RTCDisplacementFunc)&displacementFunction,NULL); #endif } else if (mesh->numTriangles) { unsigned int geomID = rtcNewTriangleMesh (scene_out, RTC_GEOMETRY_STATIC, mesh->numTriangles, mesh->numVertices, mesh->positions2 ? 2 : 1); rtcSetBuffer(scene_out,geomID,RTC_VERTEX_BUFFER,mesh->positions,0,sizeof(Vertex)); if (mesh->positions2) rtcSetBuffer(scene_out,geomID,RTC_VERTEX_BUFFER1,mesh->positions2,0,sizeof(Vertex)); rtcSetBuffer(scene_out,geomID,RTC_INDEX_BUFFER,mesh->triangles,0,sizeof(ISPCTriangle)); rtcSetOcclusionFilterFunction(scene_out,geomID,(RTCFilterFunc)&filterDispatch); } } /* commit changes to scene */ rtcCommit (scene_out); return scene_out; }
/* adds a cube to the scene */ unsigned int addCube (RTCScene scene_i) { /* create a triangulated cube with 12 triangles and 8 vertices */ unsigned int mesh = rtcNewTriangleMesh (scene_i, RTC_GEOMETRY_STATIC, 12, 8); /* set vertices */ Vertex* vertices = (Vertex*) rtcMapBuffer(scene_i,mesh,RTC_VERTEX_BUFFER); vertices[0].x = -1; vertices[0].y = -1; vertices[0].z = -1; vertices[1].x = -1; vertices[1].y = -1; vertices[1].z = +1; vertices[2].x = -1; vertices[2].y = +1; vertices[2].z = -1; vertices[3].x = -1; vertices[3].y = +1; vertices[3].z = +1; vertices[4].x = +1; vertices[4].y = -1; vertices[4].z = -1; vertices[5].x = +1; vertices[5].y = -1; vertices[5].z = +1; vertices[6].x = +1; vertices[6].y = +1; vertices[6].z = -1; vertices[7].x = +1; vertices[7].y = +1; vertices[7].z = +1; rtcUnmapBuffer(scene_i,mesh,RTC_VERTEX_BUFFER); /* create triangle color array */ colors = (Vec3fa*) alignedMalloc(12*sizeof(Vec3fa)); /* set triangles and colors */ int tri = 0; Triangle* triangles = (Triangle*) rtcMapBuffer(scene_i,mesh,RTC_INDEX_BUFFER); // left side colors[tri] = Vec3fa(1,0,0); triangles[tri].v0 = 0; triangles[tri].v1 = 2; triangles[tri].v2 = 1; tri++; colors[tri] = Vec3fa(1,0,0); triangles[tri].v0 = 1; triangles[tri].v1 = 2; triangles[tri].v2 = 3; tri++; // right side colors[tri] = Vec3fa(0,1,0); triangles[tri].v0 = 4; triangles[tri].v1 = 5; triangles[tri].v2 = 6; tri++; colors[tri] = Vec3fa(0,1,0); triangles[tri].v0 = 5; triangles[tri].v1 = 7; triangles[tri].v2 = 6; tri++; // bottom side colors[tri] = Vec3fa(0.5f); triangles[tri].v0 = 0; triangles[tri].v1 = 1; triangles[tri].v2 = 4; tri++; colors[tri] = Vec3fa(0.5f); triangles[tri].v0 = 1; triangles[tri].v1 = 5; triangles[tri].v2 = 4; tri++; // top side colors[tri] = Vec3fa(1.0f); triangles[tri].v0 = 2; triangles[tri].v1 = 6; triangles[tri].v2 = 3; tri++; colors[tri] = Vec3fa(1.0f); triangles[tri].v0 = 3; triangles[tri].v1 = 6; triangles[tri].v2 = 7; tri++; // front side colors[tri] = Vec3fa(0,0,1); triangles[tri].v0 = 0; triangles[tri].v1 = 4; triangles[tri].v2 = 2; tri++; colors[tri] = Vec3fa(0,0,1); triangles[tri].v0 = 2; triangles[tri].v1 = 4; triangles[tri].v2 = 6; tri++; // back side colors[tri] = Vec3fa(1,1,0); triangles[tri].v0 = 1; triangles[tri].v1 = 3; triangles[tri].v2 = 5; tri++; colors[tri] = Vec3fa(1,1,0); triangles[tri].v0 = 3; triangles[tri].v1 = 7; triangles[tri].v2 = 5; tri++; rtcUnmapBuffer(scene_i,mesh,RTC_INDEX_BUFFER); return mesh; }