예제 #1
0
        private void MainCameraChanged(object sender, CameraChangedRoutedEventArgs cameraChangedRoutedEventArgs)
        {
            // If line with text and text plane are not visible than we can exit this method
            if (TextPlaneVisual3D.Material != null)
            {
                // Else we need to convert the 3D start and end positions into 2D screen position
                Point screenPosition1 = MainCamera.Point3DTo2D(DistanceLineVisual3D.StartPosition);
                Point screenPosition2 = MainCamera.Point3DTo2D(DistanceLineVisual3D.EndPosition);

                // Now we check if the start position has moved to the right of the end position
                // This means that because of rotated camera, we are not watching the text from behind - it appears flipped
                if (screenPosition1.X > screenPosition2.X)
                {
                    if (!_isTextPlaneNormalFlipped)
                    {
                        // To flip the rendered text texture, we just flip the normal of the plane
                        TextPlaneVisual3D.Normal  = -1 * TextPlaneVisual3D.Normal;
                        _isTextPlaneNormalFlipped = true;
                    }
                }
                else if (_isTextPlaneNormalFlipped)
                {
                    // Uh, the normal was previously flipped - we need to flip it again to make it as original value
                    TextPlaneVisual3D.Normal  = -1 * TextPlaneVisual3D.Normal;
                    _isTextPlaneNormalFlipped = false;
                }
            }

            UpdateDisplayedDistanceMeasurement();
        }
        private void CameraOnCameraChanged(object sender, CameraChangedRoutedEventArgs e)
        {
            UpdateCanvasSize();

            // When camera is changed, we need to update the 2D positions that are get from 3D points
            UpdateScreenPositions();
        }
 protected void OnCameraChanged(CameraChangedRoutedEventArgs e)
 {
     if (CameraChanged != null)
     {
         CameraChanged(this, e);
     }
 }
            private void OnMainCameraChanged(object sender, CameraChangedRoutedEventArgs e)
            {
                if (_transparencySorter != null)
                {
                    if (_stopwatch == null)
                    {
                        _stopwatch = new Stopwatch();
                    }

                    _stopwatch.Restart();

                    _transparencySorter.Sort(TransparencySorter.SortingModeTypes.ByCameraDistance);

                    _stopwatch.Stop();
                    _totalSortTime += _stopwatch.Elapsed.TotalMilliseconds;
                }


                if (_isSyncingCamera)
                {
                    return;
                }

                OnCameraChanged(e);
            }
        private void Camera1OnCameraChanged(object sender, CameraChangedRoutedEventArgs cameraChangedRoutedEventArgs)
        {
            // On each change of camera we will update the orientation of billboard objects.
            // When using PlaneVisual3D, TextBlockVisual3D or TextVisual3D we can simply call the AlignWithCamera method.

            // If we did some changes to the Camera1 in the code,
            // it is recommended to call Refresh before calling AlignWithCamera method:
            // Camera1.Refresh();

            AlignBillboards();
        }
        private void OnCameraChanged(object sender, CameraChangedRoutedEventArgs e)
        {
            var testScene     = sender as TestScene;
            var changedCamera = testScene.MainCamera;

            for (var i = 0; i < _testScenes.Length; i++)
            {
                if (_testScenes[i] == testScene)
                {
                    continue;
                }

                _testScenes[i].SyncCamera(changedCamera);
            }
        }
예제 #7
0
        private void Camera2_OnCameraChanged(object sender, CameraChangedRoutedEventArgs e)
        {
            if (!this.IsLoaded || _isInternalCameraChange)
            {
                return;
            }

            //Synchronize Camera1 and Camera2
            _isInternalCameraChange = true;

            Camera1.Heading  = Camera2.Heading;
            Camera1.Attitude = Camera2.Attitude;
            Camera1.Distance = Camera2.Distance;

            _isInternalCameraChange = false;
        }
