UnityEngine.Quaternion.Angle(UnityEngine.Quaternion, UnityEngine.Quaternion)

Here are the examples of the csharp api UnityEngine.Quaternion.Angle(UnityEngine.Quaternion, UnityEngine.Quaternion) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

21 Examples 7

19 View Source File : Extensions.cs
License : GNU General Public License v3.0
Project Creator : aelariane

public static bool AlmostEquals(this Quaternion target, Quaternion second, float maxAngle)
    {
        return Quaternion.Angle(target, second) < maxAngle;
    }

19 View Source File : MovementUpdate.cs
License : GNU General Public License v3.0
Project Creator : aelariane

private void Update()
    {
        if (this.disabled)
        {
            return;
        }
        if (Network.peerType == NetworkPeerType.Disconnected)
        {
            return;
        }
        if (Network.peerType == NetworkPeerType.Connecting)
        {
            return;
        }
        if (base.networkView.isMine)
        {
            if (Vector3.Distance(base.transform.position, this.lastPosition) >= 0.5f)
            {
                this.lastPosition = base.transform.position;
                base.networkView.RPC("updateMovement", RPCMode.Others, new object[]
                {
                    base.transform.position,
                    base.transform.rotation,
                    base.transform.localScale,
                    base.rigidbody.velocity
                });
            }
            else if (Vector3.Distance(base.transform.rigidbody.velocity, this.lastVelocity) >= 0.1f)
            {
                this.lastVelocity = base.transform.rigidbody.velocity;
                base.networkView.RPC("updateMovement", RPCMode.Others, new object[]
                {
                    base.transform.position,
                    base.transform.rotation,
                    base.transform.localScale,
                    base.rigidbody.velocity
                });
            }
            else if (Quaternion.Angle(base.transform.rotation, this.lastRotation) >= 1f)
            {
                this.lastRotation = base.transform.rotation;
                base.networkView.RPC("updateMovement", RPCMode.Others, new object[]
                {
                    base.transform.position,
                    base.transform.rotation,
                    base.transform.localScale,
                    base.rigidbody.velocity
                });
            }
        }
        else
        {
            base.transform.position = Vector3.Slerp(base.transform.position, this.targetPosition, Time.deltaTime * 2f);
        }
    }

19 View Source File : Interpolator.cs
License : MIT License
Project Creator : dag10

public void Update()
        {
            bool interpOccuredThisFrame = false;

            if (AnimatingPosition)
            {
                Vector3 lerpTargetPosition = targetPosition;
                if (SmoothLerpToTarget)
                {
                    lerpTargetPosition = Vector3.Lerp(transform.position, lerpTargetPosition, SmoothPositionLerpRatio);
                }

                Vector3 newPosition = NonLinearInterpolateTo(transform.position, lerpTargetPosition, Time.deltaTime, PositionPerSecond);
                if ((targetPosition - newPosition).sqrMagnitude <= smallNumber)
                {
                    // Snap to final position
                    newPosition = targetPosition;
                    AnimatingPosition = false;
                }
                else
                {
                    interpOccuredThisFrame = true;
                }

                transform.position = newPosition;

                //calculate interpolatedVelocity and store position for next frame
                PositionVelocity = oldPosition - newPosition;
                oldPosition = newPosition;
            }

            // Determine how far we need to rotate
            if (AnimatingRotation)
            {
                Quaternion lerpTargetRotation = targetRotation;
                if (SmoothLerpToTarget)
                {
                    lerpTargetRotation = Quaternion.Lerp(transform.rotation, lerpTargetRotation, SmoothRotationLerpRatio);
                }

                float angleDiff = Quaternion.Angle(transform.rotation, lerpTargetRotation);
                float speedScale = 1.0f + (Mathf.Pow(angleDiff, RotationSpeedScaler) / 180.0f);
                float ratio = Mathf.Clamp01((speedScale * RotationDegreesPerSecond * Time.deltaTime) / angleDiff);

                if (angleDiff < Mathf.Epsilon)
                {
                    AnimatingRotation = false;
                    transform.rotation = targetRotation;
                }
                else
                {
                    // Only lerp rotation here, as ratio is NaN if angleDiff is 0.0f
                    transform.rotation = Quaternion.Slerp(transform.rotation, lerpTargetRotation, ratio);
                    interpOccuredThisFrame = true;
                }
            }

            // Determine how far we need to rotate
            if (AnimatingLocalRotation)
            {
                Quaternion lerpTargetLocalRotation = targetLocalRotation;
                if (SmoothLerpToTarget)
                {
                    lerpTargetLocalRotation = Quaternion.Lerp(transform.localRotation, lerpTargetLocalRotation, SmoothRotationLerpRatio);
                }

                float angleDiff = Quaternion.Angle(transform.localRotation, lerpTargetLocalRotation);
                float speedScale = 1.0f + (Mathf.Pow(angleDiff, RotationSpeedScaler) / 180.0f);
                float ratio = Mathf.Clamp01((speedScale * RotationDegreesPerSecond * Time.deltaTime) / angleDiff);

                if (angleDiff < Mathf.Epsilon)
                {
                    AnimatingLocalRotation = false;
                    transform.localRotation = targetLocalRotation;
                }
                else
                {
                    // Only lerp rotation here, as ratio is NaN if angleDiff is 0.0f
                    transform.localRotation = Quaternion.Slerp(transform.localRotation, lerpTargetLocalRotation, ratio);
                    interpOccuredThisFrame = true;
                }
            }

            if (AnimatingLocalScale)
            {
                Vector3 lerpTargetLocalScale = targetLocalScale;
                if (SmoothLerpToTarget)
                {
                    lerpTargetLocalScale = Vector3.Lerp(transform.localScale, lerpTargetLocalScale, SmoothScaleLerpRatio);
                }

                Vector3 newScale = NonLinearInterpolateTo(transform.localScale, lerpTargetLocalScale, Time.deltaTime, ScalePerSecond);
                if ((targetLocalScale - newScale).sqrMagnitude <= smallNumber)
                {
                    // Snap to final scale
                    newScale = targetLocalScale;
                    AnimatingLocalScale = false;
                }
                else
                {
                    interpOccuredThisFrame = true;
                }

                transform.localScale = newScale;
            }

            // If all interpolations have completed, stop updating
            if (!interpOccuredThisFrame)
            {
                if (InterpolationDone != null)
                {
                    InterpolationDone();
                }
                enabled = false;
            }
        }

19 View Source File : Throwable.cs
License : MIT License
Project Creator : dag10

