public void Process(ref MoCapData data)
        {
            if (!enabled)
            {
                return;
            }

            switch (axis)
            {
            case Axis.X_Axis:
                data.pos.x = -data.pos.x;
                data.rot.x = -data.rot.x;
                data.rot.w = -data.rot.w;
                break;

            case Axis.Y_Axis:
                data.pos.y = -data.pos.y;
                // TODO: not fully functional with rotation. Why?
                //data.rot.y = -data.rot.y;
                //data.rot.w = -data.rot.w;
                break;

            case Axis.Z_Axis:
                data.pos.z = -data.pos.z;
                data.rot.z = -data.rot.z;
                data.rot.w = -data.rot.w;
                break;
            }
        }
Esempio n. 2
0
        public void Process(ref MoCapData data)
        {
            if (!enabled)
            {
                return;
            }

            // build relative distance to centre object
            Vector3 offset = centreObject.localPosition;

            data.pos -= offset;

            // calculate distance (possibly ignoring Y)
            Vector3 distVec = data.pos;

            if (ignoreY_Axis)
            {
                distVec.y = 0;
            }
            float scaleFactor = curve.Evaluate(distVec.magnitude);

            // scale object position
            data.pos.x *= scaleFactor;
            data.pos.z *= scaleFactor;
            if (!ignoreY_Axis)
            {
                data.pos.y *= scaleFactor;
            }

            data.length *= scaleFactor;

            // turn back to absolute coordinate
            data.pos += offset;
        }
		public void Process(ref MoCapData data)
		{
			if (!enabled) return;

			switch (axis)
			{
				case Axis.X_Axis:
					data.pos.x = -data.pos.x;
					data.rot.x = -data.rot.x;
					data.rot.w = -data.rot.w;
					break;

				case Axis.Y_Axis:
					data.pos.y = -data.pos.y;
					// TODO: not fully functional with rotation. Why?
					//data.rot.y = -data.rot.y;
					//data.rot.w = -data.rot.w;
					break;

				case Axis.Z_Axis:
					data.pos.z = -data.pos.z;
					data.rot.z = -data.rot.z;
					data.rot.w = -data.rot.w;
					break;
			}
		}
        public float length;                    // length of bone


        /// <summary>
        /// Creates a cloned MoCap data object.
        /// </summary>
        ///
        public MoCapData(MoCapData clone)
        {
            buffer  = clone.buffer;
            pos     = clone.pos;
            rot     = clone.rot;
            tracked = clone.tracked;
            length  = clone.length;
        }
		public void Process(ref MoCapData data)
		{
			// if (!enabled) return;

			// The actual delay happens in the MoCapDataBuffer class
			// by storing the data in a FIFO the length of which
			// is determined by the "delay" value of this component
		}
Esempio n. 6
0
        //// <summary>
        /// Called once per frame. Updates the model based on the bone rotations and positions.
        /// </summary>
        ///
        void Update()
        {
            // create bone array if necessary
            if ((boneList == null) && (actor != null))
            {
                MatchBones(actor.bones);
            }

            if (boneList == null)
            {
                return;
            }

            // update bones
            Quaternion rot = new Quaternion();

            foreach (KeyValuePair <Bone, BoneObject> entry in boneList)
            {
                Bone       bone = entry.Key;
                BoneObject obj  = entry.Value;
                MoCapData  data = bone.buffer.RunModifiers(modifiers);

                // update bone game object
                if (data.tracked)
                {
                    if ((trackingUsage == TrackingUsage.PositionAndRotation) ||
                        (bone.parent == null))
                    {
                        // change position only when desired, or when a root bone
                        obj.node.transform.localRotation = Quaternion.identity;
                        obj.node.transform.localPosition = data.pos;
                    }

                    rot = Quaternion.identity;

                    string transforms = obj.entry.axisTransformation;
                    foreach (char c in transforms)
                    {
                        switch (c)
                        {
                        case 'X': rot *= Quaternion.Euler(90, 0, 0); break;

                        case 'x': rot *= Quaternion.Euler(-90, 0, 0); break;

                        case 'Y': rot *= Quaternion.Euler(0, 90, 0); break;

                        case 'y': rot *= Quaternion.Euler(0, -90, 0); break;

                        case 'Z': rot *= Quaternion.Euler(0, 0, 90); break;

                        case 'z': rot *= Quaternion.Euler(0, 0, -90); break;
                        }
                    }

                    obj.node.transform.localRotation = data.rot * rot;
                }
            }
        }
