Beispiel #1
0
void Skeleton::update( const float &time, bool updateAnim)
{
	if( updateAnim )
	{
		// update all bones local values (rotation fcurves)
		int c = 0;
		for(int i=0; i<m_bones.size(); ++i )
		{
			//float rx = getBone(i)->localEulerRotation.x;
			//float ry = getBone(i)->localEulerRotation.y;
			//float rz = getBone(i)->localEulerRotation.z;

			//if( ((FCurve*)m_localEulerRotationAnims.m_data[c])->m_numKeys > 0 )
			//	rx = math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c])->eval(time));
			//if( ((FCurve*)m_localEulerRotationAnims.m_data[c+1])->m_numKeys > 0 )
			//	ry = math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c+1])->eval(time));
			//if( ((FCurve*)m_localEulerRotationAnims.m_data[c+2])->m_numKeys > 0 )
			//	rz = math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c+2])->eval(time));

			getBone(i)->localEulerRotation = math::Vec3f( math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c])->eval(time)), math::degToRad(((FCurve *)m_localEulerRotationAnims.m_data[c+1])->eval(time)), math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c+2])->eval(time)) );
			//getBone(i)->localEulerRotation = math::Vec3f( rx, ry, rz );
			c+=3;
		}
	}
	

	// update global transforms (depends on hierarchy)
	//updateBone(time, m_root, math::Matrix44f::Identity(), 0.0f);
	updateBone(time, m_root, math::Matrix44f::ScaleMatrix(0.1f,0.1f,0.1f), 0.0f);

	// update uniform which goes via geometry into the shader
	for( int j=0; j<m_bones.size(); ++j )
		m_boneMatricesUniform->setElement( j, &getBone(j)->vertexTransform );
}
Beispiel #2
0
	BoneNode* Skeleton::createBone( char const* name , char const* parentName )
	{
		if ( !parentName )
			parentName = CF_BASE_BONE_NAME;
		BoneNode* parent = getBone( parentName );
		return createBone( name , parent->id );
	}
