/** 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 )); } } }
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++; } }
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(); }