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); }
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); }
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); }
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); }
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(); }
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))); }