Exemple #1
0
void ResourceWindow::updateCharacter( Fl_Tree_Item* tree, SmartBody::SBCharacter* character )
{
	SmartBody::SBCharacter* sbcharacter = dynamic_cast<SmartBody::SBCharacter*>(character);
	Fl_Tree_Item* item = resourceTree->add(tree,character->getName().c_str());
	item->user_data((void*) addSpecialName(character->getName()));
	resourceTree->sortorder(FL_TREE_SORT_NONE);		
	Fl_Tree_Item* skeletonFolder = resourceTree->add(item,"skeleton");	
	skeletonFolder->user_data((void*) _reverseSpecialNames["skeleton"]); 
	SmartBody::SBSkeleton* sbSk = sbcharacter->getSkeleton();
	if (sbSk)
	{
		Fl_Tree_Item* charSkItem = resourceTree->add(skeletonFolder, sbSk->getName().c_str());
	}
	Fl_Tree_Item* controllerFolder = resourceTree->add(item,"controllers");	
	controllerFolder->user_data((void*) _reverseSpecialNames["controller"]); 
	controllerFolder->close();
	// add controllers
	MeControllerTreeRoot* ctTree = character->ct_tree_p ;
	if( ctTree )
	{
		int n = ctTree->count_controllers();
		for (int c = 0; c < n; c++)
		{
			//LOG( "%s", ctTree->controller(c)->name() );
			Fl_Tree_Item* ctrlItem = resourceTree->add(controllerFolder,ctTree->controller(c)->getName().c_str());
//			ctrlItem->user_data((void*)ITEM_CONTROLLER);
		}
	}
	/*
	// add gesture map
	Fl_Tree_Item* gestureFolder = resourceTree->add(item,"gestures");	
	gestureFolder->user_data((void*)-1);
	gestureFolder->close();
	// add individual gesture mappings
	SmartBody::SBScene* scene = SmartBody::SBScene::getScene();

	SBGestureMap* gestureMap = scene->getGestureMapManager()->getGestureMap(sbcharacter->getName());
	if (gestureMap)
	{
		std::string lexeme;
		std::string type;
		std::string hand;
		std::string style;
		std::string posture;

		gestureMap->getGestureByInfo(lexeme, type, hand, style, posture);
		Fl_Tree_Item* gestureItem = resourceTree->add(gestureFolder, lexeme.c_str());
		gestureItem->user_data((void*)ITEM_GESTUREMAP);
	}
	*/

	// add NVBG
	Fl_Tree_Item* nvbgItem = resourceTree->add(item, "minibrain");
	nvbgItem->user_data((void*) _reverseSpecialNames["minibrain"]); 
	SmartBody::Nvbg* nvbg = character->getNvbg();
	if (nvbg)
	{
		nvbgItem = resourceTree->add(item, nvbg->getName().c_str());
	}
}
void SBDebuggerUtility::updateCharacter(const std::string& cName, const std::string& jName, 
										 float& posX, float& posY, float& posZ, 
										 float& rotX, float& rotY, float& rotZ, float& rotW)
{
	SmartBody::SBCharacter* sbCharacter = SmartBody::SBScene::getScene()->getCharacter(cName);
	if (!sbCharacter)
		return;

	SmartBody::SBJoint* sbJoint = sbCharacter->getSkeleton()->getJointByName(jName);
	if (sbJoint)
	{
		sbJoint->pos()->value(0, (float)posX);
		sbJoint->pos()->value(1, (float)posY);
		sbJoint->pos()->value(2, (float)posZ);
		SrQuat q = SrQuat((float)rotW, (float)rotX, (float)rotY, (float)rotZ);
		SrQuat newq = sbJoint->getPrerotation().inverse()*q;
		sbJoint->quat()->value(newq);
	}
}
Exemple #3
0
bool OgreSmartBody::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    if(mWindow->isClosed())
        return false;
 
    //Need to capture/update each device
    mKeyboard->capture();
    mMouse->capture();
 
    if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
        return false;

	// smartbody
	if (!m_pScene)
		return true;

	SmartBody::SBSimulationManager* sim = m_pScene->getSimulationManager();
	sim->setTime((Ogre::Root::getSingleton().getTimer()->getMilliseconds() / 1000.0f) - mStartTime);
	m_pScene->update();

	int numCharacters = m_pScene->getNumCharacters();
	if (numCharacters == 0)
		return true;

	const std::vector<std::string>& characterNames = m_pScene->getCharacterNames();

	for (size_t n = 0; n < characterNames.size(); n++)
	{
		SmartBody::SBCharacter* character = m_pScene->getCharacter(characterNames[n]);
		if (!this->getSceneManager()->hasEntity(characterNames[n]))
			continue;

		Ogre::Entity* entity = this->getSceneManager()->getEntity(characterNames[n]);
		Ogre::Skeleton* meshSkel = entity->getSkeleton();
		Ogre::Node* node = entity->getParentNode();

		SrVec pos = character->getPosition();
		SrQuat ori = character->getOrientation();
		//std::cout << ori.w << ori.x << " " << ori.y << " " << ori.z << std::endl;
		node->setPosition(pos.x, pos.y, pos.z);
		node->setOrientation(ori.w, ori.x, ori.y, ori.z);
	
		// Update joints
		SmartBody::SBSkeleton* sbSkel = character->getSkeleton();
			
		int numJoints = sbSkel->getNumJoints();
		for (int j = 0; j < numJoints; j++)
		{
			SmartBody::SBJoint* joint = sbSkel->getJoint(j);
	
			try
			{
				SrQuat orientation = joint->quat()->value();
	
				Ogre::Vector3 posDelta(joint->getPosition().x, joint->getPosition().y, joint->getPosition().z);
				Ogre::Quaternion quatDelta(orientation.w, orientation.x, orientation.y, orientation.z);
				Ogre::Bone* bone = meshSkel->getBone(joint->getName());
				if (!bone)
					continue;
				bone->setPosition(bone->getInitialPosition() + posDelta);
				bone->setOrientation(quatDelta);
			}
			catch (Ogre::ItemIdentityException& ex)
			{
				// Should not happen as we filtered using m_mValidBones
			}
		}
	}
	

 
    return true;
}
void PAAutoFootStepsEditor::confirmEditting(Fl_Widget* widget, void* data)
{
	PAAutoFootStepsEditor* footStepEditor = (PAAutoFootStepsEditor*) data;
	
	PABlend* currentState = footStepEditor->stateEditor->getCurrentState();
	if (!currentState)
	{	
		LOG("PAAutoFootStepsEditor::confirmEditting WARNING: please select a state!");
		return;
	}

	// take down previous correspondence points first
	footStepEditor->stateEditor->previousKeys.clear();
	footStepEditor->stateEditor->previousKeys.resize(currentState->getNumMotions());
	for (int i = 0; i < currentState->getNumMotions(); i++)
	{
		footStepEditor->stateEditor->previousKeys[i].resize(currentState->getNumKeys());
		footStepEditor->stateEditor->previousKeys[i] = currentState->keys[i];
	}

	// auto foot steps algorithm
	float floorHeight = (float)atof(footStepEditor->inputFloorHeight->value());
	float heightThresh = (float)atof(footStepEditor->inputHeightThreshold->value());
	float speedThresh = (float)atof(footStepEditor->inputSpeedThreshold->value());
	int speedWindow = atoi(footStepEditor->inputSpeedDetectWindow->value());
	int stepsPerJoint = atoi(footStepEditor->inputStepsPerJoint->value());
	if (stepsPerJoint < 1)
		stepsPerJoint = 1;
	int checkDebugInfoVal = footStepEditor->checkDebugInfo->value();
	if (checkDebugInfoVal == 0)
		footStepEditor->isPrintDebugInfo = false;
	if (checkDebugInfoVal == 1)
		footStepEditor->isPrintDebugInfo = true;

	const std::vector<std::string>& selectedMotions = footStepEditor->stateEditor->getSelectedMotions();
	SmartBody::SBCharacter* curCharacter = footStepEditor->stateEditor->paWindow->getCurrentCharacter();
	std::vector<std::string> selectedJoints;
	for (int i = 0; i < footStepEditor->browserJoint->size(); i++)
	{
		if (footStepEditor->browserJoint->selected(i+1))
		{
			selectedJoints.push_back(footStepEditor->browserJoint->text(i + 1));
		}
	}
	if (selectedJoints.size() == 0)
	{
		fl_alert("Please select at least one joint.");
		return;
	}

	std::stringstream finalMessage;
	std::vector<std::string> motionsNeedManualAdjusting;
	finalMessage << "Current State: " << currentState->stateName << "\n";

	bool isConvergent = true;
	for (size_t m = 0; m < selectedMotions.size(); m++)
	{
		// shared
		std::vector<double> possibleTiming;

		// divided
		std::vector<std::vector<double> > vecOutMeans;
		vecOutMeans.resize(selectedJoints.size());
		std::vector<std::vector<double> > vecTiming;
		vecTiming.resize(selectedJoints.size());

		SmartBody::SBMotion* motion = SmartBody::SBScene::getScene()->getMotion(selectedMotions[m]);
		if (!motion)
			continue;

#if 1 // feng : I tried to refactor the footstep detection into a API function in SBMotion. 
	  // Still contains too many parameters to be used as an API. But would clean it up more and see if we can come up with 
	  // a version that can also detect the number of steps as the input. If this is interfering with the editor, set this back to 0.	  
		std::vector<double> outMeans;
		int maxNumSteps = footStepEditor->stateEditor->getCurrentState()->getNumKeys();
		if (!footStepEditor->isProcessAll)
		{
			stepsPerJoint = maxNumSteps / selectedJoints.size();
		}
		else
		{
			maxNumSteps = stepsPerJoint * selectedJoints.size();
		}

// 		std::vector<FootStepRecord> footSteps;
// 		motion->autoFootPlantDetection(curCharacter->getSkeleton(),selectedJoints,floorHeight, heightThresh,speedThresh,footSteps);
// 
// 		for (int i=0;i<footSteps.size();i++)
// 		{
// 			FootStepRecord& record = footSteps[i];
// 			LOG("Footstep joint = %s, start frame = %f, end frame = %f",record.jointName.c_str(), record.startTime, record.endTime);
// 		}


		isConvergent = motion->autoFootStepDetection(outMeans, stepsPerJoint, maxNumSteps, curCharacter->getSkeleton(), selectedJoints,
			                          floorHeight, heightThresh, speedThresh, speedWindow, footStepEditor->isPrintDebugInfo);

#else 
		motion->connect(curCharacter->getSkeleton());

		for(int f = 0; f < motion->getNumFrames(); f++)
		{
			motion->apply_frame(f);
			motion->connected_skeleton()->update_global_matrices();

			for (size_t jointId = 0; jointId < selectedJoints.size(); jointId ++)
			{
				std::string jointName = selectedJoints[jointId];
				SBJoint* joint = curCharacter->getSkeleton()->getJointByName(jointName);
				if (!joint)
					continue;

				// get height
				const SrMat& gMat = joint->gmat();
				SrVec gPos = SrVec(gMat.get(12), gMat.get(13), gMat.get(14));

				// get speed
				int startFrame = f - speedWindow / 2;
				int endFrame = f + speedWindow / 2;
				float startTime = startFrame * (float)motion->getFrameRate();
				float endTime = endFrame * (float)motion->getFrameRate();
				float speed = motion->getJointSpeed(joint, startTime, endTime);
				
				// print info
				if (footStepEditor->isPrintDebugInfo)
					LOG("motion %s at time %f-> speed is %f, height is %f, joint is %s", motion->getName().c_str(), f * motion->getFrameRate(), speed, gPos.y, jointName.c_str());

				// filter for height
				if (gPos.y < floorHeight || gPos.y > (floorHeight + heightThresh))
					continue;

				// filter speed
				if (speed <= speedThresh)
				{
					vecTiming[jointId].push_back(f * (float)motion->getFrameRate());
					possibleTiming.push_back(f * (float)motion->getFrameRate());
				}
			}
		}

		// K means algorithm according to desired number of steps
		std::vector<double> outMeans;
		int maxNumSteps = footStepEditor->stateEditor->getCurrentState()->getNumKeys();
		if (!footStepEditor->isProcessAll)
		{
			stepsPerJoint = maxNumSteps / selectedJoints.size();
		}
		else
		{
			maxNumSteps = stepsPerJoint * selectedJoints.size();
		}

		/*
		int numSteps = footStepEditor->stateEditor->getCurrentState()->getNumKeys();
		isConvergent = footStepEditor->kMeansClustering1D(numSteps, possibleTiming, outMeans);
		*/

		for (size_t jointId = 0; jointId < selectedJoints.size(); jointId++)
		{
			if (jointId == (selectedJoints.size() - 1) && !footStepEditor->isProcessAll)
			{
				int mod = footStepEditor->stateEditor->getCurrentState()->getNumKeys() % selectedJoints.size();
				stepsPerJoint += mod;
			}

			bool retBoolean = footStepEditor->kMeansClustering1D(stepsPerJoint, vecTiming[jointId], vecOutMeans[jointId]);
			if (!retBoolean)
			{
				isConvergent = false;
				break;
			}
		}
		if (isConvergent)
		{
			outMeans.clear();
			for (size_t joinId = 0; joinId < selectedJoints.size(); joinId++)
			{
				for (size_t meanId = 0; meanId < vecOutMeans[joinId].size(); meanId++)
					outMeans.push_back(vecOutMeans[joinId][meanId]);
			}
			std::sort(outMeans.begin(), outMeans.end());
		}
#endif

		// apply it to corresponding points
		// also appending starting and ending corresponding points
		int motionIndex = currentState->getMotionId(selectedMotions[m]);
		if (isConvergent)
		{
			std::stringstream ss;
			ss << "[" << motion->getName() << "]detected ";
			for (size_t i = 0; i < outMeans.size(); i++)
				ss << outMeans[i] << " ";
			LOG("%s", ss.str().c_str());
			finalMessage << ss.str() << "\n";
			currentState->keys[motionIndex].clear();
			if (footStepEditor->isProcessAll)
				currentState->keys[motionIndex].push_back(0);
			for (size_t i = 0; i < outMeans.size(); i++)
				currentState->keys[motionIndex].push_back(outMeans[i]);
			if (footStepEditor->isProcessAll)
				currentState->keys[motionIndex].push_back(motion->getDuration());
		}
		else
		{
			motionsNeedManualAdjusting.push_back(motion->getName());
			std::stringstream ss;
			ss << "[" << motion->getName() << "]NOT detected(evenly distrubted): ";
			int actualNum = maxNumSteps;
			currentState->keys[motionIndex].clear();
			if (footStepEditor->isProcessAll)
				actualNum += 2;
			for (int i = 0; i < actualNum; i++)
			{
				double step = motion->getDuration() / double(actualNum - 1);
				currentState->keys[motionIndex].push_back(step * i);
				ss << step * i << " ";
			}
			LOG("%s", ss.str().c_str());
			finalMessage << ss.str() << "\n";
		}
		motion->disconnect();
	}

	// print out final message
	finalMessage << "\n\n=======Summary=======\n";
	for (size_t m = 0; m < motionsNeedManualAdjusting.size(); m++)
	{
		finalMessage << motionsNeedManualAdjusting[m] << " may need manual adjusting\n";
	}
	fl_message("%s", finalMessage.str().c_str());

	// refresh state editor
	footStepEditor->stateEditor->buttonUndoAutoFootSteps->activate();
	footStepEditor->stateEditor->refresh();
	footStepEditor->hide();	
}
PAAutoFootStepsEditor::PAAutoFootStepsEditor(PABlendEditor* editor, int x, int y, int w, int h) : Fl_Window(x, y, w, h)
{
	set_modal();
	stateEditor = editor;
	xDis = 10;
	yDis = 10;
	int csx = xDis;
	int csy = yDis;	
	isPrintDebugInfo = false;

	this->label("Auto Footsteps Editor");
	this->begin();
	inputFloorHeight = new Fl_Input(xDis + csx + 100, yDis, 10 * xDis, 2 * yDis, "FloorHeight");
	inputFloorHeight->value("0");
	inputHeightThreshold = new Fl_Input(xDis + csx + 100, 4 * yDis, 10 * xDis, 2 * yDis, "HeightThreshold");
	std::stringstream inputHeightSS;
	inputHeightSS << 0.15f / SmartBody::SBScene::getScene()->getScale();
	inputHeightThreshold->value(inputHeightSS.str().c_str());
	inputSpeedThreshold = new Fl_Input(xDis + csx + 100, 7 * yDis, 10 * xDis, 2 * yDis, "SpeedThreshold");
	std::stringstream inputSpeedSS;
	inputSpeedSS << 0.4f / SmartBody::SBScene::getScene()->getScale();
	inputSpeedThreshold->value(inputSpeedSS.str().c_str());

	inputSpeedDetectWindow = new Fl_Input(xDis + csx + 100, 10 * yDis, 10 * xDis, 2 * yDis, "SpeedDetectWindow");
	inputSpeedDetectWindow->value("3");
	inputSpeedDetectWindow->deactivate();
	
	browserJoint = new Fl_Multi_Browser(xDis + csx + 100, 13 * yDis, 28 * xDis, 20 * yDis, "Joint");
	SmartBody::SBCharacter* character = stateEditor->paWindow->getCurrentCharacter();
	if (character)
	{
		const std::vector<std::string>& charJNames = character->getSkeleton()->getJointNames();
		for (size_t i = 0; i < charJNames.size(); i++)
			browserJoint->add(charJNames[i].c_str());
	}

	inputStepsPerJoint = new Fl_Input(xDis + csx + 100, 36 * yDis, 10 * xDis, 2 * yDis, "StepsPerJoint");
	PABlend* curState = stateEditor->getCurrentState();
	std::vector<std::string> selectedMotions = stateEditor->getSelectedMotions();
	if (selectedMotions.size() == curState->getNumMotions())
		inputStepsPerJoint->activate();
	else
		inputStepsPerJoint->deactivate();
	int stepsPerJoint = 2;
	std::stringstream ss;
	ss << stepsPerJoint;
	inputStepsPerJoint->value(ss.str().c_str());


	browserSelectedMotions = new Fl_Browser(xDis + csx + 100, 39 * yDis, 28 * xDis, 10 * yDis, "SelectedMotions");
	browserSelectedMotions->deactivate();
	refreshSelectedMotions();

	checkDebugInfo = new Fl_Check_Button(xDis + csx + 100, 51 * yDis, 10 * xDis, 2 * yDis, "DumpDetailInformation");

	buttonConfirm = new Fl_Button(xDis + csx, 55 * yDis, 10 * xDis, 2 * yDis, "Apply");
	buttonConfirm->callback(confirmEditting, this);
	buttonCancel = new Fl_Button(xDis + csx + 120, 55 * yDis, 10 * xDis, 2 * yDis, "Leave");
	buttonCancel->callback(cancelEditting, this);
	this->end();
}