private void OnAttachedToHand( Hand hand )
		{
			attached = true;

			onPickUp.Invoke();

			hand.HoverLock( null );

			Rigidbody rb = GetComponent<Rigidbody>();
			rb.isKinematic = true;
			rb.interpolation = RigidbodyInterpolation.None;

			if ( hand.controller == null )
			{
				velocityEstimator.BeginEstimatingVelocity();
			}

			attachTime = Time.time;
			attachPosition = transform.position;
			attachRotation = transform.rotation;

			if ( attachEaseIn )
			{
				attachEaseInTransform = hand.transform;
				if ( !Util.IsNullOrEmpty( attachEaseInAttachmentNames ) )
				{
					float smallestAngle = float.MaxValue;
					for ( int i = 0; i < attachEaseInAttachmentNames.Length; i++ )
					{
						Transform t = hand.GetAttachmentTransform( attachEaseInAttachmentNames[i] );
						float angle = Quaternion.Angle( t.rotation, attachRotation );
						if ( angle < smallestAngle )
						{
							attachEaseInTransform = t;
							smallestAngle = angle;
						}
					}
				}
			}

			snapAttachEaseInCompleted = false;
		}

19 View Source File : MMISceneObject.cs
License : MIT License
Project Creator : Daimler

public bool HasChanged(Transform transform)
            {
                bool hasChanged = false;

                //Check if the position has changed
                if ((lastLocalPosition - transform.localPosition).magnitude > Threshold || (lastGlobalPosition - transform.position).magnitude > Threshold)
                    hasChanged = true;


                //Check if the rotation has changed
                if (Mathf.Abs(Quaternion.Angle(this.lastLocalRotation, transform.localRotation)) > threshold || Mathf.Abs(Quaternion.Angle(this.lastGlobalRotation, transform.rotation)) > Threshold)
                    hasChanged = true;

                //Check if parent has changed
                if (lastParent != transform.parent)
                    hasChanged = true;

                return hasChanged;
            }

19 View Source File : AnimationTracker.cs
License : MIT License
Project Creator : Daimler

public void UpdateStats(Transform transform, float time)
        {
            if (!initialized)
            {
                this.lastPosition = transform.position;

                this.lastRotation = transform.rotation;

                this.initialized = true;
            }

            this.Position = transform.position;
            this.Rotation = transform.rotation;

            this.VelocityVector = (transform.position - this.lastPosition) / time;
            this.AngularVelocity = (UnityEngine.Quaternion.Angle(this.lastRotation, this.Rotation));
            this.Velocity = this.VelocityVector.magnitude;

            this.lastPosition = transform.position;
            this.lastRotation = transform.rotation;
        }

19 View Source File : ArucoTrackingUtil.cs
License : MIT License
Project Creator : KeyMaster-

public static void posRotLowpreplaced(Dictionary<int, PoseData> oldDict, Dictionary<int, PoseData> newDict, float posThreshold, float rotThreshold) {
        posThreshold *= posThreshold; //We'll compare square distances so adjust the threshold accordingly

        //Check all keys and copy over previous pose values if our new changes were not significant enough
        //We are using the newDict here since that already made sure that new markers exist, and old ones were removed.
        //Updating the old dict would mean adding missing ones, and then looping over its keys to find and remove markers that disappeared.
        List<int> keys = new List<int>(newDict.Keys);
        foreach (int key in keys) {
            if (!oldDict.ContainsKey(key)) continue;
            
            PoseData oldPose = oldDict[key];
            PoseData newPose = newDict[key];

            float posDiff = (newPose.pos - oldPose.pos).sqrMagnitude;
            float rotDiff = Quaternion.Angle(newPose.rot, oldPose.rot);

            //If our changes didn't go over the low preplaced, copy over our previous values
            if (posDiff < posThreshold) {
                newPose.pos = oldPose.pos;
            }

            if (rotDiff < rotThreshold) {
                newPose.rot = oldPose.rot;
            }

            newDict[key] = newPose;
        }
    }

19 View Source File : UIPanelInspector.cs
License : MIT License
Project Creator : mamoniem

