public static List <GameObject> GetVisibleObjects(this Camera camera, CameraViewVolume viewVolume)
        {
            // Retrieve the objects which are overlapped by the camera volume's OBB
            List <GameObject> overlappedObjects = RTScene.Get.OverlapBox(viewVolume.WorldOBB);

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

            // Loop through each overlapped object
            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(1e-5f);

            var visibleObjects = new List <GameObject>(overlappedObjects.Count);

            foreach (var gameObject in overlappedObjects)
            {
                // Retrieve the object's world AABB
                AABB worldAABB = ObjectBounds.CalcWorldAABB(gameObject, boundsQConfig);

                // If the AABB is valid and if the camera's view volume intersects the AABB,
                // it means we are dealing with a visible object so we store it inside the
                // output list.
                if (worldAABB.IsValid && viewVolume.CheckAABB(worldAABB))
                {
                    visibleObjects.Add(gameObject);
                }
            }

            return(visibleObjects);
        }
Esempio n. 2
0
        public List <GameObject> OverlapBox(OBB obb)
        {
            List <SphereTreeNode <GameObject> > overlappedNodes = _objectTree.OverlapBox(obb);

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

            var boundsQConfig = new ObjectBounds.QueryConfig();

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

            var 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);
        }
Esempio n. 3
0
        protected override void CalculateDragValues()
        {
            Vector3 planeDragPoint        = _planeDragSession.DragPoint;
            Vector3 offsetFromScaleOrigin = (planeDragPoint - _workData.DragOrigin);

            float dragAlongAxis0 = offsetFromScaleOrigin.Dot(_planeAxis0);
            float dragAlongAxis1 = offsetFromScaleOrigin.Dot(_planeAxis1);

            if (CanSnap())
            {
                _relativeDragScale = Vector3.one;
                float accumDrag = (dragAlongAxis0 + dragAlongAxis1);
                if (SnapMath.CanExtractSnap(_workData.SnapStep, accumDrag))
                {
                    float oldScaledSize = _scaledSize;
                    _scaledSize        = _workData.BaseSize + SnapMath.ExtractSnap(_workData.SnapStep, accumDrag);
                    _relativeScale     = _scaledSize / oldScaledSize;
                    _totalScale        = _scaledSize / _workData.BaseSize;
                    _relativeDragScale = Vector3Ex.FromValue(_relativeScale);
                }
            }
            else
            {
                float oldScaledSize = _scaledSize;
                _scaledSize        = _workData.BaseSize + (dragAlongAxis0 + dragAlongAxis1) * Sensitivity;
                _relativeScale     = _scaledSize / oldScaledSize;
                _totalScale        = _scaledSize / _workData.BaseSize;
                _relativeDragScale = Vector3Ex.FromValue(_relativeScale);
            }

            _totalDragScale = Vector3Ex.FromValue(_totalScale);
        }
        protected override void CalculateDragValues()
        {
            if (CanSnap())
            {
                _relativeDragScale = Vector3.one;
                _accumSnapDrag    += _planeDragSession.DragDelta.Dot(_scaleDragAxis);

                if (SnapMath.CanExtractSnap(_workData.SnapStep, _accumSnapDrag))
                {
                    float snapAmount = SnapMath.ExtractSnap(_workData.SnapStep, ref _accumSnapDrag);

                    float oldScale = _scale;
                    _scale            += snapAmount;
                    _relativeScale     = _scale / oldScale;
                    _totalScale        = _scale / 1.0f;
                    _relativeDragScale = Vector3Ex.FromValue(_relativeScale);
                }
            }
            else
            {
                _accumSnapDrag = 0;

                float oldScale = _scale;
                _scale            += _planeDragSession.DragDelta.Dot(_scaleDragAxis) * Sensitivity;
                _relativeScale     = _scale / oldScale;
                _totalScale        = _scale / 1.0f;
                _relativeDragScale = Vector3Ex.FromValue(_relativeScale);
            }

            _totalDragScale = Vector3Ex.FromValue(_totalScale);
        }
        public override void Render(Camera camera)
        {
            var sgLookAndFeel = _sceneGizmo.LookAndFeel;
            RTSceneGizmoCamera sceneGizmoCamera = _sceneGizmo.SceneGizmoCamera;

            _cap.Render(camera);

            if (_axisDesc.IsPositive)
            {
                GizmoLabelMaterial labelMaterial = GizmoLabelMaterial.Get;
                labelMaterial.SetZWriteEnabled(false);
                labelMaterial.SetZTestLessEqual();
                labelMaterial.SetColor(ColorEx.KeepAllButAlpha(sgLookAndFeel.AxesLabelTint, _color.Value.a));
                labelMaterial.SetTexture(_labelTexture);
                labelMaterial.SetPass(0);

                Vector3 gizmoAxis  = _sceneGizmo.Gizmo.Transform.GetAxis3D(_axisDesc);
                Vector3 labelScale = Vector3Ex.FromValue(sgLookAndFeel.GetAxesLabelWorldSize(sceneGizmoCamera.Camera, _cap.Position));
                Vector3 labelPos   = _cap.Position + gizmoAxis * (labelScale.x * 0.5f);

                Vector2 labelScreenPos   = sceneGizmoCamera.Camera.WorldToScreenPoint(labelPos);
                Vector2 midAxisScreenPos = sceneGizmoCamera.Camera.WorldToScreenPoint(_sceneGizmo.SceneGizmoCamera.LookAtPoint);
                Vector2 labelScreenDir   = (labelScreenPos - midAxisScreenPos).normalized;

                float absDotCamLook = Mathf.Abs(Vector3Ex.AbsDot(sceneGizmoCamera.Look, gizmoAxis));
                labelScreenPos = labelScreenPos + Vector2.Scale(labelScreenDir, Vector2Ex.FromValue(SceneGizmoLookAndFeel.AxisLabelScreenSize)) * absDotCamLook;
                labelPos       = sceneGizmoCamera.Camera.ScreenToWorldPoint(new Vector3(labelScreenPos.x, labelScreenPos.y, (labelPos - sceneGizmoCamera.WorldPosition).magnitude));

                Quaternion labelRotation     = Quaternion.LookRotation(sceneGizmoCamera.Look, sceneGizmoCamera.Up);
                Matrix4x4  labelTransformMtx = Matrix4x4.TRS(labelPos, labelRotation, labelScale);

                Graphics.DrawMeshNow(MeshPool.Get.UnitQuadXY, labelTransformMtx);
            }
        }
        public bool OverlapBox(OBB obb, List <GameObject> gameObjects)
        {
            gameObjects.Clear();
            if (!_objectTree.OverlapBox(obb, _nodeBuffer))
            {
                return(false);
            }

            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(_nonMeshObjectSize);

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

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

            return(gameObjects.Count != 0);
        }
        private ObjectBounds.QueryConfig GetObjectBoundsQConfig()
        {
            var config = new ObjectBounds.QueryConfig();

            config.NoVolumeSize = Vector3Ex.FromValue(1e-6f);
            config.ObjectTypes  = GameObjectTypeHelper.AllCombined;

            return(config);
        }