Esempio n. 7
0
 public void Process(ref MoCapData data)
 {
     if (!enabled)
     {
         return;
     }
     data.pos    *= scaleFactor;
     data.length *= scaleFactor;
 }
        /// <summary>
        /// Runs a chain of MoCap data modifiers on the buffer.
        /// </summary>
        /// <param name="modifiers">The array of modifiers to run</param>
        /// <returns>the result of running the modifier chain</returns>
        ///
        public MoCapData RunModifiers(IMoCapDataModifier[] modifiers)
        {
            MoCapData result = new MoCapData(GetElement(0));

            foreach (IMoCapDataModifier m in modifiers)
            {
                m.Process(ref result);
            }
            return(result);
        }
		public void Process(ref MoCapData data)
		{
			if (!enabled) return;
			switch (influence)
			{
				case Influence.Position: // TODO: Not very nice implementation so far
					data.pos.x += amount * Mathf.PerlinNoise(data.pos.y, data.pos.z);
					data.pos.y += amount * Mathf.PerlinNoise(data.pos.x, data.pos.z);
					data.pos.z += amount * Mathf.PerlinNoise(data.pos.x, data.pos.y);
					break;
			}
		}
		public void Process(ref MoCapData data)
		{
			if (!enabled) return;

			foreach (string name in names)
			{
				if (data.buffer.Name.Equals(namePrefix + name))
				{
					data.tracked = false;
					break;
				}
			}
		}
Esempio n. 11
0
        //// <summary>
        /// Called once per frame.
        /// </summary>
        ///
        void Update()
        {
            // create marker position array if necessary
            // but only when tracking is OK, otherwise the bone lengths are undefined
            if ((skeletonNode == null) && (actor != null) && actor.bones[0].tracked)
            {
                CreateBones(actor.bones);
            }

            if (skeletonNode == null)
            {
                return;
            }

            // update bones
            foreach (KeyValuePair <Bone, BoneObject> entry in boneList)
            {
                BoneObject obj  = entry.Value;
                Bone       bone = entry.Key;
                MoCapData  data = bone.buffer.RunModifiers(modifiers);

                // update bone game object
                if (data.tracked)
                {
                    obj.node.transform.localPosition = data.pos;
                    obj.node.transform.localRotation = data.rot;

                    // update length of representation
                    GameObject boneRepresentation = obj.visual;
                    if (boneRepresentation != null)
                    {
                        boneRepresentation.transform.localScale = data.length * Vector3.one;
                    }

                    obj.node.SetActive(true);

                    if (bone.parent != null)
                    {
                        Debug.DrawLine(
                            obj.node.transform.parent.position,
                            obj.node.transform.position,
                            Color.red);
                    }
                }
                else
                {
                    // bone not tracked anymore
                    obj.node.SetActive(false);
                }
            }
        }
		public void Process(ref MoCapData data)
		{
			if (!enabled) return;

			foreach (string name in names)
			{
				if (data.buffer.Name.Equals(namePrefix + name))
				{
					data.pos    *= scaleFactor;
					data.length *= scaleFactor;
					break;
				}
			}
		}
 /// <summary>
 /// Makes sure the buffer pipeline has at least this amount of elements.
 /// If not, the buffer is enlarged.
 /// </summary>
 /// <param name="minimumCapacity">the minimum amount of elements in the pieline</param>
 ///
 public void EnsureCapacity(int minimumCapacity)
 {
     if ((pipeline == null) || (minimumCapacity > pipeline.Length))
     {
         // create new buffer
         pipeline = new MoCapData[minimumCapacity];
         for (int i = 0; i < pipeline.Length; i++)
         {
             pipeline[i] = new MoCapData(this);
         }
         pipelineIndex = 0;
         firstPush     = true;
         // Debug.Log("Extended buffer size to " + minimumCapacity + " for " + GetName());
     }
 }
