Пример #1
0
void RotateCam(int x, int y)
{
	float axis_x = 0;
	float axis_y = 0;
	if (x != oldXM) {
		if ((float)(x - oldXM) > 0)
			axis_x = 1;
		else
			axis_x = -1;

		oldXM = x;
	}
	if (y != oldYM) {
		if ((float)(y - oldYM) > 0)
			axis_y = 1;
		else
			axis_y = -1;

		oldYM = y;
	}


	rot_x += axis_x*xSpeed*0.02;
	rot_y += axis_y*ySpeed*0.02;

	rot_x = ClampAngle(rot_x, -80, 80);
	rot_y = ClampAngle(rot_y, -80, 20);
}
Пример #2
0
/**
 * @brief Derives Euler angles for the specified directional vector.
 */
void VectorAngles(const vec3_t vector, vec3_t angles) {

	const vec_t forward = sqrt(vector[0] * vector[0] + vector[1] * vector[1]);

	vec_t pitch = ClampAngle(-Degrees(atan2(vector[2], forward)));
	vec_t yaw = ClampAngle(Degrees(atan2(vector[1], vector[0])));

	VectorSet(angles, pitch, yaw, 0.0);
}
Пример #3
0
void ClampAngles(Vector &angles)
{
   ClampAngle(angles.x);
   ClampAngle(angles.y);
   angles.z = 0.0;
}
Пример #4
0
void PmxBoneSolveInverseKinematics(PMX_BONE* bone)
{
	PMX_IK_CONSTRAINT *constraints = (PMX_IK_CONSTRAINT*)bone->constraints->buffer;
	float root_bone_position[3];
	const float angle_limit = bone->angle_limit;
	const int num_constraints = (int)bone->constraints->num_data;
	const int num_iteration = bone->num_iteration;
	const int num_half_of_iteration = num_iteration / 2;
	PMX_BONE *effector_bone = (PMX_BONE*)bone->interface_data.effector_bone;
	float original_target_rotation[4];
	float joint_rotation[4] = IDENTITY_QUATERNION;
	float new_joint_local_rotation[4];
	float matrix[9];
	float local_effector_position[3] = {0};
	float local_root_bone_position[3] = {0};
	float local_axis[3] = {0};
	int i, j, k;

	if((bone->flags & PMX_BONE_FLAG_HAS_INVERSE_KINEMATICS) == 0)
	{
		return;
	}

	BtTransformGetOrigin(bone->world_transform, root_bone_position);
	COPY_VECTOR4(original_target_rotation, effector_bone->local_rotation);

	for(i=0; i<num_iteration; i++)
	{
		int perform_constraint = i < num_half_of_iteration;
		for(j=0; j<num_constraints; j++)
		{
			PMX_IK_CONSTRAINT *constraint = &constraints[j];
			PMX_BONE *joint_bone = constraint->joint_bone;
			float current_effector_position[3];
			void *joint_bone_transform = BtTransformCopy(joint_bone->world_transform);
			void *inversed_joint_bone_transform = BtTransformCopy(joint_bone->world_transform);
			float dot;
			float new_angle_limit;
			float angle;
			float value;

			BtTransformGetOrigin(effector_bone->world_transform, current_effector_position);
			BtTransformInverse(inversed_joint_bone_transform);

			BtTransformMultiVector3(inversed_joint_bone_transform, root_bone_position, local_root_bone_position);
			Normalize3DVector(local_root_bone_position);
			BtTransformMultiVector3(inversed_joint_bone_transform, current_effector_position, local_effector_position);
			Normalize3DVector(local_effector_position);
			dot = Dot3DVector(local_root_bone_position, local_effector_position);
			if(FuzzyZero(dot) != 0)
			{
				break;
			}
			Cross3DVector(local_axis, local_effector_position, local_root_bone_position);
			SafeNormalize3DVector(local_axis);
			new_angle_limit = angle_limit * (j + 1) * 2;
			/*if(dot < -1)
			{
				angle = -1;
			}
			else if(dot > 1)
			{
				angle = 1;
			}
			else
			{
				angle = acosf(dot);
			}*/
			value = dot;
			value = ExtendedFuzzyZero(1.0f - value) ? 1.0f : ExtendedFuzzyZero(1.0f + value) ? -1.0f : value;
			angle = acosf(value);
			CLAMPED(angle, - new_angle_limit, new_angle_limit);
			QuaternionSetRotation(joint_rotation, local_axis, angle);
			if(constraint->has_angle_limit != FALSE && perform_constraint != FALSE)
			{
				float lower_limit[3];
				float upper_limit[3];

				COPY_VECTOR3(lower_limit, constraint->lower_limit);
				COPY_VECTOR3(upper_limit, constraint->upper_limit);

				if(i == 0)
				{
					if(FuzzyZero(lower_limit[1]) && FuzzyZero(upper_limit[1])
						&& FuzzyZero(lower_limit[2]) && FuzzyZero(upper_limit[2]))
					{
						local_axis[0] = 1;
						local_axis[1] = 0;
						local_axis[2] = 0;
					}
					else if(FuzzyZero(lower_limit[0]) && FuzzyZero(upper_limit[0])
						&& FuzzyZero(lower_limit[2]) && FuzzyZero(upper_limit[2]))
					{
						local_axis[0] = 0;
						local_axis[1] = 1;
						local_axis[2] = 0;
					}
					else if(FuzzyZero(lower_limit[0]) && FuzzyZero(upper_limit[0])
						&& FuzzyZero(lower_limit[1]) && FuzzyZero(upper_limit[1]))
					{
						local_axis[0] = 0;
						local_axis[1] = 0;
						local_axis[2] = 1;
					}
					QuaternionSetRotation(joint_rotation, local_axis, angle);
				}
				else
				{
					float x1, y1, z1, x2, y2, z2, x3, y3, z3;
					Matrix3x3SetRotation(matrix, joint_rotation);
					Matrix3x3GetEulerZYX(matrix, &z1, &y1, &x1);
					Matrix3x3SetRotation(matrix, joint_bone->local_rotation);
					Matrix3x3GetEulerZYX(matrix, &z2, &y2, &x2);
					x3 = x1 + x2,	y3 = y1 + y2,	z3 = z1 + z2;
					x1 = ClampAngle(lower_limit[0], upper_limit[0], x3, x1);
					y1 = ClampAngle(lower_limit[1], upper_limit[1], y3, y1);
					z1 = ClampAngle(lower_limit[2], upper_limit[2], z3, z1);
					QuaternionSetEulerZYX(joint_rotation, z1, y1, x1);
				}
				COPY_VECTOR4(new_joint_local_rotation, joint_rotation);
				MultiQuaternion(new_joint_local_rotation, joint_bone->local_rotation);
			}
			else if(i == 0)
			{
				//COPY_VECTOR4(new_joint_local_rotation, joint_bone->local_rotation);
				//MultiQuaternion(new_joint_local_rotation, joint_rotation);
				COPY_VECTOR4(new_joint_local_rotation, joint_rotation);
				MultiQuaternion(new_joint_local_rotation, joint_bone->local_rotation);
			}
			else
			{
				//COPY_VECTOR4(new_joint_local_rotation, joint_rotation);
				//MultiQuaternion(new_joint_local_rotation, joint_bone->local_rotation);
				COPY_VECTOR4(new_joint_local_rotation, joint_bone->local_rotation);
				MultiQuaternion(new_joint_local_rotation, joint_rotation);
			}
			PmxBoneSetLocalOrientation(joint_bone, new_joint_local_rotation);
			COPY_VECTOR4(joint_bone->joint_rotation, joint_rotation);

			for(k=j; k>=0; k--)
			{
				PMX_IK_CONSTRAINT *ik = &constraints[k];
				PMX_BONE *joint = ik->joint_bone;
				PmxBoneUpdateWorldTransformSimple(joint);
			}
			PmxBoneUpdateWorldTransformSimple(effector_bone);

			DeleteBtTransform(joint_bone_transform);
			DeleteBtTransform(inversed_joint_bone_transform);
		}
	}

	PmxBoneSetLocalOrientation(effector_bone, original_target_rotation);
}