Esempio n. 8
0
        public static Vector3 GetPointCloudCenter(IEnumerable <Vector3> ptCloud)
        {
            Vector3 max = Vector3Ex.FromValue(float.MinValue);
            Vector3 min = Vector3Ex.FromValue(float.MaxValue);

            foreach (var pt in ptCloud)
            {
                max = Vector3.Max(max, pt);
                min = Vector3.Min(min, pt);
            }

            return((max + min) * 0.5f);
        }
        public override void UpdateEpsilons(float zoomFactor)
        {
            Vector3 sizeEps = Vector3Ex.FromValue(_data.PlaneSlider.Settings.BorderBoxHoverEps * zoomFactor);

            _data.TopLeftBox.SizeEps     = sizeEps;
            _data.TopRightBox.SizeEps    = sizeEps;
            _data.BottomRightBox.SizeEps = sizeEps;
            _data.BottomLeftBox.SizeEps  = sizeEps;

            _data.TopBox.SizeEps    = sizeEps;
            _data.BottomBox.SizeEps = sizeEps;
            _data.LeftBox.SizeEps   = sizeEps;
            _data.RightBox.SizeEps  = sizeEps;
        }
        private void UpdateTransform(Camera camera)
        {
            Vector3            midAxisPos       = _sceneGizmo.SceneGizmoCamera.LookAtPoint;
            RTSceneGizmoCamera sceneGizmoCamera = _sceneGizmo.SceneGizmoCamera;
            Vector3            axisDirection    = _sceneGizmo.Gizmo.Transform.GetAxis3D(_axisDesc);

            _zoomFactorTransform.Position3D = midAxisPos;
            float zoomFactor = _cap.GetZoomFactor(camera);

            Vector3 midCapSize = _sceneGizmo.LookAndFeel.MidCapType == GizmoCap3DType.Box ?
                                 Vector3Ex.FromValue(SceneGizmoLookAndFeel.MidCapBoxSize * zoomFactor) : Vector3Ex.FromValue(SceneGizmoLookAndFeel.MidCapSphereRadius * 2.0f * zoomFactor);
            Vector3 midBoxFaceCenter = BoxMath.CalcBoxFaceCenter(midAxisPos, midCapSize, Quaternion.identity, _midAxisBoxFace);

            _cap.CapSlider3DInvert(axisDirection, midBoxFaceCenter);
        }
        public void OnObjectTransformChanged(Transform objectTransform)
        {
            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(_nonMeshObjectSize);

            AABB   worldAABB   = ObjectBounds.CalcWorldAABB(objectTransform.gameObject, boundsQConfig);
            Sphere worldSphere = new Sphere(worldAABB);

            SphereTreeNode <GameObject> objectNode = _objectToNode[objectTransform.gameObject];

            objectNode.Sphere = worldSphere;

            _objectTree.OnNodeSphereUpdated(objectNode);
            RTFocusCamera.Get.SetObjectVisibilityDirty();
        }
        public static GameObject SpawnInFrontOfCamera(GameObject sourceObject, Camera camera, float objectSize)
        {
            float halfSize = objectSize * 0.5f;

            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(1.0f);

            Transform cameraTransform = camera.transform;
            AABB      aabb            = ObjectBounds.CalcHierarchyWorldAABB(sourceObject, boundsQConfig);

            if (!aabb.IsValid)
            {
                return(null);
            }

            Sphere  sphere          = new Sphere(aabb);
            Vector3 fromCenterToPos = sourceObject.transform.position - sphere.Center;
            float   zOffset         = Mathf.Max(camera.nearClipPlane + sphere.Radius, sphere.Radius / halfSize);
            Vector3 spherePos       = cameraTransform.position + cameraTransform.forward * zOffset;

            GameObject spawned       = GameObject.Instantiate(sourceObject, spherePos + fromCenterToPos, sourceObject.transform.rotation) as GameObject;
            OBB        spawnedOBB    = ObjectBounds.CalcHierarchyWorldOBB(spawned, boundsQConfig);
            Ray        ray           = new Ray(camera.transform.position, (spawnedOBB.Center - camera.transform.position).normalized);
            var        raycastFilter = new SceneRaycastFilter();

            raycastFilter.AllowedObjectTypes.Add(GameObjectType.Mesh);

            var rayHit = RTScene.Get.Raycast(ray, SceneRaycastPrecision.BestFit, raycastFilter);

            if (rayHit.WasAnObjectHit)
            {
                Vector3 oldCenter = spawnedOBB.Center;
                spawnedOBB.Center = rayHit.ObjectHit.HitPoint;
                Vector3 offsetVector = spawnedOBB.Center - oldCenter;
                offsetVector += ObjectSurfaceSnap.CalculateSitOnSurfaceOffset(spawnedOBB, rayHit.ObjectHit.HitPlane, 0.0f);

                spawned.transform.position += offsetVector;
            }

            return(spawned);
        }
