示例#1
0
int CalSkeleton::getBoneLinesStatic(float *pLines)
{
  int nrLines;
  nrLines = 0;

  rde::vector<CalBone *>::iterator iteratorBone;
  for(iteratorBone = m_vectorBone.begin(); iteratorBone != m_vectorBone.end(); ++iteratorBone)
  {
    int parentId;
    parentId = (*iteratorBone)->getCoreBone()->getParentId();

    if(parentId != -1)
    {
      CalBone *pParent;
      pParent = m_vectorBone[parentId];

      const CalVector& translation = (*iteratorBone)->getCoreBone()->getTranslationAbsolute();
      const CalVector& translationParent = pParent->getCoreBone()->getTranslationAbsolute();

      *pLines++ = translationParent[0];
      *pLines++ = translationParent[1];
      *pLines++ = translationParent[2];

      *pLines++ = translation[0];
      *pLines++ = translation[1];
      *pLines++ = translation[2];

      nrLines++;
    }
  }

  return nrLines;
}
示例#2
0
void
CalMixer::applyBoneAdjustments()
{
  CalSkeleton * pSkeleton = m_pModel->getSkeleton();
  std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone();
  unsigned int i;
  for( i = 0; i < m_numBoneAdjustments; i++ ) {
    CalMixerBoneAdjustmentAndBoneId * ba = & m_boneAdjustmentAndBoneIdArray[ i ];
    CalBone * bo = vectorBone[ ba->boneId_ ];
    CalCoreBone * cbo = bo->getCoreBone();
    if( ba->boneAdjustment_.flags_ & CalMixerBoneAdjustmentFlagMeshScale ) {
      bo->setMeshScaleAbsolute( ba->boneAdjustment_.meshScaleAbsolute_ );
    }
    if( ba->boneAdjustment_.flags_ & CalMixerBoneAdjustmentFlagPosRot ) {
      const CalVector & localPos = cbo->getTranslation();
      CalVector adjustedLocalPos = localPos;
      CalQuaternion adjustedLocalOri = ba->boneAdjustment_.localOri_;
      static float const scale = 1.0f;
      float rampValue = ba->boneAdjustment_.rampValue_;
      static bool const replace = true;
      static float const unrampedWeight = 1.0f;
      bo->blendState( unrampedWeight, 
        adjustedLocalPos,
        adjustedLocalOri, 
        scale, replace, rampValue );
    }
  }
}
示例#3
0
void IKCharacter::pullWorldPositions( int root_id, int leaf_id )
{
	CalVector root_pos;
	if ( auto_root_follow )
	{
		// get root pos
		int skel_root_id = skeleton->getCoreSkeleton()->getVectorRootCoreBoneId()[0];
		root_pos = skeleton->getBone(skel_root_id)->getTranslationAbsolute();
	}
	
	// work from the leaves down to the root
	deque<int> queue;
	if ( leaf_id == -1 )
		queue.insert( queue.begin(), leaf_bones.begin(), leaf_bones.end() );
	else
		queue.push_back( leaf_id );
	while ( !queue.empty() )
	{
		int id = queue.front();
		queue.pop_front();
		CalBone* bone = skeleton->getBone(id);
		world_positions[id] = bone->getTranslationAbsolute() - root_pos;
		int parent_id = bone->getCoreBone()->getParentId();
		if ( parent_id != -1 && id != root_id )
			queue.push_back( parent_id );
	}
	
}
示例#4
0
const std::list<int>& BoneBridgeCAL3D::GetListChildBoneID() const
{
   CalBone*     calBone  = (CalBone*)GetCalBone();
   CalCoreBone* coreBone = calBone->getCoreBone();

   std::list<int>& listChildID = coreBone->getListChildId();

   return listChildID;
}
示例#5
0
void IKCharacter::pullWorldPositions( int root_id, int leaf_id )
{
    deque<int> queue;
    if ( leaf_id == -1 )
        queue.insert( queue.begin(), leaf_bones.begin(), leaf_bones.end() );
    else
        queue.push_back( leaf_id );

    // work backwards up the tree
    while ( !queue.empty() )
    {
        int id = queue.front();
        queue.pop_front();
        CalBone* bone = skeleton->getBone(id);
        world_positions[id] = bone->getTranslationAbsolute();
        int parent_id = bone->getCoreBone()->getParentId();
        if ( parent_id != -1 && id != root_id )
            queue.push_back( parent_id );
    }

}
示例#6
0
void IKCharacter::draw( int bone_id, float scale, bool additional_drawing )
{
	CalBone* bone = skeleton->getBone( bone_id );
	int parent_id = bone->getCoreBone()->getParentId();
	if ( parent_id != -1 )
	{
		// current
		CalBone* parent = skeleton->getBone( parent_id );
		glBegin( GL_LINES );
		CalVector v = parent->getTranslationAbsolute();
		v*=scale;
		CalVector c = v;
		glVertex3f( v.x, v.y, v.z );
		v = bone->getTranslationAbsolute();
		v*=scale;
		c += v;
		c /= 2.0f;
		glVertex3f( v.x, v.y, v.z );
		glEnd();

		// world
		glPushAttrib( GL_CURRENT_BIT );
		glColor3f( 0.1f, 0.8f, 0.1f );
		glBegin( GL_LINES );
		v = world_positions[parent_id];
		v*=scale;
		glVertex3f( v.x, v.y, v.z );
		v = world_positions[bone_id];
		v*=scale;
		glVertex3f( v.x, v.y, v.z );
		glEnd();
		glPopAttrib();


		if ( additional_drawing )
		{
			glPushAttrib( GL_CURRENT_BIT );
			glBegin( GL_LINES );
			// core
			glColor3f( (parent_id==debug_bone)?1.0f:0.3f, 0.3f, 0.5f );
			v = parent->getCoreBone()->getTranslationAbsolute();
			v*=scale;
			glVertex3f( v.x, v.y, v.z );
			v = bone->getCoreBone()->getTranslationAbsolute();
			v*=scale;
			glVertex3f( v.x, v.y, v.z );
			glEnd();
			

			// draw rotation
			glPushMatrix();
			CalVector root = bone->getCoreBone()->getTranslationAbsolute();
			glTranslatef( root.x, root.y, root.z );
			CalVector rot;
			
			rot.set( 0, 0.1f*scale, 0 );
			rot *= bone->getCoreBone()->getRotationAbsolute();
			ofEnableAlphaBlending();
			glColor4f( 0.2f, 0.2f, 0.8f, 0.2f );
			glBegin( GL_TRIANGLES );
			//glVertex3f( 0,0,0 );
			glVertex3f( rot.x, rot.y, rot.z );
			rot *= debug_cached_rotations[bone_id];
			glVertex3f( rot.x, rot.y, rot.z );
			glEnd();
			
			glColor4f( 0.2f, 0.2f, 0.8f, 0.8f );
			rot.set( 0, 0.1f*scale, 0 );
			rot *= bone->getCoreBone()->getRotationAbsolute();
			glBegin( GL_LINES );
			glVertex3f( 0,0,0 );
			glVertex3f( rot.x, rot.y, rot.z );
			rot *= debug_cached_rotations[bone_id];
			glVertex3f( 0,0,0 );
			glVertex3f( rot.x, rot.y, rot.z );
			glEnd();
			
			ofDisableAlphaBlending();
			
			glPopMatrix();
			
			CalVector u( 0, 0.1f*scale, 0);
			u *= bone->getRotationAbsolute();
			CalVector r( 0.1f*scale, 0, 0 );
			r *= bone->getRotationAbsolute();
			CalVector f( 0, 0, 0.1f*scale );
			f *= bone->getRotationAbsolute();
			
			
			// right blue
			glPushMatrix();
			root = bone->getTranslationAbsolute();
			glTranslatef( root.x, root.y, root.z );
			glBegin( GL_LINES );
			glColor3f( 0, 0, 1 );
			glVertex3f( 0,0,0 );
			glVertex3f( r.x, r.y, r.z );
			// up red
			glColor3f( 1, 0, 0 );
			glVertex3f( 0,0,0 );
			glVertex3f( u.x, u.y, u.z );
			// forward green
			glColor3f( 0, 1, 0 );
			glVertex3f( 0,0,0 );
			glVertex3f( f.x, f.y, f.z );
			glEnd();
			glPopMatrix();

			// right blue
			glPushMatrix();
			root = world_positions[bone_id];
			glTranslatef( root.x, root.y, root.z );
			glBegin( GL_LINES );
			glColor3f( 0, 0, 1 );
			glVertex3f( 0,0,0 );
			glVertex3f( r.x, r.y, r.z );
			// up red
			glColor3f( 1, 0, 0 );
			glVertex3f( 0,0,0 );
			glVertex3f( u.x, u.y, u.z );
			// forward green
			glColor3f( 0, 1, 0 );
			glVertex3f( 0,0,0 );
			glVertex3f( f.x, f.y, f.z );
			glEnd();
			glPopMatrix();
			
			glPopAttrib();
		}
		
	}
	
	
	list<int> children = bone->getCoreBone()->getListChildId();
	for ( list<int>::iterator it = children.begin(); 
		 it != children.end();
		 ++it )
	{
		draw( *it, scale, additional_drawing );
	}
	
	
}
示例#7
0
void IKCharacter::solve( int iterations, int root_id, int leaf_id )
{
	while ( iterations>0 )
	{
		// start at leaf nodes
		deque<int> queue;
		
		// push leaf bones to target positions
		for ( int i=0; i<leaf_bones.size(); i++ )
		{
			// if we have a leaf id to use, skip all other leaves
			if ( leaf_id != -1 && leaf_id != leaf_bones[i] )
				continue;
			
			// if we have a target for this one
			if ( leaf_targets.find(leaf_bones[i]) != leaf_targets.end() )
			{
				// set it
				world_positions[leaf_bones[i]] = leaf_targets[leaf_bones[i]].second;
			}
			int parent_id = skeleton->getCoreSkeleton()->getCoreBone( leaf_bones[i] )->getParentId();
			if ( parent_id != -1 )
				queue.push_back( parent_id );
		}
		
		// queue to handle branching
		deque< int > branch_queue;
		while ( !queue.empty() || !branch_queue.empty() )
		{
			// if main queue is empty then we are ready to deal with branches
			if ( queue.empty() )
			{
				queue.push_back( branch_queue.front() );
				branch_queue.pop_front();
				continue;
			}
			
			int next_id = queue.front();
			queue.pop_front();
			// bail out if we should
			if ( root_id != -1 && next_id == root_id )
				continue;
			
			CalBone* bone = skeleton->getBone( next_id );
			list<int>& children = bone->getCoreBone()->getListChildId();
			// is this a branch?
			if ( children.size()>1 )
			{
				// still other children to process -- push to branch queue
				if ( !queue.empty() )
				{
					branch_queue.push_back( next_id );
					continue;
				}
				
				// otherwise, process branch here
				// if we're here, then all the children of this branch have been processed already
				int parent_id = bone->getCoreBone()->getParentId();
				if ( parent_id != -1 )
				{
					//printf("averaging %lu positions for %s wc %f: ", children.size(), bone->getCoreBone()->getName().c_str(), getWeightCentre( next_id ) );
					// fetch all child positions
					vector<CalVector> results;
					results.insert( results.begin(), children.size(), world_positions[next_id] );
					int count=0;
					for ( list<int>::iterator it = children.begin(); it != children.end(); ++it,++count ) 
					{
						
						// child_pos
						CalVector& b_c = world_positions[*it];
						// current pos
						CalVector& b_p = results[count];

						// now, the bone is the wrong length. correct its length to fulfil size constraint.
						CalVector delta = b_c - b_p;
						float length = delta.length();
						length = max( 0.00001f, length );
						// pointing from parent to child
						CalVector direction = delta/length;
						
						CalCoreBone* child_bone = skeleton->getCoreSkeleton()->getCoreBone( *it );
						CalVector rest_delta = bone->getCoreBone()->getTranslationAbsolute() - child_bone->getTranslationAbsolute();
						float desired_length = rest_delta.length();
						float delta_length = desired_length - length;
						
						// balance according to weight_centre
						float weight_centre = getWeightCentre(next_id);
						
						// move
						b_c += weight_centre * delta_length * direction;
						b_p -= (1.0f-weight_centre) * delta_length * direction;
						
						//printf("%s %f (%f %f %f), ", child_bone->getName().c_str(), delta_length, b_p.x, b_p.y, b_p.z );
						
					}
					//printf("\n");
					
					// now average
					CalVector average;
					for ( int i=0; i<results.size(); i++ )
					{
						average += results[i];
					}
					average /= results.size();

					// store
					world_positions[next_id] = average;
					
					// add parent
					queue.push_back( parent_id );
				}				
				
			}
			else
			{
				// children.size() is exactly 1
				assert( children.size()==1 );
				int child_id = children.front();
				
				// child_pos
				CalVector& b_c = world_positions[child_id];
				// current pos
				CalVector& b_p = world_positions[next_id];
				
				// now, the bone is the wrong length. correct its length to fulfil size constraint.
				float desired_length = getBoneLength(next_id);
				CalVector delta = b_c - b_p;
				float length = delta.length();
				length = max( 0.00001f, length );
				length = min( desired_length*1.5f, length );
				// pointing from parent to child
				CalVector direction = delta/length;
				
				float delta_length = desired_length - length;
				
				// balance according to weight_centre
				float weight_centre = getWeightCentre(next_id);
				
				// move
				b_c += weight_centre * delta_length * direction;
				b_p -= (1.0f-weight_centre) * delta_length * direction;
				
				
				// add parent
				int parent_id = bone->getCoreBone()->getParentId();
				if ( parent_id != -1 )
					queue.push_back( parent_id );
			}
		}	
		
		iterations--;
	}
	
	
}