/** modifies gesture appearancy according to POWER settings, move first key pose, changes hold durations
 *param _motionSegments key poses of the sequence 
 *param _nucleusStart first pose of the nucleus at this position
 **/
void GestureModifier::applyPower(vector<MotionSegment *> & _motionSegments, unsigned int _nucleusStart)
{
  float power = _motionSegments[_nucleusStart]->getGestureModifier()->getPointee()->getPower();
  if (power == 0) return;
  if (power > 0 )
  { 
    unsigned int holdTime = static_cast<unsigned int> ( 300 * floor(power));
    unsigned int stopTime = _motionSegments[_nucleusStart]->getAbsoluteStopTime();
    _motionSegments[_nucleusStart]->setHoldDuration(_motionSegments[_nucleusStart]->getHoldDuration() + holdTime);
    if (_motionSegments.size() > (_nucleusStart +1) ) 
    {
      unsigned int nextStopTime = _motionSegments[_nucleusStart + 1]->getAbsoluteStopTime();
      unsigned int nextHoldTime = _motionSegments[_nucleusStart + 1]->getHoldDuration();
      
      if ((nextStopTime-nextHoldTime) < (stopTime + holdTime))    
      {
        if (nextHoldTime >0 )
        {  
          nextHoldTime -= holdTime;
          if (nextHoldTime >= 0)
          {
            _motionSegments[_nucleusStart + 1]->setHoldDuration(nextHoldTime);
            _motionSegments[_nucleusStart]->setAbsoluteStopTime(stopTime + holdTime);
            
          }else
          {
            _motionSegments[_nucleusStart + 1]->setAbsoluteStopTime(nextStopTime - nextHoldTime +100);
            _motionSegments[_nucleusStart + 1]->setHoldDuration(0);
          }
        }else
        {
           _motionSegments[_nucleusStart + 1]->setAbsoluteStopTime(stopTime + holdTime);
           _motionSegments[_nucleusStart]->setAbsoluteStopTime(nextStopTime);
        }
      }else
        _motionSegments[_nucleusStart]->setAbsoluteStopTime(stopTime + holdTime);
    }else 
      _motionSegments[_nucleusStart]->setAbsoluteStopTime(stopTime + holdTime);   
    SMRIKConstraint* constraintPtr = static_cast<ActuatorHybridIKSlerp*>(((_motionSegments[_nucleusStart]->getActuator(0))))->getConstraintPtr(0);
    SMRVector3 currentKeyPoint = constraintPtr->getPosition();
    SMRVector3 nextKeyPoint = (static_cast<ActuatorHybridIKSlerp*>((_motionSegments[_nucleusStart+1])->getActuator(0)))->getConstraintPtr(0)->getPosition();
    constraintPtr->setPosition(currentKeyPoint +((currentKeyPoint - nextKeyPoint).normalize() * (0.1f * power )));
  }else
  {
    unsigned int holdTime = _motionSegments[_nucleusStart]->getHoldDuration();
    if (holdTime > 0 ) 
    {
      unsigned int newHoldTime = static_cast<unsigned int> (max(0.0f,holdTime + (power * holdTime)));
      _motionSegments[_nucleusStart]->setHoldDuration(newHoldTime);
      _motionSegments[_nucleusStart]->setAbsoluteStopTime(_motionSegments[_nucleusStart]->getAbsoluteStopTime() - (holdTime -newHoldTime ));
    }
  }
}
Exemple #2
0
void Tutorial02::onUpdate()
{
  float tx,ty,tz;
  m_flyNode.getPosition(&tx,&ty,&tz);
  
  //roughly simulates the random fly of a fly
  if((rand()%100)>95)
  {
    m_dx=((SMRUtils::ranf()))/50.0f;
    m_dy=((SMRUtils::ranf()))/50.0f;
    m_dz=((SMRUtils::ranf()))/50.0f;
  }
  //change fly position
  m_flyNode.setPosition(tx+m_dx,ty+m_dy,tz+m_dz);
  if(tx<-2.0) m_dx=0.05f;
  if(tx>2.0) m_dx=-0.05f;
  if(ty<2.0) m_dy=0.05f;
  if(ty>4.0) m_dy=-0.05f;
  if(tz<-2.0) m_dz=0.05f;
  if(tz>2.0) m_dz=-0.05f;

  m_flyNode.getPosition(&tx,&ty,&tz);

  //update constraint position according to fly position
  m_ikConstraint->setPosition(SMRVector3(tx,ty,tz));

  //compute inverse kinematics
  m_ikSolver->process();

  //update visual representations
  m_bones.update();
}
void ActuatorHybridIKSlerp::setTarget(const char* _jointTarget, const char* _jointName, const SMRVector3 &_offset, const SMRVector3 &_rotationOffset)
{
  SMRIKConstraint *constraint = new SMRIKConstraint();  // use a factory later on
  constraint->setJointTarget(_jointTarget, _rotationOffset);
  constraint->setOffset(_offset);
  constraint->setRelatedJointName(_jointName);
  m_constraints.push_back(constraint);
  //if related joint is the last one, enable analitical solver
  if (string(_jointName) == (m_kinematicChain->getJoint(m_kinematicChain->getNumJoints()-1))->getName() && m_kinematicChain->getName().find("arm") != string::npos  ) // hack to limit IK to arms
  {
    m_analyticalIKSolver.addConstraintPtr(constraint);
    m_perfomAnalyticalIK = true;
  }
  m_iterativeIKSolver.addConstraintPtr(constraint);

  //computeTargetPose();
}
void ActuatorHybridIKSlerp::setTarget(const SMRVector3 &target, const char* _jointName, const SMRVector3 &_offset)
{
  SMRIKConstraint *constraint = new SMRIKConstraint();  // use a factory later on
  constraint->setPosition(target);
  constraint->setOffset(_offset);
  constraint->setRelatedJointName(_jointName);
  m_constraints.push_back(constraint);

  if (string(_jointName) == (m_kinematicChain->getJoint(m_kinematicChain->getNumJoints()-1))->getName() )
  {
    m_analyticalIKSolver.addConstraintPtr(constraint);
    m_perfomAnalyticalIK = true;
  }
  m_iterativeIKSolver.addConstraintPtr(constraint);

  //computeTargetPose();
}
/* extents spatial dimension by scaling the motion bounding box
*/
void GestureModifier::spatialExtent(vector<MotionSegment *> & _motionSegments, const SMRVector3 & _lowerBoxBound, const SMRVector3 & _higherBoxBound)
{
  if (m_v_s == 0.0) return; // no spatial extent to apply, return
  vector<MotionSegment *>::iterator motionSegIt = _motionSegments.begin();
  while ( motionSegIt < _motionSegments.end() && (*motionSegIt)->getGestureModifier() == NULL )
  {
    motionSegIt++;
  }
  if ( motionSegIt == _motionSegments.end())
    return; //no nucleus assigned to this gesture
 
  //first key pose:
  SMRIKConstraint* constraintPtr = (static_cast<ActuatorHybridIKSlerp*>((*motionSegIt)->getActuator(0)))->getConstraintPtr(0);  
  SMRVector3 currentKeyPoint = constraintPtr->getPosition();
  motionSegIt++;
  if ( motionSegIt == _motionSegments.end()  || (*motionSegIt)->getGestureModifier() == NULL )
  {
    //only one pose in the nucleus
    ((*motionSegIt)->getGestureModifier())->getPointee()->spatialExtent(currentKeyPoint);
    constraintPtr->setPosition(currentKeyPoint);
    return;
  }
  SMRVector3 boundingBoxCenter =  (_lowerBoxBound + _higherBoxBound) * 0.5f;
  const float scaleFactor = m_v_s * 0.8f;
  constraintPtr->setPosition(currentKeyPoint + ((currentKeyPoint-boundingBoxCenter)* scaleFactor));
  constraintPtr = (static_cast<ActuatorHybridIKSlerp*>((*motionSegIt)->getActuator(0)))->getConstraintPtr(0); 
  currentKeyPoint = constraintPtr->getPosition();
  constraintPtr->setPosition(currentKeyPoint + ((currentKeyPoint-boundingBoxCenter)* scaleFactor));
  motionSegIt++;
  while ( motionSegIt < _motionSegments.end() && (*motionSegIt)->getGestureModifier() != NULL )
  {
    constraintPtr = (static_cast<ActuatorHybridIKSlerp*>((*motionSegIt)->getActuator(0)))->getConstraintPtr(0); 
    currentKeyPoint = constraintPtr->getPosition();
    constraintPtr->setPosition(currentKeyPoint + ((currentKeyPoint-boundingBoxCenter)* scaleFactor));
    motionSegIt++;  
  }
}  
Exemple #6
0
void Tutorial03::onUpdate()
{
  float tx,ty,tz;
  m_flyNode.getPosition(&tx,&ty,&tz);
  
  //roughly simulates the random fly of a fly
  if((rand()%100)>95)
  {
    m_dx=((SMRUtils::ranf()))/100.0f;
    m_dy=((SMRUtils::ranf()))/100.0f;
    m_dz=((SMRUtils::ranf()))/100.0f;
  }
  //change fly position
  if(tx<-1.0) m_dx=  0.01f;
  if(tx>1.0)  m_dx= -0.01f;
  if(ty<1.0)  m_dy=  0.01f;
  if(ty>2.2)  m_dy= -0.01f;
  if(tz<-1.0) m_dz=  0.01f;
  if(tz>1.0)  m_dz= -0.01f;
  m_flyNode.setPosition(tx+m_dx,ty+m_dy,tz+m_dz);

  m_flyNode.getPosition(&tx,&ty,&tz);

  SMRQuaternion rotCorrection;
  rotCorrection.fromEulerAngles(-M_PI/2.0, 0.0, 0.0);
  //update constraint position according to fly position
  SMRVector3 targetPosition(tx,ty,tz);
  rotCorrection.rotate(targetPosition);  
  m_ikConstraint->setPosition(targetPosition);

  //compute inverse kinematics
  m_ikSolver->process();

  //update tentacle's joint (IK)
  updateTentacle();
}