Пример #1
0
        protected override void ExecuteCore()
        {
            int index       = 0;
            var outputs     = new ITaskItem[Sources.Length * Languages.Length];
            var outputPaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var source in Sources)
            {
                string sourcePath = source.ItemSpec;

                foreach (var language in Languages)
                {
                    string xlfPath = GetXlfPath(sourcePath, language);
                    var    xlf     = new TaskItem(source)
                    {
                        ItemSpec = xlfPath
                    };
                    xlf.SetMetadata(MetadataKey.XlfSource, source.ItemSpec);
                    xlf.SetMetadata(MetadataKey.XlfTranslatedFullPath, GetTranslatedOutputPath(source, language, outputPaths));
                    xlf.SetMetadata(MetadataKey.XlfLanguage, language);
                    outputs[index++] = xlf;
                }
            }

            Release.Assert(index == outputs.Length);
            Outputs = outputs;
        }
Пример #2
0
        protected override void ExecuteCore()
        {
            int index   = 0;
            var outputs = new ITaskItem[XlfFiles.Length];

            foreach (ITaskItem xlf in XlfFiles)
            {
                string translatedFullPath = xlf.GetMetadataOrThrow(MetadataKey.XlfTranslatedFullPath);
                string language           = xlf.GetMetadataOrThrow(MetadataKey.XlfLanguage);

                var output = new TaskItem(xlf)
                {
                    ItemSpec = translatedFullPath
                };

                // Set up metadata required to give the correct resource names to translated source.
                SetLink(xlf, output, translatedFullPath);
                AdjustManifestResourceName(xlf, output, language);
                AdjustLogicalName(xlf, output, language);

                outputs[index++] = output;
            }

            Release.Assert(index == XlfFiles.Length);
            Outputs = outputs;
        }
Пример #3
0
        private ImmutableArray <MethodOrInterfaceMethod> CalculateRequiredMethodKeys()
        {
            var index   = 0;
            var builder = ImmutableArray.CreateBuilder <MethodOrInterfaceMethod>(_original.RequiredMethodKeys.Length);

            var originalDirectlyRequiredMethodKeys = _original.DirectlyRequiredMethodKeys;
            var directlyRequiredMethodKeys         = _directlyRequiredMethodKeys.Value;

            foreach (var requiredMethod in _original.RequiredMethodKeys)
            {
                if (index < originalDirectlyRequiredMethodKeys.Length && requiredMethod.Equals(originalDirectlyRequiredMethodKeys[index]))
                {
                    builder.Add(directlyRequiredMethodKeys[index]);
                    index++;
                }
                else
                {
                    builder.Add(requiredMethod.SubstituteTypeParameters(_substitutions, _substituted));
                }
            }

            Release.Assert(index == directlyRequiredMethodKeys.Length);

            return(builder.MoveToImmutable());
        }
        public static IType GetTypeOrError(
            this SourceSymbolContext context,
            QualifiedName name,
            ImmutableArray <IType> typeArguments,
            out Func <Location, Diagnostic>?diagnostic)
        {
            diagnostic = default;
            var possibleTypes = context.GetPossibleTypes(name, typeArguments);

            if (possibleTypes.Count == 0)
            {
                diagnostic = l => new Diagnostic(l, ErrorCode.TypeNotFound, ImmutableArray.Create <object?>(name));
                return(ErrorInterface.Instance);
            }

            if (possibleTypes.Count > 1)
            {
                diagnostic = l => new Diagnostic(l, ErrorCode.AmbigiousInterfaceReference, ImmutableArray.Create <object?>(possibleTypes.Cast <object?>().Prepend(name).ToImmutableArray()));
                return(ErrorInterface.Instance);
            }

            var type = possibleTypes[0];

            if (typeArguments.Length > 0)
            {
                Release.Assert(type is IInterface);
                var @interface     = (IInterface)type;
                var typeParameters = @interface.TypeParameters;
                HasValidTypeArguments(typeArguments, typeParameters, out diagnostic);
                type = @interface.Construct(typeArguments);
            }

            return(type);
        }
Пример #5
0
    public bool IsEquivalentToOriginal()
    {
        Release.Assert(_method != null);

        var originalTypeParameters = _method.OriginalDefinition.TypeParameters;

        if (_typeArguments.Length != originalTypeParameters.Length)
        {
            return(false);
        }

        return(_typeArguments.Zip(originalTypeParameters, (a, b) => a == b).All(x => x));
    }