void Skeleton::addAnimationTrackGroup(animation::AnimationTrackGroup*group){
	animation::TransAnimationGroup* tgroup=dynamic_cast<animation::TransAnimationGroup*>(group);
	if(!tgroup)
		return;
	animation::AnimationController*c=m_animationMixer->addTrackGroup(tgroup);
	//connect tracks to bones
	animation::IAnimationTrackList::const_iterator p=group->getTracks().begin();
	animation::IAnimationTrackList::const_iterator end=group->getTracks().end();
	for(;p!=end;++p)
	{
		animation::IAnimationTrack* t=*p;
		animation::TransformationAnimationTrack* tt= dynamic_cast<animation::TransformationAnimationTrack*>(t);
		if(tt)
		{
			BoneNode* b=getBone(t->getName());
			if(b){
				tt->setAffectedNodeID(b->getID());
					//tt->SetNode(b);
				b->AttachAnimationTrack(tt,c);
			}
		}
	}
	group->refreshAffectIDMap();

}
Beispiel #4
0
/*
This function sets sibling or child for parent bone
If parent bone does not have a child, 
then pChild is set as parent's child
else pChild is set as a sibling of parents already existing child
*/
int CMUSkeleton::setChildrenAndSibling(int parent, Bone *pChild)
{
  Bone *pParent;  

  //Get pointer to root bone
  pParent = getBone(m_pRootBone, parent);

  if(pParent==NULL)
  {
    printf("inbord bone is undefined\n"); 
    return(0);
  }
  else
  {
    //if pParent bone does not have a child
    //set pChild as parent bone child
    if(pParent->child == NULL)   
    {
      pParent->child = pChild;
    }
    else
    { 
      //if pParent bone already has a child 
      //set pChils as pParent bone's child sibling
      pParent=pParent->child;              
      while(pParent->sibling != NULL) 
        pParent = pParent->sibling;            

      pParent->sibling = pChild;
    }
    return(1);
  }
}
Beispiel #5
0
// attach a gameobject inplace to a specified bone
void gkSkeleton::attachObjectToBoneInPlace(gkString boneName,gkGameObject* gobj)
{
	gkBone* bone = getBone(boneName);
	if (bone)
	{
		if (m_controller)
			gobj->setParentInPlace(m_controller);
		else
			gobj->setParentInPlace(this);

		bone->attachObject(gobj);

		gkMatrix4 objMat = gobj->getTransform();

		// get the current transformation of this bone
		gkMatrix4 boneMat = bone->getTransform();

		gkMatrix4 objInBoneSpace = boneMat.inverse() * objMat ;
		gkTransformState* ts = new gkTransformState(objInBoneSpace);
		gobj->_setBoneTransform(ts);
	}
	else
	{
		gkLogger::write("unknown bone-name:"+boneName+" to attach "+gobj->getName()+" to "+getName(),true);
	}
}
Beispiel #6
0
/*
This recursive function traverces skeleton hierarchy 
and returns a pointer to the bone with index - bIndex
ptr should be a pointer to the root node 
when this function first called
*/
Bone* CMUSkeleton::getBone(Bone *ptr, int bIndex)
{
  static Bone *theptr;
  if(ptr==NULL) 
    return(NULL);
  else if(ptr->idx == bIndex)
  {
    theptr=ptr;
    return(theptr);
  }
  else
  { 
    getBone(ptr->child, bIndex);
    getBone(ptr->sibling, bIndex);
    return(theptr);
  }
}
Beispiel #7
0
void HelloWorld::onFrameEvent( cocos2d::extension::CCBone* bone, const char* evt, int originFrameIndex, int currentFrameIndex )
{
	if (originFrameIndex == currentFrameIndex)
	{
		CCPoint p = m_pArmature->getBone("Layer2")->getDisplayRenderNode()->convertToWorldSpaceAR( ccp (0, 0)); 

		CCLOG("%s", evt);

		m_pArmature->getAnimation()->pause();
	}
}
//--------------------------------------------------------------
void ofxFBXSkeleton::enableExternalControlRecursive( ofxFBXBone* aBone ) {
    if( aBone == NULL ) return;
    map<string, ofxFBXBone* >::iterator it;
    for(it = sourceBones.begin(); it != sourceBones.end(); ++it ) {
        if( it->second->fbxNode->GetParent() == aBone->fbxNode ) {
//            it->second->enableExternalControl();
            getBone( it->first )->enableExternalControl();
            enableExternalControlRecursive( it->second );
        }
    }
}
//--------------------------------------------------------------
void ofxFBXSkeleton::enableExternalControl( string aName ) {
    // loop through hierarchy to make children also controlled externally
    ofxFBXBone* bone = getBone( aName );
    if(bone == NULL) {
        ofLogWarning("ofxFBXSkeleton :: enableExternalControl : can not find bone with name ") << aName;
        return;
    }
    bone->enableExternalControl();
    
    enableExternalControlRecursive( getSourceBone(aName) );
    
}
	void Armature::removeBoneByName(std::string boneName){
		if((boneName == "") || (boneName == " "))
		{
			return;
		}
			
		Bone* bone = getBone(boneName);
		if(bone)
		{
			removeBone(bone);
		}
	}