Esempio n. 14
0
 public void Process(ref MoCapData data)
 {
     if (!enabled)
     {
         return;
     }
     switch (influence)
     {
     case Influence.Position:                     // TODO: Not very nice implementation so far
         data.pos.x += amount * Mathf.PerlinNoise(data.pos.y, data.pos.z);
         data.pos.y += amount * Mathf.PerlinNoise(data.pos.x, data.pos.z);
         data.pos.z += amount * Mathf.PerlinNoise(data.pos.x, data.pos.y);
         break;
     }
 }
        private void UpdateObject()
        {
            // create node hierarchy if not already built.
            // but only when tracking is OK, otherwise the bone lengths are undefined
            if ((rootNode == null) && (controllingBone != null))
            {
                CreateHierarchy();
            }

            if (controllingBone == null)
            {
                return;
            }

            // update bones
            foreach (KeyValuePair <Bone, GameObject> pair in boneList)
            {
                GameObject obj  = pair.Value;
                Bone       bone = pair.Key;
                MoCapData  data = bone.buffer.RunModifiers(modifiers);

                // update hierarchy object
                if (data.tracked)
                {
                    if ((trackingUsage == TrackingUsage.RotationOnly) ||
                        (trackingUsage == TrackingUsage.PositionAndRotation))
                    {
                        obj.transform.localRotation = data.rot * Quaternion.Euler(RotationOffset);
                    }
                    if ((trackingUsage == TrackingUsage.PositionOnly) ||
                        (trackingUsage == TrackingUsage.PositionAndRotation))
                    {
                        obj.transform.localPosition = data.pos + (obj.transform.localRotation * PositionOffset);
                    }
                    obj.SetActive(true);
                    disabled = false;
                }
                else
                {
                    // bone not tracked anymore, freeze or disable
                    if (trackingLostBehaviour == TrackingLostBehaviour.Disable)
                    {
                        obj.SetActive(false);
                        disabled = true;
                    }
                }
            }
        }
