Beispiel #1
0
void SargassoNode::updateSpace(MDataBlock& block, unsigned idx)
{
	MStatus stat;
	/* // jump to elm is slow
	MArrayDataHandle hparentspaces = block.inputArrayValue(aconstraintParentInverseMatrix, &stat);
	// if(!stat) MGlobal::displayInfo("cannot input array");
	stat = hparentspaces.jumpToElement(idx);
	//if(!stat) AHelper::Info<unsigned>("cannot jump to elm", iobject);
	MDataHandle hspace = hparentspaces.inputValue(&stat);
	// if(!stat) MGlobal::displayInfo("cannot input single");
	const MMatrix parentSpace = hspace.asMatrix();
	*/
	const unsigned itri = objectTriangleInd()[idx];
         
	Matrix33F q = m_diff->Q()[itri];
	q.orthoNormalize();
	const Vector3F t = m_mesh->triangleCenter(itri);
	Matrix44F sp(q, t);

    AHelper::ConvertToMMatrix(m_currentSpace, sp);
	// m_currentSpace *= parentSpace;
	// AHelper::PrintMatrix("parent inv", m_currentSpace);
	
	const Vector3F objectP = localP()[idx];
	m_solvedT = MPoint(objectP.x, objectP.y, objectP.z) * m_currentSpace;
         
	MTransformationMatrix mtm(m_currentSpace);
	MTransformationMatrix::RotationOrder rotorder =  MTransformationMatrix::kXYZ;
	mtm.getRotation(m_rot, rotorder);
}
Beispiel #2
0
/// This should be subclassed to actually add some physics, based on your given game. By default it will send a PT_SET_ACCELERATION message to the entity using walkingAcceleration.
void PathableProperty::GoToWaypoint(Waypoint * wp)
{
	if (wp == 0)
	{
		StopWalking();
		return;
	}
	MoveToMessage mtm(wp->position);
	owner->ProcessMessage(&mtm);
}
Beispiel #3
0
// static
void GMatrixd::homography( QVector< Vector3f > from,
	QVector< Vector3f > to, GMatrixd& output )
{
	output.resize( 3, 3 );
	GMatrixd m( 8, 9 );

	for( int i = 0; i < 4; ++i )
	{
		m(2*i,0) = from[i].x() * to[i].z();
		m(2*i,1) = from[i].y() * to[i].z();
		m(2*i,2) = from[i].z() * to[i].z();
		m(2*i,6) = -from[i].x() * to[i].x();
		m(2*i,7) = -from[i].y() * to[i].x();
		m(2*i,8) = -from[i].z() * to[i].x();

		m(2*i+1,3) = from[i].x() * to[i].z();
		m(2*i+1,4) = from[i].y() * to[i].z();
		m(2*i+1,5) = from[i].z() * to[i].z();
		m(2*i+1,6) = -from[i].x() * to[i].y();
		m(2*i+1,7) = -from[i].y() * to[i].y();
		m(2*i+1,8) = -from[i].z() * to[i].y();
	}

	QVector< QVector< double > > eigenvectors;
	QVector< double > eigenvalues;

	GMatrixd mt( 9, 8 );
	m.transpose( mt );

	GMatrixd mtm( 9, 9 );
	GMatrixd::times( mt, m, mtm );

	mtm.eigenvalueDecomposition( &eigenvectors, &eigenvalues );

	for( int i=0;i<3;i++){
		for( int j=0;j<3;j++){
			output( i, j ) = eigenvectors[0][3*i+j];
		}
	}
}
ModelTracker::Transform ModelTracker::epnp(const ModelTracker::ImgPoint imagePoints[])
	{
	/*********************************************************************
	Step 1: Calculate four control points enveloping the model points by
	running Principal Component Analysis on the set of model points.
	*********************************************************************/
	
	Point cps[4]; // The four control points
	Geometry::Matrix<Scalar,3,3> cpm; // The matrix to calculate barycentric control point weights for model points
	
	Geometry::PCACalculator<3> pca;
	for(unsigned int mpi=0;mpi<numModelPoints;++mpi)
		pca.accumulatePoint(modelPoints[mpi]);
	
	/* First control point is model point set's centroid: */
	cps[0]=Point(pca.calcCentroid());
	
	/* Next three control points are aligned with the model point set's principal axes: */
	pca.calcCovariance();
	double pcaEvals[3];
	pca.calcEigenvalues(pcaEvals);
	Vector pcaEvecs[3];
	for(int i=0;i<3;++i)
		pcaEvecs[i]=Vector(pca.calcEigenvector(pcaEvals[i]));
	if((pcaEvecs[0]^pcaEvecs[1])*pcaEvecs[2]<0.0)
		{
		// std::cout<<"World control points are left-handed!"<<std::endl;
		pcaEvecs[2]*=Scalar(-1);
		}
	for(int i=0;i<3;++i)
		for(int j=0;j<3;++j)
			cpm(i,j)=pcaEvecs[i][j];
	Transform worldToModel(Vector(cpm*(Point::origin-cps[0])),Transform::Rotation::fromMatrix(cpm));
	for(int i=0;i<3;++i)
		{
		Scalar scale=Scalar(Math::sqrt(pcaEvals[i])); // Scale principal components to the model
		cps[1+i]=cps[0]+pcaEvecs[i]*scale; // Should add a check for zero Eigenvalue here
		
		/* Calculate the inverse control point matrix directly, as it's orthogonal: */
		for(int j=0;j<3;++j)
			cpm(i,j)/=scale;
		}
	
	#if EPNP_DEBUG
	std::cout<<"Principal components: "<<Math::sqrt(pcaEvals[0])<<", "<<Math::sqrt(pcaEvals[1])<<", "<<Math::sqrt(pcaEvals[2])<<std::endl;
	std::cout<<"Control points: "<<cps[0]<<", "<<cps[1]<<", "<<cps[2]<<", "<<cps[3]<<std::endl;
	#endif
	
	/*********************************************************************
	Step 2: Calculate the linear system M^T*M.
	*********************************************************************/
	
	Math::Matrix mtm(12,12,0.0);
	const Projection::Matrix& pm=projection.getMatrix();
	Scalar fu=pm(0,0);
	Scalar sk=pm(0,1);
	Scalar uc=pm(0,2);
	Scalar fv=pm(1,1);
	Scalar vc=pm(1,2);
	for(unsigned int mpi=0;mpi<numModelPoints;++mpi)
		{
		/* Calculate the model point's control point weights: */
		Vector mpc=modelPoints[mpi]-cps[0];
		Scalar alphai[4];
		for(int i=0;i<3;++i)
			alphai[1+i]=cpm(i,0)*mpc[0]+cpm(i,1)*mpc[1]+cpm(i,2)*mpc[2];
		alphai[0]=Scalar(1)-alphai[1]-alphai[2]-alphai[3];
		
		/* Calculate the coefficients of the model point / image point association's two linear equations: */
		double eqs[2][12];
		for(int i=0;i<4;++i)
			{
			/* Equation for image point's u coordinate: */
			eqs[0][i*3+0]=alphai[i]*fu;
			eqs[0][i*3+1]=alphai[i]*sk;
			eqs[0][i*3+2]=alphai[i]*(uc-imagePoints[mpi][0]);
			
			/* Equation for image point's v coordinate: */
			eqs[1][i*3+0]=0.0;
			eqs[1][i*3+1]=alphai[i]*fv;
			eqs[1][i*3+2]=alphai[i]*(vc-imagePoints[mpi][1]);
			}
		
		/* Enter the model point / image point association's two linear equations into the least-squares matrix: */
		for(unsigned int i=0;i<12;++i)
			for(unsigned int j=0;j<12;++j)
				mtm(i,j)+=eqs[0][i]*eqs[0][j]+eqs[1][i]*eqs[1][j];
		}
	
	/*********************************************************************
	Step 3: Find four potential solutions to the pose estimation problem
	by assuming that either 1, 2, 3, or 4 Eigenvalues of the least-squares
	linear system are zero or very small, and calculate a scale-preserving
	transformation for all cases. Then pick the one that minimizes
	reprojection error.
	*********************************************************************/
	
	/* Get the full set of eigenvalues and eigenvectors of the least-squares matrix: */
	std::pair<Math::Matrix,Math::Matrix> qe=mtm.jacobiIteration();
	
	/* Find the indices of the four smallest Eigenvalues: */
	unsigned int evIndices[12];
	for(unsigned int i=0;i<12;++i)
		evIndices[i]=i;
	for(unsigned int i=0;i<4;++i)
		{
		/* Find the next-smallest Eigenvalue: */
		int minI=i;
		double minE=Math::abs(qe.second(evIndices[i],0));
		for(unsigned int j=i+1;j<12;++j)
			{
			double e=Math::abs(qe.second(evIndices[j],0));
			if(minE>e)
				{
				minI=j;
				minE=e;
				}
			}
		
		/* Move the found Eigenvalue to the front: */
		int ti=evIndices[i];
		evIndices[i]=evIndices[minI];
		evIndices[minI]=ti;
		}
	
	#if EPNP_DEBUG
	std::cout<<"MTM Eigenvalues:";
	for(unsigned int i=0;i<12;++i)
		std::cout<<' '<<qe.second(evIndices[i],0);
	std::cout<<std::endl;
	#endif
	
	/* Calculate the pairwise distances between the four control points in world space: */
	Scalar cpDists[6];
	cpDists[0]=Geometry::sqrDist(cps[0],cps[1]);
	cpDists[1]=Geometry::sqrDist(cps[0],cps[2]);
	cpDists[2]=Geometry::sqrDist(cps[0],cps[3]);
	cpDists[3]=Geometry::sqrDist(cps[1],cps[2]);
	cpDists[4]=Geometry::sqrDist(cps[1],cps[3]);
	cpDists[5]=Geometry::sqrDist(cps[2],cps[3]);
	
	/*********************************************************************
	Step 3a: Calculate the solution vector for the assumed case of one
	very small Eigenvalue:
	*********************************************************************/
	
	/* Extract the positions of the four control points in camera space from the smallest Eigenvector: */
	Point cpcs[4];
	for(unsigned int cpi=0;cpi<4;++cpi)
		for(unsigned int i=0;i<3;++i)
			cpcs[cpi][i]=Scalar(qe.first(cpi*3+i,evIndices[0]));
	
	/* Calculate the pairwise distances between the four control points in camera space: */
	Scalar cpcDists[6];
	cpcDists[0]=Geometry::sqrDist(cpcs[0],cpcs[1]);
	cpcDists[1]=Geometry::sqrDist(cpcs[0],cpcs[2]);
	cpcDists[2]=Geometry::sqrDist(cpcs[0],cpcs[3]);
	cpcDists[3]=Geometry::sqrDist(cpcs[1],cpcs[2]);
	cpcDists[4]=Geometry::sqrDist(cpcs[1],cpcs[3]);
	cpcDists[5]=Geometry::sqrDist(cpcs[2],cpcs[3]);
	
	/* Calculate the scaling factor: */
	Scalar betaCounter(0);
	Scalar betaDenominator(0);
	for(int i=0;i<6;++i)
		{
		betaCounter+=Math::sqrt(cpcDists[i]*cpDists[i]);
		betaDenominator+=cpcDists[i];
		}
	Scalar beta=-betaCounter/betaDenominator;
	#if EPNP_DEBUG
	std::cout<<"Scaling factor: "<<beta<<std::endl;
	#endif
	
	/* Recalculate the camera-space control points: */
	for(int i=0;i<4;++i)
		for(int j=0;j<3;++j)
			cpcs[i][j]*=beta;
	
	/* Check if the control point order was flipped: */
	if(((cpcs[1]-cpcs[0])^(cpcs[2]-cpcs[0]))*(cpcs[3]-cpcs[0])<0.0)
		{
		// std::cout<<"Control points got done flipped"<<std::endl;
		// cpcs[3]=cpcs[0]-(cpcs[3]-cpcs[0]);
		}
	
	#if EPNP_DEBUG
	/* Print the camera-space control points: */
	for(int i=0;i<4;++i)
		std::cout<<"CCP "<<i<<": "<<cpcs[i][0]<<", "<<cpcs[i][1]<<", "<<cpcs[i][2]<<std::endl;
	std::cout<<Math::sqrt((cpcs[1]-cpcs[0])*(cpcs[1]-cpcs[0]));
	std::cout<<' '<<(cpcs[1]-cpcs[0])*(cpcs[2]-cpcs[0]);
	std::cout<<' '<<(cpcs[1]-cpcs[0])*(cpcs[3]-cpcs[0]);
	std::cout<<' '<<Math::sqrt((cpcs[2]-cpcs[0])*(cpcs[2]-cpcs[0]));
	std::cout<<' '<<(cpcs[2]-cpcs[0])*(cpcs[3]-cpcs[0]);
	std::cout<<' '<<Math::sqrt((cpcs[3]-cpcs[0])*(cpcs[3]-cpcs[0]))<<std::endl;
	
	std::cout<<Math::sqrt((cps[1]-cps[0])*(cps[1]-cps[0]));
	std::cout<<' '<<(cps[1]-cps[0])*(cps[2]-cps[0]);
	std::cout<<' '<<(cps[1]-cps[0])*(cps[3]-cps[0]);
	std::cout<<' '<<Math::sqrt((cps[2]-cps[0])*(cps[2]-cps[0]));
	std::cout<<' '<<(cps[2]-cps[0])*(cps[3]-cps[0]);
	std::cout<<' '<<Math::sqrt((cps[3]-cps[0])*(cps[3]-cps[0]))<<std::endl;
	#endif
	
	/* Calculate the transformation from camera control point space to camera space: */
	Vector cbase[3];
	for(int i=0;i<3;++i)
		cbase[i]=cpcs[1+i]-cpcs[0];
	cbase[0].normalize();
	cbase[1]-=(cbase[0]*cbase[1])*cbase[0];
	cbase[1].normalize();
	cbase[2]-=(cbase[0]*cbase[2])*cbase[0];
	cbase[2]-=(cbase[1]*cbase[2])*cbase[1];
	cbase[2].normalize();
	Geometry::Matrix<Scalar,3,3> camera;
	for(int i=0;i<3;++i)
		for(int j=0;j<3;++j)
			camera(i,j)=cbase[j][i];
	Transform modelToCamera(cpcs[0]-Point::origin,Transform::Rotation::fromMatrix(camera));
	
	return modelToCamera*worldToModel;
	}