Beispiel #11
0
MOBone * MArmature::getBoneByName(const char * name)
{
        M_PROFILE_SCOPE(MArmature::getBoneByName);
	unsigned int i;
	for(i=0; i<m_bonesNumber; i++) // scan bones
	{
		MOBone * bone = getBone(i);
		if(strcmp(name, bone->getName()) == 0)
			return bone;
	}

	return NULL;
}
Beispiel #12
0
	void Skeleton::setupBoneWorldTransform( RenderSystem* renderSys , Matrix4 const& baseWorld , Matrix4* boneTrans )
	{
		if ( boneTrans )
		{
			if ( mUseInvLocalTrans )
			{
				for( int i = 0 ; i < getBoneNum(); ++i )
				{
					BoneNode* bone = getBone(i);
					Matrix4 worldTrans;
					//World = InvLocal * Bone * BaseWorld
					TransformUntility::mul( worldTrans , bone->invLocalTrans , boneTrans[i] );
					TransformUntility::mul( worldTrans , worldTrans , baseWorld );
					renderSys->setWorldMatrix( i , worldTrans );
				}
			}
			else
			{
				for( int i = 0 ; i < getBoneNum(); ++i )
				{
					BoneNode* bone = getBone(i);
					Matrix4 worldTrans;
					TransformUntility::mul( worldTrans , boneTrans[i] , baseWorld );
					renderSys->setWorldMatrix( i , worldTrans );
				}
			}
		}
		else
		{
			for( int i = 0 ; i < getBoneNum(); ++i )
			{
				BoneNode* bone = getBone(i);
				Matrix4 worldTrans;
				renderSys->setWorldMatrix( i , baseWorld );
			}
		}
	}
void gkSkeletonResource::copyBones(gkSkeletonResource& other)
{
    {
        Bones::Iterator biter = other.m_bones.iterator();
        while (biter.hasMoreElements())
            createBone(biter.getNext().second->getName());
    }
    {
        Bones::Iterator biter = other.m_bones.iterator();
        while (biter.hasMoreElements())
        {
            gkBone* sBone = biter.getNext().second;
            gkBone* sParent = sBone->getParent();

            gkBone* dBone = getBone(sBone->getName());
            GK_ASSERT(dBone);
            if (sParent)
            {
                gkBone* dParent = getBone(sParent->getName());
                GK_ASSERT(dParent);
                dBone->setParent(dParent);
            }
            dBone->setRestPosition(sBone->getRest());
        }
    }
    {
        gkBone::BoneList::Iterator biter = other.m_rootBoneList.iterator();
        while (biter.hasMoreElements())
        {
            gkBone* sBone = biter.getNext();
            gkBone* dBone = getBone(sBone->getName());
            GK_ASSERT(dBone);
            m_rootBoneList.push_back(dBone);
        }
    }
}
	void Armature::addDBObject(DBObject* object){
		if(checkIfClass<Slot>(object))
		{
			Slot* slot = (Slot*)object;
			if(!getSlot(slot->name))
			{
				_slotList.push_back(slot);
			}
		}
		else if(checkIfClass<Bone>(object))
		{
			Bone* bone = (Bone*) object;
			if(!getBone(bone->name))
			{
				_boneList.push_back(bone);
				sortBoneList();
			}
		}
	}
Beispiel #15
0
// attach a gameobject to the specified bone with optional transformation
void gkSkeleton::attachObjectToBone(gkString boneName,gkGameObject* gobj,gkTransformState* transform)
{
	gkBone* bone = getBone(boneName);
	if (bone)
	{
		// if there is an entity add the attached object there otherwise on the skeleton itself
		if (m_controller)
			m_controller->addChild(gobj);
		else
			addChild(gobj);

		bone->attachObject(gobj);
		if (transform)
			gobj->_setBoneTransform(transform);
	}
	else
	{
		gkLogger::write("unknown bone-name:"+boneName+" to attach "+gobj->getName()+" to "+getName(),true);
	}
}
Beispiel #16
0
DBBone* DBArmature::createBone(BoneData* boneData)
{
    std::string boneName = boneData->name;
    DBBone *existedBone = getBone(boneName);
    if(existedBone != nullptr)
        return existedBone;
    
    std::string parentName = boneData->parent;
    
    DBBone *bone = nullptr;
    
    if( !parentName.empty() && !this->getBone(parentName))
    {
        BoneData* parentBoneData = this->_pArmatureData->getBoneData(parentName);
        createBone(parentBoneData);
    }
    
    bone = DBBone::create(boneData);
    addBone(bone, parentName.c_str());
    
    return bone;
}
	void Armature::addChild(DBObject* object, std::string parentName){
		if(!object)
		{
			return;
		}
			
		if(parentName != "")
		{
			Bone* boneParent = getBone(parentName);
			if (boneParent)
			{
				boneParent->addChild(object);
			}
		}
		else
		{
			if(object->parent)
			{
					object->parent->removeChild(object);
			}
			object->setArmature(this);
		}
	}
