private void Pose() { // Make sure aiming target is not too close (might make the solver instable when the target is closer to the first bone than the last bone is). LimitAimTarget(); // Get the aiming direction Vector3 direction = (aim.solver.IKPosition - aim.solver.bones[0].transform.position); // Getting the direction relative to the root transform Vector3 localDirection = transform.InverseTransformDirection(direction); // Get the Pose from AimPoser aimPose = aimPoser.GetPose(localDirection); // If the Pose has changed if (aimPose != lastPose) { // Increase the angle buffer of the pose so we won't switch back too soon if the direction changes a bit aimPoser.SetPoseActive(aimPose); // Store the pose so we know if it changes lastPose = aimPose; } // Direct blending foreach (AimPoser.Pose pose in aimPoser.poses) { if (pose == aimPose) { DirectCrossFade(pose.name, 1f); } else { DirectCrossFade(pose.name, 0f); } } }
private static void DrawPose(AimPoser.Pose pose, Vector3 position, Quaternion rotation, Color color) { if (pose.pitch <= 0f || pose.yaw <= 0f) { return; } if (pose.direction == Vector3.zero) { return; } Handles.color = color; GUI.color = color; Vector3 up = rotation * Vector3.up; Vector3 normalizedPoseDirection = pose.direction.normalized; Vector3 direction = rotation * normalizedPoseDirection; // Direction and label Handles.DrawLine(position, position + direction); Handles.ConeCap(0, position + direction, Quaternion.LookRotation(direction), 0.05f); Handles.Label(position + direction.normalized * 1.1f, pose.name); if (pose.yaw >= 180f && pose.pitch >= 180f) { Handles.color = Color.white; GUI.color = Color.white; return; } Quaternion halfYaw = Quaternion.AngleAxis(pose.yaw, up); float directionPitch = Vector3.Angle(up, direction); Vector3 crossRight = halfYaw * Vector3.Cross(up, direction); Vector3 crossLeft = Quaternion.Inverse(halfYaw) * Vector3.Cross(up, direction); bool isVertical = normalizedPoseDirection == Vector3.up || normalizedPoseDirection == Vector3.down; if (isVertical) { crossRight = halfYaw * Vector3.right; crossLeft = Quaternion.Inverse(halfYaw) * Vector3.right; } float minPitch = Mathf.Clamp(directionPitch - pose.pitch, 0f, 180f); float maxPitch = Mathf.Clamp(directionPitch + pose.pitch, 0f, 180f); Quaternion upToCornerUpperRight = Quaternion.AngleAxis(minPitch, crossRight); Quaternion upToCornerLowerRight = Quaternion.AngleAxis(maxPitch, crossRight); Quaternion upToCornerUpperLeft = Quaternion.AngleAxis(minPitch, crossLeft); Quaternion upToCornerLowerLeft = Quaternion.AngleAxis(maxPitch, crossLeft); Vector3 toCornerUpperRight = upToCornerUpperRight * up; Vector3 toCornerLowerRight = upToCornerLowerRight * up; Vector3 toCornerUpperLeft = upToCornerUpperLeft * up; Vector3 toCornerLowerLeft = upToCornerLowerLeft * up; if (pose.yaw < 180f) { Handles.DrawLine(position, position + toCornerUpperRight); Handles.DrawLine(position, position + toCornerUpperLeft); Handles.DrawLine(position, position + toCornerLowerRight); Handles.DrawLine(position, position + toCornerLowerLeft); } Vector3 d = direction; if (isVertical) { d = Vector3.forward; } if (pose.pitch < 180f) { DrawPolyLineOnSphere(position, toCornerUpperLeft, toCornerUpperRight, d, Vector3.up, color); DrawPolyLineOnSphere(position, toCornerLowerLeft, toCornerLowerRight, d, Vector3.up, color); } if (pose.yaw < 180f) { DrawPolyLineOnSphere(position, toCornerUpperLeft, toCornerLowerLeft, Quaternion.Inverse(halfYaw) * d, crossLeft, color); DrawPolyLineOnSphere(position, toCornerUpperRight, toCornerLowerRight, halfYaw * d, crossRight, color); } Handles.color = Color.white; GUI.color = Color.white; }