public void OnSceneGUI ()
	{
		if (Selection.objects.Length > 1) return;

		UICamera cam = UICamera.FindCameraForLayer(mPanel.gameObject.layer);
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6
		if (cam == null || !cam.cachedCamera.isOrthoGraphic) return;
#else
		if (cam == null || !cam.cachedCamera.orthographic) return;
#endif

		NGUIEditorTools.HideMoveTool(true);
		if (!UIWidget.showHandles) return;

		Event e = Event.current;
		int id = GUIUtility.GetControlID(s_Hash, FocusType.Preplacedive);
		EventType type = e.GetTypeForControl(id);
		Transform t = mPanel.cachedTransform;

		Vector3[] handles = UIWidgetInspector.GetHandles(mPanel.worldCorners);

		// Time to figure out what kind of action is underneath the mouse
		UIWidgetInspector.Action actionUnderMouse = mAction;

		Color handlesColor = new Color(0.5f, 0f, 0.5f);
		NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

		if (mPanel.isAncreplacedd)
		{
			UIWidgetInspector.DrawAnchorHandle(mPanel.leftAnchor, mPanel.cachedTransform, handles, 0, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.topAnchor, mPanel.cachedTransform, handles, 1, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.rightAnchor, mPanel.cachedTransform, handles, 2, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.bottomAnchor, mPanel.cachedTransform, handles, 3, id);
		}

		if (type == EventType.Repaint)
		{
			bool showDetails = (mAction == UIWidgetInspector.Action.Scale) || NGUISettings.drawGuides;
			if (mAction == UIWidgetInspector.Action.None && e.modifiers == EventModifiers.Control) showDetails = true;
			if (NGUITools.GetActive(mPanel) && mPanel.parent == null) showDetails = true;
			if (showDetails) NGUIHandles.DrawSize(handles, Mathf.RoundToInt(mPanel.width), Mathf.RoundToInt(mPanel.height));
		}

		bool canResize = (mPanel.clipping != UIDrawCall.Clipping.None);

		// NOTE: Remove this part when it's possible to neatly resize rotated ancreplacedd panels.
		if (canResize && mPanel.isAncreplacedd)
		{
			Quaternion rot = mPanel.cachedTransform.localRotation;
			if (Quaternion.Angle(rot, Quaternion.idenreplacedy) > 0.01f) canResize = false;
		}

		bool[] resizable = new bool[8];

		resizable[4] = canResize;	// left
		resizable[5] = canResize;	// top
		resizable[6] = canResize;	// right
		resizable[7] = canResize;	// bottom

		resizable[0] = resizable[7] && resizable[4]; // bottom-left
		resizable[1] = resizable[5] && resizable[4]; // top-left
		resizable[2] = resizable[5] && resizable[6]; // top-right
		resizable[3] = resizable[7] && resizable[6]; // bottom-right

		UIWidget.Pivot pivotUnderMouse = UIWidgetInspector.GetPivotUnderMouse(handles, e, resizable, true, ref actionUnderMouse);

		switch (type)
		{
			case EventType.Repaint:
			{
				Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
				Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

				if ((v2 - v0).magnitude > 60f)
				{
					Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
					Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

					Handles.BeginGUI();
					{
						for (int i = 0; i < 4; ++i)
							DrawKnob(handles[i], id, resizable[i]);

						if (Mathf.Abs(v1.y - v0.y) > 80f)
						{
							if (mPanel.leftAnchor.target == null || mPanel.leftAnchor.absolute != 0)
								DrawKnob(handles[4], id, resizable[4]);

							if (mPanel.rightAnchor.target == null || mPanel.rightAnchor.absolute != 0)
								DrawKnob(handles[6], id, resizable[6]);
						}

						if (Mathf.Abs(v3.x - v0.x) > 80f)
						{
							if (mPanel.topAnchor.target == null || mPanel.topAnchor.absolute != 0)
								DrawKnob(handles[5], id, resizable[5]);

							if (mPanel.bottomAnchor.target == null || mPanel.bottomAnchor.absolute != 0)
								DrawKnob(handles[7], id, resizable[7]);
						}
					}
					Handles.EndGUI();
				}
			}
			break;

			case EventType.MouseDown:
			{
				if (actionUnderMouse != UIWidgetInspector.Action.None)
				{
					mStartMouse = e.mousePosition;
					mAllowSelection = true;

					if (e.button == 1)
					{
						if (e.modifiers == 0)
						{
							GUIUtility.hotControl = GUIUtility.keyboardControl = id;
							e.Use();
						}
					}
					else if (e.button == 0 && actionUnderMouse != UIWidgetInspector.Action.None &&
						UIWidgetInspector.Raycast(handles, out mStartDrag))
					{
						mWorldPos = t.position;
						mLocalPos = t.localPosition;
						mStartRot = t.localRotation.eulerAngles;
						mStartDir = mStartDrag - t.position;
						mStartCR = mPanel.baseClipRegion;
						mDragPivot = pivotUnderMouse;
						mActionUnderMouse = actionUnderMouse;
						GUIUtility.hotControl = GUIUtility.keyboardControl = id;
						e.Use();
					}
				}
			}
			break;

			case EventType.MouseUp:
			{
				if (GUIUtility.hotControl == id)
				{
					GUIUtility.hotControl = 0;
					GUIUtility.keyboardControl = 0;

					if (e.button < 2)
					{
						bool handled = false;

						if (e.button == 1)
						{
							// Right-click: Open a context menu listing all widgets underneath
							NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
							handled = true;
						}
						else if (mAction == UIWidgetInspector.Action.None)
						{
							if (mAllowSelection)
							{
								// Left-click: Select the topmost widget
								NGUIEditorTools.SelectWidget(e.mousePosition);
								handled = true;
							}
						}
						else
						{
							// Finished dragging something
							Vector3 pos = t.localPosition;
							pos.x = Mathf.Round(pos.x);
							pos.y = Mathf.Round(pos.y);
							pos.z = Mathf.Round(pos.z);
							t.localPosition = pos;
							handled = true;
						}

						if (handled) e.Use();
					}

					// Clear the actions
					mActionUnderMouse = UIWidgetInspector.Action.None;
					mAction = UIWidgetInspector.Action.None;
				}
				else if (mAllowSelection)
				{
					List<UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition);
					if (widgets.Count > 0) Selection.activeGameObject = widgets[0].gameObject;
				}
				mAllowSelection = true;
			}
			break;

			case EventType.MouseDrag:
			{
				// Prevent selection once the drag operation begins
				bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
				if (dragStarted) mAllowSelection = false;

				if (GUIUtility.hotControl == id)
				{
					e.Use();

					if (mAction != UIWidgetInspector.Action.None || mActionUnderMouse != UIWidgetInspector.Action.None)
					{
						Vector3 pos;

						if (UIWidgetInspector.Raycast(handles, out pos))
						{
							if (mAction == UIWidgetInspector.Action.None && mActionUnderMouse != UIWidgetInspector.Action.None)
							{
								// Wait until the mouse moves by more than a few pixels
								if (dragStarted)
								{
									if (mActionUnderMouse == UIWidgetInspector.Action.Move)
									{
										NGUISnap.Recalculate(mPanel);
									}
									else if (mActionUnderMouse == UIWidgetInspector.Action.Rotate)
									{
										mStartRot = t.localRotation.eulerAngles;
										mStartDir = mStartDrag - t.position;
									}
									else if (mActionUnderMouse == UIWidgetInspector.Action.Scale)
									{
										mStartCR = mPanel.baseClipRegion;
										mDragPivot = pivotUnderMouse;
									}
									mAction = actionUnderMouse;
								}
							}

							if (mAction != UIWidgetInspector.Action.None)
							{
								NGUIEditorTools.RegisterUndo("Change Rect", t);
								NGUIEditorTools.RegisterUndo("Change Rect", mPanel);

								if (mAction == UIWidgetInspector.Action.Move)
								{
									Vector3 before = t.position;
									Vector3 beforeLocal = t.localPosition;
									t.position = mWorldPos + (pos - mStartDrag);
									pos = NGUISnap.Snap(t.localPosition, mPanel.localCorners,
										e.modifiers != EventModifiers.Control) - beforeLocal;
									t.position = before;

									NGUIMath.MoveRect(mPanel, pos.x, pos.y);
								}
								else if (mAction == UIWidgetInspector.Action.Rotate)
								{
									Vector3 dir = pos - t.position;
									float angle = Vector3.Angle(mStartDir, dir);

									if (angle > 0f)
									{
										float dot = Vector3.Dot(Vector3.Cross(mStartDir, dir), t.forward);
										if (dot < 0f) angle = -angle;
										angle = mStartRot.z + angle;
										angle = (NGUISnap.allow && e.modifiers != EventModifiers.Control) ?
											Mathf.Round(angle / 15f) * 15f : Mathf.Round(angle);
										t.localRotation = Quaternion.Euler(mStartRot.x, mStartRot.y, angle);
									}
								}
								else if (mAction == UIWidgetInspector.Action.Scale)
								{
									// World-space delta since the drag started
									Vector3 delta = pos - mStartDrag;

									// Adjust the widget's position and scale based on the delta, restricted by the pivot
									AdjustClipping(mPanel, mLocalPos, mStartCR, delta, mDragPivot);
								}
							}
						}
					}
				}
			}
			break;

			case EventType.KeyDown:
			{
				if (e.keyCode == KeyCode.UpArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 0f, 1f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.DownArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 0f, -1f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.LeftArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, -1f, 0f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.RightArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 1f, 0f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.Escape)
				{
					if (GUIUtility.hotControl == id)
					{
						if (mAction != UIWidgetInspector.Action.None)
							Undo.PerformUndo();

						GUIUtility.hotControl = 0;
						GUIUtility.keyboardControl = 0;

						mActionUnderMouse = UIWidgetInspector.Action.None;
						mAction = UIWidgetInspector.Action.None;
						e.Use();
					}
					else Selection.activeGameObject = null;
				}
			}
			break;
		}
	}