Esempio n. 16
0
        public void Process(ref MoCapData data)
        {
            if (!enabled)
            {
                return;
            }

            foreach (string name in names)
            {
                if (data.buffer.GetName().Equals(namePrefix + name))
                {
                    data.tracked = false;
                    break;
                }
            }
        }
        public void Process(ref MoCapData data)
        {
            if (!enabled)
            {
                return;
            }

            foreach (string name in names)
            {
                if (data.buffer.GetName().Equals(namePrefix + name))
                {
                    data.pos    *= scaleFactor;
                    data.length *= scaleFactor;
                    break;
                }
            }
        }
		/// <summary>
		/// Creates a new MoCap data buffer object.
		/// </summary>
		/// <param name="name">name of this buffer</param>
		/// <param name="owner">game object that owns this buffer</param>
		/// <param name="obj">game object to associate with this buffer</param>
		/// <param name="data">arbitrary object to associate with this buffer</param>
		/// 
		public MoCapDataBuffer(string name, GameObject owner, GameObject obj, System.Object data = null)
		{
			// find any manipulators and store them
			modifiers = owner.GetComponents<IModifier>();

			// specifically find the delay manipulator and set the FIFO size accordingly
			DelayModifier delayComponent = owner.GetComponent<DelayModifier>();
			float delay = (delayComponent != null) ? delayComponent.delay : 0;
			int   delayInFrames = Mathf.Max(1, 1 + (int)(delay * 60)); // TODO: Find out or define framerate somewhere central
			pipeline = new MoCapData[delayInFrames];
			for (int i = 0; i < pipeline.Length; i++)
			{
				pipeline[i] = new MoCapData(this);
			}
			index = 0;

			firstPush       = true;
			this.Name       = name;
			this.GameObject = obj;
			this.DataObject = data;
		}
        //// <summary>
        /// Called once per frame.
        /// </summary>
        ///
        void Update()
        {
            if (markerNode == null)
            {
                if (actor != null)
                {
                    // did we just find the actor > create markers
                    CreateMarkers(actor.markers);
                }
                else
                {
                    // nothing to work with > get out
                    return;
                }
            }

            // update marker positions
            foreach (KeyValuePair <Marker, GameObject> entry in markerList)
            {
                GameObject obj    = entry.Value;
                Marker     marker = entry.Key;
                MoCapData  data   = marker.buffer.RunModifiers(modifiers);

                // update marker game object
                if (data.tracked)
                {
                    obj.transform.localPosition = data.pos;
                    obj.SetActive(true);
                }
                else
                {
                    // marker has vanished
                    obj.SetActive(false);
                }
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Filtering of mocap data with a somewhat crude approach to handling quaternions
        /// as described in
        /// </summary>
        /// <param name="data">the MoCap data item to process</param>
        ///
        public void _Process(ref MoCapData data)
        {
            if (!enabled)
            {
                return;
            }

            // has the filter time changed?
            if (filterTime != oldFilterTime)
            {
                InitialiseFilter();
            }

            Vector3   pos = Vector3.zero;
            float     qx, qy, qz, qw; qx = qy = qz = qw = 0;
            float     length = 0;
            MoCapData first  = data;

            float factorSum  = 0;
            bool  firstEntry = true;

            for (int idx = 0; idx < filter.Length; idx++)
            {
                MoCapData d = data.buffer.GetElement(idx);
                if (d.tracked)
                {
                    // determine first valid entry
                    if (firstEntry)
                    {
                        first      = d;
                        firstEntry = false;
                    }

                    // position and length: standard application of FIR filter
                    float factor = filter[idx];
                    factorSum += factor;

                    pos    += d.pos * factor;
                    length += d.length * factor;

                    // quaternions: consider q = -q condition by checking dot product with first element
                    float dot = first.rot.x * d.rot.x + first.rot.y * d.rot.y + first.rot.z * d.rot.z + first.rot.w * d.rot.w;
                    if (dot < 0)
                    {
                        factor = -factor;
                    }
                    qx += d.rot.x * factor;
                    qy += d.rot.y * factor;
                    qz += d.rot.z * factor;
                    qw += d.rot.w * factor;
                }
            }

            // done adding up: now "normalize"
            if (factorSum > 0)
            {
                pos /= factorSum;
                float mag = Mathf.Sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
                qx     /= mag; qy /= mag; qz /= mag; qw /= mag;
                length /= factorSum;
            }

            // and write back into result
            data.pos = pos;
            data.rot.Set(qx, qy, qz, qw);
            data.tracked = !firstEntry;
            data.length  = length;
        }
 public void Process(ref MoCapData data)
 {
     // replace by object further down in the pipeline depending on the delay
     data = data.buffer.GetElement(GetRequiredBufferSize() - 1);
 }
Esempio n. 22
0
        /// <summary>
        /// Filtering of MoCap data using the matrix eigenvalue approach described in
        /// https://github.com/tolgabirdal/averaging_quaternions/blob/master/wavg_quaternion_markley.m
        /// Eigenvalue calculation using the Power Iteration algorithm described in
        /// http://www.bragitoff.com/2015/10/eigen-value-and-eigen-vector-of-a-matrix-by-iterative-method-c-program/
        /// </summary>
        /// <param name="data">the MoCap data item to process</param>
        ///
        public void Process(ref MoCapData data)
        {
            if (!enabled)
            {
                return;
            }

            // has the filter time changed?
            if (filterTime != oldFilterTime)
            {
                InitialiseFilter();
            }

            Vector3   pos    = Vector3.zero;
            Matrix4x4 rot    = Matrix4x4.zero;
            float     length = 0;
            MoCapData first  = data;
            Vector4   v      = Vector4.zero;

            float factorSum  = 0;
            bool  firstEntry = true;

            for (int idx = 0; idx < filter.Length; idx++)
            {
                MoCapData d = data.buffer.GetElement(idx);
                if (d.tracked)
                {
                    // determine first valid entry
                    if (firstEntry)
                    {
                        first      = d;
                        firstEntry = false;
                    }

                    // position and length: standard application of FIR filter
                    float factor = filter[idx];
                    factorSum += factor;

                    pos    += d.pos * factor;
                    length += d.length * factor;

                    // quaternions: build up matrix
                    Add(ref rot, ref d.rot, factor);
                }
            }

            // done adding up: now "normalize"
            if (factorSum > 0)
            {
                pos /= factorSum;
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        rot[i, j] /= factorSum;
                    }
                }
                length /= factorSum;
            }

            // and write back into result
            data.pos     = pos;
            data.tracked = !firstEntry;
            data.length  = length;
            // average quaterion is eigenvector of accumulated matrix
            v.Set(first.rot.x, first.rot.w, first.rot.z, first.rot.w);
            v = FindEigenvector(rot, v);
            data.rot.Set(v.x, v.y, v.z, v.w);
        }
		public void Process(ref MoCapData data)
		{
			if (!enabled) return;
			data.pos *= scaleFactor;
			data.length *= scaleFactor;
		}