public void Build()
        {
            Vector3D axis  = new Vector3D(0, 1, 0);
            Vector3D scale = new Vector3D(2.5, 1.5, .2);

            //this allows us to dynamically add items to the carousel
            _ItemOffsetAngle = 360 / this.Items.Count;
            //these are private variable we will use to layout each plane
            double angle      = 360.0 / this.Items.Count;
            double totalAngle = 0;

            // Layout the meshes
            for (int i = 0; i < this.Items.Count; i++)
            {
                //create a translation vector relative to the angle
                Vector3D tVector = GetTranslationOffsetForCarouselAngle(totalAngle);
                // fetch the list3DItem
                ListBox3DItem li = this.Items[i] as ListBox3DItem;
                //set some properties
                li.Status = (int)Carousel3DItemStates.Unselected;
                li.SetToDefaultPosition(scale, tVector, axis, _PerpendicularAngle - totalAngle);


                //add it to the _ModelItem Model3DGroup
                _ModelItems.Children.Add(li.ItemGroup);
                //here we set up the video on the mesh
                li.Initialize();
                //increment angle
                totalAngle += angle;
            }
        }
        public void Add(string VideoSrc)
        {
            ListBox3DItem expListItem = new ListBox3DItem();

            expListItem.VideoSrc = VideoSrc;
            this.AddChild(expListItem);
        }
        public bool DoHitTest(Visual target, Point p)
        {
            _ciHitTest         = null; // _HitMesh will be update by HTResult delegate when intersection occurs.
            _ciHitTestDistance = 9999999.0;

            VisualTreeHelper.HitTest(target, null, new HitTestResultCallback(HTResult),
                                     new PointHitTestParameters(p));

            return(_ciHitTest != null);
        }
        /// Returns the relative position of the item on a scale of -180 to 180, where 0 is directly in front of the viewer
        private double GetRelativeAngleForItem(ListBox3DItem item)
        {
            double angle = -((GetAnglePositionForItem(item) - (CurrentRotationAngle - GetZeroAngle())) - 90);

            if (angle % 360 == 0)
            {
                angle = 0;
            }

            if (angle > 180)
            {
                angle -= 360;
            }


            return(angle);
        }
        /// Given an item, returns the angle of rotation required to locate that item
        /// directly in front of the user
        private double GetFrontmostAngleForItem(ListBox3DItem item)
        {
            // with no rotation, 90 degrees is the frontmost position
            // we need to account for the number of rotations past 360 the carousel has made and factor
            // that in to our result.
            // find the shortest distance from the current position to the front, which will determine
            // the direction of rotation

            double baseAngle    = GetZeroAngle() + GetAnglePositionForItem(item);
            double frontAngle1  = baseAngle - 90;
            double frontAngle2  = baseAngle + 270;
            double distAngle1   = Math.Abs(frontAngle1 - CurrentRotationAngle);
            double distAngle2   = Math.Abs(frontAngle2 - CurrentRotationAngle);
            double shortestDist = Math.Min(distAngle1, distAngle2);

            return(shortestDist == distAngle1 ? frontAngle1 : frontAngle2);
        }
        public void RotateToNextItem()
        {
            _FrontmostItemIndex++;
            if (_FrontmostItemIndex > this.Items.Count - 1)
            {
                _FrontmostItemIndex = 0;
            }
            ListBox3DItem nextItem = GetFrontmostItem();
            double        start    = CurrentRotationAngle;
            double        end      = GetFrontmostAngleForItem(nextItem) - (SHOWCASE_ANGLE / 2);

            if (!_IsAutoRotating)
            {
                return;
            }
            RotateModel(start, end, AUTOROTATION_ADVANCE_DURATION);
            _AutoRotationState = (int)Carousel3DRotationStates.AdvanceRotate;
        }
        public HitTestResultBehavior HTResult(HitTestResult2D result2d)
        {
            RayMeshGeometry3DHitTestResult rayht = (result2d as RayMeshGeometry3DHitTestResult);
            Model3D model = rayht.ModelHit;

            foreach (ListBox3DItem ci in this.Items)
            {
                if (ci.ItemGroup.Children.Contains(model))
                {
                    if (rayht.DistanceToRayOrigin < _ciHitTestDistance)
                    {
                        _ciHitTest         = ci;
                        _ciHitTestDistance = rayht.DistanceToRayOrigin;
                    }
                }
            }

            return(HitTestResultBehavior.Continue);
        }
 private double GetAnglePositionForItem(ListBox3DItem item)
 {
     return(-(item.AngleY - _PerpendicularAngle));
 }