19 View Source File : PredictionInterpolation.cs
License : MIT License
Project Creator : microsoft

public void AddAndProcessRemoteBodyForPrediction(RigidBodyPhysicsBridgeInfo rb,
			RigidBodyTransform transform, UnityEngine.Vector3 keyFramedPos,
			UnityEngine.Quaternion keyFramedOrientation, float timeOfSnapshot,
			PredictionTimeParameters timeInfo)
		{
			var collisionInfo = new CollisionSwitchInfo();
			collisionInfo.startPosition = rb.RigidBody.transform.position;
			collisionInfo.startOrientation = rb.RigidBody.transform.rotation;
			collisionInfo.rigidBodyId = rb.Id;
			collisionInfo.isKeyframed = rb.IsKeyframed;
			// test is this remote body is in the monitor stream or if this is grabbed & key framed then this should not be dynamic
			if (_monitorCollisionInfo.ContainsKey(rb.Id) && !rb.IsKeyframed)
			{
				// dynamic
				rb.RigidBody.isKinematic = false;
				collisionInfo.monitorInfo = _monitorCollisionInfo[rb.Id];
				collisionInfo.monitorInfo.timeFromStartCollision += timeInfo.DT;
				collisionInfo.linearVelocity = rb.RigidBody.velocity;
				collisionInfo.angularVelocity = rb.RigidBody.angularVelocity;
#if MRE_PHYSICS_DEBUG
						Debug.Log(" Remote body: " + rb.Id.ToString() + " is dynamic since:"
							+ collisionInfo.monitorInfo.timeFromStartCollision + " relative distance:" + collisionInfo.monitorInfo.relativeDistance
							+ " interpolation:" + collisionInfo.monitorInfo.keyframedInterpolationRatio);
#endif
				// if time preplacedes by then make a transformation between key framed and dynamic
				// but only change the positions not the velocity
				if (collisionInfo.monitorInfo.keyframedInterpolationRatio > 0.05f)
				{
					// interpolate between key framed and dynamic transforms
					float t = collisionInfo.monitorInfo.keyframedInterpolationRatio;
					UnityEngine.Vector3 interpolatedPos;
					UnityEngine.Quaternion interpolatedQuad;
					interpolatedPos = t * keyFramedPos + (1.0f - t) * rb.RigidBody.transform.position;
					interpolatedQuad = UnityEngine.Quaternion.Slerp(keyFramedOrientation, rb.RigidBody.transform.rotation, t);
#if MRE_PHYSICS_DEBUG
							Debug.Log(" Interpolate body " + rb.Id.ToString() + " t=" + t
								+ " time=" + UnityEngine.Time.time
								+ " pos KF:" + keyFramedPos
								+ " dyn:" + rb.RigidBody.transform.position
							    + " interp pos:" + interpolatedPos
								+ " rb vel:" + rb.RigidBody.velocity
								+ " KF vel:" + rb.lastValidLinerVelocityOrPos);
#endif
					// apply these changes only if they are significant in order to not to bother the physics engine
					// for settled objects
					UnityEngine.Vector3 posdiff = rb.RigidBody.transform.position - interpolatedPos;
					if (posdiff.magnitude > interpolationPosEpsilon)
					{
						rb.RigidBody.transform.position = interpolatedPos;
					}
					float angleDiff = Math.Abs(
						UnityEngine.Quaternion.Angle(rb.RigidBody.transform.rotation, interpolatedQuad));
					if (angleDiff > interpolationAngularEps)
					{
						rb.RigidBody.transform.rotation = interpolatedQuad;
					}

					// apply velocity damping if we are in the interpolation phase 
					if (collisionInfo.monitorInfo.keyframedInterpolationRatio >= velocityDampingInterpolationValueStart)
					{
						rb.RigidBody.velocity *= velocityDampingForInterpolation;
						rb.RigidBody.angularVelocity *= velocityDampingForInterpolation;
					}
				}
			}
			else
			{
				// 100% key framing
				rb.RigidBody.isKinematic = true;
				rb.RigidBody.transform.position = keyFramedPos;
				rb.RigidBody.transform.rotation = keyFramedOrientation;
				rb.RigidBody.velocity.Set(0.0f, 0.0f, 0.0f);
				rb.RigidBody.angularVelocity.Set(0.0f, 0.0f, 0.0f);
				collisionInfo.linearVelocity = rb.lastValidLinerVelocityOrPos;
				collisionInfo.angularVelocity = rb.lastValidAngularVelocityorAng;
				collisionInfo.monitorInfo = new CollisionMonitorInfo();
#if MRE_PHYSICS_DEBUG
				if (rb.IsKeyframed)
				{
						Debug.Log(" Remote body: " + rb.Id.ToString() + " is key framed:"
							+ " linvel:" + collisionInfo.linearVelocity
							+ " angvel:" + collisionInfo.angularVelocity);
				}
#endif
			}
			// <todo> add more filtering here to cancel out unnecessary items,
			// but for small number of bodies should be OK
			_switchCollisionInfos.Add(collisionInfo);
		}

19 View Source File : Quaternion.cs
License : MIT License
Project Creator : NathanWarden

public static Quaternion RotateTowards (Quaternion from, Quaternion to, float maxDegreesDelta)
		{
			float num = Quaternion.Angle (from, to);
			Quaternion result;
			if (num == 0f) {
				result = to;
			} else {
				float t = Mathf.Min (1f, maxDegreesDelta / num);
				result = Quaternion.SlerpUnclamped (from, to, t);
			}
			return result;
		}

19 View Source File : UIPanelInspector.cs
License : Apache License 2.0
Project Creator : OOXXXXOO

