public static Ray Transform(Ray ray, Matrix4X4 matrix) { Vector3 transformedOrigin = Vector3.TransformPosition(ray.origin, matrix); Vector3 transformedDirecton = Vector3.TransformVector(ray.directionNormal, matrix); return(new Ray(transformedOrigin, transformedDirecton, ray.minDistanceToConsider, ray.maxDistanceToConsider, ray.intersectionType)); }
//Mouse drag, calculate rotation public void OnMouseMove(Vector2 mousePosition) { switch (currentTrackingType) { case MouseDownType.Rotation: activeRotationQuaternion = Quaternion.Identity; //Map the point to the sphere MapToSphere(mousePosition, out rotationCurrent); //Return the quaternion equivalent to the rotation //Compute the vector perpendicular to the begin and end vectors Vector3 Perp = Vector3.Cross(rotationStart, rotationCurrent); //Compute the length of the perpendicular vector if (Perp.Length > Epsilon) { //if its non-zero //We're ok, so return the perpendicular vector as the transform after all activeRotationQuaternion.X = Perp.x; activeRotationQuaternion.Y = Perp.y; activeRotationQuaternion.Z = Perp.z; //In the quaternion values, w is cosine (theta / 2), where theta is the rotation angle activeRotationQuaternion.W = Vector3.Dot(rotationStart, rotationCurrent); } break; case MouseDownType.Translation: { Vector2 mouseDelta = mousePosition - lastTranslationMousePosition; Vector2 scalledDelta = mouseDelta / screenCenter.x * 4.75; Vector3 offset = new Vector3(scalledDelta.x, scalledDelta.y, 0); offset = Vector3.TransformPosition(offset, Matrix4X4.Invert(CurrentRotation)); offset = Vector3.TransformPosition(offset, localToScreenTransform); currentTranslationMatrix = currentTranslationMatrix * Matrix4X4.CreateTranslation(offset); lastTranslationMousePosition = mousePosition; } break; case MouseDownType.Scale: { Vector2 mouseDelta = mousePosition - lastScaleMousePosition; double zoomDelta = 1; if (mouseDelta.y < 0) { zoomDelta = 1 - (-1 * mouseDelta.y / 100); } else if (mouseDelta.y > 0) { zoomDelta = 1 + (1 * mouseDelta.y / 100); } currentTranslationMatrix *= Matrix4X4.CreateScale(zoomDelta); lastScaleMousePosition = mousePosition; } break; default: throw new NotImplementedException(); } }
//Mouse drag, calculate rotation public void OnMouseMove(Vector2 mousePosition, bool rotateOnZ) { switch (currentTrackingType) { case MouseDownType.Rotation: var activeRotationQuaternion = Quaternion.Identity; //Map the point to the sphere moveSpherePosition = MapMoveToSphere(mousePosition, rotateOnZ); //Return the quaternion equivalent to the rotation //Compute the vector perpendicular to the begin and end vectors var rotationStart3D = new Vector3(0, 0, 1); if (rotateOnZ) { rotationStart3D = new Vector3(1, 0, 0); } Vector3 Perp = Vector3.Cross(rotationStart3D, moveSpherePosition); //Compute the length of the perpendicular vector if (Perp.Length > Epsilon) { //if its non-zero //We're ok, so return the perpendicular vector as the transform after all activeRotationQuaternion.X = Perp.X; activeRotationQuaternion.Y = Perp.Y; activeRotationQuaternion.Z = Perp.Z; //In the quaternion values, w is cosine (theta / 2), where theta is the rotation angle activeRotationQuaternion.W = Vector3.Dot(rotationStart3D, moveSpherePosition); mouseDownPosition = mousePosition; world.RotationMatrix = world.RotationMatrix * Matrix4X4.CreateRotation(activeRotationQuaternion); OnTransformChanged(null); } break; case MouseDownType.Translation: { Vector2 mouseDelta = mousePosition - lastTranslationMousePosition; Vector2 scaledDelta = mouseDelta / world.ScreenCenter.X * 4.75; Vector3 offset = new Vector3(scaledDelta.X, scaledDelta.Y, 0); offset = Vector3.TransformPosition(offset, Matrix4X4.Invert(world.RotationMatrix)); offset = Vector3.TransformPosition(offset, localToScreenTransform); world.TranslationMatrix = world.TranslationMatrix * Matrix4X4.CreateTranslation(offset); lastTranslationMousePosition = mousePosition; OnTransformChanged(null); } break; case MouseDownType.Scale: { Vector2 mouseDelta = mousePosition - lastScaleMousePosition; double zoomDelta = 1; if (mouseDelta.Y < 0) { zoomDelta = 1 - (-1 * mouseDelta.Y / 100); } else if (mouseDelta.Y > 0) { zoomDelta = 1 + (1 * mouseDelta.Y / 100); } world.Scale = world.Scale * zoomDelta; lastScaleMousePosition = mousePosition; OnTransformChanged(null); } break; default: throw new NotImplementedException(); } }