A visual element that displays a cube.
Наследование: BoxVisual3D
Пример #1
0
        public MainWindow()
        {
            InitializeComponent();

            cubit = new CubeVisual3D { SideLength = a * b, Fill = Brushes.SandyBrown };
            Loaded += this.MainWindowLoaded;
        }
Пример #2
0
        public Element()
        {
            Tube = new TubeVisual3D();
            Tube.Path = new Point3DCollection();
            Tube.Path.Add(new Point3D(-15, 0, 0));
            Tube.Path.Add(new Point3D(15, 0, 0));
            Tube.Diameter = tubeDiameter;
            Tube.IsSectionClosed = true;
            Tube.Fill = new SolidColorBrush(Colors.Silver);
            Tube.IsPathClosed = false;

            Sphere = new CubeVisual3D();
            //Sphere.Center = new Point3D(15, 0, 0);
            Sphere.Fill = new SolidColorBrush(Colors.Silver);
            Sphere.SideLength = 0.75;
        }
        private void InitializeHelix()
        {
            _helixItems.Add(new SunLight());
            _helixItems.Add(new GridLinesVisual3D
            {
                Width = 500,
                Length = 500
            });

            foreach (CameraModel cameraModel in Cameras)
            {
                CubeVisual3D cube = new CubeVisual3D();
                cube.SideLength = 10;
                cube.Fill = new SolidColorBrush(Colors.Blue);
                cube.Center = new Point3D(cameraModel.Calibration.TranslationToWorld[0, 0],
                    cameraModel.Calibration.TranslationToWorld[2, 0],
                    cameraModel.Calibration.TranslationToWorld[1, 0]);
                _helixItems.Add(cube);
            }

            if (Cameras.Count == 4)
            {
                ArrowVisual3D arrow = new ArrowVisual3D
                {
                    Point1 = new Point3D(
                        GetCamera(0).Calibration.TranslationToWorld[0, 0],
                        GetCamera(0).Calibration.TranslationToWorld[2, 0],
                        GetCamera(0).Calibration.TranslationToWorld[1, 0]),
                    Point2 = new Point3D(
                        GetCamera(2).Calibration.TranslationToWorld[0, 0],
                        GetCamera(2).Calibration.TranslationToWorld[2, 0],
                        GetCamera(2).Calibration.TranslationToWorld[1, 0]),
                    Fill = new SolidColorBrush(Colors.Yellow)
                };
                _helixItems.Add(arrow);

                arrow = new ArrowVisual3D
                {
                    Point1 = new Point3D(
                        GetCamera(1).Calibration.TranslationToWorld[0, 0],
                        GetCamera(1).Calibration.TranslationToWorld[2, 0],
                        GetCamera(1).Calibration.TranslationToWorld[1, 0]),
                    Point2 = new Point3D(
                        GetCamera(3).Calibration.TranslationToWorld[0, 0],
                        GetCamera(3).Calibration.TranslationToWorld[2, 0],
                        GetCamera(3).Calibration.TranslationToWorld[1, 0]),
                    Fill = new SolidColorBrush(Colors.Yellow)
                };
                _helixItems.Add(arrow);
            }

            ArrowVisual3D axis = new ArrowVisual3D
            {
                Origin = new Point3D(0, 0, 0),
                Direction = new Vector3D(100, 0, 0),
                Diameter = 2,
                Fill = new SolidColorBrush(Colors.Red)
            };
            _helixItems.Add(axis);

            axis = new ArrowVisual3D
            {
                Origin = new Point3D(0, 0, 0),
                Direction = new Vector3D(0, 100, 0),
                Diameter = 2,
                Fill = new SolidColorBrush(Colors.Green)
            };
            _helixItems.Add(axis);

            axis = new ArrowVisual3D
            {
                Origin = new Point3D(0, 0, 0),
                Direction = new Vector3D(0, 0, 100),
                Diameter = 2,
                Fill = new SolidColorBrush(Colors.Blue)
            };
            _helixItems.Add(axis);
        }
        private void InitializeHelix()
        {
            _items.Clear();
            _controllerObjects = new ObservableConcurrentDictionary<MotionControllerModel, SphereVisual3D>();

            _items.Add(new SunLight());
            _items.Add(new GridLinesVisual3D
            {
                Width = 500,
                Length = 500
            });

            CubeVisual3D camera = new CubeVisual3D
            {
                SideLength = 10,
                Fill = new SolidColorBrush(Colors.Blue),
                Center = new Point3D(_camera.Calibration.TranslationToWorld[0, 0],
                    _camera.Calibration.TranslationToWorld[2, 0],
                    _camera.Calibration.TranslationToWorld[1, 0])
            };
            _items.Add(camera);

            ArrowVisual3D axis = new ArrowVisual3D
            {
                Origin = new Point3D(0, 0, 0),
                Direction = new Vector3D(100, 0, 0),
                Diameter = 2,
                Fill = new SolidColorBrush(Colors.Red)
            };
            _items.Add(axis);

            axis = new ArrowVisual3D
            {
                Origin = new Point3D(0, 0, 0),
                Direction = new Vector3D(0, 100, 0),
                Diameter = 2,
                Fill = new SolidColorBrush(Colors.Green)
            };
            _items.Add(axis);

            axis = new ArrowVisual3D
            {
                Origin = new Point3D(0, 0, 0),
                Direction = new Vector3D(0, 0, 100),
                Diameter = 2,
                Fill = new SolidColorBrush(Colors.Blue)
            };
            _items.Add(axis);
        }