public void OnSceneGUI ()
	{
		NGUIEditorTools.HideMoveTool(true);
		if (!UIWidget.showHandles) return;

		Event e = Event.current;
		int id = GUIUtility.GetControlID(s_Hash, FocusType.Preplacedive);
		EventType type = e.GetTypeForControl(id);
		Transform t = mPanel.cachedTransform;

		Vector3[] handles = UIWidgetInspector.GetHandles(mPanel.worldCorners);

		// Time to figure out what kind of action is underneath the mouse
		UIWidgetInspector.Action actionUnderMouse = mAction;

		Color handlesColor = new Color(0.5f, 0f, 0.5f);
		NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

		if (mPanel.isAncreplacedd)
		{
			UIWidgetInspector.DrawAnchorHandle(mPanel.leftAnchor, mPanel.cachedTransform, handles, 0, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.topAnchor, mPanel.cachedTransform, handles, 1, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.rightAnchor, mPanel.cachedTransform, handles, 2, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.bottomAnchor, mPanel.cachedTransform, handles, 3, id);
		}

		if (type == EventType.Repaint)
		{
			bool showDetails = (mAction == UIWidgetInspector.Action.Scale) || NGUISettings.drawGuides;
			if (mAction == UIWidgetInspector.Action.None && e.modifiers == EventModifiers.Control) showDetails = true;
			if (NGUITools.GetActive(mPanel) && mPanel.parent == null) showDetails = true;
			if (showDetails) NGUIHandles.DrawSize(handles, Mathf.RoundToInt(mPanel.width), Mathf.RoundToInt(mPanel.height));
		}

		bool canResize = (mPanel.clipping != UIDrawCall.Clipping.None);

		// NOTE: Remove this part when it's possible to neatly resize rotated ancreplacedd panels.
		if (canResize && mPanel.isAncreplacedd)
		{
			Quaternion rot = mPanel.cachedTransform.localRotation;
			if (Quaternion.Angle(rot, Quaternion.idenreplacedy) > 0.01f) canResize = false;
		}

		bool[] resizable = new bool[8];

		resizable[4] = canResize;	// left
		resizable[5] = canResize;	// top
		resizable[6] = canResize;	// right
		resizable[7] = canResize;	// bottom

		resizable[0] = resizable[7] && resizable[4]; // bottom-left
		resizable[1] = resizable[5] && resizable[4]; // top-left
		resizable[2] = resizable[5] && resizable[6]; // top-right
		resizable[3] = resizable[7] && resizable[6]; // bottom-right

		UIWidget.Pivot pivotUnderMouse = UIWidgetInspector.GetPivotUnderMouse(handles, e, resizable, true, ref actionUnderMouse);

		switch (type)
		{
			case EventType.Repaint:
			{
				Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
				Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

				if ((v2 - v0).magnitude > 60f)
				{
					Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
					Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

					Handles.BeginGUI();
					{
						for (int i = 0; i < 4; ++i)
							DrawKnob(handles[i], id, resizable[i]);

						if (Mathf.Abs(v1.y - v0.y) > 80f)
						{
							if (mPanel.leftAnchor.target == null || mPanel.leftAnchor.absolute != 0)
								DrawKnob(handles[4], id, resizable[4]);

							if (mPanel.rightAnchor.target == null || mPanel.rightAnchor.absolute != 0)
								DrawKnob(handles[6], id, resizable[6]);
						}

						if (Mathf.Abs(v3.x - v0.x) > 80f)
						{
							if (mPanel.topAnchor.target == null || mPanel.topAnchor.absolute != 0)
								DrawKnob(handles[5], id, resizable[5]);

							if (mPanel.bottomAnchor.target == null || mPanel.bottomAnchor.absolute != 0)
								DrawKnob(handles[7], id, resizable[7]);
						}
					}
					Handles.EndGUI();
				}
			}
			break;

			case EventType.MouseDown:
			{
				if (actionUnderMouse != UIWidgetInspector.Action.None)
				{
					mStartMouse = e.mousePosition;
					mAllowSelection = true;

					if (e.button == 1)
					{
						if (e.modifiers == 0)
						{
							GUIUtility.hotControl = GUIUtility.keyboardControl = id;
							e.Use();
						}
					}
					else if (e.button == 0 && actionUnderMouse != UIWidgetInspector.Action.None &&
						UIWidgetInspector.Raycast(handles, out mStartDrag))
					{
						mWorldPos = t.position;
						mLocalPos = t.localPosition;
						mStartRot = t.localRotation.eulerAngles;
						mStartDir = mStartDrag - t.position;
						mStartCR = mPanel.baseClipRegion;
						mDragPivot = pivotUnderMouse;
						mActionUnderMouse = actionUnderMouse;
						GUIUtility.hotControl = GUIUtility.keyboardControl = id;
						e.Use();
					}
				}
			}
			break;

			case EventType.MouseUp:
			{
				if (GUIUtility.hotControl == id)
				{
					GUIUtility.hotControl = 0;
					GUIUtility.keyboardControl = 0;

					if (e.button < 2)
					{
						bool handled = false;

						if (e.button == 1)
						{
							// Right-click: Open a context menu listing all widgets underneath
							NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
							handled = true;
						}
						else if (mAction == UIWidgetInspector.Action.None)
						{
							if (mAllowSelection)
							{
								// Left-click: Select the topmost widget
								NGUIEditorTools.SelectWidget(e.mousePosition);
								handled = true;
							}
						}
						else
						{
							// Finished dragging something
							Vector3 pos = t.localPosition;
							pos.x = Mathf.Round(pos.x);
							pos.y = Mathf.Round(pos.y);
							pos.z = Mathf.Round(pos.z);
							t.localPosition = pos;
							handled = true;
						}

						if (handled) e.Use();
					}

					// Clear the actions
					mActionUnderMouse = UIWidgetInspector.Action.None;
					mAction = UIWidgetInspector.Action.None;
				}
				else if (mAllowSelection)
				{
					BetterList<UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition);
					if (widgets.size > 0) Selection.activeGameObject = widgets[0].gameObject;
				}
				mAllowSelection = true;
			}
			break;

			case EventType.MouseDrag:
			{
				// Prevent selection once the drag operation begins
				bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
				if (dragStarted) mAllowSelection = false;

				if (GUIUtility.hotControl == id)
				{
					e.Use();

					if (mAction != UIWidgetInspector.Action.None || mActionUnderMouse != UIWidgetInspector.Action.None)
					{
						Vector3 pos;

						if (UIWidgetInspector.Raycast(handles, out pos))
						{
							if (mAction == UIWidgetInspector.Action.None && mActionUnderMouse != UIWidgetInspector.Action.None)
							{
								// Wait until the mouse moves by more than a few pixels
								if (dragStarted)
								{
									if (mActionUnderMouse == UIWidgetInspector.Action.Move)
									{
										NGUISnap.Recalculate(mPanel);
									}
									else if (mActionUnderMouse == UIWidgetInspector.Action.Rotate)
									{
										mStartRot = t.localRotation.eulerAngles;
										mStartDir = mStartDrag - t.position;
									}
									else if (mActionUnderMouse == UIWidgetInspector.Action.Scale)
									{
										mStartCR = mPanel.baseClipRegion;
										mDragPivot = pivotUnderMouse;
									}
									mAction = actionUnderMouse;
								}
							}

							if (mAction != UIWidgetInspector.Action.None)
							{
								NGUIEditorTools.RegisterUndo("Change Rect", t);
								NGUIEditorTools.RegisterUndo("Change Rect", mPanel);

								if (mAction == UIWidgetInspector.Action.Move)
								{
									Vector3 before = t.position;
									Vector3 beforeLocal = t.localPosition;
									t.position = mWorldPos + (pos - mStartDrag);
									pos = NGUISnap.Snap(t.localPosition, mPanel.localCorners,
										e.modifiers != EventModifiers.Control) - beforeLocal;
									t.position = before;

									NGUIMath.MoveRect(mPanel, pos.x, pos.y);
								}
								else if (mAction == UIWidgetInspector.Action.Rotate)
								{
									Vector3 dir = pos - t.position;
									float angle = Vector3.Angle(mStartDir, dir);

									if (angle > 0f)
									{
										float dot = Vector3.Dot(Vector3.Cross(mStartDir, dir), t.forward);
										if (dot < 0f) angle = -angle;
										angle = mStartRot.z + angle;
										angle = (NGUISnap.allow && e.modifiers != EventModifiers.Control) ?
											Mathf.Round(angle / 15f) * 15f : Mathf.Round(angle);
										t.localRotation = Quaternion.Euler(mStartRot.x, mStartRot.y, angle);
									}
								}
								else if (mAction == UIWidgetInspector.Action.Scale)
								{
									// World-space delta since the drag started
									Vector3 delta = pos - mStartDrag;

									// Adjust the widget's position and scale based on the delta, restricted by the pivot
									AdjustClipping(mPanel, mLocalPos, mStartCR, delta, mDragPivot);
								}
							}
						}
					}
				}
			}
			break;

			case EventType.KeyDown:
			{
				if (e.keyCode == KeyCode.UpArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 0f, 1f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.DownArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 0f, -1f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.LeftArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, -1f, 0f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.RightArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 1f, 0f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.Escape)
				{
					if (GUIUtility.hotControl == id)
					{
						if (mAction != UIWidgetInspector.Action.None)
							Undo.PerformUndo();

						GUIUtility.hotControl = 0;
						GUIUtility.keyboardControl = 0;

						mActionUnderMouse = UIWidgetInspector.Action.None;
						mAction = UIWidgetInspector.Action.None;
						e.Use();
					}
					else Selection.activeGameObject = null;
				}
			}
			break;
		}
	}

