Пример #1
0
void CircleShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const
{
  int const TriangleCount = 20;
  double const etalonSector = (2.0 * math::pi) / static_cast<double>(TriangleCount);

  dp::TextureManager::ColorRegion region;
  textures->GetColorRegion(m_params.m_color, region);
  glsl::vec2 colorPoint(glsl::ToVec2(region.GetTexRect().Center()));

  buffer_vector<gpu::SolidTexturingVertex, 22> vertexes;
  vertexes.push_back(gpu::SolidTexturingVertex
  {
    glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, 0.0f),
    glsl::vec2(0.0f, 0.0f),
    colorPoint
  });

  m2::PointD startNormal(0.0f, m_params.m_radius);

  for (size_t i = 0; i < TriangleCount + 1; ++i)
  {
    m2::PointD rotatedNormal = m2::Rotate(startNormal, (i) * etalonSector);
    vertexes.push_back(gpu::SolidTexturingVertex
    {
      glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, 0.0f),
      glsl::ToVec2(rotatedNormal),
      colorPoint
    });
  }

  dp::GLState state(gpu::TEXTURING_PROGRAM, dp::GLState::OverlayLayer);
  state.SetColorTexture(region.GetTexture());

  double handleSize = 2 * m_params.m_radius;

  drape_ptr<dp::OverlayHandle> overlay = make_unique_dp<dp::SquareHandle>(m_params.m_id,
                                                                          dp::Center, m_pt,
                                                                          m2::PointD(handleSize, handleSize),
                                                                          GetOverlayPriority(), "");

  dp::AttributeProvider provider(1, TriangleCount + 2);
  provider.InitStream(0, gpu::SolidTexturingVertex::GetBindingInfo(), make_ref(vertexes.data()));
  batcher->InsertTriangleFan(state, make_ref(&provider), move(overlay));
}
Пример #2
0
void gouradFill(int s, int e, int y, Edge line1, Edge line2, int oct, int plane, Surface ob, Point view, float* buffer) {
    Vector3 tempcolor(1,1,1);
    Vector3 inten_left, inten_right, i1, i2, color;
    float y1, y2, x1, x2;
    int start, end;

    if (s > e) {
        start = e;
        end = s;
        if (plane == XY)
        {
            y1 = flatlist[oct].pl[line2.p1 - 1].y;
            y2 = flatlist[oct].pl[line2.p2 - 1].y;
        }
        else if (plane == XZ)
        {
            y1 = flatlist[oct].pl[line2.p1 - 1].z;
            y2 = flatlist[oct].pl[line2.p2 - 1].z;
        }
        else if (plane == YZ)
        {
            y1 = flatlist[oct].pl[line2.p1 - 1].z;
            y2 = flatlist[oct].pl[line2.p2 - 1].z;
        }
        i1 = flatlist[oct].pl[line2.p1 - 1].ip;
        i2 = flatlist[oct].pl[line2.p2 - 1].ip;
        inten_left = i1 * ((y - y2) / (y1 - y2)) + i2 * ((y - y1) / (y2 - y1));
        //if (oct == 1) cout << i1 << " " << i2 << " ";

        if (plane == XY)
        {
            y1 = flatlist[oct].pl[line1.p1 - 1].y;
            y2 = flatlist[oct].pl[line1.p2 - 1].y;
        }
        else if (plane == XZ)
        {
            y1 = flatlist[oct].pl[line1.p1 - 1].z;
            y2 = flatlist[oct].pl[line1.p2 - 1].z;
        }
        else if (plane == YZ)
        {
            y1 = flatlist[oct].pl[line1.p1 - 1].z;
            y2 = flatlist[oct].pl[line1.p2 - 1].z;
        }
        i1 = flatlist[oct].pl[line1.p1 - 1].ip;
        i2 = flatlist[oct].pl[line1.p2 - 1].ip;
        inten_right = i1 * ((y - y2) / (y1 - y2)) + i2 * ((y - y1) / (y2 - y1));
    }
    else {
        start = s;
        end = e;
        if (plane == XY)
        {
            y1 = flatlist[oct].pl[line1.p1 - 1].y;
            y2 = flatlist[oct].pl[line1.p2 - 1].y;
        }
        else if (plane == XZ)
        {
            y1 = flatlist[oct].pl[line1.p1 - 1].z;
            y2 = flatlist[oct].pl[line1.p2 - 1].z;
        }
        else if (plane == YZ)
        {
            y1 = flatlist[oct].pl[line1.p1 - 1].z;
            y2 = flatlist[oct].pl[line1.p2 - 1].z;
        }
        i1 = flatlist[oct].pl[line1.p1 - 1].ip;
        i2 = flatlist[oct].pl[line1.p2 - 1].ip;
        inten_left = i1 * ((y - y2) / (y1 - y2)) + i2 * ((y - y1) / (y2 - y1));
        
        if (plane == XY)
        {
            y1 = flatlist[oct].pl[line2.p1 - 1].y;
            y2 = flatlist[oct].pl[line2.p2 - 1].y;
        }
        else if (plane == XZ)
        {
            y1 = flatlist[oct].pl[line2.p1 - 1].z;
            y2 = flatlist[oct].pl[line2.p2 - 1].z;
        }
        else if (plane == YZ)
        {
            y1 = flatlist[oct].pl[line2.p1 - 1].z;
            y2 = flatlist[oct].pl[line2.p2 - 1].z;
        }
        i1 = flatlist[oct].pl[line2.p1 - 1].ip;
        i2 = flatlist[oct].pl[line2.p2 - 1].ip;
        inten_right = i1 * ((y - y2) / (y1 - y2)) + i2 * ((y - y1) / (y2 - y1));
    }
    
    float ndotv, ndotl;
    Vector3 normal(ob.normx, ob.normy, ob.normz);
    Vector3 p_v(0,0,0);
    Vector3 v_v;
    Vector3 l_v;
    
    for (int x = start; x < end; x++)
    {
        x1 = start;
        x2 = end;
        color = inten_left *  ((x - x2) / (x1 - x2)) +
        inten_right * ((x - x1) / (x2 - x1));
        if ((ndotl > 0 && ndotv > 0) || (ndotl < 0 && ndotv < 0)) {
            colorPoint(x, y, color, buffer);
        }
        else {
            colorPoint(x, y, color, buffer);
        }
    }
}
Пример #3
0
void downloadCalibration(unsigned int index)
	{
	/* Open a Kinect camera: */
	Kinect::Camera camera(usbContext,index);
	std::cout<<"Downloading factory calibration data for Kinect "<<camera.getSerialNumber()<<"..."<<std::endl;
	
	/* Retrieve the factory calibration data: */
	Kinect::Camera::CalibrationParameters cal;
	camera.getCalibrationParameters(cal);
	
	/* Calculate the depth-to-distance conversion formula: */
	double numerator=10.0*(4.0*cal.dcmosEmitterDist*cal.referenceDistance)/cal.referencePixelSize;
	double denominator=4.0*cal.dcmosEmitterDist/cal.referencePixelSize+4.0*cal.constantShift+1.5;
	std::cout<<"Depth conversion formula: dist[mm] = "<<numerator<<" / ("<<denominator<<" - depth)"<<std::endl;
	
	/* Calculate the depth pixel unprojection matrix: */
	double scale=2.0*cal.referencePixelSize/cal.referenceDistance;
	Math::Matrix depthMatrix(4,4,0.0);
	depthMatrix(0,0)=scale;
	depthMatrix(0,3)=-scale*640.0/2.0;
	depthMatrix(1,1)=scale;
	depthMatrix(1,3)=-scale*480.0/2.0;
	depthMatrix(2,3)=-1.0;
	depthMatrix(3,2)=-1.0/numerator;
	depthMatrix(3,3)=denominator/numerator;
	
	{
	std::cout<<std::endl<<"Depth unprojection matrix:"<<std::endl;
	std::streamsize oldPrec=std::cout.precision(8);
	std::cout.setf(std::ios::fixed);
	for(int i=0;i<4;++i)
		{
		std::cout<<"    ";
		for(int j=0;j<4;++j)
			std::cout<<' '<<std::setw(11)<<depthMatrix(i,j);
		std::cout<<std::endl;
		}
	std::cout.unsetf(std::ios::fixed);
	std::cout.precision(oldPrec);
	}
	
	/* Calculate the depth-to-color mapping: */
	double colorShiftA=cal.dcmosRcmosDist/(cal.referencePixelSize*2.0)+0.375;
	double colorShiftB=cal.dcmosRcmosDist*cal.referenceDistance*10.0/(cal.referencePixelSize*2.0);
	std::cout<<"Depth-to-color pixel shift formula: Shift = "<<colorShiftA<<" - "<<colorShiftB<<"/dist[mm]"<<std::endl;
	
	/* Formula to go directly from depth to displacement: */
	double dispA=colorShiftA-colorShiftB*denominator/numerator;
	double dispB=colorShiftB/numerator;
	std::cout<<"Or: Shift = "<<dispA<<" + "<<dispB<<"*depth"<<std::endl;
	
	/* Tabulate the bivariate pixel mapping polynomial using forward differencing: */
	double* colorx=new double[640*480];
	double* colory=new double[640*480];
	double ax=cal.ax;
	double bx=cal.bx;
	double cx=cal.cx;
	double dx=cal.dx;
	
	double ay=cal.ay;
	double by=cal.by;
	double cy=cal.cy;
	double dy=cal.dy;
	
	double dx0=(cal.dxStart<<13)>>4;
	double dy0=(cal.dyStart<<13)>>4;
	
	double dxdx0=(cal.dxdxStart<<11)>>3;
	double dxdy0=(cal.dxdyStart<<11)>>3;
	double dydx0=(cal.dydxStart<<11)>>3;
	double dydy0=(cal.dydyStart<<11)>>3;
	
	double dxdxdx0=(cal.dxdxdxStart<<5)<<3;
	double dydxdx0=(cal.dydxdxStart<<5)<<3;
	double dxdxdy0=(cal.dxdxdyStart<<5)<<3;
	double dydxdy0=(cal.dydxdyStart<<5)<<3;
	double dydydx0=(cal.dydydxStart<<5)<<3;
	double dydydy0=(cal.dydydyStart<<5)<<3;
	
	for(int y=0;y<480;++y)
		{
		dxdxdx0+=cx;
		dxdx0  +=dydxdx0/256.0;
		dydxdx0+=dx;
		
		dx0    +=dydx0/64.0;
		dydx0  +=dydydx0/256.0;
		dydydx0+=bx;
		
		dxdxdy0+=cy;
		
		dxdy0  +=dydxdy0/256.0;
		dydxdy0+=dy;
		
		dy0    +=dydy0/64.0;
		dydy0  +=dydydy0/256.0;
		dydydy0+=by;
		
		double coldxdxdy=dxdxdy0;
		double coldxdy=dxdy0;
		double coldy=dy0;
		
		double coldxdxdx=dxdxdx0;
		double coldxdx=dxdx0;
		double coldx=dx0;
		
		for(int x=0;x<640;++x)
			{
			colorx[y*640+x]=double(x)+coldx/131072.0+1.0;
			colory[y*640+x]=double(y)+coldy/131072.0+1.0;
			
			#if 0
			if(x%40==20&&y%40==20)
				std::cout<<x<<", "<<y<<": "<<colorx[y*640+x]<<", "<<colory[y*640+x]<<std::endl;
			#endif
			
			coldx+=coldxdx/64.0;
			coldxdx+=coldxdxdx/256.0;
			coldxdxdx+=ax;
			
			coldy+=coldxdy/64.0;
			coldxdy+=coldxdxdy/256.0;
			coldxdxdy+=ay;
			}
		}
	
	/* Calculate the texture projection matrix by sampling the pixel mapping polynomial: */
	int minDepth=Math::ceil(denominator-numerator/500.0); // 500mm is minimum viewing distance
	int maxDepth=Math::ceil(denominator-numerator/3000.0); // 3000mm is maximum reasonable viewing distance
	std::cout<<"Calculating best-fit color projection matrix for depth value range "<<minDepth<<" - "<<maxDepth<<"..."<<std::endl;
	
	Math::Matrix colorSystem(12,12,0.0);
	Math::Matrix depthPoint(4,1,0.0);
	depthPoint(3)=1.0;
	for(int y=20;y<480;y+=40)
		{
		depthPoint(1)=(double(y)+0.5)/480.0;
		for(int x=20;x<640;x+=40)
			{
			depthPoint(0)=(double(x)+0.5)/640.0;
			for(int depth=minDepth;depth<=maxDepth;depth+=20)
				{
				/* Transform the depth point to color image space using the non-linear transformation: */
				// int xdisp=x+Math::floor(dispA+dispB*double(depth)+0.5);
				// if(xdisp>=0&&xdisp<640)
					{
					// double colX=double(xdisp)/640.0;
					// double colY=double(y)/480.0;
					// double colX=colorx[(479-y)*640+xdisp]/640.0;
					// double colY=(479.0-colory[(479-y)*640+xdisp])/480.0;
					double colX=(colorx[(479-y)*640+x]+dispA+dispB*double(depth))/640.0;
					double colY=(479.0-colory[(479-y)*640+x])/480.0;
					
					/* Calculate the 3D point based on the depth unprojection matrix: */
					depthPoint(2)=double(depth)/double(maxDepth);
					Math::Matrix worldPoint=depthMatrix*depthPoint;
					
					/* Make the world point affine: */
					for(int i=0;i<3;++i)
						worldPoint(i)/=worldPoint(3);
					
					/* Enter the world point / color point pair into the color projection system: */
					double eq[2][12];
					eq[0][0]=depthPoint(0);
					eq[0][1]=depthPoint(1);
					eq[0][2]=depthPoint(2);
					eq[0][3]=1.0;
					eq[0][4]=0.0;
					eq[0][5]=0.0;
					eq[0][6]=0.0;
					eq[0][7]=0.0;
					eq[0][8]=-colX*depthPoint(0);
					eq[0][9]=-colX*depthPoint(1);
					eq[0][10]=-colX*depthPoint(2);
					eq[0][11]=-colX;

					eq[1][0]=0.0;
					eq[1][1]=0.0;
					eq[1][2]=0.0;
					eq[1][3]=0.0;
					eq[1][4]=depthPoint(0);
					eq[1][5]=depthPoint(1);
					eq[1][6]=depthPoint(2);
					eq[1][7]=1.0;
					eq[1][8]=-colY*depthPoint(0);
					eq[1][9]=-colY*depthPoint(1);
					eq[1][10]=-colY*depthPoint(2);
					eq[1][11]=-colY;
					
					for(int row=0;row<2;++row)
						for(unsigned int i=0;i<12;++i)
							for(unsigned int j=0;j<12;++j)
								colorSystem(i,j)+=eq[row][i]*eq[row][j];
					}
				}
			}
		}
	
	/* Find the linear system's smallest eigenvalue: */
	std::pair<Math::Matrix,Math::Matrix> qe=colorSystem.jacobiIteration();
	unsigned int minEIndex=0;
	double minE=Math::abs(qe.second(0,0));
	for(unsigned int i=1;i<12;++i)
		{
		if(minE>Math::abs(qe.second(i,0)))
			{
			minEIndex=i;
			minE=Math::abs(qe.second(i,0));
			}
		}
	std::cout<<"Smallest eigenvalue of color system = "<<minE<<std::endl;
	
	/* Create the normalized homography and extend it to a 4x4 matrix: */
	Math::Matrix colorMatrix(4,4);
	double cmScale=qe.first(11,minEIndex);
	for(int i=0;i<2;++i)
		for(int j=0;j<4;++j)
			colorMatrix(i,j)=qe.first(i*4+j,minEIndex)/cmScale;
	for(int j=0;j<4;++j)
		colorMatrix(2,j)=j==2?1.0:0.0;
	for(int j=0;j<4;++j)
		colorMatrix(3,j)=qe.first(2*4+j,minEIndex)/cmScale;
	
	/* Un-normalize the color matrix: */
	for(int i=0;i<4;++i)
		{
		colorMatrix(i,0)/=640.0;
		colorMatrix(i,1)/=480.0;
		colorMatrix(i,2)/=double(maxDepth);
		}
	
	/* Calculate the approximation error: */
	double rms=0.0;
	unsigned int numPoints=0;
	depthPoint(3)=1.0;
	for(int y=20;y<480;y+=40)
		{
		depthPoint(1)=double(y)+0.5;
		for(int x=20;x<640;x+=40)
			{
			depthPoint(0)=double(x)+0.5;
			for(int depth=minDepth;depth<=maxDepth;depth+=20)
				{
				/* Transform the depth point to color image space using the non-linear transformation: */
				// int xdisp=x+Math::floor(dispA+dispB*double(depth)+0.5);
				// if(xdisp>=0&&xdisp<640)
					{
					// double colX=double(xdisp)/640.0;
					// double colY=double(y)/480.0;
					// double colX=colorx[y*640+xdisp]/640.0;
					// double colY=(colory[y*640+xdisp]-50.0)/480.0;
					double colX=(colorx[y*640+x]+dispA+dispB*double(depth))/640.0;
					double colY=(colory[y*640+x]-0.0)/480.0;
					
					/* Transform the depth image point to color space using the color matrix: */
					depthPoint(2)=double(depth);
					Math::Matrix colorPoint=colorMatrix*depthPoint;
					
					/* Calculate the approximation error: */
					double dist=Math::sqr(colorPoint(0)/colorPoint(3)-colX)+Math::sqr(colorPoint(1)/colorPoint(3)-colY);
					rms+=dist;
					++numPoints;
					}
				}
			}
		}
	
	/* Print the RMS: */
	std::cout<<"Color matrix approximation RMS = "<<Math::sqrt(rms/double(numPoints))<<std::endl;
	
	/* Make the color matrix compatible with Kinect::Projector's way of doing things: */
	// colorMatrix*=depthMatrix;
	
	{
	std::cout<<"Optimal homography from world space to color image space:"<<std::endl;
	std::streamsize oldPrec=std::cout.precision(8);
	std::cout.setf(std::ios::fixed);
	for(int i=0;i<4;++i)
		{
		std::cout<<"    ";
		for(int j=0;j<4;++j)
			std::cout<<' '<<std::setw(11)<<colorMatrix(i,j);
		std::cout<<std::endl;
		}
	std::cout.unsetf(std::ios::fixed);
	std::cout.precision(oldPrec);
	}
	
	delete[] colorx;
	delete[] colory;
	
	/* Convert the depth matrix from mm to cm: */
	Math::Matrix scaleMatrix(4,4,1.0);
	for(int i=0;i<3;++i)
		scaleMatrix(i,i)=0.1;
	depthMatrix=scaleMatrix*depthMatrix;
	
	/* Write the depth and color matrices to an intrinsic parameter file: */
	std::string calibFileName=KINECT_CONFIG_DIR;
	calibFileName.push_back('/');
	calibFileName.append(KINECT_CAMERA_INTRINSICPARAMETERSFILENAMEPREFIX);
	calibFileName.push_back('-');
	calibFileName.append(camera.getSerialNumber());
	calibFileName.append(".dat");
	if(!Misc::doesPathExist(calibFileName.c_str()))
		{
		std::cout<<"Writing full intrinsic camera parameters to "<<calibFileName<<std::endl;
		
		IO::FilePtr calibFile=IO::openFile(calibFileName.c_str(),IO::File::WriteOnly);
		calibFile->setEndianness(Misc::LittleEndian);
		for(int i=0;i<4;++i)
			for(int j=0;j<4;++j)
				calibFile->write<double>(depthMatrix(i,j));
		for(int i=0;i<4;++i)
			for(int j=0;j<4;++j)
				calibFile->write<double>(colorMatrix(i,j));
		}
	else
		std::cout<<"Intrinsic camera parameter file "<<calibFileName<<" already exists"<<std::endl;
	}