Пример #5
0
        public World() {
            // instantiate our world
            WorldObjects = new ModelVisual3D();
            Cubes = new ModelVisual3D();
            JointObjects = new ModelVisual3D();

            // create something to represent where the kinect is
            Kinect = new CubeVisual3D() {
                SideLength = 0.1,
                Center = new Point3D(0, 0, 0),
                Material = MaterialHelper.CreateMaterial(_Constants.KinectBrush, _Constants.KinectBrush)
            };

            // something to represent the floor
            RectangleVisual3D Floor = new RectangleVisual3D() {
                LengthDirection = new Vector3D(0, 0, 1),
                Normal = new Vector3D(0, 1, 0),
                Origin = new Point3D(0, -0.01, 0),
                Length = 20,
                Width = 20,
                Fill = Brushes.White,
                Material = MaterialHelper.CreateMaterial(Brushes.White, Brushes.White)
            };
            WorldObjects.Children.Add(Floor);

            // grid lines to layer on top of the floor
            GridLines = new GridLinesVisual3D() {
                LengthDirection = new Vector3D(0, 0, 1),
                Normal = new Vector3D(0, 1, 0),
                Transform = new ScaleTransform3D(0.025, 0.025, 0.025),
                Center = new Point3D(0, 0, 100),
            };
            WorldObjects.Children.Add(GridLines);

            // and a reference co-ordinate system
            CoordinateSystem = new CoordinateSystemVisual3D() {
                ArrowLengths = 0.3
            };
            WorldObjects.Children.Add(CoordinateSystem);

            // setup our world transformations
            FloorTransform = new TranslateTransform3D();
            AngleRotationTransform = new RotateTransform3D(Rotation3D.Identity, Kinect.Center);
            WorldTransforms = new Transform3DGroup();
            WorldTransforms.Children.Add(FloorTransform);
            WorldTransforms.Children.Add(AngleRotationTransform);
            Kinect.Transform = WorldTransforms;
            JointObjects.Transform = FloorTransform;
        }