예제 #8
0
        private void Camera2_OnCameraChanged(object sender, CameraChangedRoutedEventArgs e)
        {
            if (_isInternalChange) // Prevent infinite call or Camera1 / 2 change handlers
            {
                return;
            }

            _isInternalChange = true;

            Camera1.BeginInit();
            Camera1.Heading  = Camera2.Heading;
            Camera1.Attitude = Camera2.Attitude;
            Camera1.Distance = Camera2.Distance;
            Camera1.Offset   = Camera2.Offset;
            Camera1.EndInit();

            _isInternalChange = false;
        }
        private void Camera1OnCameraChanged(object o, CameraChangedRoutedEventArgs cameraChangedRoutedEventArgs)
        {
            // To check if we need to flip TextDirection,
            // we first calculate the 3D vector that points into the direction from which the text is correctly seen.
            // This can be get with calculating cross product from TextDirection and UpDirection - getting perpendicular vector to those two vectors.
            Vector3D textFaceVector = Vector3D.CrossProduct(CenteredTextVisual2.TextDirection, CenteredTextVisual2.UpDirection);

            // Now calculate dot product from textFaceVector and camera's LookDirection
            // If the result is negative, then those two vectors are facing in opposite direction.
            // This is a desired result - text is facing towards camera and camera towards text.
            // But if the result is positive, then text is seen correctly from the other side.
            // In this case we flip the TextDirection by multiplying it with -1.
            // In our case this flips between initial (1, 0, 0) and (-1, 0, 0) vectors.
            if (Vector3D.DotProduct(textFaceVector, Camera1.LookDirection) > 0)
            {
                CenteredTextVisual2.TextDirection = CenteredTextVisual2.TextDirection * (-1);
            }
        }
        private void CustomCamera_OnCameraChanged(object sender, CameraChangedRoutedEventArgs e)
        {
            double newCameraDistance = _customCamera.Distance;

            double distanceChangeFactor = newCameraDistance / _previousCameraDistance;

            _previousCameraDistance = newCameraDistance;

            // When custom camera (controller by user) is changed, we also change other cameras
            // But do not change distance (because this is different based on the size of the sphere)
            foreach (var targetPositionCamera in RootGrid.Children.OfType <TargetPositionCamera>())
            {
                if (ReferenceEquals(_customCamera, targetPositionCamera))
                {
                    continue;
                }

                targetPositionCamera.Heading   = _customCamera.Heading;
                targetPositionCamera.Attitude  = _customCamera.Attitude;
                targetPositionCamera.Distance *= distanceChangeFactor;
            }
        }
예제 #11
0
 private void WpfCamera_OnCameraChanged(object sender, CameraChangedRoutedEventArgs e)
 {
     CopyWpfCamera();
 }
예제 #12
0
 private void CameraOnCameraChanged(object sender, CameraChangedRoutedEventArgs cameraChangedRoutedEventArgs)
 {
     UpdateAxis(recreateEverything: false);
 }
