예제 #1
0
        //Loops:
        private void Update()
        {
            //wait for hand input to come online:
            if (!HandInput.Ready)
            {
                return;
            }

            //shoulder:
            float shoulderDistance = shoulderWidth * .5f;

            //swap for the left shoulder:
            if (handedness == MLHandTracking.HandType.Left)
            {
                shoulderDistance *= -1;
            }

            //source locations:
            Vector3 flatForward   = Vector3.ProjectOnPlane(_mainCamera.forward, Vector3.up);
            Vector3 shoulder      = TransformUtilities.WorldPosition(_mainCamera.position, Quaternion.LookRotation(flatForward), new Vector2(shoulderDistance, Mathf.Abs(shoulderDistanceBelowHead) * -1));
            Vector3 pointerOrigin = Vector3.Lerp(Hand.Skeleton.Thumb.Knuckle.positionFiltered, Hand.Skeleton.Position, .5f);

            //direction:
            Quaternion orientation = Quaternion.LookRotation(Vector3.Normalize(pointerOrigin - shoulder), Hand.Skeleton.Rotation * Vector3.up);

            //application:
            transform.position = pointerOrigin;
            transform.rotation = orientation;
        }
예제 #2
0
        private void PreviewArea()
        {
            //visualize:
            Vector3[] playspacePerimeterOnFloor   = new Vector3[_playspaceCorners.Count];
            Vector3[] playspacePerimeterOnCeiling = new Vector3[_playspaceCorners.Count];

            //populate floor and ceiling corner loops:
            for (int i = 0; i < _playspaceCorners.Count; i++)
            {
                //cache floor and ceiling locations:
                Vector3 floor   = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i]);
                Vector3 ceiling = floor + new Vector3(0, Height);
                playspacePerimeterOnFloor[i]   = floor;
                playspacePerimeterOnCeiling[i] = ceiling;

                //draw corner supports:
                LineRenderer cornerSupportsOutline = Lines.DrawLine($"PlayspaceCornerSupport{i}", Color.green, Color.green, .005f, floor, ceiling);
                cornerSupportsOutline.material = perimeterOutlineMaterial;
            }

            //draw ceiling and floor perimeter:
            LineRenderer ceilingOutline = Lines.DrawLine($"PlayspaceCeilingOutline", Color.green, Color.green, .005f, playspacePerimeterOnCeiling);
            LineRenderer floorOutline   = Lines.DrawLine($"PlayspaceFloorOutline", Color.green, Color.green, .005f, playspacePerimeterOnFloor);

            ceilingOutline.material = perimeterOutlineMaterial;
            floorOutline.material   = perimeterOutlineMaterial;
        }
예제 #3
0
        private void FindWalls_GenerateGeometry()
        {
            //transform matrix:
            Vector3    correctedForward  = Vector3.ProjectOnPlane(pcfAnchor.Rotation * Vector3.forward, Vector3.up).normalized;
            Quaternion correctedRotation = Quaternion.LookRotation(correctedForward);
            Matrix4x4  transformMatrix   = Matrix4x4.TRS(pcfAnchor.Position, correctedRotation, Vector3.one);

            //build wall geometry:
            Vector3        verticalOffset = Vector3.up * Height;
            List <Vector3> wallVerticies  = new List <Vector3>();
            List <int>     wallTriangles  = new List <int>();

            for (int i = 0; i < _playspaceCorners.Count - 1; i++)
            {
                Vector3 pointA = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i]);
                Vector3 pointB = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i + 1]);

                //locate verticies (local space):
                Vector3 a = transformMatrix.inverse.MultiplyPoint3x4(pointA);
                Vector3 b = transformMatrix.inverse.MultiplyPoint3x4(pointB);
                Vector3 c = b + verticalOffset;
                Vector3 d = a + verticalOffset;

                //store verticies (reverse order so normals face inwards):
                wallVerticies.Add(d);
                wallVerticies.Add(c);
                wallVerticies.Add(b);
                wallVerticies.Add(a);

                //store triangles
                wallTriangles.Add(wallVerticies.Count - 4);
                wallTriangles.Add(wallVerticies.Count - 3);
                wallTriangles.Add(wallVerticies.Count - 2);
                wallTriangles.Add(wallVerticies.Count - 2);
                wallTriangles.Add(wallVerticies.Count - 1);
                wallTriangles.Add(wallVerticies.Count - 4);
            }

            //get points for polygon construction:
            Vector2[] polygonPoints    = new Vector2[_playspaceCorners.Count - 1];
            Vector3[] floorVerticies   = new Vector3[_playspaceCorners.Count - 1];
            Vector3[] ceilingVerticies = new Vector3[_playspaceCorners.Count - 1];
            for (int i = 0; i < _playspaceCorners.Count - 1; i++)
            {
                Vector3 point = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i]);
                Vector3 local = transformMatrix.inverse.MultiplyPoint3x4(point);
                polygonPoints[i]    = new Vector2(local.x, local.z);
                floorVerticies[i]   = local;
                ceilingVerticies[i] = local + verticalOffset;
            }

            //triangles:
            int[] floorTriangles = new Triangulator(polygonPoints).Triangulate();

            BuildGeometry(wallVerticies.ToArray(), wallTriangles.ToArray(), floorVerticies, floorTriangles, ceilingVerticies);

            //FindWalls_Analyze();
            ChangeState(State.ConfirmArea);
        }
        private void HandleTransformSync(TransformSyncMessage transformSyncMessage)
        {
            //is this a pose message for us?
            if (transformSyncMessage.ig != guid)
            {
                return;
            }

            //unpack:
            Vector3    receivedLocalPosition  = new Vector3((float)transformSyncMessage.px, (float)transformSyncMessage.py, (float)transformSyncMessage.pz);
            Quaternion receivedRotationOffset = new Quaternion((float)transformSyncMessage.rx, (float)transformSyncMessage.ry, (float)transformSyncMessage.rz, (float)transformSyncMessage.rw);

            _targetPosition = TransformUtilities.WorldPosition(Transmission.Instance.sharedOrigin.position, Transmission.Instance.sharedOrigin.rotation, receivedLocalPosition);
            _targetRotation = TransformUtilities.ApplyRotationOffset(Transmission.Instance.sharedOrigin.rotation, receivedRotationOffset);
            targetScale     = new Vector3((float)transformSyncMessage.sx, (float)transformSyncMessage.sy, (float)transformSyncMessage.sz);
        }