Пример #6
0
        /// <summary>
        /// Tick the engine. Usually gets called by the kinect when AllFramesReady fires
        /// </summary>
        public void Tick(object sender, SkeletonFrameReadyEventArgs e) {


            // first thing we want to do is check if the kinect and all our objects
            // are valid

            // if there's no kinect, we need to forcibly denotify everything
            // and throw an exception
            if (Kinect == null || !Kinect.IsRunning) {
                DenotifyEverything();
                throw new NoKinectException();
            }

            SkeletonFrame skeletonFrame = e.OpenSkeletonFrame();

            // now is where we put any pre-conditions of the objects
            if (
                skeletonFrame == null       // no skeleton data 
             || JointsToTrack == null       // nothing has been specified to track
             || JointsToTrack.Count == 0
                )
                return;                     // get the f**k outta here

            // bring in our skeletons
            Skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
            skeletonFrame.CopySkeletonDataTo(Skeletons);


            // re-arrange our world according to parameters from the kinect
            // such as where it thinks the floor is
            //if (skeletonFrame.FloorClipPlane.Item4 != 0)
            //    World.SetFloorHeight(skeletonFrame.FloorClipPlane.Item4);
            // and the angle the kinect is lookint at

            // stabilise our angles by picking the median from a set of angle samples
            floorStabilisationAngles[currentFloorStabilisationAngleIndex++] = Kinect.ElevationAngle;
            if (currentFloorStabilisationAngleIndex == _Constants.FloorStabilisationSamples) {
                World.SetKinectAngle((float)_Math.GetMedian(floorStabilisationAngles));
                currentFloorStabilisationAngleIndex = 0;

                // adjust the camera view so it shows out from the kinect
                Viewport3D.Camera.Position = World.Kinect.Center;
                Viewport3D.Camera.LookDirection = new Vector3D(0, 0, 1);
                Viewport3D.Camera.Transform = World.FloorTransform;
            }


            // denotify any cubes that are associated with skeletons that no longer exist
            List<int> skeletonsToNuke = new List<int>();
            foreach (int skeletonTrackingId in DenotifyQueue.Keys) {
                // if it exists in this new list of skeletons, fine
                bool exists = false;
                foreach (Skeleton skeleton in Skeletons)
                    if (skeleton.TrackingId == skeletonTrackingId)
                        exists = true;

                // if it doesnt, denotify its arse off
                // and remove the joint geometry too
                if (!exists) {
                    foreach (JointType jointType in DenotifyQueue[skeletonTrackingId].Keys) {
                        foreach (Cube cube in DenotifyQueue[skeletonTrackingId][jointType])
                            cube.DeNotify();
                        World.JointObjects.Children.Remove(Joint3DGeometry[skeletonTrackingId][jointType]);
                    }
                    skeletonsToNuke.Add(skeletonTrackingId);
                }
            }
            foreach (int skeletonToNuke in skeletonsToNuke)
                DenotifyQueue.Remove(skeletonToNuke);



            // ok at this point we should be all stable and ready to do operations
            if (Mode != EngineMode.NoInteractive) {

                // first thing we need to do is register our skeletons & joints
                // and sort out their reference 3d geometry
                // for each skeleton
                bool firstSkeleton = true;
                foreach (Skeleton skeleton in Skeletons) {

                    // only track full skeletons that we can find (will be 2 - all the API supports)
                    if (skeleton != null && skeleton.TrackingState == SkeletonTrackingState.Tracked) {

                        // initialise this skeleton if we need to
                        if (!DenotifyQueue.ContainsKey(skeleton.TrackingId))
                            DenotifyQueue.Add(skeleton.TrackingId, new Dictionary<JointType, List<Cube>>()); // initialise it

                        // and the joint geometry if we need to
                        if (!Joint3DGeometry.ContainsKey(skeleton.TrackingId))
                            Joint3DGeometry.Add(skeleton.TrackingId, new Dictionary<JointType, CubeVisual3D>());

                        // for each jointType
                        foreach (JointType jointType in JointsToTrack) {

                            // check its being tracked by the skeleton tracker
                            if (skeleton.Joints[jointType].TrackingState != JointTrackingState.NotTracked) {

                                // transform the location of this joint to something more useful
                                Point3D jointLocation = _3DUtil.Joint3DGeometryToPoint3D(skeleton.Joints[jointType].Position);
                                jointLocation.X = -jointLocation.X;

                                // initialise in our denotify queue
                                if (!DenotifyQueue[skeleton.TrackingId].ContainsKey(jointType))
                                    DenotifyQueue[skeleton.TrackingId].Add(jointType, new List<Cube>());    // initialise it

                                // create some geometry for the joint if necessary (to visualise)
                                if (!Joint3DGeometry[skeleton.TrackingId].ContainsKey(jointType)) {
                                    CubeVisual3D cube = new CubeVisual3D() {
                                        SideLength = _Constants.JointRadius,
                                        Center = jointLocation,
                                        Material = MaterialHelper.CreateMaterial(_Constants.JointBrush, _Constants.JointBrush)
                                    };
                                    Joint3DGeometry[skeleton.TrackingId].Add(jointType, cube);
                                    World.JointObjects.Children.Add(cube);
                                }

                                // Move the joint representation geometry
                                Joint3DGeometry[skeleton.TrackingId][jointType].Center = jointLocation;

                                // adjust the joint geometry because of the world transform
                                jointLocation.Y += World.FloorHeight;


                                // now go through our notification queue
                                // only do this if we are in normal interaction mode
                                if (Mode == EngineMode.NormalInteractive) {

                                    // if the point of this joint is in a cube
                                    foreach (Cube cube in Cubes) {
                                        if (cube.ModelVisual3D.Content.Bounds.Contains(jointLocation)) {

                                            // and the cube is not already notified (if someone hasnt already stuck their limb in there)
                                            if (!cube.Notified) {

                                                // notify it, and add it to the list of things to denotify for this skeleton and joint type
                                                DenotifyQueue[skeleton.TrackingId][jointType].Add(cube);
                                                cube.Notify();
                                            }
                                            else {  // delays detection by a frame, but makes the program more efficient
                                                AnalogueCube analogueCube = cube as AnalogueCube;
                                                if (analogueCube != null) {
                                                    // if its an analogue cube we have to always notify with the
                                                    // relative x position
                                                    Rect3D cubeRect = cube.ModelVisual3D.Content.Bounds;
                                                    Point3D cubeCenter = new Point3D(
                                                        cubeRect.X + cubeRect.SizeX / 2d,
                                                        cubeRect.Y + cubeRect.SizeY / 2d,
                                                        cubeRect.Z + cubeRect.SizeZ / 2d
                                                    );
                                                    ((AnalogueCube)cube).NotifyAnalogue(_3DUtil.UnitDirectionVectorFromPointAToB(cubeCenter, jointLocation));
                                                }
                                            }
                                        }

                                        // otherwise if it exists in the denotify queue for this skeleton and joint, denotify and remove it
                                        else {
                                            if (DenotifyQueue[skeleton.TrackingId][jointType].Contains(cube)) {
                                                cube.DeNotify();
                                                DenotifyQueue[skeleton.TrackingId][jointType].Remove(cube);
                                            }
                                        }
                                    }
                                }
                            }
                            else {  // this joint has been marked as not tracked. So we need to denotify all its cubes
                                foreach (Cube cube in DenotifyQueue[skeleton.TrackingId][jointType])
                                    cube.DeNotify();
                                // kill from our view
                                World.JointObjects.Children.Remove(Joint3DGeometry[skeleton.TrackingId][jointType]);
                            }
                        }

                        // at this point all our joints are guaranteed to have been registered / moved
                        // so now we need to do our CRMD operations
                        // notification of cubes was already disabled if we are in one of these modes (not the interactivenormal mode)
                        // first of all, make sure our pre-requisites are in place
                        // we also only want to do it for the first skeleton
                        if (firstSkeleton) {
                            if (JointsToTrack.Contains(JointType.HandLeft) && JointsToTrack.Contains(JointType.HandRight)
                                && Skeletons.Length > 0) {
                                Point3D leftHandPoint = Joint3DGeometry[skeleton.TrackingId][JointType.HandLeft].Center;
                                Point3D rightHandPoint = Joint3DGeometry[skeleton.TrackingId][JointType.HandRight].Center;
                                Point3D skeletonSpineMidpoint = _3DUtil.Midpoint(
                                    _3DUtil.Joint3DGeometryToPoint3D(skeleton.Joints[JointType.ShoulderCenter].Position),
                                    _3DUtil.Joint3DGeometryToPoint3D(skeleton.Joints[JointType.HipCenter].Position)
                                    );
                                
                                // check to see whether we should be put into create mode
                                // wait until the hands are crossed for the set period of time
                                if (Mode == EngineMode.NormalInteractive && 
                                    leftHandPoint.X > rightHandPoint.X)
                                    stableTime = DateTime.Now.Ticks;
                                else if ((DateTime.Now.Ticks - stableTime) / TimeSpan.TicksPerMillisecond >= _Constants.CreateStableTimout) {
                                    if (createCube != null) {
                                        Mode = EngineMode.CreateCube;
                                        Debug.WriteLine("Hands are crossed");

                                        ((CubeVisual3D)Joint3DGeometry[skeleton.TrackingId][JointType.HandLeft]).Material = MaterialHelper.CreateMaterial(_Constants.JointBrush, _Constants.JointCreateBrush);
                                        ((CubeVisual3D)Joint3DGeometry[skeleton.TrackingId][JointType.HandRight]).Material = MaterialHelper.CreateMaterial(_Constants.JointBrush, _Constants.JointCreateBrush);
                                    }
                                }
                                // --old mode
                                // check to see whether we should be put into create mode
                                // wait until the hands are together for the set period of time
                                /*if (Mode == EngineMode.NormalInteractive && _3DUtil.DistanceBetween(leftHandPoint, rightHandPoint) > _Constants.CreateHandDistance * 2.0)
                                    stableTime = DateTime.Now.Ticks;
                                else if ((DateTime.Now.Ticks - stableTime) / TimeSpan.TicksPerMillisecond >= _Constants.CreateStableTimout) {
                                    if (createCube != null) {
                                        Mode = EngineMode.CreateCube;
                                        Debug.WriteLine("Hands are together");
                                    }
                                }*/
                                


                                // now, what we want to do depends on what mode we are in!
                                switch (Mode) {
                                    case EngineMode.CreateCube:
                                        // only do this stuff if our arms are not crossed (stops bullshit)
                                        DenotifyEverything();
                                        if (leftHandPoint.X > rightHandPoint.X) {
                                            // move and resize the cube we are creating relative to the hands
                                            Point3D cubeCenter = _3DUtil.Midpoint(leftHandPoint, rightHandPoint);
                                            cubeCenter.Y += World.FloorHeight;
                                            createCube.Resize(_3DUtil.DistanceBetween(leftHandPoint, rightHandPoint));
                                            createCube.MoveTo(cubeCenter);

                                            // step 3
                                            // we need to materialise the cube and get out of this process
                                            // we do this through a timeout 
                                            // or TODO: A signal

                                            // reset the counter if we fall outside the deadzone
                                            if (previousPoint == null || _3DUtil.DistanceBetween(previousPoint, cubeCenter) > _Constants.CreateStableDeadzone) {
                                                previousPoint = cubeCenter;
                                                stableTime = DateTime.Now.Ticks;
                                            }
                                            // otherwise if our time has elapsed, materialise the arsehole and leave create mode!
                                            else {
                                                long currentTime = DateTime.Now.Ticks;

                                                // fade colour to joint mode colour
                                                // work out percentage of time through the wait period
                                                long currentTimeMS = (currentTime - stableTime) / TimeSpan.TicksPerMillisecond;
                                                //double currentTimePercent = (double)currentTimeMS / (double)_Constants.CreateStableTimout;

                                                if (currentTimeMS >= _Constants.CreateStableTimout) {
                                                    Debug.WriteLine("timeout, cube is materialised");
                                                    OnEngineCubeCreated(new EngineCubeCreatedEventArgs(createCube));
                                                    Mode = EngineMode.NormalInteractive;
                                                    ReorderTransparentObjects();

                                                    ((CubeVisual3D)Joint3DGeometry[skeleton.TrackingId][JointType.HandLeft]).Material = MaterialHelper.CreateMaterial(_Constants.JointBrush, _Constants.JointBrush);
                                                    ((CubeVisual3D)Joint3DGeometry[skeleton.TrackingId][JointType.HandRight]).Material = MaterialHelper.CreateMaterial(_Constants.JointBrush, _Constants.JointBrush);
                                                }
                                            }
                                        }
                                        break;
                                    case EngineMode.DeleteCube:

                                        break;
                                    case EngineMode.MoveCube:

                                        break;
                                }
                            }
                            firstSkeleton = false;
                        }
                    }
                }
            }

            // drawing of the cubes is handled already
            // we're a done done!
            skeletonFrame.Dispose();
        }