19 View Source File : TransformSynchronizer.cs
License : MIT License
Project Creator : pampas93

private void LateUpdate()
        {
            // Determine if the transform has changed locally, in which case we need to update the data model
            if (transform.localPosition != Position.Value ||
                Quaternion.Angle(transform.localRotation, Rotation.Value) > 0.2f ||
                transform.localScale != Scale.Value)
            {
                transformDataModel.Position.Value = transform.localPosition;
                transformDataModel.Rotation.Value = transform.localRotation;
                transformDataModel.Scale.Value = transform.localScale;

                // The object was moved locally, so reset the target positions to the current position
                Position.Reset(transform.localPosition);
                Rotation.Reset(transform.localRotation);
                Scale.Reset(transform.localScale);
            }
        }

19 View Source File : InterpolatedQuaternion.cs
License : MIT License
Project Creator : pampas93

public override bool DoValuesEqual(Quaternion one, Quaternion other)
        {
            return Quaternion.Angle(one, other) < SmallNumber;
        }

19 View Source File : Interpolator.cs
License : MIT License
Project Creator : pampas93

public void Update()
        {
            float deltaTime = UseUnscaledTime
                ? Time.unscaledDeltaTime
                : Time.deltaTime;

            bool interpOccuredThisFrame = false;

            if (AnimatingPosition)
            {
                Vector3 lerpTargetPosition = targetPosition;
                if (SmoothLerpToTarget)
                {
                    lerpTargetPosition = Vector3.Lerp(transform.position, lerpTargetPosition, SmoothPositionLerpRatio);
                }

                Vector3 newPosition = NonLinearInterpolateTo(transform.position, lerpTargetPosition, deltaTime, PositionPerSecond);
                if ((targetPosition - newPosition).sqrMagnitude <= smallNumber)
                {
                    // Snap to final position
                    newPosition = targetPosition;
                    AnimatingPosition = false;
                }
                else
                {
                    interpOccuredThisFrame = true;
                }

                transform.position = newPosition;

                //calculate interpolatedVelocity and store position for next frame
                PositionVelocity = oldPosition - newPosition;
                oldPosition = newPosition;
            }

            // Determine how far we need to rotate
            if (AnimatingRotation)
            {
                Quaternion lerpTargetRotation = targetRotation;
                if (SmoothLerpToTarget)
                {
                    lerpTargetRotation = Quaternion.Lerp(transform.rotation, lerpTargetRotation, SmoothRotationLerpRatio);
                }

                float angleDiff = Quaternion.Angle(transform.rotation, lerpTargetRotation);
                float speedScale = 1.0f + (Mathf.Pow(angleDiff, RotationSpeedScaler) / 180.0f);
                float ratio = Mathf.Clamp01((speedScale * RotationDegreesPerSecond * deltaTime) / angleDiff);

                if (angleDiff < Mathf.Epsilon)
                {
                    AnimatingRotation = false;
                    transform.rotation = targetRotation;
                }
                else
                {
                    // Only lerp rotation here, as ratio is NaN if angleDiff is 0.0f
                    transform.rotation = Quaternion.Slerp(transform.rotation, lerpTargetRotation, ratio);
                    interpOccuredThisFrame = true;
                }
            }

            // Determine how far we need to rotate
            if (AnimatingLocalRotation)
            {
                Quaternion lerpTargetLocalRotation = targetLocalRotation;
                if (SmoothLerpToTarget)
                {
                    lerpTargetLocalRotation = Quaternion.Lerp(transform.localRotation, lerpTargetLocalRotation, SmoothRotationLerpRatio);
                }

                float angleDiff = Quaternion.Angle(transform.localRotation, lerpTargetLocalRotation);
                float speedScale = 1.0f + (Mathf.Pow(angleDiff, RotationSpeedScaler) / 180.0f);
                float ratio = Mathf.Clamp01((speedScale * RotationDegreesPerSecond * deltaTime) / angleDiff);

                if (angleDiff < Mathf.Epsilon)
                {
                    AnimatingLocalRotation = false;
                    transform.localRotation = targetLocalRotation;
                }
                else
                {
                    // Only lerp rotation here, as ratio is NaN if angleDiff is 0.0f
                    transform.localRotation = Quaternion.Slerp(transform.localRotation, lerpTargetLocalRotation, ratio);
                    interpOccuredThisFrame = true;
                }
            }

            if (AnimatingLocalScale)
            {
                Vector3 lerpTargetLocalScale = targetLocalScale;
                if (SmoothLerpToTarget)
                {
                    lerpTargetLocalScale = Vector3.Lerp(transform.localScale, lerpTargetLocalScale, SmoothScaleLerpRatio);
                }

                Vector3 newScale = NonLinearInterpolateTo(transform.localScale, lerpTargetLocalScale, deltaTime, ScalePerSecond);
                if ((targetLocalScale - newScale).sqrMagnitude <= smallNumber)
                {
                    // Snap to final scale
                    newScale = targetLocalScale;
                    AnimatingLocalScale = false;
                }
                else
                {
                    interpOccuredThisFrame = true;
                }

                transform.localScale = newScale;
            }

            // If all interpolations have completed, stop updating
            if (!interpOccuredThisFrame)
            {
                if (InterpolationDone != null)
                {
                    InterpolationDone();
                }
                enabled = false;
            }
        }

