Пример #1
0
bool UpdateTextured(Textured & t, Range & r){
  
  //now, set new current_range:
  V3f center((r.min+r.max)/2);
  center.x = floorf(center.x);
  center.y = floorf(center.y);
  center.z = floorf(center.z);

  V3f half_diagonal(SIZE/2, SIZE/2, SIZE/2);
  t.current_range = Range(center-half_diagonal, 
			  center+half_diagonal);
  
  //fill it with a dummy texture for now (maybe 
  //better done with an external class
  Range fast_volume_range(V3f(0,0,0), V3f(255,255,255));

  unsigned char res;

  V3f c(t.current_range.min); //start
  for(int x = 0; x < SIZE; x++)
    for(int y = 0; y < SIZE; y++)
      for(int z = 0; z < SIZE; z++){
	V3f cur(c.x+x, c.y+y, c.z+z);
	if(t.texturing_fastvolume){
	  res = 
	    (unsigned char)t.texturing_fastvolume->\
	    SampleCentered((int)cur.x%255, 
		   (int)cur.y%255, 
		   (int)cur.z%255);

	  //Color conversion.
	  int r = res * 3; r=(r<0)?0:(r>255?255:r);
	  int g = (res - 80) * 3; g=(g<0)?0:(g>255?255:g);
	  int b = (res - 160) * 3; b=(b<0)?0:(b>255?255:b);

	  ((BYTE)t.data)[Offset(x,y,z)] = r;
	  ((BYTE)t.data)[Offset(x,y,z)+1] = g;
	  ((BYTE)t.data)[Offset(x,y,z)+2] =  b;
	  ((BYTE)t.data)[Offset(x,y,z)+3] =  255;
	}else{
	  bool line_hit = 
	    !((int)cur.x % 10) || 
	    !((int)cur.y % 10) || 
	    !((int)cur.z % 10);
	  ((BYTE)t.data)[Offset(x,y,z)] = line_hit?30:300;
	  ((BYTE)t.data)[Offset(x,y,z)+1] =line_hit?70:0;
	  ((BYTE)t.data)[Offset(x,y,z)+2] =line_hit?300:30;
	  ((BYTE)t.data)[Offset(x,y,z)+3] =  200;
	};
      };
  //ready; now load the texture
  UploadTexture(t.data);

  return true;
};
Пример #2
0
TEST(MAIN, RangeExpand){
  Range one(V3f(0,0,0), V3f(1,1,1)); //start
  const V3f pnt(100, -100, -100);
  const V3f out(100.1, -100.1, -100.1);
  const V3f in(99.9, -99.9, -99.9);
  
  Range expanded( (ExpandRange(one, pnt)) );

  EXPECT_TRUE(ContainsPoint(expanded, pnt));
  EXPECT_FALSE(ContainsPoint(expanded, out));
  EXPECT_TRUE(ContainsPoint(expanded, in));
};
Пример #3
0
V3f
direction (const Box2i &dataWindow, const V2f &pixelPosition)
{
    V2f ll = latLong (dataWindow, pixelPosition);

    return V3f (sin (ll.y) * cos (ll.x),
		sin (ll.x),
		cos (ll.y) * cos (ll.x));
}
//-*****************************************************************************
void MeshDrwHelper::updateNormals( V3fArraySamplePtr iN )
{
    if ( !m_valid || !m_meshP )
    {
        makeInvalid();
        return;
    }

//std::cout << "normals - " << m_name << std::endl;

    // Now see if we need to calculate normals.
    if ( ( m_meshN && iN == m_meshN ) )//||
//         ( !iN && m_customN.size() > 0 ) )
    {
        return;
    }

    size_t numPoints = m_meshP->size();
    m_meshN = iN;
    m_customN.clear();

    // Right now we only handle "vertex varying" normals,
    // which have the same cardinality as the points
    if ( !m_meshN || m_meshN->size() != numPoints )
    {
        // Make some custom normals.
        m_meshN.reset();
        m_customN.resize( numPoints );
        std::fill( m_customN.begin(), m_customN.end(), V3f( 0.0f ) );

        //std::cout << "Recalcing normals for object: "
        //          << m_host.name() << std::endl;

        for ( size_t tidx = 0; tidx < m_triangles.size(); ++tidx )
        {
            const Tri &tri = m_triangles[tidx];

            const V3f &A = (*m_meshP)[tri[0]];
            const V3f &B = (*m_meshP)[tri[1]];
            const V3f &C = (*m_meshP)[tri[2]];

            V3f AB = B - A;
            V3f AC = C - A;

            V3f wN = AB.cross( AC );
            m_customN[tri[0]] += wN;
            m_customN[tri[1]] += wN;
            m_customN[tri[2]] += wN;
        }

        // Normalize normals.
        for ( size_t nidx = 0; nidx < numPoints; ++nidx )
        {
            m_customN[nidx].normalize();
        }
    }
}
Пример #5
0
MeshModel::MeshModel(GLfloat x,GLfloat y,GLfloat z, vector<V3f> &mv,vector<int> &mvi){
	textured=false;
	for(int i=0; i<mv.size();i++)
		v.push_back(V3f(mv[i].x+x,mv[i].y+y,mv[i].z+z));
	for(int i=0; i<mvi.size(); i+=3)
		vi.push_back(V3i(mvi[i],mvi[i+1],mvi[i+2]));
	

	calcFaceNormals();
	calcVertexNormalsAverage();
	calcVertexNormalsWeight();
}
Пример #6
0
MeshPlane::MeshPlane(GLfloat x, GLfloat y, GLfloat z, GLfloat x_len, GLfloat y_len, int x_tiles, int y_tiles){
	textured=false;
	for(int i = 0; i<=x_tiles; i++)
		for(int j = 0; j<=y_tiles; j++)
			v.push_back(V3f(i*x_len+x,y, j*y_len+z));

	for(int i = 1; i<v.size()-y_tiles-1; i++){
		if(i%(y_tiles+1)!=0){
		vi.push_back(V3i(i-1,i,i+y_tiles+1));
		vi.push_back(V3i( i-1,i+y_tiles+1, i+y_tiles));
		}
	}
	calcFaceNormals();
	calcVertexNormalsAverage();
	calcVertexNormalsWeight();
}
Пример #7
0
// update the trackball state using the current mouse state
void Trackball::Update() {
  V3f *v;

  // SPIN+DRAG (first two buttons) translates the origin of rotation
  if (mouse.buttonsPressed == SPIN+DRAG) {
    v = &p3f_origin; mouse.buttonsPressed = DRAG; }
  else 
    v = &v3f_trans;

  // If the user drags the mouse, Spin or [O]Trans are updated.  If no
  // mouse buttons are pressed, just keep on applying the previous spin
  // rotation, over and over.

  switch (mouse.buttonsPressed) {
  case SPIN:
    Spin();  // updates Spin, which we then apply.
    qRot = qSpin * qRot;
    isChanged = true;
    break;
  case DRAG:
    //qRot = qSpin * qRot; 
    *v += V3f(mouse.dx, mouse.dy, 0.);  
    isChanged = true;
    break;
  case ZOOM: 
    //qRot = qSpin * qRot; 
    scale *= 1+.001*(mouse.du+mouse.dv);  
    isChanged = true;
    break;
  case SPIN+ZOOM:
    v3f_trans (0,0,0); qSpin(1,0,0,0);
    p3f_origin(0,0,0); qRot (1,0,0,0);
    break;
  case DRAG+ZOOM:
    scale=1;
    break;
  case SPIN+DRAG+ZOOM:
    v3f_trans (0,0,0); qSpin(1,0,0,0);
    p3f_origin(0,0,0); qRot (1,0,0,0);
    scale=1;
    break;
  default:
    //qRot = qSpin * qRot;
	break;
  }
  transformed = !isChanged;
} // Update
Пример #8
0
/// Create an octree over the given set of points with position P
///
/// The points for consideration in the current node are the set
/// P[inds[beginIndex..endIndex]]; the tree building process sorts the inds
/// array in place so that points for the output leaf nodes are held in
/// the range P[inds[node.beginIndex, node.endIndex)]].  center is the central
/// split point for splitting children of the current node; radius is the
/// current node radius measured along one of the axes.
static OctreeNode* makeTree(int depth, size_t* inds,
                            size_t beginIndex, size_t endIndex,
                            const V3f* P, const V3f& center,
                            float halfWidth, ProgressFunc& progressFunc)
{
    OctreeNode* node = new OctreeNode(center, halfWidth);
    const size_t pointsPerNode = 100000;
    // Limit max depth of tree to prevent infinite recursion when
    // greater than pointsPerNode points lie at the same position in
    // space.  floats effectively have 24 bit of precision in the
    // mantissa, so there's never any point splitting more than 24 times.
    const int maxDepth = 24;
    size_t* beginPtr = inds + beginIndex;
    size_t* endPtr = inds + endIndex;
    if (endIndex - beginIndex <= pointsPerNode || depth >= maxDepth)
    {
        // Leaf node: set up indices into point list
        std::random_shuffle(beginPtr, endPtr);
        for (size_t i = beginIndex; i < endIndex; ++i)
            node->bbox.extendBy(P[inds[i]]);
        node->beginIndex = beginIndex;
        node->endIndex = endIndex;
        progressFunc(endIndex - beginIndex);
        return node;
    }
    // Partition points into the 8 child nodes
    size_t* childRanges[9] = {0};
    multi_partition(beginPtr, endPtr, OctreeChildIdx(P, center), &childRanges[1], 8);
    childRanges[0] = beginPtr;
    // Recursively generate child nodes
    float h = halfWidth/2;
    for (int i = 0; i < 8; ++i)
    {
        size_t childBeginIndex = childRanges[i]   - inds;
        size_t childEndIndex   = childRanges[i+1] - inds;
        if (childEndIndex == childBeginIndex)
            continue;
        V3f c = center + V3f((i     % 2 == 0) ? -h : h,
                             ((i/2) % 2 == 0) ? -h : h,
                             ((i/4) % 2 == 0) ? -h : h);
        node->children[i] = makeTree(depth+1, inds, childBeginIndex,
                                     childEndIndex, P, c, h, progressFunc);
        node->bbox.extendBy(node->children[i]->bbox);
    }
    return node;
}
Пример #9
0
void		
AcesInputFile::readPixels (int scanLine1, int scanLine2)
{
    //
    // Copy the pixels from the RgbaInputFile into the frame buffer.
    //

    _data->rgbaFile->readPixels (scanLine1, scanLine2);

    //
    // If the RGB space of the input file is not the same as the ACES
    // RGB space, then the pixels in the frame buffer must be transformed
    // into the ACES RGB space.
    //

    if (!_data->mustConvertColor)
	return;

    int minY = min (scanLine1, scanLine2);
    int maxY = max (scanLine1, scanLine2);

    for (int y = minY; y <= maxY; ++y)
    {
	Rgba *base = _data->fbBase +
		     _data->fbXStride * _data->minX +
		     _data->fbYStride * y;

	for (int x = _data->minX; x <= _data->maxX; ++x)
	{
	    V3f aces = V3f (base->r, base->g, base->b) * _data->fileToAces;

	    base->r = aces[0];
	    base->g = aces[1];
	    base->b = aces[2];

	    base += _data->fbXStride;
	}
    }
}
Пример #10
0
MeshPlane::MeshPlane(GLfloat x, GLfloat y, GLfloat z, GLfloat x_len, GLfloat y_len, int x_tiles, int y_tiles, GLuint texid){
	MeshPlane::texid=texid;
	textured=true;
	t.push_back(V2f(0,0));
	t.push_back(V2f(0,1));
	t.push_back(V2f(1,1));
	t.push_back(V2f(1,0));
	for(int i = 0; i<=x_tiles; i++)
		for(int j = 0; j<=y_tiles; j++)
			v.push_back(V3f(i*x_len+x,y, j*y_len+z));

	for(int i = 1; i<v.size()-y_tiles-1; i++){
		if(i%(y_tiles+1)!=0){
		vi.push_back(V3i(i-1,i,i+y_tiles+1));
		ti.push_back(V3i(0,1,2));
		vi.push_back(V3i( i-1,i+y_tiles+1, i+y_tiles));
		ti.push_back(V3i(0,2,3));
		}
	}
	calcFaceNormals();
	calcVertexNormalsAverage();
	calcVertexNormalsWeight();
}
Пример #11
0
 V3f Y(){return V3f(ex.y, ey.y, ez.y);};
