// Released under the OSGPL license, as part of the OpenSceneGraph distribution. // // specification : http://www.trackvis.org/docs/?subsect=fileformat // #include #include #include #include #include #include struct TrkHeader { char id_string[6]; short dim[3]; float voxel_size[3]; float origin[3]; short n_scalars; char scalar_name[10][20]; short n_properties; char property_name[10][20]; float vox_to_ras[4][4]; char reserved[444]; char voxel_order[4]; char pad2[4]; float image_orientation_patient[6]; char pad1[2]; unsigned char invert_x; unsigned char invert_y; unsigned char invert_z; unsigned char swap_xy; unsigned char swap_yz; unsigned char swap_zx; int n_count; int version; int hdr_size; }; const char vert_shader_str[] = "void main(void)\n" "{\n" " vec4 eye = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);\n" " vec3 rayVector = normalize(gl_Vertex.xyz-eye.xyz);\n" "\n" " vec3 dv = gl_Normal;\n" " float d = dot(rayVector, dv);\n" " float d2 = abs(d);//*d;\n" " const float base=1.5;\n" " float l = (base-d2)/base;\n" " float half_l = l*0.5;\n" "\n" " // gl_FrontColor = vec4( (dv.x+1.0)*half_l, (dv.y+1.0)*half_l, (dv.z+1.0)*half_l, 1.0);\n" " // gl_FrontColor = vec4( abs(dv.x)*half_l, abs(dv.y)*half_l, abs(dv.z)*half_l, 1.0);\n" " gl_FrontColor = vec4( abs(dv.x), abs(dv.y), abs(dv.z), 1.0);\n" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" " gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" "}\n"; struct AssignDirectionColour { AssignDirectionColour() {} void assign(osg::Geometry* geometry) { osg::Vec3Array* vertices = dynamic_cast(geometry->getVertexArray()); if (!vertices) return; // allocate colours osg::ref_ptr colours = dynamic_cast(geometry->getColorArray()); if (!colours) { colours = new osg::Vec4Array; geometry->setColorArray(colours); } geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); colours->resize(vertices->size(), osg::Vec4(0.0,0.0,0.0,0.0)); #if 1 // allocate normals osg::ref_ptr normals = dynamic_cast(geometry->getNormalArray()); if (!normals) { normals = new osg::Vec3Array; geometry->setNormalArray(normals); } geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); normals->resize(vertices->size(), osg::Vec3(0.0,0.0,0.0)); #endif typedef std::vector Divisors; Divisors divisors; divisors.resize(vertices->size(), 0.0f); for(unsigned int i=0; igetNumPrimitiveSets(); ++i) { osg::PrimitiveSet* pset = geometry->getPrimitiveSet(i); if (pset->getMode()==GL_LINES) { for(unsigned int pi=0; pigetNumIndices()-1; pi+=2) { unsigned int vi_0 = pset->index(pi); unsigned int vi_1 = pset->index(pi+1); osg::Vec3& v0 = (*vertices)[vi_0]; osg::Vec3& v1 = (*vertices)[vi_1]; osg::Vec3 dv(v1-v0); dv.normalize(); // assign colours osg::Vec4& c0 = (*colours)[vi_0]; osg::Vec4& c1 = (*colours)[vi_1]; osg::Vec4 colour( (dv.x()+1.0f/2.0f), (dv.y()+1.0f/2.0f), (dv.z()+1.0f/2.0f), 1.0f ); if (divisors[vi_0]==0.0f) c0 = colour; else c0 += colour; if (divisors[vi_1]==0.0f) c1 = colour; else c1 += colour; // assign normals osg::Vec3& n0 = (*normals)[vi_0]; osg::Vec3& n1 = (*normals)[vi_1]; #if 1 if (divisors[vi_0]==0.0f) n0 = dv; else n0 += dv; if (divisors[vi_1]==0.0f) n1 = dv; else n1 += dv; #else float len_xy = sqrtf(dv.x()*dv.x() + dv.y()*dv.y()); osg::Vec3 normal(0.0f, 0.0f, 0.0f); if (len_xy!=0.0) { normal.set((-dv.x()/len_xy)*dv.z(), (-dv.y()/len_xy)*dv.z(), len_xy); } else { normal.set(1.0f, 0.0f, 0.0f); } if (divisors[vi_0]==0.0f) n0 = normal; else n0 += normal; if (divisors[vi_1]==0.0f) n1 = normal; else n1 += normal; #endif divisors[vi_0] += 1.0f; divisors[vi_1] += 1.0f; } } } for(unsigned int vi=0; visize(); ++vi) { if (divisors[vi]>0.0f) { (*colours)[vi] /= divisors[vi]; (*normals)[vi].normalize(); } } std::string vertexShaderFile("track.vert"); osg::ref_ptr stateset = geometry->getOrCreateStateSet(); osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = osgDB::readShaderFile(osg::Shader::VERTEX, vertexShaderFile); if (!vertexShader) { vertexShader = new osg::Shader(osg::Shader::VERTEX, vert_shader_str); } program->addShader(vertexShader); stateset->setAttribute(program.get()); } }; class ReaderWriterTRK : public osgDB::ReaderWriter { public: ReaderWriterTRK() { supportsExtension("trk","Track file format"); OSG_NOTICE<<"sizeof(TrkHeader)="<(&header), sizeof(TrkHeader)); if (fin.fail()) return ReadResult::ERROR_IN_READING_FILE; OSG_NOTICE<<"Read header successfuly ["< geode = new osg::Geode; osg::ref_ptr geometry = new osg::Geometry; geode->addDrawable(geometry.get()); #if 0 osg::ref_ptr stateset = new osg::StateSet; stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); geometry->setStateSet(stateset.get()); #endif osg::ref_ptr colours = new osg::Vec4Array; geometry->setColorArray(colours.get()); geometry->setColorBinding(osg::Geometry::BIND_OVERALL); colours->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); osg::ref_ptr vertices = new osg::Vec3Array; geometry->setVertexArray(vertices.get()); osg::ref_ptr lines = new osg::DrawElementsUInt(GL_LINES); geometry->addPrimitiveSet(lines.get()); for(int i=0; i(&n_points),4); if (fin.fail()) break; // OSG_NOTICE<<" n_points="<(point_data), n_point_floats*4); if (fin.fail()) break; if (n_p!=0) { float* property_data = new float[n_p]; fin.read(reinterpret_cast(&property_data), n_p*4); if (fin.fail()) break; delete [] property_data; } if (n_points>0) { // record the index of the first vertex of the new track int vi = vertices->size(); // add the vertices of the track for(int pi=0; pipush_back(osg::Vec3(vptr[0],vptr[1],vptr[2])); } // add the line segmenets for track for(int pi=0; pipush_back(vi); lines->push_back(vi+1); } } delete [] point_data; } if (fin.fail()) { OSG_NOTICE<<"Error on reading track file."<