Esempio n. 13
0
        public void RegisterObject(GameObject gameObject)
        {
            if (!CanRegisterObject(gameObject))
            {
                return;
            }

            var boundsQConfig = new ObjectBounds.QueryConfig();

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

            AABB   worldAABB   = ObjectBounds.CalcWorldAABB(gameObject, boundsQConfig);
            Sphere worldSphere = new Sphere(worldAABB);

            SphereTreeNode <GameObject> objectNode = _objectTree.AddNode(gameObject, worldSphere);

            _objectToNode.Add(gameObject, objectNode);

            RTFocusCamera.Get.SetObjectVisibilityDirty();
        }
Esempio n. 14
0
        private void GatherDestinationObjects()
        {
            Camera focusCamera = RTFocusCamera.Get.TargetCamera;

            _destinationObjects.Clear();

            IInputDevice inputDevice = RTInputDevice.Get.Device;

            if (!inputDevice.HasPointer())
            {
                return;
            }
            Vector2 inputDevicePos = inputDevice.GetPositionYAxisUp();

            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(1e-5f);

            RTFocusCamera.Get.GetVisibleObjects(_visibleObjectBuffer);
            List <GameObject> targetObjects = new List <GameObject>(_targetObjects);

            _visibleObjectBuffer.RemoveAll(a => targetObjects.Contains(a) ||
                                           !ObjectBounds.CalcScreenRect(a, focusCamera, boundsQConfig).Contains(inputDevicePos) ||
                                           targetObjects.FindAll(b => a.transform.IsChildOf(b.transform)).Count != 0);

            foreach (var visibleObject in _visibleObjectBuffer)
            {
                if (!CanUseObjectAsSnapDestination(visibleObject))
                {
                    continue;
                }

                GameObjectType objectType = visibleObject.GetGameObjectType();
                if (objectType == GameObjectType.Mesh || objectType == GameObjectType.Sprite)
                {
                    _destinationObjects.Add(visibleObject);
                }
            }
        }
        public bool RaycastAll(Ray ray, SceneRaycastPrecision raycastPresicion, List <GameObjectRayHit> hits)
        {
            hits.Clear();
            if (!_objectTree.RaycastAll(ray, _nodeHitBuffer))
            {
                return(false);
            }

            var boundsQConfig = new ObjectBounds.QueryConfig();

            boundsQConfig.ObjectTypes  = GameObjectTypeHelper.AllCombined;
            boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(_nonMeshObjectSize);

            Vector3 camLook = RTFocusCamera.Get.Look;

            if (raycastPresicion == SceneRaycastPrecision.BestFit)
            {
                foreach (var nodeHit in _nodeHitBuffer)
                {
                    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)
                        {
                            hits.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))
                            {
                                hits.Add(new GameObjectRayHit(ray, hitInfo));
                            }
                        }
                    }
                    else
                    if (objectType == GameObjectType.Sprite)
                    {
                        GameObjectRayHit objectHit = RaycastSpriteObject(ray, sceneObject);
                        if (objectHit != null)
                        {
                            hits.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))
                            {
                                var faceDesc = BoxMath.GetFaceClosestToPoint(ray.GetPoint(t), worldOBB.Center, worldOBB.Size, worldOBB.Rotation, camLook);
                                var hit      = new GameObjectRayHit(ray, sceneObject, faceDesc.Plane.normal, t);
                                hits.Add(hit);
                            }
                        }
                    }
                }
            }
            else
            if (raycastPresicion == SceneRaycastPrecision.Box)
            {
                foreach (var nodeHit in _nodeHitBuffer)
                {
                    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))
                        {
                            var faceDesc = BoxMath.GetFaceClosestToPoint(ray.GetPoint(t), worldOBB.Center, worldOBB.Size, worldOBB.Rotation, camLook);
                            var hit      = new GameObjectRayHit(ray, sceneObject, faceDesc.Plane.normal, t);
                            hits.Add(hit);
                        }
                    }
                }
            }

            return(hits.Count != 0);
        }
        /// <summary>
        /// Allows the node to render itself for debugging purposes. The client
        /// code is responsible for setting up the rendering material.
        /// </summary>
        /// <remarks>
        /// This method is recursive and will draw the node's children also. Thus,
        /// it is enough to call this method for the root of a sphere tree in order
        /// to draw the entire tree.
        /// </remarks>
        public void DebugDraw()
        {
            // Draw the node
            Matrix4x4 nodeTransform = Matrix4x4.TRS(_sphere.Center, Quaternion.identity, Vector3Ex.FromValue(_sphere.Radius));

            Graphics.DrawMeshNow(MeshPool.Get.UnitSphere, nodeTransform);

            // Draw the node's children
            foreach (var child in _children)
            {
                child.DebugDraw();
            }
        }
        public override AABB GetAABB()
        {
            float sphereRadius = TorusMath.CalcSphereRadius(_coreRadius, _tubeRadius);

            return(new AABB(_center, Vector3Ex.FromValue(sphereRadius * 2.0f)));
        }
 public override void RenderWire()
 {
     Graphics.DrawMeshNow(MeshPool.Get.UnitWireCircleXY, Matrix4x4.TRS(_center, _rotation, Vector3Ex.FromValue(_radius)));
 }
 public void Inflate(float amount)
 {
     Size += Vector3Ex.FromValue(amount);
 }
 public override AABB GetAABB()
 {
     return(new AABB(_center, Vector3Ex.FromValue(_radius * 2.0f)));
 }
 public override void RenderSolid()
 {
     Graphics.DrawMeshNow(MeshPool.Get.UnitSphere, Matrix4x4.TRS(Center, Quaternion.identity, Vector3Ex.FromValue(Radius)));
 }