コード例 #1
0
 public AliceFileBuilder(String inputAliceClassFile = @"Alice\AdultPerson.a3c", int framesPerSegment = 25, int maxSegments = 50, string animationClassName = "KinectAnimation", string outputDirectory = ".")
 {
     aliceGenerator = new AliceCodeGenerator();
     aliceKinect    = new AliceKinect(inputAliceClassFile);
     // note: it's approx. 10 statements per frame
     FramesPerSegment   = framesPerSegment;
     MaxSegments        = maxSegments;
     AnimationClassName = animationClassName;
     OutputDirectory    = outputDirectory;
 }
コード例 #2
0
        /// <summary>
        /// Generates Alice code for rotating a Biped's joints using another object present in the scene.
        /// The object is placed at each of the skeleton's joints, and then in Alice the parent joint is is pointed at the object to create the desired rotation.
        /// </summary>
        /// <param name="skeleton">The Kinect skeleton to calculate joint rotations from</param>
        /// <returns>A string of Alice code that rotates the joints into their final positions according to the provided Kinect skeleton</returns>
        public void GetJointsCode(Skeleton skeleton, AliceKinect aliceKinect)
        {
            const double twoPi = Math.PI;
            // compute the final positions for each joint and add the Alice code to the stringbuilder
            SkeletonPoint fromJoint;
            SkeletonPoint toJoint;
            SkeletonPoint adjustedDifference;

            for (int i = 0; i < boneData.Length; i++)
            {
                fromJoint = skeleton.Joints[boneData[i].KinectJointFrom].Position;
                toJoint   = skeleton.Joints[boneData[i].KinectJointTo].Position;
                // adjust the position difference between the two joints so that it matches the length of the Alice joint
                // to do this,
                //		(1) get the difference [subtract],
                //		(2) get a unit vector [normalize], and
                //		(3) multiply by the length of the bone
                adjustedDifference = toJoint
                                     .Subtract(fromJoint)
                                     .Normalize()
                                     .Multiply(boneData[i].JointLength);
                // the adjusted difference needs to be added to the final position of the 'from' joint,
                // which is stored in a dictionary and has been computed already if the values in boneData are ordered correctly
                // ~ it's kind of a dynamic programming approach in that it avoids repeated calculation of the previous joints
                var finalPosition = finalPositions[boneData[i].KinectJointFrom].Add(adjustedDifference);
                finalPositions[boneData[i].KinectJointTo] = finalPosition;

                var rotation   = skeleton.BoneOrientations[boneData[i].KinectJointFrom].HierarchicalRotation.Quaternion;
                var rollAmount = rotation.Y / twoPi;

                // add the Alice code
                // (ignore rotations from the neck and pelvis for now, which screw stuff up)
                if (!ignore.Contains(boneData[i].AliceJointFrom))
                {
                    // position the box and point the joint at it
                    aliceKinect.addSetBoxPositionRelativeToVehicle(finalPosition.X, finalPosition.Y, finalPosition.Z);
                    aliceKinect.addPointAt(boneData[i].AliceJointFrom);
                    // roll the bone to match the Kinect data
                    aliceKinect.addRoll(boneData[i].AliceJointFrom, rollAmount, finalPosition.X > 0 ? RollDirection.LEFT : RollDirection.RIGHT);
                    // if the final joint position was behind its parent joint, the parent needs to be rolled 180 degrees (0.5 rotations)
                    // otherwise the joint gets turned around and everything looks weird (twisted spines and knees and such)
                    if (finalPosition.Z > 0 && !rotationIgnore.Contains(boneData[i].AliceJointFrom))
                    {
                        aliceKinect.addRoll(boneData[i].AliceJointFrom, 0.5, RollDirection.LEFT);
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Generates Alice code for moving the entire Biped (allows the Biped to bounce a little during a walking animation, for example).
        /// </summary>
        /// <param name="skeleton">The Kinect skeleton to calculate movements from</param>
        /// <returns>A string of Alice code that executes a Biped's movements</returns>
        public void GetMovementCode(Skeleton skeleton, AliceKinect aliceKinect)
        {
            // get the pelvis
            var pelvis = skeleton.Joints[JointType.HipCenter].Position;

            // set the pelvis as the original root if it hasn't been set yet (should happen on the first frame after init() only)
            if (!originalRootPositionSet)
            {
                originalRootPosition    = pelvis;
                originalRootPositionSet = true;
            }
            // get the position difference between the original root position and the current position of the root
            var moveDifference = pelvis.Subtract(originalRootPosition).Normalize().Multiply(0.25f);

            // this moving algorithm attempts to use absolute positioning rather than relative positioning (adjusting based on the previous position)
            // in order to stop Alice characters from drifting away after the animation has run a few iterations
            // 1. move a box that does not have the biped as a vehicle to the desired position
            aliceKinect.addSetRootPositionRelativeToVehicle(0, moveDifference.Y, 0);
            // 2. move the person to the box
            aliceKinect.addMoveToRoot();
        }