Ejemplo n.º 1
0
        public List <GameObject> OverlapBox(OBB obb)
        {
            List <SphereTreeNode <GameObject> > overlappedNodes = _objectTree.OverlapBox(obb);

            if (overlappedNodes.Count == 0)
            {
                return(new List <GameObject>());
            }

            ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig();
            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(RTScene.Get.Settings.NonMeshObjectSize);

            List <GameObject> overlappedObjects = new List <GameObject>();

            foreach (SphereTreeNode <GameObject> node in overlappedNodes)
            {
                GameObject sceneObject = (GameObject)node.Data;
                if (sceneObject == null || !sceneObject.activeInHierarchy)
                {
                    continue;
                }

                OBB worldOBB = ObjectBounds.CalcWorldOBB(sceneObject, boundsQConfig);
                if (obb.IntersectsOBB(worldOBB))
                {
                    overlappedObjects.Add(sceneObject);
                }
            }

            return(overlappedObjects);
        }
Ejemplo n.º 2
0
        private void SnapToObjectHitPoint(GameObjectRayHit objectHit, SnapToPointMode snapMode)
        {
            if (snapMode == SnapToPointMode.Exact)
            {
                float distToPlane = new Plane(Normal, Vector3.zero).GetDistanceToPoint(objectHit.HitPoint);
                YOffset = distToPlane;
            }
            else
            {
                ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig();
                boundsQConfig.ObjectTypes = GameObjectType.Mesh;

                OBB worldOBB = ObjectBounds.CalcWorldOBB(objectHit.HitObject, boundsQConfig);
                if (worldOBB.IsValid)
                {
                    Plane          slicePlane = new Plane(Normal, worldOBB.Center);
                    Vector3        destPt     = worldOBB.Center;
                    List <Vector3> obbCorners = BoxMath.CalcBoxCornerPoints(worldOBB.Center, worldOBB.Size, worldOBB.Rotation);

                    float sign = Mathf.Sign(slicePlane.GetDistanceToPoint(objectHit.HitPoint));
                    if (sign > 0.0f)
                    {
                        int furthestPtInFront = slicePlane.GetFurthestPtInFront(obbCorners);
                        if (furthestPtInFront >= 0)
                        {
                            destPt = obbCorners[furthestPtInFront];
                        }
                    }
                    else
                    {
                        int furthestPtBehind = slicePlane.GetFurthestPtBehind(obbCorners);
                        if (furthestPtBehind >= 0)
                        {
                            destPt = obbCorners[furthestPtBehind];
                        }
                    }

                    float distToPlane = new Plane(Normal, Vector3.zero).GetDistanceToPoint(destPt);
                    YOffset = distToPlane;
                }
            }
        }
        private void SelectPivot()
        {
            if (!RTInputDevice.Get.Device.HasPointer())
            {
                return;
            }

            var boundsQConfig = GetObjectBoundsQConfig();

            Vector2 inputDevicePos    = RTInputDevice.Get.Device.GetPositionYAxisUp();
            float   minDistFromDevice = float.MaxValue;

            foreach (var targetObject in _targetObjects)
            {
                if (targetObject == null)
                {
                    continue;
                }

                OBB worldOBB = ObjectBounds.CalcWorldOBB(targetObject, boundsQConfig);
                if (worldOBB.IsValid)
                {
                    Camera         camera                 = RTFocusCamera.Get.TargetCamera;
                    List <Vector3> centerAndCorners       = worldOBB.GetCenterAndCornerPoints();
                    List <Vector2> screenCenterAndCorners = camera.ConvertWorldToScreenPoints(centerAndCorners);
                    for (int ptIndex = 0; ptIndex < screenCenterAndCorners.Count; ++ptIndex)
                    {
                        float distance = (inputDevicePos - screenCenterAndCorners[ptIndex]).magnitude;
                        if (distance < minDistFromDevice)
                        {
                            minDistFromDevice = distance;
                            _snapPivotPoint   = centerAndCorners[ptIndex];
                        }
                    }
                }
            }
        }
        public void Render()
        {
            if (_sharedLookAndFeel == null)
            {
                return;
            }

            if (IsActive)
            {
                Material material = MaterialPool.Get.SimpleColor;

                if (_sharedLookAndFeel.DrawBoxes)
                {
                    material.SetColor(_sharedLookAndFeel.BoxLineColor);
                    material.SetZTestEnabled(true);
                    material.SetPass(0);

                    var boundsQConfig = GetObjectBoundsQConfig();
                    foreach (var targetObject in _targetObjects)
                    {
                        if (targetObject == null)
                        {
                            continue;
                        }

                        OBB worldOBB = ObjectBounds.CalcWorldOBB(targetObject, boundsQConfig);
                        if (worldOBB.IsValid)
                        {
                            GraphicsEx.DrawWireBox(worldOBB);
                        }
                    }
                }

                Camera  camera          = Camera.current;
                Vector2 screenSnapPivot = camera.WorldToScreenPoint(_snapPivotPoint);
                if (_sharedLookAndFeel.PivotShapeType == PivotPointShapeType.Circle)
                {
                    material.SetZTestEnabled(false);
                    material.SetColor(_sharedLookAndFeel.PivotPointFillColor);
                    material.SetPass(0);

                    const int      numCirclePoints   = 100;
                    List <Vector2> pivotCirclePoints = PrimitiveFactory.Generate2DCircleBorderPointsCW(screenSnapPivot, _sharedLookAndFeel.PivotCircleRadius, numCirclePoints);
                    GLRenderer.DrawTriangleFan2D(screenSnapPivot, pivotCirclePoints, camera);

                    if (_sharedLookAndFeel.DrawPivotBorder)
                    {
                        material.SetColor(_sharedLookAndFeel.PivotPointBorderColor);
                        material.SetPass(0);
                        GLRenderer.DrawLineLoop2D(pivotCirclePoints, camera);
                    }
                }
                else
                if (_sharedLookAndFeel.PivotShapeType == PivotPointShapeType.Square)
                {
                    material.SetZTestEnabled(false);
                    material.SetColor(_sharedLookAndFeel.PivotPointFillColor);
                    material.SetPass(0);

                    Rect pivotRect = RectEx.FromCenterAndSize(screenSnapPivot, Vector2Ex.FromValue(_sharedLookAndFeel.PivotSquareSideLength));
                    GLRenderer.DrawRect2D(pivotRect, camera);

                    if (_sharedLookAndFeel.DrawPivotBorder)
                    {
                        material.SetColor(_sharedLookAndFeel.PivotPointBorderColor);
                        material.SetPass(0);
                        GLRenderer.DrawRectBorder2D(pivotRect, camera);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public static SnapResult CalculateSnapResult(GameObject root, Config snapConfig)
        {
            if (snapConfig.IgnoreDestObjects == null)
            {
                snapConfig.IgnoreDestObjects = new List <GameObject>();
            }

            List <GameObject> sourceObjects = root.GetAllChildrenAndSelf();

            if (sourceObjects.Count > MaxSourceObjects)
            {
                return(new SnapResult(SnapFailReson.MaxObjectsExceeded));
            }

            List <GameObject> sourceMeshObjects   = root.GetMeshObjectsInHierarchy();
            List <GameObject> sourceSpriteObjects = root.GetSpriteObjectsInHierarchy();

            if (sourceMeshObjects.Count == 0 && sourceSpriteObjects.Count == 0)
            {
                return(new SnapResult(SnapFailReson.InvalidSourceObjects));
            }

            ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig();
            boundsQConfig.ObjectTypes = GameObjectType.Mesh | GameObjectType.Sprite;

            Vector3             overlapSizeAdd     = Vector3.one * snapConfig.SnapRadius * 2.0f;
            List <BoxFace>      allSnapFaces       = BoxMath.AllBoxFaces;
            bool                tryMatchAreas      = (snapConfig.Prefs & Prefs.TryMatchArea) != 0;
            bool                foundMatchingAreas = false;
            List <SnapSortData> sortedSnapData     = new List <SnapSortData>(10);
            SnapSortData        sortData           = new SnapSortData();

            foreach (GameObject sourceObject in sourceObjects)
            {
                OBB overlapOBB = ObjectBounds.CalcWorldOBB(sourceObject, boundsQConfig);
                overlapOBB.Size = overlapOBB.Size + overlapSizeAdd;

                List <GameObject> nearbyObjects = RTScene.Get.OverlapBox(overlapOBB);
                nearbyObjects.RemoveAll(item => item.transform.IsChildOf(root.transform) ||
                                        snapConfig.IgnoreDestObjects.Contains(item) || !LayerEx.IsLayerBitSet(snapConfig.DestinationLayers, item.layer));
                if (nearbyObjects.Count == 0)
                {
                    continue;
                }

                Object2ObjectSnapData sourceSnapData = Object2ObjectSnapDataDb.Get.GetObject2ObjectSnapData(sourceObject);
                if (sourceSnapData == null)
                {
                    continue;
                }

                sortData.SrcObject = sourceObject;
                foreach (BoxFace srcSnapFace in allSnapFaces)
                {
                    BoxFaceAreaDesc srcAreaDesc   = sourceSnapData.GetWorldSnapAreaDesc(srcSnapFace);
                    OBB             srcAreaBounds = sourceSnapData.GetWorldSnapAreaBounds(srcSnapFace);
                    List <Vector3>  srcAreaPts    = srcAreaBounds.GetCenterAndCornerPoints();
                    sortData.SrcSnapFace = srcSnapFace;

                    foreach (GameObject destObject in nearbyObjects)
                    {
                        Object2ObjectSnapData destSnapData = Object2ObjectSnapDataDb.Get.GetObject2ObjectSnapData(destObject);
                        if (destSnapData == null)
                        {
                            continue;
                        }

                        sortData.DestObject = destObject;
                        foreach (BoxFace destSnapFace in allSnapFaces)
                        {
                            sortData.DestSnapFace = destSnapFace;
                            BoxFaceAreaDesc destAreaDesc = destSnapData.GetWorldSnapAreaDesc(destSnapFace);

                            sortData.FaceAreasMatch = false;

                            if (tryMatchAreas && destAreaDesc.AreaType == srcAreaDesc.AreaType)
                            {
                                sortData.FaceAreaDiff = Mathf.Abs(destAreaDesc.Area - srcAreaDesc.Area);
                                if (sortData.FaceAreaDiff <= 1000.0f)
                                {
                                    sortData.FaceAreasMatch = true;
                                }
                            }

                            OBB            destAreaBounds = destSnapData.GetWorldSnapAreaBounds(destSnapFace);
                            List <Vector3> destAreaPts    = destAreaBounds.GetCenterAndCornerPoints();

                            foreach (Vector3 srcPt in srcAreaPts)
                            {
                                sortData.SnapPivot = srcPt;
                                foreach (Vector3 destPt in destAreaPts)
                                {
                                    sortData.SnapDistance = (destPt - srcPt).magnitude;
                                    if (sortData.SnapDistance < snapConfig.SnapRadius)
                                    {
                                        sortData.SnapDest = destPt;
                                        sortedSnapData.Add(sortData);

                                        if (sortData.FaceAreasMatch)
                                        {
                                            foundMatchingAreas = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (sortedSnapData.Count != 0)
            {
                if (!tryMatchAreas || !foundMatchingAreas)
                {
                    sortedSnapData.Sort(delegate(SnapSortData s0, SnapSortData s1)
                    {
                        return(s0.SnapDistance.CompareTo(s1.SnapDistance));
                    });
                }
                else
                {
                    while (true)
                    {
                        if (!sortedSnapData[0].FaceAreasMatch)
                        {
                            sortedSnapData.RemoveAt(0);
                        }
                        else
                        {
                            break;
                        }
                    }

                    sortedSnapData.Sort(delegate(SnapSortData s0, SnapSortData s1)
                    {
                        return(s0.FaceAreaDiff.CompareTo(s1.FaceAreaDiff));
                    });
                }

                return(new SnapResult(sortedSnapData[0].SnapPivot, sortedSnapData[0].SnapDest, sortedSnapData[0].SnapDistance));
            }
            return(new SnapResult(SnapFailReson.NoDestinationFound));
        }
Ejemplo n.º 6
0
        public List <GameObjectRayHit> RaycastAll(Ray ray, SceneRaycastPrecision raycastPresicion)
        {
            List <SphereTreeNodeRayHit <GameObject> > nodeHits = _objectTree.RaycastAll(ray);

            if (nodeHits.Count == 0)
            {
                return(new List <GameObjectRayHit>());
            }

            ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig();
            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(RTScene.Get.Settings.NonMeshObjectSize);

            Vector3 camLook = RTFocusCamera.Get.Look;

            if (raycastPresicion == SceneRaycastPrecision.BestFit)
            {
                List <GameObjectRayHit> hitList = new List <GameObjectRayHit>(10);
                foreach (SphereTreeNodeRayHit <GameObject> nodeHit in nodeHits)
                {
                    GameObject sceneObject = nodeHit.HitNode.Data;
                    if (sceneObject == null || !sceneObject.activeInHierarchy)
                    {
                        continue;
                    }

                    Renderer renderer = sceneObject.GetComponent <Renderer>();
                    if (renderer != null && !renderer.isVisible)
                    {
                        continue;
                    }

                    GameObjectType objectType = sceneObject.GetGameObjectType();
                    if (objectType == GameObjectType.Mesh)
                    {
                        GameObjectRayHit objectHit = RaycastMeshObject(ray, sceneObject);
                        if (objectHit != null)
                        {
                            hitList.Add(objectHit);
                        }
                    }
                    else
                    if (objectType == GameObjectType.Terrain)
                    {
                        TerrainCollider terrainCollider = sceneObject.GetComponent <TerrainCollider>();
                        if (terrainCollider != null)
                        {
                            RaycastHit hitInfo;
                            if (terrainCollider.Raycast(ray, out hitInfo, float.MaxValue))
                            {
                                hitList.Add(new GameObjectRayHit(ray, hitInfo));
                            }
                        }
                    }
                    else
                    if (objectType == GameObjectType.Sprite)
                    {
                        GameObjectRayHit objectHit = RaycastSpriteObject(ray, sceneObject);
                        if (objectHit != null)
                        {
                            hitList.Add(objectHit);
                        }
                    }
                    else
                    {
                        OBB worldOBB = ObjectBounds.CalcWorldOBB(sceneObject, boundsQConfig);
                        if (worldOBB.IsValid)
                        {
                            float t;
                            if (BoxMath.Raycast(ray, out t, worldOBB.Center, worldOBB.Size, worldOBB.Rotation))
                            {
                                BoxFaceDesc      faceDesc = BoxMath.GetFaceClosestToPoint(ray.GetPoint(t), worldOBB.Center, worldOBB.Size, worldOBB.Rotation, camLook);
                                GameObjectRayHit hit      = new GameObjectRayHit(ray, sceneObject, faceDesc.Plane.normal, t);
                                hitList.Add(hit);
                            }
                        }
                    }
                }

                return(hitList);
            }
            else
            if (raycastPresicion == SceneRaycastPrecision.Box)
            {
                List <GameObjectRayHit> hitList = new List <GameObjectRayHit>(10);
                foreach (SphereTreeNodeRayHit <GameObject> nodeHit in nodeHits)
                {
                    GameObject sceneObject = nodeHit.HitNode.Data;
                    if (sceneObject == null || !sceneObject.activeInHierarchy)
                    {
                        continue;
                    }

                    Renderer renderer = sceneObject.GetComponent <Renderer>();
                    if (renderer != null && !renderer.isVisible)
                    {
                        continue;
                    }

                    OBB worldOBB = ObjectBounds.CalcWorldOBB(sceneObject, boundsQConfig);
                    if (worldOBB.IsValid)
                    {
                        float t;
                        if (BoxMath.Raycast(ray, out t, worldOBB.Center, worldOBB.Size, worldOBB.Rotation))
                        {
                            BoxFaceDesc      faceDesc = BoxMath.GetFaceClosestToPoint(ray.GetPoint(t), worldOBB.Center, worldOBB.Size, worldOBB.Rotation, camLook);
                            GameObjectRayHit hit      = new GameObjectRayHit(ray, sceneObject, faceDesc.Plane.normal, t);
                            hitList.Add(hit);
                        }
                    }
                }

                return(hitList);
            }

            return(new List <GameObjectRayHit>());
        }