Пример #6
0
        protected override void ExecuteCore()
        {
            foreach (var item in Sources)
            {
                string sourcePath                   = item.ItemSpec;
                string sourceDocumentPath           = item.GetMetadataOrDefault(MetadataKey.SourceDocumentPath, item.ItemSpec);
                string sourceFormat                 = item.GetMetadataOrThrow(MetadataKey.XlfSourceFormat);
                TranslatableDocument sourceDocument = LoadSourceDocument(sourcePath, sourceFormat);
                string sourceDocumentId             = GetSourceDocumentId(sourcePath);

                foreach (var language in Languages)
                {
                    string      xlfPath = GetXlfPath(sourceDocumentPath, language);
                    XlfDocument xlfDocument;

                    try
                    {
                        xlfDocument = LoadXlfDocument(xlfPath, language, createIfNonExistent: AllowModification);
                    }
                    catch (FileNotFoundException fileNotFoundEx) when(fileNotFoundEx.FileName == xlfPath)
                    {
                        Release.Assert(!AllowModification);
                        throw new BuildErrorException($"'{xlfPath}' for '{sourcePath}' does not exist. {HowToUpdate}");
                    }
                    catch (System.Xml.XmlException xmlEx)
                    {
                        throw new BuildErrorException($"Unable to load file: {xmlEx.Message}")
                              {
                                  RelatedFile = xlfPath
                              };
                    }

                    bool updated = xlfDocument.Update(sourceDocument, sourceDocumentId);

                    if (!updated)
                    {
                        continue; // no changes
                    }

                    if (!AllowModification)
                    {
                        throw new BuildErrorException($"'{xlfPath}' is out-of-date with '{sourcePath}'. {HowToUpdate}");
                    }

                    Directory.CreateDirectory(Path.GetDirectoryName(xlfPath));
                    xlfDocument.Save(xlfPath);
                }
            }
        }
Пример #7
0
        public RenderingStrategy(Device device, DeviceContext deviceContext, Breadcrumber breadcrumber)
        {
            mBreadcrumber  = breadcrumber;
            mDebugRenderer = new DebugRenderer(device);

            mStopwatch.Start();

            System.Threading.Thread.Sleep(1000);
            Trace.WriteLine("\nMojo initializing TinyText.Context (NOTE: TinyText.Context generates D3D11 warnings)...\n");

            bool result;

            mTinyTextContext = new Context(device, deviceContext, MAX_NUM_TEXT_CHARACTERS, out result);
            Release.Assert(result);

            Trace.WriteLine("\nMojo finished Initializing TinyText.Context...\n");
        }
Пример #8
0
        internal XlfDocument LoadXlfDocument(string path, string language = null, bool createIfNonExistent = false)
        {
            var document = new XlfDocument();

            if (File.Exists(path))
            {
                document.Load(path);
            }
            else if (createIfNonExistent)
            {
                Release.Assert(!string.IsNullOrEmpty(language));
                document.LoadNew(language);
            }
            else
            {
                throw new FileNotFoundException($"File not found: {path}", path);
            }

            return(document);
        }
        public static void WarnIfUseOfMethodWhichCapturesUnassignedLocals(this MethodBodySymbolContext methodBodySymbolContext, IMethod target, DiagnosticBag diagnostics, Method_referenceContext syntax)
        {
            var currentMethod = methodBodySymbolContext.SourceSymbolContext.Scope;

            Release.Assert(currentMethod != null);
            if (target.DeclaringMethod == currentMethod)
            {
                if (target.InScopeAfter is { } declarationStatement)
                {
                    var currentStatement = methodBodySymbolContext.CurrentStatement;
                    Release.Assert(currentStatement != null);
                    if (declarationStatement.OrdinalPositionInMethod >= currentStatement.OrdinalPositionInMethod)
                    {
                        diagnostics.Add(new Diagnostic(
                                            new Location(syntax),
                                            ErrorCode.UseOfMethodWhichCapturesUnassignedLocals,
                                            ImmutableArray.Create <object?>(target)));
                    }
                }
            }
        }
