示例#1
0
void MiniBrain::update(SBCharacter* character, double time, double dt)
{
	
	if (minibrainCounter < 300)
	{
		minibrainCounter ++;
		return;
	}
	SrVec myVelocity;
	SrVec myPosition;
	float mySpeed = 0.0f;
	SrVec myFacing(0, 0, 1);
	// determine the facing vector
	SkJoint* base = character->getSkeleton()->search_joint("base");
	if (base)
	{
		SkJointQuat* jointQuat = base->quat();
		const SrQuat& quat = jointQuat->orientation();
		SrVec zfacing(0, 0, 1);
		myFacing = zfacing * quat;
	}
	const std::vector<std::string>& pawns = SmartBody::SBScene::getScene()->getPawnNames();
	for (std::vector<std::string>::const_iterator pawnIter = pawns.begin();
		pawnIter != pawns.end();
		pawnIter++)
	{
		SBPawn* pawn = SmartBody::SBScene::getScene()->getPawn((*pawnIter));

		// determine the velocity of the object
		std::map<std::string, ObjectData>::iterator piter = _data.find(pawn->getName());
		if (piter != _data.end())
		{
			ObjectData& data = (*piter).second;
			// get the last position
			SrVec& lastPosition = data.position;
			// get the current position
			SmartBody::SBCharacter* curCharacter = dynamic_cast<SmartBody::SBCharacter*>(pawn);
			SrVec curPosition;
			if (curCharacter)
			{
				curPosition = curCharacter->getPosition();
				data.isAnimate = true;
			}
			else
			{
				float x, y, z, h, p, r;
				pawn->get_world_offset(x, y, z, h, p, r);
				curPosition.x = x;
				curPosition.y = y;
				curPosition.z = z;
				data.isAnimate = false;
			}
			
			data.velocity = (curPosition - data.position) / (float) dt;
			if ((int)data.cachePositions.size() > _cacheLimit)
				data.cachePositions.pop_front();
			data.cachePositions.push_back(curPosition);
			SrVec temp;
			for (	std::list<SrVec>::iterator iter = data.cachePositions.begin();
					iter != data.cachePositions.end();
					iter++)
			{
				temp += (*iter);
			}
			data.position = temp / float(data.cachePositions.size());

			//data.position = curPosition;
			if (curCharacter && curCharacter == character)
			{
				myVelocity = data.velocity;
				myPosition = data.position;
				mySpeed = myVelocity.len();
			}
		}
		else
		{
			// seed the object data with position, no velocity
			ObjectData data;
			// get the current position
			SmartBody::SBCharacter* curCharacter = dynamic_cast<SmartBody::SBCharacter*>(pawn);
			SrVec curPosition;
			if (curCharacter)
			{
				curPosition = curCharacter->getPosition();
			}
			else
			{
				float x, y, z, h, p, r;
				pawn->get_world_offset(x, y, z, h, p, r);
				curPosition.x = x;
				curPosition.y = y;
				curPosition.z = z;
			}
			data.velocity = SrVec();
			data.position = curPosition;
			if ((int)data.cachePositions.size() > _cacheLimit)
				data.cachePositions.pop_front();
			data.cachePositions.push_back(curPosition);
			data.startGazeTime = -1;
			_data.insert(std::pair<std::string, ObjectData>(pawn->getName(), data));
		}
	}

	std::string fastestObject = "";
	float fastest = -1;
	ObjectData* fastestData = NULL;
	for (std::map<std::string, ObjectData>::iterator piter = _data.begin();
		 piter != _data.end();
		 piter++)
	{
		std::string pawnName = (*piter).first;
		if (pawnName == character->getName())
			continue;
		// calculate the relative positon and relative velocity
		ObjectData& data = (*piter).second;
		data.relativePosition = myPosition - data.position;
		data.relativeVelocity = myVelocity - data.velocity;
		float size = data.relativeVelocity.len();
		// ignore objects that aren't moving faster than you are
		if (size <= mySpeed)
			continue;
		if (size > fastest)
		{
			// ignore activity that is happening behind the character
			SrVec diffVec = data.position - myPosition;
			float result = dot(myFacing, diffVec);
			if (result < 0.0f)
				continue;
			fastestObject = pawnName;
			fastest = size;
			fastestData = &data;
		}
	}
	
	Nvbg* nvbg = character->getNvbg();
	if (nvbg) // if an NVBG instance is running, send this information there
	{
		for (std::map<std::string, ObjectData>::iterator piter = _data.begin();
			 piter != _data.end();
			 piter++)
		{
			const std::string& pawnName = (*piter).first;
			ObjectData& data = (*piter).second;
			nvbg->objectEvent(character->getName(), pawnName, data.isAnimate, myPosition, myVelocity, data.position, data.velocity, data.relativePosition, data.relativeVelocity);
		}
	}
	else // simple functionality - look at things that move quickly
	{
		

		// now look at the fastest thing moving that exceeds a threshold
		float characterHeight = character->getHeight();
		if (fastest > characterHeight / 10.0)
		{
			SbmPawn* gazeTarget =  SmartBody::SBScene::getScene()->getPawn(fastestObject);
			if (!gazeTarget)
				return;

			// make sure that we aren't already gazing at this object
			MeCtScheduler2* gazeSchedule = character->gaze_sched_p;
			if (!gazeSchedule)
				return;
			MeCtScheduler2::VecOfTrack tracks = gazeSchedule->tracks();
			for (size_t t = 0; t < tracks.size(); t++)
			{
				MeController* controller = tracks[t]->animation_ct();
				MeCtGaze* gaze = dynamic_cast<MeCtGaze*>(controller);
				if (gaze)
				{
					float x, y, z;
					SkJoint* joint = gaze->get_target_joint(x, y, z);
					if (joint && joint->skeleton() == gazeTarget->getSkeleton())
					{
						// update the time
						fastestData->startGazeTime = time;
						return;
					}
				}
			}
			std::stringstream strstr;
			strstr << "bml char " << character->getName() << " <gaze target=\"" << fastestObject << "\" sbm:joint-range=\"EYES NECK\"/>" << std::endl;
			fastestData->startGazeTime = time;
			SmartBody::SBScene::getScene()->getCommandManager()->execute((char*) strstr.str().c_str());
			return;
		}

		// if we are staring at nothing, fade out any gazes for objects that have been 'uninteresting' for more than 2 seconds
		for (std::map<std::string, ObjectData>::iterator piter = _data.begin();
			 piter != _data.end();
			 piter++)
		{
			ObjectData& data = (*piter).second;
			if (data.startGazeTime > 0 && (time - data.startGazeTime) > 2.0 + float(rand() % 100) * .01f)
			{
				std::stringstream strstr;
				strstr << "char " << character->getName() << " gazefade out .5" << std::endl;
				data.startGazeTime = -1;
				SmartBody::SBScene::getScene()->getCommandManager()->execute((char*) strstr.str().c_str());

				std::stringstream strstr2;
				strstr2 << "char " << character->getName() << " prune" << std::endl;
				SmartBody::SBScene::getScene()->getCommandManager()->execute_later((char*) strstr2.str().c_str(), 3 + float(rand() % 100) * .01f);


			}
		}
	}

	
}
示例#2
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;
}