Пример #12
0
// Test loading of volume
TEST(MAIN, RangeBasic){
  Range one(V3f(0,0,0), V3f(1,1,1)); //start
  Range inside(V3f(0.1,0.1,0.1), V3f(0.9,0.9,0.9)); 
  Range intersecting(V3f(0.1,0.1,0.1), V3f(0.9,5,0.9)); 
  Range outside(V3f(1.1,-2,3), V3f(1.2,-1,3.8)); 

  EXPECT_TRUE(ContainsPoint(one, V3f(0.5, 0.5, 0.5)));  // Some common cases
  EXPECT_FALSE(ContainsPoint(one, V3f(1.1, 0.5, 0.5)));
  EXPECT_FALSE(ContainsPoint(one, V3f(-0.1, 0.5, 0.5)));
  EXPECT_FALSE(ContainsPoint(one, V3f(0.5, 1.1, 0.5)));
  EXPECT_FALSE(ContainsPoint(one, V3f(0.5, -0.1, 0.5)));
  EXPECT_FALSE(ContainsPoint(one, V3f(0.5, 0.5, 1.1)));
  EXPECT_FALSE(ContainsPoint(one, V3f(0.5, 0.5, -0.1)));
  EXPECT_TRUE(ContainsRange(one, inside));
  EXPECT_TRUE(IntersectsRange(one, intersecting));
  EXPECT_FALSE(ContainsRange(one, intersecting));
  EXPECT_FALSE(ContainsRange(one, outside));
};
int mapBranches (V3f pos)
{
	string sline;
	int axis,nn, ln, descend;
	//for the python section to get axis lengths
	FILE *fp;
	char line[256];
	//
	ifstream mtg; // file containg the details for bulding the Lsystem
	bool foundStart;
	char * cstr, *pch;
	int retValue=1;
	int nodenum, curBranch,nb,curOrder;
	float bx,by,bz;
	int loc;
	int branchLevel [10]; //keeps track of the branch level we are on
	for(int i=0;i<10;i++){
		branchLevel[i]=0;
	}
	foundStart=false;
	mtg.open(mtgName, ifstream::in);
		if(mtg.good()){
		Printf("all good with %s in mapBranches\n",mtgName);
	} else {
		Printf("%s NOT good in mapBranches ", mtgName);
		if(mtg.fail()){
			Printf("it failed\n");
		}
		if(mtg.eof()){
			Printf("it eof\n");
		}
		if(mtg.bad()){
			Printf("it bad\n");
		}
	}
	/*use python to create nbranches.txt which is a list of nodes for S types and the length of the axis*/
	char cmdLine[256];
	
	sprintf(cmdLine,"%s combined.py %s",PYTHON,mtgName);
	#ifdef _MSC_VER
		fp = _popen(cmdLine, "r");
	#else
		fp = popen(cmdLine, "r");
	#endif
	while ( fgets( line, sizeof line, fp))
	{
		Printf("%s", line);
  }
  #ifdef _MSC_VER
	_pclose(fp);
  #else
	pclose(fp);
  #endif
  	
	fp=fopen("nbranches.txt","r");
	while (fscanf(fp,"%i %i %i", &axis, &loc, &nn) != EOF) {
		//fprintf(stdout,"%i %i\n",axis,nn);
		nodesPerAxis[axis]=nn;
	}
	fclose(fp);

	fp=fopen("parents.txt","r");
	while (fscanf(fp,"%i %i", &nn, &axis) != EOF) {
		ParentOfNode[nn]=axis;
	}
	fclose(fp);

	fp=fopen("lastNodes.txt","r");
	while (fscanf(fp,"%i %i %i", &axis, &ln, &nb) != EOF) {
		//check=LastNodeOfAxis.find(axis)  -> second;
		//if(check==0)
			LastNodeOfAxis[axis]=ln;
	}
	fclose(fp);

	fp=fopen("branchXYZ.txt","r");
	while (fscanf(fp,"%i %i %f %f %f", &axis, &loc, &bx, &by, &bz) != EOF) {
		sxXYZ[loc]=V3f(bx+pos.x,by+pos.y,bz+pos.z);
		//Printf("%i %.2f %.2f %.2f\n",axis,bx,by,bz);
	}
	fclose(fp);
	
  /*----------------------------------*/
	while (!mtg.eof() && mtg.good() ){
		getline(mtg,sline);
		if(foundStart){
			cstr = new char [sline.size()+1];
			if(foundStart){
				strcpy (cstr, sline.c_str());
				pch = strtok (cstr,"\t");
				int ic=1;
				while (pch != NULL) {
					pch = strtok (NULL, "\t");
					if(pch!= NULL)
						if(ic==nodeN){nodenum=atoi(pch);}
						if(ic==levelN){curOrder=atoi(pch)-1;}
						ic++;
					}
				}
			if(sline.find("P1") != -1){ // start of plant
				//get the current branch node number
				// and store this so it can be used to map branches from this point
				curBranch=nodenum;
				
			}
			if(sline.find("^/N") != -1 ) {
				curBranch=branchLevel[curOrder-1];
				nb=nbranches.find(curBranch)->second;
				nb++;
				nbranches[curBranch]=nb;
//				if(curBranch==27)
//					Printf("Branch %i at %i ^/N= %i\n",nb,curBranch,nodenum);
			}
			if(sline.find("^<N") != -1 ) {
				branchLevel[curOrder]=nodenum;
			}
		} else { // !foundStart
			
			//Printf("%s\n",sline.c_str());
			if((int)sline.find("ENTITY-CODE") != -1){
				foundStart=true;
				Printf("Found start of data\n");
				//workout the column numbers for the entities
				cstr = new char [sline.size()+1];
	  		strcpy (cstr, sline.c_str());
	  		pch = strtok (cstr,"\t");
	  			
				xN=0;
				yN=0;
				zN=0;
				widthN=0;
				lenN=0;
				typeN=0;
				nodeN=0;
				levelN=0; //order
				char test[10];
				int ic=1;
	  			while (pch != NULL)
	  			{
	    			pch = strtok (NULL, "\t");
						if(pch != NULL) {
							sprintf(test,"%s",pch);
							//Printf("%s| %s: %i\n",test,pch,ic);
							if(strcmp("XX",test) ==0) {xN=ic;}
							if(strcmp("YY",test) ==0){yN=ic;}
							if(strcmp("ZZ",test) ==0){zN=ic;}
							if(strcmp("TopDia",test) ==0){widthN=ic;}
							if(strcmp("ILength",test) ==0){lenN=ic;}
							if(strcmp("NType",test) ==0){typeN=ic;}
							if(strcmp("Node",test) ==0){nodeN=ic;}
							if(strcmp("Level",test) ==0){levelN=ic;}
							ic++;
						}
	  			}
	  			Printf("Test we have all the data\n");
				if( xN==0 || yN==0 || zN==0 || widthN==0 || lenN==0 || typeN==0 || nodeN==0 || levelN==0){
					Printf("Not all of the the required features were found\n");
					Printf("%i %i %i %i %i %i %i %i \n",xN,yN,zN,widthN,lenN,typeN,nodeN, levelN);
					retValue=1;
				} else {
					Printf("Found all the bits we want\n");
					Printf("%i %i %i %i %i %i %i %i \n",xN,yN,zN,widthN,lenN,typeN,nodeN, levelN);
					retValue=0;
				}
			}
		}
		
	}
	
	Printf("Finished with ret = %i\n\n",retValue);
	mtg.close();
  return retValue;
}
Пример #14
0
int runScene(Drawable & scene){
    
    glfwInit();
    if( !glfwOpenWindow( 500, 500, 0,0,0,0, 16,0, 
			 GLFW_WINDOW ) )
      {
        glfwTerminate();
      }
    glfwSetWindowTitle( "3D" );
   
    glfwEnable( GLFW_STICKY_KEYS );
    glfwEnable( GLFW_MOUSE_CURSOR );
    glfwDisable( GLFW_AUTO_POLL_EVENTS );
  
    setupCallbacks();

    do //Main Loop.
      {
	setupProjection();

	//	stereo_state.Ping();

       	projection_state.Load();


	float zoom=2.0;
	glScalef(zoom*2.0/256.0, zoom*2.0/256.0, zoom*2.0/256.0);
	glDisable (GL_BLEND); 
	glDisable(GL_LIGHTING);
	glClear(GL_COLOR_BUFFER_BIT | 
		GL_DEPTH_BUFFER_BIT | 
		GL_STENCIL_BUFFER_BIT);

	setupModelview();

	/*   Temporary light insertion:
	 */

	navigator.Draw();
	//reference plane
	DrawPlane(V3f(0,0,0), V3f(20,0,0), V3f(0,20,0), 5);

	SetupLighting();
	scene.Draw();
	
	//Clear modified mouse state.
	mouse_state.Moved();
	
       	glfwSwapBuffers();
	if(!stereo_state.enabled){
	  glfwWaitEvents();
	}else{
	  glfwPollEvents();
	  glfwSleep(0.01); //just sleep.
	};

	navigator.idle_move();

      }
    while(!glfwGetKey( GLFW_KEY_ESC ) &&
	  glfwGetWindowParam( GLFW_OPENED ));
 

  return true;
};
Пример #15
0
 Navigator(): cur_x(0), cur_y(0), center(V3f(0,0,0)), dx(V3f(1,0,0)), dy(V3f(0,1,0)){};