예제 #13
0
        private void Camera1OnCameraChanged(object sender, CameraChangedRoutedEventArgs cameraChangedRoutedEventArgs)
        {
            if (!(AlignWithCameraCheckBox.IsChecked ?? false))
            {
                return;
            }


            // On each change of camera we will update the orientation of billboard objects.
            // When using PlaneVisual3D, TextBlockVisual3D or TextVisual3D we can simply call the AlignWithCamera method.

            // If we did some changes to the Camera1 in the code,
            // it is recommended to call Refresh before calling AlignWithCamera method:
            // Camera1.Refresh();

            bool fixYAxis = FixYAxisCheckBox.IsChecked ?? false;

            PlaneVisual1.AlignWithCamera(Camera1);
            TextBlockVisual3D1.AlignWithCamera(Camera1);


            if (fixYAxis)
            {
                // To show a billboard with fixed Y axis, we first call AlignWithCamera and then set the UpDirection back to Y axis.
                PlaneVisual1.HeightDirection   = Ab3d.Common.Constants.UpVector; // = new Vector3D(0, 1, 0);
                TextBlockVisual3D1.UpDirection = Ab3d.Common.Constants.UpVector;
            }


            if (FixScreenSizeCheckBox.IsChecked ?? false)
            {
                // When FixScreenSizeCheckBox is checked, we update the size of the billboards in 3D works
                // so that they are rendered to the same size on the screen.
                //
                // This is done with the GetWorldSize method that calculates a size in 3D world coordinates from a size provided in 2D screen coordinates.
                // You can also use CameraUtils.GetOrthographicWorldSize and CameraUtils.GetPerspectiveWorldSize methods to get the same results but with more low level parameters.
                //
                // It is also possible to get the opposite value - size on screen - with the following methods:
                // Camera1.GetScreenSize(Size worldSize, Point3D targetPosition3D)
                // CameraUtils.GetPerspectiveScreenSize(Size worldSize, double lookDirectionDistance, double fieldOfView, Size viewport3DSize)
                // CameraUtils.GetOrthographicScreenSize(Size worldSize, double cameraWidth, Size viewport3DSize)

                // Set the size so that it will be shown in 200 x 40 box on the screen.
                Size worldSize = Camera1.GetWorldSize(new Size(200, 40), TextBlockVisual3D1.Position);


                // With TextBlockVisual3D we can use multiple methods to adjust the size of the text:
                // 1) Change FontSize property - this is the most performance expensive method because this will require to update the text (and render the bitmap if it is used to show the content of TextBlockVisual3D - for example when in DXEngine).
                // 2) Change Size property - this is better but would require to update the plane's MeshGeometry3D. This creates a lot of objects on each camera change and require frequent garbage collections.
                //    TextBlockVisual3D1.Size = worldSize;
                // 3) Scale the TextBlockVisual3D1 to the required size. This is by far the fastest and most efficient method because only the transformation is changed:

                var scaleTransform3D = TextBlockVisual3D1.Transform as ScaleTransform3D;
                if (scaleTransform3D == null)
                {
                    scaleTransform3D = new ScaleTransform3D();

                    // To prevent scaling the position (multiplying it with the scale factor), we need to set the center of scale
                    scaleTransform3D.CenterX = TextBlockVisual3D1.Position.X;
                    scaleTransform3D.CenterY = TextBlockVisual3D1.Position.Y;
                    scaleTransform3D.CenterZ = TextBlockVisual3D1.Position.Z;

                    TextBlockVisual3D1.Transform = scaleTransform3D;
                }

                // Calculate required scale to get the size of the TextBlockVisual3D to the required worldSize
                double scaleFactor = worldSize.Width / TextBlockVisual3D1.Size.Width;
                scaleTransform3D.ScaleX = scaleFactor;
                scaleTransform3D.ScaleY = scaleFactor;
                scaleTransform3D.ScaleZ = scaleFactor;


                // Do the same for PlaneVisual3D
                worldSize = Camera1.GetWorldSize(new Size(200, 40), PlaneVisual1.CenterPosition);

                // The easiest way to update the size of a PlaneVisual3D is to change its Size.
                // But because this creates a new MeshGeometry3D, this can produce a lot of garbage because this is called on each frame (on each camera change).
                // Therefore it is better to use ScaleTransform3D to update the size.
                //PlaneVisual1.Size = worldSize;

                scaleTransform3D = PlaneVisual1.Transform as ScaleTransform3D;
                if (scaleTransform3D == null)
                {
                    scaleTransform3D = new ScaleTransform3D();

                    // To prevent scaling the position (multiplying it with the scale factor), we need to set the center of scale
                    scaleTransform3D.CenterX = PlaneVisual1.CenterPosition.X;
                    scaleTransform3D.CenterY = PlaneVisual1.CenterPosition.Y;
                    scaleTransform3D.CenterZ = PlaneVisual1.CenterPosition.Z;

                    PlaneVisual1.Transform = scaleTransform3D;
                }

                scaleFactor             = worldSize.Width / PlaneVisual1.Size.Width;
                scaleTransform3D.ScaleX = scaleFactor;
                scaleTransform3D.ScaleY = scaleFactor;
                scaleTransform3D.ScaleZ = scaleFactor;
            }
            else
            {
                // When FixScreenSizeCheckBox is unchecked, reset the size back to initial size

                TextBlockVisual3D1.Transform = null;
                PlaneVisual1.Transform       = null;

                // The following code is used if we do not use ScaleTransform3D but instead change the Size

                //if (TextBlockVisual3D1.Size.Width != 80)
                //    TextBlockVisual3D1.Size = new Size(80, 20);

                //if (PlaneVisual1.Size.Width != 80)
                //    PlaneVisual1.Size = new Size(80, 20);
            }


            // Update all tree objects
            foreach (var treePlaneVisual in TreesPlaceholerVisual3D.Children.OfType <PlaneVisual3D>())
            {
                treePlaneVisual.AlignWithCamera(Camera1);

                if (fixYAxis)
                {
                    treePlaneVisual.HeightDirection = Ab3d.Common.Constants.UpVector;
                }
            }


            // After objects were rotated, we can reorder them so that those farther away from the camera are rendered first.
            // This way the objects will be correctly visible through transparent objects.
            _transparencySorter.Sort(TransparencySorter.SortingModeTypes.ByCameraDistance);


            UpdateOverlayCanvasElements();
        }