예제 #1
0
void CharacterSkeleton::updateBones() {
	if (animations.size() > 0) {
		/*Animation& anim = animations.begin()->second;
		float timeInTicks = timeInSeconds * anim.getTicksPerSecond();
		float animationTime = fmod(timeInTicks, anim.getDuration());*/

		updateBoneTransforms(boneHierarchy, rootTransform);
	}
}
예제 #2
0
void IkSolver::iterateIk()
{
	if (ikChain.size() == 0)
		buildChain(*rootBone, *effectorBone, ikChain);

	// perform basic CCD
	stepIk();

	// need the bone transforms to be valid again afterwards for consistency
	updateBoneTransforms();
}
예제 #3
0
void IkSolver::solveIk(int maxIterations, double threshold)
{
	if (ikChain.size() == 0)
		buildChain(*rootBone, *effectorBone, ikChain);

	for (int i = 0; i < maxIterations; ++i)
	{
		// perform basic CCD
		stepIk();

		// need the bone transforms to be valid again afterwards for consistency
		updateBoneTransforms();

		vec3d delta = getEffectorPos() - getTargetPos();
		if (abs(dot(delta,delta)) < threshold*threshold)
			break;
	}
}
예제 #4
0
void IkSolver::updateBoneTransforms(const Bone *parent, const Bone &b, const mat4d &base) const
{
	const BoneState &bs = boneStates[b.id];

	if (parent == 0)
		bs.boneToWorld = base * mat4d(bs.rot);
	else
	{
		const Bone::Connection &c = *b.findJointWith(*parent);
		bs.boneToWorld = base * mat4d(bs.rot) * vmath::translation_matrix(-c.pos);
	}

	for (int i = 0; i < (int)b.joints.size(); ++i)
	{
		const Bone::Connection &c = b.joints[i];
		Bone &bn = *c.to;
		if (&bn != parent)
			updateBoneTransforms(&b, bn, bs.boneToWorld * vmath::translation_matrix(c.pos));
	}
}
예제 #5
0
void IkSolver::setRootBone(const Bone &bone)
{
	// early out if we're not changing anything
	if (rootBone == &bone) return;

	// clear the existing IK chain
	ikChain.clear();

	// form a chain between the old root and the new root
	std::vector<const Bone*> chain;
	buildChain(bone, *rootBone, chain);

	// rebuild the rotation values along the chain
	// this is required because the rotation values are specified relative to the parent bone,
	// and the parent bone is dependent on which bone is root
	std::vector<const Bone*>::const_iterator it = chain.begin();
	while (it != chain.end())
	{
		const Bone &b = **it;
		BoneState &bs = boneStates[b.id];
		
		++it;
		if (it != chain.end())
		{
			const Bone &nb = **it;
			BoneState &nbs = boneStates[nb.id];
			bs.rot = transpose(nbs.rot);
		}
		else
			bs.rot = minor(bs.boneToWorld);
	}

	// set the new root, and its correct position
	rootBone = &bone;
	rootPos = boneStates[bone.id].boneToWorld.translation();
	
	updateBoneTransforms();
}
예제 #6
0
void IkSolver::updateBoneTransforms() const
{
	assert(rootBone != 0);
	updateBoneTransforms(0, *rootBone, vmath::translation_matrix(rootPos));
}
예제 #7
0
void IkSolver::applyAllConstraints()
{
	applyAllConstraints(0, *rootBone);
	updateBoneTransforms();
}
예제 #8
0
void CharacterSkeleton::updateBoneTransforms(Bone3D* bone, const glm::mat4& parentTransform) {
	string boneName = bone->boneName;

	/*if (bRagdoll) {
		nodeTransformation = bone->nodeTransformation;
	}*/
	//else {
		if (!bRagdoll && !blendComponents.empty()) {
			// assuming all bones have animations
			// TODO: fix for leaf bones that are added by blender with fbx-export "Add Leaf Bones"-option

			Animation& firstAnimation = animations[blendComponents[0].animationName];
			glm::vec3 scaling(0, 0, 0);
			glm::quat rotation = firstAnimation.interpolateRotation(blendComponents[0].animationStatus * firstAnimation.getDuration(), boneName);
			glm::vec3 translation(0, 0, 0);
			float weightAcc = blendComponents[0].weight;

			for (unsigned int i = 0; i < blendComponents.size(); ++i) {
				Animation& anim = animations[blendComponents[i].animationName];
				float cAnimationTime = blendComponents[i].animationStatus * anim.getDuration();

				scaling += anim.interpolateScaling(cAnimationTime, boneName) * blendComponents[i].weight;

				if (i != 0) {
					glm::quat cRotation = anim.interpolateRotation(cAnimationTime, boneName);
					rotation = glm::slerp(rotation, cRotation, 1.0f - weightAcc / (weightAcc + blendComponents[i].weight));
					weightAcc += blendComponents[i].weight;
				}

				translation += anim.interpolatePosition(cAnimationTime, boneName) * blendComponents[i].weight;
			}
			bone->scaling = scaling;
			glm::mat4 scalingM = glm::scale(glm::mat4(), bone->scaling);

			bone->rotation = rotation;
			glm::mat4 rotationM = glm::mat4_cast(bone->rotation);

			bone->translation = translation;
			glm::mat4 translationM = glm::translate(glm::mat4(), bone->translation);

			bone->nodeTransformation = translationM * rotationM * scalingM;
		}
		/*else {
			// TODO: remove else-case
			float animationTime = 0;

			Animation& anim = animations.begin()->second;
			//Animation& anim = animations["AnimStack::metarig|Run"];
			if (anim.hasBoneAnimation(boneName)) {
				bone->scaling = anim.interpolateScaling(animationTime, boneName);
				glm::mat4 scalingM = glm::scale(glm::mat4(), bone->scaling);

				//aiQuaternion rotation;
				//calcInterpolatedRotation(rotation, animationTime, nodeAnim);
				//aiMatrix3x3 rotationMTmp = (rotation.GetMatrix());
				//glm::mat3 rotationTmp = glm::transpose(glm::make_mat3(&rotationMTmp.a1));
				//glm::mat4 rotationM = glm::mat4();
				//rotationM[0][0] = rotationTmp[0][0];
				//rotationM[0][1] = rotationTmp[0][1];
				//rotationM[0][2] = rotationTmp[0][2];
				//rotationM[1][0] = rotationTmp[1][0];
				//rotationM[1][1] = rotationTmp[1][1];
				//rotationM[1][2] = rotationTmp[1][2];
				//rotationM[2][0] = rotationTmp[2][0];
				//rotationM[2][1] = rotationTmp[2][1];
				//rotationM[2][2] = rotationTmp[2][2];
				bone->rotation = anim.interpolateRotation(animationTime, boneName);
				glm::mat4 rotationM = glm::mat4_cast(bone->rotation);

				bone->translation = anim.interpolatePosition(animationTime, boneName);
				glm::mat4 translationM = glm::translate(glm::mat4(), bone->translation);

				nodeTransformation = translationM * rotationM * scalingM;
			}
			else
				nodeTransformation = bone->nodeTransformation;
		}

		bone->nodeTransformation = nodeTransformation;
	}*/

	//glm::mat4 globalTransformation = parentTransform * bone->nodeTransformation;

	if (bRagdoll && bone->bHasRigidBody) {
		btTransform transform = bone->rigidBody->getCenterOfMassTransform();
		glm::mat4 rigidBodyTransform;
		transform.getOpenGLMatrix(glm::value_ptr(rigidBodyTransform));
		bone->globalTransformation = glm::translate(rigidBodyTransform, -bone->rigidBodyOffset);
	}
	else
		bone->globalTransformation = parentTransform * bone->nodeTransformation;

	bone->finalTransformation = bone->globalTransformation * bone->boneOffset;

	for (auto& it : bone->children)
		updateBoneTransforms(it, bone->globalTransformation);
}