Пример #16
0
 V3f Z(){return V3f(ex.z, ey.z, ez.z);};
Пример #17
0
 V3f X(){return V3f(ex.x, ey.x, ez.x);};
Пример #18
0
static void renderNode(IntegratorT& integrator, V3f P, V3f N, float cosConeAngle,
                       float sinConeAngle, float maxSolidAngle, int dataSize,
                       const PointOctree::Node* node)
{
    // This is an iterative traversal of the point hierarchy, since it's
    // slightly faster than a recursive traversal.
    //
    // The max required size for the explicit stack should be < 200, since
    // tree depth shouldn't be > 24, and we have a max of 8 children per node.
    const PointOctree::Node* nodeStack[200];
    nodeStack[0] = node;
    int stackSize = 1;
    while(stackSize > 0)
    {
        node = nodeStack[--stackSize];
        {
            // Examine node bound and cull if possible
            // TODO: Reinvestigate using (node->aggP - P) with spherical harmonics
            V3f c = node->center - P;
            if(sphereOutsideCone(c, c.length2(), node->boundRadius, N,
                                cosConeAngle, sinConeAngle))
                continue;
        }
        float r = node->aggR;
        V3f p = node->aggP - P;
        float plen2 = p.length2();
        // Examine solid angle of interior node bounding sphere to see whether we
        // can render it directly or not.
        //
        // TODO: Would be nice to use dot(node->aggN, p.normalized()) in the solid
        // angle estimation.  However, we get bad artifacts if we do this naively.
        // Perhaps with spherical harmoics it'll be better.
        float solidAngle = M_PI*r*r / plen2;
        if(solidAngle < maxSolidAngle)
        {
            integrator.setPointData(reinterpret_cast<const float*>(&node->aggCol));
            renderDisk(integrator, N, p, node->aggN, r, cosConeAngle, sinConeAngle);
        }
        else
        {
            // If we get here, the solid angle of the current node was too large
            // so we must consider the children of the node.
            //
            // The render order is sorted so that points are rendered front to
            // back.  This greatly improves the correctness of the hider.
            //
            // FIXME: The sorting procedure gets things wrong sometimes!  The
            // problem is that points may stick outside the bounds of their octree
            // nodes.  Probably we need to record all the points, sort, and
            // finally render them to get this right.
            if(node->npoints != 0)
            {
                // Leaf node: simply render each child point.
                std::pair<float, int> childOrder[8];
                assert(node->npoints <= 8);
                for(int i = 0; i < node->npoints; ++i)
                {
                    const float* data = &node->data[i*dataSize];
                    V3f p = V3f(data[0], data[1], data[2]) - P;
                    childOrder[i].first = p.length2();
                    childOrder[i].second = i;
                }
                std::sort(childOrder, childOrder + node->npoints);
                for(int i = 0; i < node->npoints; ++i)
                {
                    const float* data = &node->data[childOrder[i].second*dataSize];
                    V3f p = V3f(data[0], data[1], data[2]) - P;
                    V3f n = V3f(data[3], data[4], data[5]);
                    float r = data[6];
                    integrator.setPointData(data+7);
                    renderDisk(integrator, N, p, n, r, cosConeAngle, sinConeAngle);
                }
                continue;
            }
            else
            {
                // Interior node: render children.
                std::pair<float, const PointOctree::Node*> children[8];
                int nchildren = 0;
                for(int i = 0; i < 8; ++i)
                {
                    PointOctree::Node* child = node->children[i];
                    if(!child)
                        continue;
                    children[nchildren].first = (child->center - P).length2();
                    children[nchildren].second = child;
                    ++nchildren;
                }
                std::sort(children, children + nchildren);
                // Interior node: render each non-null child.  Nodes we want to
                // render first must go onto the stack last.
                for(int i = nchildren-1; i >= 0; --i)
                    nodeStack[stackSize++] = children[i].second;
            }
        }
    }
}
Пример #19
0
bool PointArray::loadFile(QString fileName, size_t maxPointCount)
{
    QTime loadTimer;
    loadTimer.start();
    setFileName(fileName);
    // Read file into point data fields.  Use very basic file type detection
    // based on extension.
    uint64_t totPoints = 0;
    Imath::Box3d bbox;
    V3d offset(0);
    V3d centroid(0);
    emit loadStepStarted("Reading file");
    if (fileName.endsWith(".las") || fileName.endsWith(".laz"))
    {
        if (!loadLas(fileName, maxPointCount, m_fields, offset,
                     m_npoints, totPoints, bbox, centroid))
        {
            return false;
        }
    }
    else if (fileName.endsWith(".ply"))
    {
        if (!loadPly(fileName, maxPointCount, m_fields, offset,
                     m_npoints, totPoints, bbox, centroid))
        {
            return false;
        }
    }
#if 0
    else if (fileName.endsWith(".dat"))
    {
        // Load crappy db format for debugging
        std::ifstream file(fileName.toUtf8(), std::ios::binary);
        file.seekg(0, std::ios::end);
        totPoints = file.tellg()/(4*sizeof(float));
        file.seekg(0);
        m_fields.push_back(GeomField(TypeSpec::vec3float32(), "position", totPoints));
        m_fields.push_back(GeomField(TypeSpec::float32(), "intensity", totPoints));
        float* position = m_fields[0].as<float>();
        float* intensity = m_fields[1].as<float>();
        for (size_t i = 0; i < totPoints; ++i)
        {
            file.read((char*)position, 3*sizeof(float));
            file.read((char*)intensity, 1*sizeof(float));
            bbox.extendBy(V3d(position[0], position[1], position[2]));
            position += 3;
            intensity += 1;
        }
        m_npoints = totPoints;
    }
#endif
    else
    {
        // Last resort: try loading as text
        if (!loadText(fileName, maxPointCount, m_fields, offset,
                      m_npoints, totPoints, bbox, centroid))
        {
            return false;
        }
    }
    // Search for position field
    m_positionFieldIdx = -1;
    for (size_t i = 0; i < m_fields.size(); ++i)
    {
        if (m_fields[i].name == "position" && m_fields[i].spec.count == 3)
        {
            m_positionFieldIdx = (int)i;
            break;
        }
    }
    if (m_positionFieldIdx == -1)
    {
        g_logger.error("No position field found in file %s", fileName);
        return false;
    }
    m_P = (V3f*)m_fields[m_positionFieldIdx].as<float>();
    setBoundingBox(bbox);
    setOffset(offset);
    setCentroid(centroid);
    emit loadProgress(100);
    g_logger.info("Loaded %d of %d points from file %s in %.2f seconds",
                  m_npoints, totPoints, fileName, loadTimer.elapsed()/1000.0);
    if (totPoints == 0)
    {
        m_rootNode.reset(new OctreeNode(V3f(0), 1));
        return true;
    }

    // Sort points into octree order
    emit loadStepStarted("Sorting points");
    std::unique_ptr<size_t[]> inds(new size_t[m_npoints]);
    for (size_t i = 0; i < m_npoints; ++i)
        inds[i] = i;
    // Expand the bound so that it's cubic.  Not exactly sure it's required
    // here, but cubic nodes sometimes work better the points are better
    // distributed for LoD, splitting is unbiased, etc.
    Imath::Box3f rootBound(bbox.min - offset, bbox.max - offset);
    V3f diag = rootBound.size();
    float rootRadius = std::max(std::max(diag.x, diag.y), diag.z) / 2;
    ProgressFunc progressFunc(*this);
    m_rootNode.reset(makeTree(0, &inds[0], 0, m_npoints, &m_P[0],
                              rootBound.center(), rootRadius, progressFunc));
    // Reorder point fields into octree order
    emit loadStepStarted("Reordering fields");
    for (size_t i = 0; i < m_fields.size(); ++i)
    {
        g_logger.debug("Reordering field %d: %s", i, m_fields[i]);
        reorder(m_fields[i], inds.get(), m_npoints);
        emit loadProgress(int(100*(i+1)/m_fields.size()));
    }
    m_P = (V3f*)m_fields[m_positionFieldIdx].as<float>();

    return true;
}
Пример #20
0
TEST(MAIN, DrawSphere){
  DrawSphere a(V3f(0,0,0), 10, 8);
  Scene::run(a);
};