19 View Source File : QuaternionInterpolated.cs
License : MIT License
Project Creator : pampas93

public void SetTarget(Quaternion targetValue)
        {
            TargetValue = targetValue;
            StartValue = Value;
            Duration = Quaternion.Angle(StartValue, TargetValue) / DeltaSpeed;
            Counter = 0f;
        }

19 View Source File : QuaternionInterpolated.cs
License : MIT License
Project Creator : pampas93

public bool HasUpdate()
        {
            return Quaternion.Angle(TargetValue, Value) > 0.05f;
        }

19 View Source File : Quaternion.cs
License : MIT License
Project Creator : Viagi

public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta)
        {
            float angle = Quaternion.Angle(from, to);
            if (angle == 0.0f)
                return to;
            float slerpValue = Mathf.Min(1.0f, maxDegreesDelta / angle);
            return UnclampedSlerp(from, to, slerpValue);
        }

19 View Source File : NavmeshAdd.cs
License : MIT License
Project Creator : XINCGer

public override bool RequiresUpdate () {
			return (tr.position-lastPosition).sqrMagnitude > updateDistance*updateDistance || (useRotationAndScale && (Quaternion.Angle(lastRotation, tr.rotation) > updateRotationDistance));
		}

19 View Source File : DynamicGridObstacle.cs
License : MIT License
Project Creator : XINCGer

void Update () {
			if (!coll) {
				Debug.LogError("Removed collider from DynamicGridObstacle", this);
				enabled = false;
				return;
			}

			if (AstarPath.active == null || AstarPath.active.isScanning || Time.realtimeSinceStartup - lastCheckTime < checkTime) {
				return;
			}

			lastCheckTime = Time.realtimeSinceStartup;
			if (coll.enabled) {
				// The current bounds of the collider
				Bounds newBounds = coll.bounds;
				var newRotation = tr.rotation;

				Vector3 minDiff = prevBounds.min - newBounds.min;
				Vector3 maxDiff = prevBounds.max - newBounds.max;

				var extents = newBounds.extents.magnitude;
				// This is the distance that a point furthest out on the bounding box
				// would have moved due to the changed rotation of the object
				var errorFromRotation = extents*Quaternion.Angle(prevRotation, newRotation)*Mathf.Deg2Rad;

				// If the difference between the previous bounds and the new bounds is greater than some value, update the graphs
				if (minDiff.sqrMagnitude > updateError*updateError || maxDiff.sqrMagnitude > updateError*updateError ||
					errorFromRotation > updateError || !prevEnabled) {
					// Update the graphs as soon as possible
					DoUpdateGraphs();
				}
			} else {
				// Collider has just been disabled
				if (prevEnabled) {
					DoUpdateGraphs();
				}
			}
		}

19 View Source File : Angle.cs
License : MIT License
Project Creator : XINCGer

public override TaskStatus OnUpdate()
        {
            storeResult.Value = Quaternion.Angle(firstRotation.Value, secondRotation.Value);
            return TaskStatus.Success;
        }

19 View Source File : UIPanelInspector.cs
License : MIT License
Project Creator : XINCGer

