private static void Run(TaskWrapper parent, CancellationToken cancel, Color background) { //NOTE: This method is running on an arbitrary thread try { // Create viewport ViewportOffline viewport = new ViewportOffline(background); List <ICameraPoolCamera> cameras = new List <ICameraPoolCamera>(); while (!cancel.IsCancellationRequested) { // Add/Remove items AddRemoveItems(parent, viewport, cameras); if (cameras.Count == 0) { // Hang out for a bit, then try again. No need to burn up the processor //TODO: UseAutoResetEvent (triggered by another thread in CameraPool.Add()) //http://stackoverflow.com/questions/382173/what-are-alternative-ways-to-suspend-and-resume-a-thread Thread.Sleep(450 + StaticRandom.Next(100)); continue; } MoveVisuals(viewport); #region Take pictures //TODO: If it takes a long time to get through these cameras, then maybe the visuals should be moved after every couple cameras foreach (ICameraPoolCamera camera in cameras) { if (cancel.IsCancellationRequested) { return; } if (camera.IsOn) { var location = camera.GetWorldLocation_Camera(); IBitmapCustom bitmap = viewport.GetSnapshot(location.Item1, location.Item2.Standard, location.Item2.Orth, camera.PixelWidthHeight); camera.StoreSnapshot(bitmap); } } #endregion Thread.Sleep(0); // not sure if this is useful or not //Thread.Yield(); } } catch (Exception) { // Don't leak errors, just go away } }
private static void MoveVisuals(ViewportOffline viewport) { foreach (var visual in viewport.Visuals.Values) { if (visual.Item1.Visual == null) { // This is a statically placed object (light) continue; } visual.Item2.Transform = new MatrixTransform3D(visual.Item1.Visual.OffsetMatrix); } }
//private static void AddRemoveVisuals(TaskWrapper parent, ViewportOffline viewport) //{ // #region Removes // CameraPoolVisual visual; // while (parent.RemoveVisuals.TryDequeue(out visual)) // { // viewport.Viewport.Children.Remove(viewport.Visuals[visual.Token].Item2); // viewport.Visuals.Remove(visual.Token); // } // #endregion // #region Adds // while (parent.AddVisuals.TryDequeue(out visual)) // { // // Deserialize into an instance that is specific to this thread // Model3D model; // using (MemoryStream stream = new MemoryStream(visual.Model3D)) // { // model = XamlServices.Load(stream) as Model3D; // } // // Create a visual to hold it (no need to set the transform here, that will be done each frame) // ModelVisual3D modelVisual = new ModelVisual3D(); // modelVisual.Content = model; // // Store it // viewport.Viewport.Children.Add(modelVisual); // viewport.Visuals.Add(visual.Token, Tuple.Create(visual, (Visual3D)modelVisual)); // } // #endregion //} //private static void AddRemoveCameras(TaskWrapper parent, List<ICameraPoolCamera> cameras) //{ // bool hadChange = false; // // Removes // ICameraPoolCamera camera; // while (parent.RemoveCameras.TryDequeue(out camera)) // { // cameras.Remove(camera); // hadChange = true; // } // // Adds // while (parent.AddCameras.TryDequeue(out camera)) // { // cameras.Add(camera); // hadChange = true; // } // // Store the new count // if (hadChange) // { // parent._count = cameras.Count; // } //} private static void AddRemoveItems(TaskWrapper parent, ViewportOffline viewport, List <ICameraPoolCamera> cameras) { bool numCamerasChanged = false; while (parent.AddRemoves.TryDequeue(out Tuple <object, bool> item)) { if (item.Item1 is CameraPoolVisual visual) { if (item.Item2) { #region Add Visual // Deserialize into an instance that is specific to this thread Model3D model; using (MemoryStream stream = new MemoryStream(visual.Model3D)) { model = XamlServices.Load(stream) as Model3D; } // Create a visual to hold it (no need to set the transform here, that will be done each frame) ModelVisual3D modelVisual = new ModelVisual3D(); modelVisual.Content = model; // Store it viewport.Viewport.Children.Add(modelVisual); viewport.Visuals.Add(visual.Token, Tuple.Create(visual, (Visual3D)modelVisual)); #endregion } else { #region Remove Visual viewport.Viewport.Children.Remove(viewport.Visuals[visual.Token].Item2); viewport.Visuals.Remove(visual.Token); #endregion } } else if (item.Item1 is ICameraPoolCamera) { ICameraPoolCamera camera = (ICameraPoolCamera)item.Item1; numCamerasChanged = true; if (item.Item2) { #region Add Camera cameras.Add(camera); #endregion } else { #region Remove Camera cameras.Remove(camera); #endregion } } else { throw new ApplicationException("Unknown type of item: " + item.Item1.GetType().ToString()); } } // Store the new count if (numCamerasChanged) { parent._count = cameras.Count; } }
//private static void AddRemoveVisuals(TaskWrapper parent, ViewportOffline viewport) //{ // #region Removes // CameraPoolVisual visual; // while (parent.RemoveVisuals.TryDequeue(out visual)) // { // viewport.Viewport.Children.Remove(viewport.Visuals[visual.Token].Item2); // viewport.Visuals.Remove(visual.Token); // } // #endregion // #region Adds // while (parent.AddVisuals.TryDequeue(out visual)) // { // // Deserialize into an instance that is specific to this thread // Model3D model; // using (MemoryStream stream = new MemoryStream(visual.Model3D)) // { // model = XamlServices.Load(stream) as Model3D; // } // // Create a visual to hold it (no need to set the transform here, that will be done each frame) // ModelVisual3D modelVisual = new ModelVisual3D(); // modelVisual.Content = model; // // Store it // viewport.Viewport.Children.Add(modelVisual); // viewport.Visuals.Add(visual.Token, Tuple.Create(visual, (Visual3D)modelVisual)); // } // #endregion //} //private static void AddRemoveCameras(TaskWrapper parent, List<ICameraPoolCamera> cameras) //{ // bool hadChange = false; // // Removes // ICameraPoolCamera camera; // while (parent.RemoveCameras.TryDequeue(out camera)) // { // cameras.Remove(camera); // hadChange = true; // } // // Adds // while (parent.AddCameras.TryDequeue(out camera)) // { // cameras.Add(camera); // hadChange = true; // } // // Store the new count // if (hadChange) // { // parent._count = cameras.Count; // } //} private static void AddRemoveItems(TaskWrapper parent, ViewportOffline viewport, List<ICameraPoolCamera> cameras) { bool numCamerasChanged = false; Tuple<object, bool> item; while (parent.AddRemoves.TryDequeue(out item)) { if (item.Item1 is CameraPoolVisual) { CameraPoolVisual visual = (CameraPoolVisual)item.Item1; if (item.Item2) { #region Add Visual // Deserialize into an instance that is specific to this thread Model3D model; using (MemoryStream stream = new MemoryStream(visual.Model3D)) { model = XamlServices.Load(stream) as Model3D; } // Create a visual to hold it (no need to set the transform here, that will be done each frame) ModelVisual3D modelVisual = new ModelVisual3D(); modelVisual.Content = model; // Store it viewport.Viewport.Children.Add(modelVisual); viewport.Visuals.Add(visual.Token, Tuple.Create(visual, (Visual3D)modelVisual)); #endregion } else { #region Remove Visual viewport.Viewport.Children.Remove(viewport.Visuals[visual.Token].Item2); viewport.Visuals.Remove(visual.Token); #endregion } } else if (item.Item1 is ICameraPoolCamera) { ICameraPoolCamera camera = (ICameraPoolCamera)item.Item1; numCamerasChanged = true; if (item.Item2) { #region Add Camera cameras.Add(camera); #endregion } else { #region Remove Camera cameras.Remove(camera); #endregion } } else { throw new ApplicationException("Unknown type of item: " + item.Item1.GetType().ToString()); } } // Store the new count if (numCamerasChanged) { parent._count = cameras.Count; } }
private static void Run(TaskWrapper parent, CancellationToken cancel, Color background) { //NOTE: This method is running on an arbitrary thread try { // Create viewport ViewportOffline viewport = new ViewportOffline(background); List<ICameraPoolCamera> cameras = new List<ICameraPoolCamera>(); while (!cancel.IsCancellationRequested) { // Add/Remove items AddRemoveItems(parent, viewport, cameras); if (cameras.Count == 0) { // Hang out for a bit, then try again. No need to burn up the processor //TODO: UseAutoResetEvent (triggered by another thread in CameraPool.Add()) //http://stackoverflow.com/questions/382173/what-are-alternative-ways-to-suspend-and-resume-a-thread Thread.Sleep(450 + StaticRandom.Next(100)); continue; } MoveVisuals(viewport); #region Take pictures //TODO: If it takes a long time to get through these cameras, then maybe the visuals should be moved after every couple cameras foreach (ICameraPoolCamera camera in cameras) { if (cancel.IsCancellationRequested) { return; } if (camera.IsOn) { var location = camera.GetWorldLocation_Camera(); IBitmapCustom bitmap = viewport.GetSnapshot(location.Item1, location.Item2.Standard, location.Item2.Orth, camera.PixelWidthHeight); camera.StoreSnapshot(bitmap); } } #endregion Thread.Sleep(0); // not sure if this is useful or not //Thread.Yield(); } } catch (Exception) { // Don't leak errors, just go away } }
private static void ThreadTest2(byte[] geometryBytes) { Model3D model; using (MemoryStream stream = new MemoryStream(geometryBytes)) { model = XamlServices.Load(stream) as Model3D; } // Store it in a new viewport ModelVisual3D visual = new ModelVisual3D(); visual.Content = model; ViewportOffline viewport = new ViewportOffline(Brushes.Black); viewport.Visuals.Add(visual); viewport.Viewport.Children.Add(visual); // Take a picture IBitmapCustom bitmap = UtilityWPF.RenderControl(viewport.Control, 100, 100, true, Colors.Black, false); }
private static void ThreadTest1(Model3D model) { // Store it in a new viewport ModelVisual3D visual = new ModelVisual3D(); visual.Content = model; ViewportOffline viewport = new ViewportOffline(Brushes.Black); viewport.Visuals.Add(visual); viewport.Viewport.Children.Add(visual); // Take a picture IBitmapCustom bitmap = UtilityWPF.RenderControl(viewport.Control, 100, 100, true, Colors.Black, false); }
private void AddVisual(Model3D model) { #region Standard ModelVisual3D visual = new ModelVisual3D(); visual.Content = model; _visuals.Add(visual); _viewport.Children.Add(visual); #endregion #region Offline 1 if (_offline1 == null) { Brush background = null; if (radSceneBlack.IsChecked.Value) { background = Brushes.Black; } else if (radSceneTransparent.IsChecked.Value) { background = Brushes.Transparent; } else { throw new ApplicationException("Unknown background color"); } _offline1 = new ViewportOffline(background); radSceneBlack.IsEnabled = false; // crude, but I don't want to listen to events radSceneTransparent.IsEnabled = false; } visual = new ModelVisual3D(); visual.Content = model; _offline1.Visuals.Add(visual); _offline1.Viewport.Children.Add(visual); #endregion #region Camera Pool // Create pool if (_cameraPool == null) { _cameraPool = new CameraPool(1, radSceneBlack.IsChecked.Value ? Colors.Black : Colors.Transparent); } // Serialize model byte[] modelBytes = null; using (MemoryStream stream = new MemoryStream()) { XamlServices.Save(stream, model); stream.Position = 0; modelBytes = stream.ToArray(); } CameraPoolVisual poolVisual = new CameraPoolVisual(TokenGenerator.NextToken(), modelBytes, null); // Add it _cameraPoolVisuals.Add(poolVisual); _cameraPool.Add(poolVisual); #endregion }