コード例 #1
0
ファイル: IKSolver.cpp プロジェクト: jpike/cs4496-final
///-------------------------------------------------------------
/// Calculates gradient for a given frame.
///-------------------------------------------------------------
Vecd IKSolver::CalculateGradient(int frameNum)
{
	// setup initial gradient to be zero
	// the dimensions should be equal to the number of DOFs we have
	Vecd gradient;
	gradient.SetSize(mModel->GetDofCount());
	gradient.MakeZero();

	// loop over all of our constraints, getting Jacobian and
	// combining to form final value to add to total gradient
	for (int i = 0; i < mConstraintList.size(); i++)
	{
		// get constraint
		Constraint & constraint = mConstraintList[i];
		Vec4d constraintVec(constraint.GetConstraintValue(), 1.0);

		// get Jacobian - TODO
		ConstraintJacobian jacobian(mModel, constraint);
		Matd jacobianMatrix = jacobian.CalculateJacobian();		

		// calculate current value and add to gradient
		Vecd currentValue = jacobianMatrix * constraintVec;
		gradient = gradient + currentValue;
	}

	// final computation of doubling after above calculation
	gradient = 2.0 * gradient;

	return gradient;
}
コード例 #2
0
ファイル: Solver.cpp プロジェクト: jkindle88/4496p4
void Solver::solve() {
	// Utility constants
	const int sIFreq = 20;
	const double sIF = 4.0;
	const double sDF = 2.0;
	const int eIFreq = 2;
	const double eIF = 2.0;
	// Loop over all valid frames
	for (int f = 0; f < mMaxFrames; f++)
	{
		// Build C[]
		buildConstraintMat(f);

		//Objective function value
		double o = 0.0;

		Markers &handles = mModel->mHandleList;
		for (int i = 0; i < constraintIDs.size(); i++)
		{
			// Get handle and target position for the given constraint
			Marker *h = handles[constraintIDs[i]];
			Vec3d cPos = mModel->mOpenedC3dFile->GetMarkerPos(f, constraintIDs[i]);

			// Calculate values and store
			Vec3d cVal = h->mGlobalPos - cPos;
			double cLength = sqrlen(cVal);

			//Store results
			constraintVals.push_back(cVal);
			constraintLengths.push_back(cLength);

			//Update objective function
			o += cLength; 
		}
		
		// Main loop
		double e = mEps;
		double s = mStep;
		int iterCount = 0;
		int stepCount = 0;
		while (o > e) //while Objective Function > Epsilon
		{
			// Compute gradient -- TODO: Move this somewhere else for the sake of keeping this compact!
			Vecd gradient;
			gradient.SetSize(mModel->GetDofCount());
			gradient.MakeZero();

			for (int i = 0; i < constraintIDs.size(); i++)
			{
				//Get Constraint
				Vec4d cVec(constraintVals[i], 1.0);

				//Get Jacobian
				Matd J = computeJ(mModel->mHandleList, constraintIDs[i]);

				//Calculate current and add to gradient matrix
				Vecd currentVal = J * cVec;
				gradient = gradient + currentVal;

			}

			// Finally, double it
			gradient = 2.0 * gradient;

			// Get previous DOFs
			Vecd prevDofs;
			prevDofs.SetSize(mModel->GetDofCount());
			mModel->mDofList.GetDofs(&prevDofs);

			// Update DOFs
			Vecd nextDofs = prevDofs - s * gradient;
			mModel->SetDofs(nextDofs);

			
			// Recalculate constraints and objective function
			double newO = 0.0;

			Markers &handles = mModel->mHandleList;
			for (int i = 0; i < constraintIDs.size(); i++)
			{
				// Get handle and target position for the given constraint
				Marker *h = handles[constraintIDs[i]];
				Vec3d cPos = mModel->mOpenedC3dFile->GetMarkerPos(f, constraintIDs[i]);

				// Calculate values and store
				Vec3d cVal = h->mGlobalPos - cPos;
				double cLength = sqrlen(cVal);

				//Store results
				constraintVals.push_back(cVal);
				constraintLengths.push_back(cLength);

				//Update objective function
				newO += cLength; 
			}


			// Attempting to make sure we don't go infinite...
			if (newO < o)
			{		
				if (newO > mEps && iterCount > 0 && iterCount % 20 == 0)
				{
					s *= 3.0;
				}
				o = newO;	
			}
			else
			{
				stepCount++;
				// Decrease step size
				s = s / 2.0;
				
				// based on how many times we've had to decrease the step size, choose different options
				if (stepCount < mMaxIters)
				{
					// Reset to the previous dofs and try again
					mModel->SetDofs(prevDofs);
				}
				else if (stepCount < eIFreq*mMaxIters)
				{
					// Try increasing epsilon
					e *= 3.0;

					// Reset to the previous dofs and try again
					mModel->SetDofs(prevDofs);
				}
				else
				{
					// Otherwise, halt or we will never finish
					o = 0.0;
				}
			}
			iterCount++;
		}

		// Update the frame counter
		UI->mFrameCounter_cou->value(f);

		//Refresh the screen
		UI->mGLWindow->flush();
	}	
}