public void OnSceneGUI ()
	{
		if (Selection.objects.Length > 1) return;

		UICamera cam = UICamera.FindCameraForLayer(mPanel.gameObject.layer);
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7
		if (cam == null || !cam.cachedCamera.isOrthoGraphic) return;
#else
		if (cam == null || !cam.cachedCamera.orthographic) return;
#endif

		NGUIEditorTools.HideMoveTool(true);
		if (!UIWidget.showHandles) return;

		Event e = Event.current;
		int id = GUIUtility.GetControlID(s_Hash, FocusType.Preplacedive);
		EventType type = e.GetTypeForControl(id);
		Transform t = mPanel.cachedTransform;

		Vector3[] handles = UIWidgetInspector.GetHandles(mPanel.worldCorners);

		// Time to figure out what kind of action is underneath the mouse
		UIWidgetInspector.Action actionUnderMouse = mAction;

		Color handlesColor = new Color(0.5f, 0f, 0.5f);
		NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
		NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

		if (mPanel.isAncreplacedd)
		{
			UIWidgetInspector.DrawAnchorHandle(mPanel.leftAnchor, mPanel.cachedTransform, handles, 0, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.topAnchor, mPanel.cachedTransform, handles, 1, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.rightAnchor, mPanel.cachedTransform, handles, 2, id);
			UIWidgetInspector.DrawAnchorHandle(mPanel.bottomAnchor, mPanel.cachedTransform, handles, 3, id);
		}

		if (type == EventType.Repaint)
		{
			bool showDetails = (mAction == UIWidgetInspector.Action.Scale) || NGUISettings.drawGuides;
			if (mAction == UIWidgetInspector.Action.None && e.modifiers == EventModifiers.Control) showDetails = true;
			if (NGUITools.GetActive(mPanel) && mPanel.parent == null) showDetails = true;
			if (showDetails) NGUIHandles.DrawSize(handles, Mathf.RoundToInt(mPanel.width), Mathf.RoundToInt(mPanel.height));
		}

		bool canResize = (mPanel.clipping != UIDrawCall.Clipping.None);

		// NOTE: Remove this part when it's possible to neatly resize rotated ancreplacedd panels.
		if (canResize && mPanel.isAncreplacedd)
		{
			Quaternion rot = mPanel.cachedTransform.localRotation;
			if (Quaternion.Angle(rot, Quaternion.idenreplacedy) > 0.01f) canResize = false;
		}

		bool[] resizable = new bool[8];

		resizable[4] = canResize;	// left
		resizable[5] = canResize;	// top
		resizable[6] = canResize;	// right
		resizable[7] = canResize;	// bottom

		resizable[0] = resizable[7] && resizable[4]; // bottom-left
		resizable[1] = resizable[5] && resizable[4]; // top-left
		resizable[2] = resizable[5] && resizable[6]; // top-right
		resizable[3] = resizable[7] && resizable[6]; // bottom-right

		UIWidget.Pivot pivotUnderMouse = UIWidgetInspector.GetPivotUnderMouse(handles, e, resizable, true, ref actionUnderMouse);

		switch (type)
		{
			case EventType.Repaint:
			{
				Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
				Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

				if ((v2 - v0).magnitude > 60f)
				{
					Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
					Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

					Handles.BeginGUI();
					{
						for (int i = 0; i < 4; ++i)
							DrawKnob(handles[i], id, resizable[i]);

						if (Mathf.Abs(v1.y - v0.y) > 80f)
						{
							if (mPanel.leftAnchor.target == null || mPanel.leftAnchor.absolute != 0)
								DrawKnob(handles[4], id, resizable[4]);

							if (mPanel.rightAnchor.target == null || mPanel.rightAnchor.absolute != 0)
								DrawKnob(handles[6], id, resizable[6]);
						}

						if (Mathf.Abs(v3.x - v0.x) > 80f)
						{
							if (mPanel.topAnchor.target == null || mPanel.topAnchor.absolute != 0)
								DrawKnob(handles[5], id, resizable[5]);

							if (mPanel.bottomAnchor.target == null || mPanel.bottomAnchor.absolute != 0)
								DrawKnob(handles[7], id, resizable[7]);
						}
					}
					Handles.EndGUI();
				}
			}
			break;

			case EventType.MouseDown:
			{
				if (actionUnderMouse != UIWidgetInspector.Action.None)
				{
					mStartMouse = e.mousePosition;
					mAllowSelection = true;

					if (e.button == 1)
					{
						if (e.modifiers == 0)
						{
							GUIUtility.hotControl = GUIUtility.keyboardControl = id;
							e.Use();
						}
					}
					else if (e.button == 0 && actionUnderMouse != UIWidgetInspector.Action.None &&
						UIWidgetInspector.Raycast(handles, out mStartDrag))
					{
						mWorldPos = t.position;
						mLocalPos = t.localPosition;
						mStartRot = t.localRotation.eulerAngles;
						mStartDir = mStartDrag - t.position;
						mStartCR = mPanel.baseClipRegion;
						mDragPivot = pivotUnderMouse;
						mActionUnderMouse = actionUnderMouse;
						GUIUtility.hotControl = GUIUtility.keyboardControl = id;
						e.Use();
					}
				}
			}
			break;

			case EventType.MouseUp:
			{
				if (GUIUtility.hotControl == id)
				{
					GUIUtility.hotControl = 0;
					GUIUtility.keyboardControl = 0;

					if (e.button < 2)
					{
						bool handled = false;

						if (e.button == 1)
						{
							// Right-click: Open a context menu listing all widgets underneath
							NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
							handled = true;
						}
						else if (mAction == UIWidgetInspector.Action.None)
						{
							if (mAllowSelection)
							{
								// Left-click: Select the topmost widget
								NGUIEditorTools.SelectWidget(e.mousePosition);
								handled = true;
							}
						}
						else
						{
							// Finished dragging something
							Vector3 pos = t.localPosition;
							pos.x = Mathf.Round(pos.x);
							pos.y = Mathf.Round(pos.y);
							pos.z = Mathf.Round(pos.z);
							t.localPosition = pos;
							handled = true;
						}

						if (handled) e.Use();
					}

					// Clear the actions
					mActionUnderMouse = UIWidgetInspector.Action.None;
					mAction = UIWidgetInspector.Action.None;
				}
				else if (mAllowSelection)
				{
					List<UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition);
					if (widgets.Count > 0) Selection.activeGameObject = widgets[0].gameObject;
				}
				mAllowSelection = true;
			}
			break;

			case EventType.MouseDrag:
			{
				// Prevent selection once the drag operation begins
				bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
				if (dragStarted) mAllowSelection = false;

				if (GUIUtility.hotControl == id)
				{
					e.Use();

					if (mAction != UIWidgetInspector.Action.None || mActionUnderMouse != UIWidgetInspector.Action.None)
					{
						Vector3 pos;

						if (UIWidgetInspector.Raycast(handles, out pos))
						{
							if (mAction == UIWidgetInspector.Action.None && mActionUnderMouse != UIWidgetInspector.Action.None)
							{
								// Wait until the mouse moves by more than a few pixels
								if (dragStarted)
								{
									if (mActionUnderMouse == UIWidgetInspector.Action.Move)
									{
										NGUISnap.Recalculate(mPanel);
									}
									else if (mActionUnderMouse == UIWidgetInspector.Action.Rotate)
									{
										mStartRot = t.localRotation.eulerAngles;
										mStartDir = mStartDrag - t.position;
									}
									else if (mActionUnderMouse == UIWidgetInspector.Action.Scale)
									{
										mStartCR = mPanel.baseClipRegion;
										mDragPivot = pivotUnderMouse;
									}
									mAction = actionUnderMouse;
								}
							}

							if (mAction != UIWidgetInspector.Action.None)
							{
								NGUIEditorTools.RegisterUndo("Change Rect", t);
								NGUIEditorTools.RegisterUndo("Change Rect", mPanel);

								if (mAction == UIWidgetInspector.Action.Move)
								{
									Vector3 before = t.position;
									Vector3 beforeLocal = t.localPosition;
									t.position = mWorldPos + (pos - mStartDrag);
									pos = NGUISnap.Snap(t.localPosition, mPanel.localCorners,
										e.modifiers != EventModifiers.Control) - beforeLocal;
									t.position = before;

									NGUIMath.MoveRect(mPanel, pos.x, pos.y);
								}
								else if (mAction == UIWidgetInspector.Action.Rotate)
								{
									Vector3 dir = pos - t.position;
									float angle = Vector3.Angle(mStartDir, dir);

									if (angle > 0f)
									{
										float dot = Vector3.Dot(Vector3.Cross(mStartDir, dir), t.forward);
										if (dot < 0f) angle = -angle;
										angle = mStartRot.z + angle;
										angle = (NGUISnap.allow && e.modifiers != EventModifiers.Control) ?
											Mathf.Round(angle / 15f) * 15f : Mathf.Round(angle);
										t.localRotation = Quaternion.Euler(mStartRot.x, mStartRot.y, angle);
									}
								}
								else if (mAction == UIWidgetInspector.Action.Scale)
								{
									// World-space delta since the drag started
									Vector3 delta = pos - mStartDrag;

									// Adjust the widget's position and scale based on the delta, restricted by the pivot
									AdjustClipping(mPanel, mLocalPos, mStartCR, delta, mDragPivot);
								}
							}
						}
					}
				}
			}
			break;

			case EventType.KeyDown:
			{
				if (e.keyCode == KeyCode.UpArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 0f, 1f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.DownArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 0f, -1f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.LeftArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, -1f, 0f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.RightArrow)
				{
					NGUIEditorTools.RegisterUndo("Nudge Rect", t);
					NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
					NGUIMath.MoveRect(mPanel, 1f, 0f);
					e.Use();
				}
				else if (e.keyCode == KeyCode.Escape)
				{
					if (GUIUtility.hotControl == id)
					{
						if (mAction != UIWidgetInspector.Action.None)
							Undo.PerformUndo();

						GUIUtility.hotControl = 0;
						GUIUtility.keyboardControl = 0;

						mActionUnderMouse = UIWidgetInspector.Action.None;
						mAction = UIWidgetInspector.Action.None;
						e.Use();
					}
					else Selection.activeGameObject = null;
				}
			}
			break;
		}
	}