Пример #10
0
        private ValueTask <IAssembly> LoadDependencyAsync(
            AssemblyLoadContext assemblyLoadContext,
            Reference reference,
            IEnumerable <IAssembly> alreadyLoadedProjects,
            ProjectInfo project,
            CancellationToken cancellationToken)
        {
            if (reference.Type == Project)
            {
                var name     = QualifiedName.Parse(reference.Name);
                var assembly = alreadyLoadedProjects.FirstOrDefault(x => x.Name == name)
                               ?? throw new InvalidOperationException($"{name} is a dependency of {project}, so must be built first");
                return(new ValueTask <IAssembly>(assembly));
            }

            Release.Assert(reference.Version != null);

            return(new ValueTask <IAssembly>(LoadDependencyAsync(
                                                 assemblyLoadContext,
                                                 new Dependency(reference.Name, reference.Version),
                                                 cancellationToken)));
        }
        public void OnMouseUp(System.Windows.Forms.MouseEventArgs mouseEventArgs, int width, int height)
        {
            if (mSegmenter.DatasetLoaded)
            {
                switch (mSegmenter.CurrentSegmenterToolMode)
                {
                case SegmenterToolMode.Adjust:
                    mSegmenter.EndScribble();
                    break;

                case SegmenterToolMode.Merge:
                    break;

                case SegmenterToolMode.Split:
                    break;

                default:
                    Release.Assert(false);
                    break;
                }
            }
        }
 public static bool HasValidTypeArguments(
     ImmutableArray <IType> typeArguments,
     ImmutableArray <ITypeParameter> typeParameters,
     [NotNullWhenAttribute(false)] out Func <Location, Diagnostic>?diagnostic)
 {
     Release.Assert(typeArguments.Length == typeParameters.Length);
     for (var i = 0; i < typeArguments.Length; i++)
     {
         var typeArgument  = typeArguments[i];
         var typeParameter = typeParameters[i];
         if (typeParameter.ConstrainedTo is { } constrainedTo &&
             !typeArgument.IsSubtypeOf(constrainedTo))
         {
             diagnostic = l => new Diagnostic(
                 l,
                 ErrorCode.TypeArgumentDoesntMatchConstraints,
                 ImmutableArray.Create <object?>(typeArgument, typeParameter));
             return(false);
         }
     }
     diagnostic = default;
     return(true);
 }
        public async ValueTask <AssemblyLoadResult?> TryLoadAssemblyAsync(
            AssemblyLoadContext assemblyLoadContext,
            Dependency dependency,
            CancellationToken cancellationToken = default)
        {
            if (!NuGetVersion.TryParse(dependency.Version, out var nuGetVersion))
            {
                throw new ArgumentException($"invalid version {dependency.Version} for nuget package {dependency.Name}", nameof(dependency));
            }

            var assemblyLoadResult = await
                                     _nugetFeedUrls
                                     .ToAsyncEnumerable()
                                     .SelectAwait(TryLoadAssemblyFromFeed)
                                     .FirstOrDefaultAsync(x => x != null, cancellationToken);

            if (assemblyLoadResult is null)
            {
                _logger.LogInformation("Could not download nuget package {0} {1} from any nuget feed", dependency.Name, dependency.Version);
            }

            return(assemblyLoadResult);

            async ValueTask <AssemblyLoadResult?> TryLoadAssemblyFromFeed(string feedUrl)
            {
                _logger.LogInformation(
                    "Attempting to download Nuget Package ID: {0}, Version: {1} from {2}",
                    dependency.Name,
                    dependency.Version,
                    feedUrl);
                var repository       = Repository.Factory.GetCoreV3(feedUrl);
                var downloadResource = await repository.GetResourceAsync <DownloadResource>();

                using var downloadResourceResult = await downloadResource.GetDownloadResourceResultAsync(
                          new PackageIdentity (dependency.Name, nuGetVersion),
                          new PackageDownloadContext (_sourceCacheContext),
                          globalPackagesFolder : _globalPackagesFolder,
                          logger : _nugetLogger,
                          token : cancellationToken);

                if (downloadResourceResult.Status != DownloadResourceResultStatus.Available)
                {
                    _logger.LogInformation(
                        $"Download of NuGet package from {0} failed. DownloadResult Status: {1}",
                        feedUrl,
                        downloadResourceResult.Status);
                    return(null);
                }

                _logger.LogInformation("Successfully Downloaded Nuget Package from {0}", feedUrl);

                var reader = downloadResourceResult.PackageReader;

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug("Nuget Package Metadata: {0}", reader.ToJson());
                }

                var libFile =
                    reader
                    .GetLibItems()
                    .SelectMany(x => x.Items)
                    .FirstOrDefault(x => Path.GetExtension(x) == ".dll");

                if (libFile is null)
                {
                    throw new FlcException("No dll found in Nuget Package");
                }

                _logger.LogInformation("Found dll {0}", libFile);
                _logger.LogInformation("Decompressing {0}", libFile);

                var archive = new ZipArchive(downloadResourceResult.PackageStream);
                var entry   = archive.GetEntry(libFile);

                Release.Assert(entry != null);
                using var decompressed = new MemoryStream();
                entry.Open().CopyTo(decompressed);
                decompressed.Position = 0;

                _logger.LogInformation("Loading {0}", libFile);
                var assembly = assemblyLoadContext.LoadFromStream(decompressed);
                var bytes    = decompressed.ToImmutableArray();

                _logger.LogInformation("Successfully loaded assembly {0}", assembly.FullName);
                return(new AssemblyLoadResult(assembly, bytes));
            }
        }
 void IUserInputHandler.OnKeyDown(KeyEventArgs e)
 {
     Release.Assert(false);
 }
        public void OnMouseDown(System.Windows.Forms.MouseEventArgs mouseEventArgs, int width, int height)
        {
            if (mSegmenter.DatasetLoaded)
            {
                var x = (int)Math.Floor(((float)mouseEventArgs.X / width) * mSegmenter.Interop.VolumeDescription.NumVoxelsX);
                var y = (int)Math.Floor(((float)mouseEventArgs.Y / height) * mSegmenter.Interop.VolumeDescription.NumVoxelsY);

                switch (mSegmenter.CurrentSegmenterToolMode)
                {
                case SegmenterToolMode.Adjust:
                    mSegmenter.BeginScribble(x, y);

                    if (Keyboard.IsKeyDown(Key.LeftAlt))
                    {
                        if (mouseEventArgs.Button == MouseButtons.Left)
                        {
                            mSegmenter.SelectNeuralProcessOrScribble(x, y, ConstraintType.Foreground, Constants.MAX_BRUSH_WIDTH);
                        }

                        if (mouseEventArgs.Button == MouseButtons.Right)
                        {
                            mSegmenter.SelectNeuralProcessOrScribble(x, y, ConstraintType.Background, Constants.MAX_BRUSH_WIDTH);
                        }
                    }
                    else
                    {
                        if (mouseEventArgs.Button == MouseButtons.Left)
                        {
                            mSegmenter.SelectNeuralProcessOrScribble(x, y, ConstraintType.Foreground, Constants.MIN_BRUSH_WIDTH);
                        }

                        if (mouseEventArgs.Button == MouseButtons.Right)
                        {
                            mSegmenter.SelectNeuralProcessOrScribble(x, y, ConstraintType.Background, Constants.MIN_BRUSH_WIDTH);
                        }
                    }
                    break;

                case SegmenterToolMode.Merge:
                    if (mouseEventArgs.Button == MouseButtons.Left)
                    {
                        mSegmenter.SelectMergeSourceNeuralProcess(x, y);
                    }

                    if (mouseEventArgs.Button == MouseButtons.Right)
                    {
                        if (mSegmenter.MergeSourceNeuralProcess != null)
                        {
                            mSegmenter.SelectMergeDestinationNeuralProcess(x, y);
                        }
                    }
                    break;

                case SegmenterToolMode.Split:
                    mSegmenter.BeginScribble(x, y);

                    if (Keyboard.IsKeyDown(Key.LeftAlt))
                    {
                        if (mouseEventArgs.Button == MouseButtons.Left)
                        {
                            mSegmenter.SelectSplitNeuralProcessOrScribble(x, y, ConstraintType.Foreground, Constants.MAX_BRUSH_WIDTH);
                        }

                        if (mouseEventArgs.Button == MouseButtons.Right)
                        {
                            mSegmenter.SelectSplitNeuralProcessOrScribble(x, y, ConstraintType.Background, Constants.MAX_BRUSH_WIDTH);
                        }
                    }
                    else
                    {
                        if (mouseEventArgs.Button == MouseButtons.Left)
                        {
                            mSegmenter.SelectSplitNeuralProcessOrScribble(x, y, ConstraintType.Foreground, Constants.MIN_BRUSH_WIDTH);
                        }

                        if (mouseEventArgs.Button == MouseButtons.Right)
                        {
                            mSegmenter.SelectSplitNeuralProcessOrScribble(x, y, ConstraintType.Background, Constants.MIN_BRUSH_WIDTH);
                        }
                    }
                    break;

                default:
                    Release.Assert(false);
                    break;
                }
            }
        }
        public RenderingStrategy(SlimDX.Direct3D11.Device device, DeviceContext deviceContext, Segmenter segmenter)
        {
            mSegmenter = segmenter;

            mStopwatch.Start();

            mEffect = EffectUtil.CompileEffect(device, @"Shaders\Segmenter2D.fx");

            // create position vertex data, making sure to rewind the stream afterward
            var positionVertexDataStream = new DataStream(NUM_VERTICES * POSITION_NUM_COMPONENTS_PER_VERTEX * POSITION_NUM_BYTES_PER_COMPONENT, true, true);

            positionVertexDataStream.Write(POSITION_TOP_LEFT);
            positionVertexDataStream.Write(POSITION_BOTTOM_LEFT);
            positionVertexDataStream.Write(POSITION_TOP_RIGHT);
            positionVertexDataStream.Write(POSITION_BOTTOM_RIGHT);
            positionVertexDataStream.Position = 0;

            // create texcoord vertex data, making sure to rewind the stream afterward
            var texCoordVertexDataStream = new DataStream(NUM_VERTICES * TEXCOORD_NUM_COMPONENTS_PER_VERTEX * TEXCOORD_NUM_BYTES_PER_COMPONENT, true, true);

            texCoordVertexDataStream.Write(TEXCOORD_TOP_LEFT);
            texCoordVertexDataStream.Write(TEXCOORD_BOTTOM_LEFT);
            texCoordVertexDataStream.Write(TEXCOORD_TOP_RIGHT);
            texCoordVertexDataStream.Write(TEXCOORD_BOTTOM_RIGHT);
            texCoordVertexDataStream.Position = 0;

            // create the input layout
            var inputElements = new[]
            {
                new InputElement("POSITION", 0, POSITION_FORMAT, POSITION_SLOT),
                new InputElement("TEXCOORD", 0, TEXCOORD_FORMAT, TEXCOORD_SLOT)
            };

            var technique = mEffect.GetTechniqueByName("Segmenter2D");

            mPass = technique.GetPassByName("Segmenter2D");

            mInputLayout = new InputLayout(device, mPass.Description.Signature, inputElements);

            // create the vertex buffers
            mPositionVertexBuffer = new Buffer(device,
                                               positionVertexDataStream,
                                               NUM_VERTICES * POSITION_NUM_COMPONENTS_PER_VERTEX * POSITION_NUM_BYTES_PER_COMPONENT,
                                               ResourceUsage.Default,
                                               BindFlags.VertexBuffer,
                                               CpuAccessFlags.None,
                                               ResourceOptionFlags.None,
                                               0);

            mTexCoordVertexBuffer = new Buffer(device,
                                               texCoordVertexDataStream,
                                               NUM_VERTICES * TEXCOORD_NUM_COMPONENTS_PER_VERTEX * TEXCOORD_NUM_BYTES_PER_COMPONENT,
                                               ResourceUsage.Default,
                                               BindFlags.VertexBuffer,
                                               CpuAccessFlags.None,
                                               ResourceOptionFlags.None,
                                               0);

            System.Threading.Thread.Sleep(1000);
            Trace.WriteLine("\nMojo initializing TinyText.Context (NOTE: TinyText.Context generates D3D11 warnings)...\n");

            bool result;

            mTinyTextContext = new Context(device, deviceContext, MAX_NUM_TEXT_CHARACTERS, out result);
            Release.Assert(result);

            Trace.WriteLine("\nMojo finished Initializing TinyText.Context...\n");
        }