예제 #5
0
        private void FindWalls_LocateBoundry()
        {
            //remove initial guides:
            RemovePlottedBounds();

            //sort by angles from a base vector to find clockwise order:
            Vector3 baseVector = Vector3.Normalize(_virtualWalls[0].plane.Center - _plottedBounds.center);
            SortedDictionary <float, int> sortedDirection = new SortedDictionary <float, int>();

            for (int i = 0; i < _virtualWalls.Count; i++)
            {
                Vector3 toNext = Vector3.Normalize(_virtualWalls[i].plane.Center - _plottedBounds.center);
                float   angle  = Vector3.SignedAngle(baseVector, toNext, Vector3.up) + 180;

                if (sortedDirection.ContainsKey(angle))
                {
                    //we have a bad set of locations so it is best to just everything:
                    Create();
                    break;
                }
                else
                {
                    sortedDirection.Add(angle, i);
                }
            }
            int[] clockwiseOrder = sortedDirection.Values.ToArray <int>();

            //find and connect 'betweens' which end up being final walls of playspace
            List <bool> physicalStatus = new List <bool>();

            _playspaceCorners = new List <Vector3>();
            for (int i = 0; i < clockwiseOrder.Length; i++)
            {
                //parts:
                int   next  = (i + 1) % clockwiseOrder.Length;
                float angle = Vector3.Angle(_virtualWalls[clockwiseOrder[i]].plane.Rotation * Vector3.right, _virtualWalls[clockwiseOrder[next]].plane.Rotation * Vector3.right);

                //save physical status:
                physicalStatus.Add(_virtualWalls[clockwiseOrder[next]].physical);

                //add solved between:
                if (angle < 45 || angle > 135)
                {
                    //wall - use mid point:
                    Vector3 mid = Vector3.Lerp(_virtualWalls[clockwiseOrder[i]].plane.Center, _virtualWalls[clockwiseOrder[next]].plane.Center, .5f);
                    mid.y = _roomFloorHeight;
                    _playspaceCorners.Add(TransformUtilities.LocalPosition(pcfAnchor.Position, pcfAnchor.Rotation, mid));
                }
                else
                {
                    //corner - use intersection by creating inverted lines from each plane:
                    Vector3 point = Vector2.zero;
                    if (MathUtilities.RayIntersection(
                            new Ray(_virtualWalls[clockwiseOrder[i]].plane.Center, _virtualWalls[clockwiseOrder[i]].plane.Rotation * Vector3.right),
                            new Ray(_virtualWalls[clockwiseOrder[next]].plane.Center, _virtualWalls[clockwiseOrder[next]].plane.Rotation * Vector3.left),
                            ref point))
                    {
                        point.y = _roomFloorHeight;
                        _playspaceCorners.Add(TransformUtilities.LocalPosition(pcfAnchor.Position, pcfAnchor.Rotation, point));
                    }
                }
            }

            //close loop:
            _playspaceCorners.Add(_playspaceCorners[0]);

            //store walls:
            List <PlayspaceWall> playspaceWalls = new List <PlayspaceWall>();

            for (int i = 0; i < _playspaceCorners.Count - 1; i++)
            {
                Vector3 pointA = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i]);
                Vector3 pointB = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i + 1]);
                Vector3 vector = pointB - pointA;
                Vector3 normal = Quaternion.AngleAxis(90, Vector3.up) * vector.normalized;
                Vector3 center = Vector3.Lerp(pointA, pointB, .5f);
                center.y = _roomVerticalCenter;
                float         width = vector.magnitude;
                PlayspaceWall wall  = new PlayspaceWall(center, Quaternion.LookRotation(normal), width, Height, physicalStatus[i]);
                playspaceWalls.Add(wall);
            }
            Walls = playspaceWalls.ToArray();

            FindWalls_GenerateGeometry();
        }