// 解析出刀塔骨架数据
Dota_Skeleton_Data* DotaAnimParser::parseDotaSkeletonData(
	const std::string &fcaFile)
{
	const float PI = 3.14159265358979323846f;

	ByteArray byteArray;
	bool bRet = byteArray.loadFromZipFile(fcaFile.c_str(), "cha");
	if (!bRet)
		return nullptr;

	Dota_Skeleton_Data * skeletonData = new Dota_Skeleton_Data();
	if (skeletonData == nullptr)
	{
		byteArray.close();
		return nullptr;
	}

	skeletonData->name = readName(byteArray);
	CCLOG("RoleName:%s\n", skeletonData->name.c_str());

	float factor = 0.1f;
	if (skeletonData->name.substr(0, 14) == "effect/eff_UI_")
		factor = 0.5f;

	int boneCount = byteArray.readInt();
	CCLOG("BoneCnt:%d\n", boneCount);

	for (int i = 0; i < boneCount; i++)
	{
		Dota_Bone_Data * boneData = new Dota_Bone_Data();
		boneData->name = readName(byteArray);
		boneData->textureName = readName(byteArray);
		boneData->index = byteArray.readInt();
		skeletonData->boneDataList.push_back(boneData);

		CCLOG("BoneData:\nName:%s\nTextureName:%s\nIndex:%d\n\n", 
			boneData->name.c_str(), boneData->textureName.c_str(), boneData->index);
	}

	CCLOG("BoneCnt:%d\n", (int)skeletonData->boneDataList.size());

	int animCount = byteArray.readInt();
	CCLOG("AnimCnt:%d\n", animCount);

	for (int i = 0; i < animCount; i++)
	{
		Dota_Anim_Data * animData = new Dota_Anim_Data();
		animData->name = readName(byteArray);
		CCLOG("AnimName:%s\n", animData->name.c_str());

		byteArray.readBytes(animData->unknownData, sizeof(animData->unknownData));

		int frameCount = byteArray.readInt();
		CCLOG("FrameCnt:%d\n", frameCount);

		for (int j = 0; j < frameCount; j++)
		{
			Dota_Frame_Data * frameData = new Dota_Frame_Data();
			frameData->type = byteArray.readInt();
			if (frameData->type == 1)
			{
				frameData->unknownData1 = byteArray.readInt();
				CCLOG("UnknownData1:%d\n", frameData->unknownData1);
				frameData->soundName = readName(byteArray);
				byteArray.readBytes(frameData->soundData, sizeof(frameData->soundData));
				frameData->unknownData2 = byteArray.readInt();
				CCLOG("UnknownData2:%d\n", frameData->unknownData2);
			}
			int slotCount = byteArray.readInt();
			for (int k = 0; k < slotCount; k++)
			{
				Dota_Slot_Data * slotData = new Dota_Slot_Data();
				slotData->boneIndex = byteArray.readShort();
				slotData->opacity = byteArray.readByte();
				float a = byteArray.readFloat();
				float b = byteArray.readFloat();
				float c = byteArray.readFloat();
				float d = byteArray.readFloat();
				float tx = byteArray.readFloat();
				float ty = byteArray.readFloat();

				slotData->x = tx * factor;
				slotData->y = ty * factor;
				slotData->skX = atan2(-c, d) * (180/PI);
				slotData->skY = atan2(b, a) * (180/PI);
				slotData->scX = sqrt(a*a + b*b);
				slotData->scY = sqrt(c*c + d*d);
				frameData->slotDataList.push_back(slotData);
			}
			animData->frameDataList.push_back(frameData);
		}
		CCLOG("FrameCnt:%d\n", animData->frameDataList.size());
		skeletonData->animDataList.push_back(animData);
	}

	byteArray.close();

	for (int i = 0; i < (int)skeletonData->animDataList.size(); i++)
	{
		Dota_Anim_Data * animData = skeletonData->animDataList[i];

		Dota_Anim_Data2 * animData2 = new Dota_Anim_Data2();
		for (int j = 0; j < (int)animData->frameDataList.size(); j++)
		{
			Dota_Frame_Data * frameData = animData->frameDataList[j];

			for (int k = 0; k < (int)frameData->slotDataList.size(); k++)
			{
				Dota_Slot_Data * slotData = frameData->slotDataList[k];
				if (frameData->type == 1 && 0 == k)
					slotData->soundName = frameData->soundName;
				slotData->zOrder = k;		//slotData->boneIndex;
				std::string boneName = getBone(skeletonData->boneDataList, slotData->boneIndex);
				Dota_Anim_Data2::iterator iter = animData2->find(boneName);
				if (iter == animData2->end())
				{
					Dota_Timeline_Data * timelineData = new Dota_Timeline_Data();
					timelineData->insert(Dota_Timeline_Data::value_type(toString(j), slotData));
					animData2->insert(Dota_Anim_Data2::value_type(boneName, timelineData));
					skeletonData->firstFrameOfBoneMap.insert(Dota_First_Frame_Data::value_type(boneName, slotData));
				}
				else
				{
					Dota_Timeline_Data * timelineData = iter->second;
					Dota_Timeline_Data::iterator iter2 = timelineData->find(toString(j));
					if (iter2 == timelineData->end())
					{
						timelineData->insert(Dota_Timeline_Data::value_type(toString(j), slotData));
					}
				}
			}
		}
		skeletonData->animDataMap.insert(std::map<std::string, Dota_Anim_Data2 *>::value_type(animData->name, animData2));
	}

	return skeletonData;
}
Beispiel #19
0
void Animator::update() {
	if (! currentAnimation) {
		return;
	}

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glLoadIdentity();
	glTranslatef(320.0f, 300.0, 0.0f);
	glScalef(1.0f / 3.0f, 1.0f / 3.0f, 1.0f);
	glBindTexture(GL_TEXTURE_2D, texture[0]);

	currentFrame = currentFrame % currentAnimation->frameCount;
	AnimationFrame* f = currentAnimation->frames[currentFrame];
	AnimationFrame::ElementList::reverse_iterator i = f->elements.rbegin();
	int test = 0;
	for (; i != f->elements.rend(); ++i) {
		AnimationFrameElement* e = *i;
		
		BoneInfo* b = getBone(e->boneID);
		if (b) {
			BoneFrameInfo* f = b->infos[e->frameID];

			// 遍历顶点范围
			glPushMatrix();
			// tx ty
			glTranslatef(e->tx, e->ty, 0);

			// sx sy
			float sx = sqrtf(e->a * e->a + e->c * e->c);
			float sy = sqrtf(e->b * e->b + e->d * e->d);
			
			// http://www.infogroupindia.com/blog/posts/589/action-script-3-2d-matrix-scale-and-rotation-extraction
			// 阿三写的居然对了
			// 不过完全没看懂
			// 通过tan得到的角度,-pi / 2 ~ pi / 2
			float sign = atanf(-e->c / e->a);
			// 通过cos得到的角度,0 ~ pi
			float rad = acosf(e->a / sx);


			// 通过cos跟tan的值才能完全判断出角度
			float deg = rad * 180.0f / M_PI;
			
			// 修正错误的角度值
			if (deg > 90 && sign > 0) {
				// 应该在第三象限
				deg = 360 - deg;
			} else if (deg < 90 && sign < 0) {
				// 应该在第四象限
				deg = 360 - deg;
			}

			// 误差值 0.001
			// 蜘蛛女王还是有些问题,很奇怪
			if (((deg > 270 && deg < 360) || (deg > 0 && deg < 90)) && e->a < -0.001 ||
				deg > 90 && deg < 270 && e->a > 0.001) {
				sx *= -1.0f;
			}
			if (((deg > 270 && deg < 360) || (deg > 0 && deg < 90)) && e->d < -0.001 ||
				deg > 90 && deg < 270 && e->d > 0.001) {
				sy *= -1.0f;
				//log.Write(COLOR_WHITE, "渲染到上下翻转帧元素 部位ID %s 帧ID %d x %f y %f z %f a %f b %f c %f d %f", boneNames[e->boneID].c_str(), e->frameID, e->tx, e->ty, e->tz, e->a, e->b, e->c, e->d);
			}
			glScalef(sx, sy, 1.0);

			glRotatef(deg, 0.0f, 0.0f, 1.0f);
			

			int nowIndex = f->vStartIndex;
			int endIndex = f->vStartIndex + f->vCount;
			glBegin(GL_POLYGON);
			for (; nowIndex < endIndex; ++nowIndex) {
				Vertex* v1 = vertexes[nowIndex];
				glTexCoord2f(v1->u, v1->v); glVertex3f(v1->x, v1->y, v1->z);
			}
			glEnd();
			glPopMatrix();
		}
	}
	//currentFrame++;
	//log.Write(COLOR_WHITE, "当前帧数 %d %d", currentFrame, currentAnimation->frameCount);
}
Beispiel #20
0
Skeleton::Skeleton( unsigned char *skel, unsigned char *_pose, unsigned char *anims )
{
	//unsigned char *data = testSkel11;



	int numBones = skel[0];
	unsigned char *parentIndices = &skel[1];
	float *lengths = (float *)&skel[1+numBones*sizeof(char)];

	float *pose = (float *)_pose;
	unsigned char *rotAnims = anims;

	for(int i=0; i<numBones; ++i )
	{
		Bone *b = new Bone();
		m_bones.push_back( b );
		if( i>0 )
		{
			((Bone*)m_bones.m_data[parentIndices[i]])->childBones.push_back( b );
			b->parent = (Bone*)m_bones.m_data[parentIndices[i]];
		}
		b->length = lengths[i];

		// apply pose
		b->localEulerRotation.x = math::degToRad(pose[i]);
		b->localEulerRotation.y = math::degToRad(pose[numBones+i]);
		b->localEulerRotation.z = math::degToRad(pose[numBones*2+i]);

		//printf( "bone %i %f   %f   %f\n", i, b->localEulerRotation.x, b->localEulerRotation.y, b->localEulerRotation.z );
		if( rotAnims )
		{
			// read animations of rotations
			// the tricky bit: we dont know how much space each anim uses so we
			// have to find out after loading it
			FCurve *rotAnimX = new FCurve( rotAnims, pose[i] );
			rotAnims += 1 + rotAnimX->m_numKeys*2*sizeof(float);
			FCurve *rotAnimY = new FCurve( rotAnims, pose[numBones+i] );
			rotAnims += 1 + rotAnimY->m_numKeys*2*sizeof(float);
			FCurve *rotAnimZ = new FCurve( rotAnims, pose[numBones*2+i] );
			rotAnims += 1 + rotAnimZ->m_numKeys*2*sizeof(float);

			m_localEulerRotationAnims.push_back( rotAnimX );
			m_localEulerRotationAnims.push_back( rotAnimY );
			m_localEulerRotationAnims.push_back( rotAnimZ );
		}
	}

	m_root = (Bone*)m_bones.m_data[0];


	// create the uniform which will be attached to geometry which has to be driven by skin deformation
	m_boneMatricesUniform = new Attribute( 16 );
	// just fill up the list with dummy entries (will be overwritten in update)
	for( int j=0; j<m_bones.size(); ++j )
		m_boneMatricesUniform->appendElement( &math::Matrix44f::Identity() );

	// update skeleton in refpose (updates global transform)
	// TODO: replace with apply pose
	update( 0.001f, false );

	// store refpose transforms
	for(int i=0; i<numBones; ++i )
	{
		math::Matrix44f bindPoseInv = getBone(i)->globalTransform;
		bindPoseInv.invert();
		getBone(i)->bindPoseInv = bindPoseInv;
	}

}