Пример #17
0
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
        private void RotateCamera(double horizontalAngleRadians, double verticalAngleRadians)
        {
            Vector3 oldPosition, oldTarget, oldUp, oldTargetToOldPositionUnit;
            Vector3 planarOldPosition, planarOldTarget, planarOldTargetToOldPosition, planarOldRight, planarNewRight;
            Vector3 newPositionParallel, newPositionPerpendicular, newPosition, newUp, newPositionToOldTarget;

            Matrix rotationMatrix;

            //
            // compute the vertical component of the rotation first
            //
            mBreadcrumber.Camera.GetLookAtVectors(out oldPosition, out oldTarget, out oldUp);

            newPositionParallel      = (float)Math.Cos(verticalAngleRadians) * (oldPosition - oldTarget);
            newPositionPerpendicular = (float)Math.Sin(verticalAngleRadians) * (oldPosition - oldTarget).Length() * oldUp;
            newPosition = oldTarget + newPositionParallel + newPositionPerpendicular;

            mBreadcrumber.Camera.SetLookAtVectors(newPosition, oldTarget, oldUp);


            //
            // horizontally rotate the camera's position by temporarily discarding the y coordinates
            // of the old position and target, compute the rotation in 2D, and set the new position
            // y coordinate to equal the old y coordinate.  in other words, do a 2D rotation on the
            // horizontal plane.
            //
            mBreadcrumber.Camera.GetLookAtVectors(out oldPosition, out oldTarget, out oldUp);

            if (CAMERA_GROUND_NORMAL_SIGN * oldUp[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE] < 0)
            {
                horizontalAngleRadians *= -1;
            }

            planarOldPosition = oldPosition;
            planarOldTarget   = oldTarget;
            planarOldTarget[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE]   = 0;
            planarOldPosition[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE] = 0;
            planarOldTargetToOldPosition = planarOldPosition - planarOldTarget;
            oldTargetToOldPositionUnit   = oldPosition - oldTarget;
            oldTargetToOldPositionUnit.Normalize();

            newPositionParallel = (float)Math.Cos(horizontalAngleRadians) * planarOldTargetToOldPosition;

            var oldRightUnit = Vector3.Cross(oldTargetToOldPositionUnit, oldUp);

            oldRightUnit.Normalize();

            newPositionPerpendicular = (float)Math.Sin(horizontalAngleRadians) * planarOldTargetToOldPosition.Length() * oldRightUnit;

            newPosition = planarOldTarget + newPositionParallel + newPositionPerpendicular;
            newPosition[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE] = oldPosition[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE];

            //
            // now rotate the camera's orientation.  assume that the camera's right vector always lies
            // in the horizontal plane.  compute the new right vector by rotating the old right vector
            // in 2D on the horizontal plane.
            //
            Release.Assert(MathUtil.ApproxEqual(Vector3.Dot(oldTargetToOldPositionUnit, oldUp), 0.0f, 0.001f));

            planarOldRight = Vector3.Cross(oldTargetToOldPositionUnit, oldUp);
            planarOldRight.Normalize();

            Release.Assert(MathUtil.ApproxEqual(planarOldRight[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE], 0, 0.001f));

            if (CAMERA_GROUND_NORMAL_SIGN * oldUp[CAMERA_GROUND_NORMAL_NON_ZERO_COORDINATE] >= 0)
            {
                rotationMatrix = Matrix.RotationAxis(CAMERA_GROUND_NORMAL, -(float)horizontalAngleRadians);
            }
            else
            {
                rotationMatrix = Matrix.RotationAxis(-CAMERA_GROUND_NORMAL, -(float)horizontalAngleRadians);
            }

            planarNewRight = MathUtil.TransformAndHomogeneousDivide(planarOldRight, rotationMatrix);
            planarNewRight.Normalize();

            Release.Assert(Vector3.Dot(planarNewRight, planarOldRight) > 0);

            newPositionToOldTarget = oldTarget - newPosition;

            newUp = Vector3.Cross(newPositionToOldTarget, planarNewRight);
            newUp.Normalize();

            Release.Assert(Vector3.Dot(newUp, oldUp) > 0);

            mBreadcrumber.Camera.SetLookAtVectors(newPosition, oldTarget, newUp);
        }