#[repr(C)]pub struct IVRCompositor { /* private fields */ }
Expand description
Allows the application to interact with the compositor
Implementations§
Source§impl IVRCompositor
impl IVRCompositor
Sourcepub fn SetTrackingSpace(
self: Pin<&mut IVRCompositor>,
eOrigin: ETrackingUniverseOrigin,
)
pub fn SetTrackingSpace( self: Pin<&mut IVRCompositor>, eOrigin: ETrackingUniverseOrigin, )
Sets tracking space returned by WaitGetPoses
Sourcepub fn GetTrackingSpace(
self: Pin<&mut IVRCompositor>,
) -> ETrackingUniverseOrigin
pub fn GetTrackingSpace( self: Pin<&mut IVRCompositor>, ) -> ETrackingUniverseOrigin
Gets current tracking space returned by WaitGetPoses
Sourcepub unsafe fn WaitGetPoses(
self: Pin<&mut IVRCompositor>,
pRenderPoseArray: *mut TrackedDevicePose_t,
unRenderPoseArrayCount: u32,
pGamePoseArray: *mut TrackedDevicePose_t,
unGamePoseArrayCount: u32,
) -> EVRCompositorError
pub unsafe fn WaitGetPoses( self: Pin<&mut IVRCompositor>, pRenderPoseArray: *mut TrackedDevicePose_t, unRenderPoseArrayCount: u32, pGamePoseArray: *mut TrackedDevicePose_t, unGamePoseArrayCount: u32, ) -> EVRCompositorError
Scene applications should call this function to get poses to render with (and optionally poses predicted an additional frame out to use for gameplay). This function will block until “running start” milliseconds before the start of the frame, and should be called at the last moment before needing to start rendering.
Return codes:
- IsNotSceneApplication (make sure to call VR_Init with VRApplicaiton_Scene)
- DoNotHaveFocus (some other app has taken focus - this will throttle the call to 10hz to reduce the impact on that app)
Sourcepub unsafe fn GetLastPoses(
self: Pin<&mut IVRCompositor>,
pRenderPoseArray: *mut TrackedDevicePose_t,
unRenderPoseArrayCount: u32,
pGamePoseArray: *mut TrackedDevicePose_t,
unGamePoseArrayCount: u32,
) -> EVRCompositorError
pub unsafe fn GetLastPoses( self: Pin<&mut IVRCompositor>, pRenderPoseArray: *mut TrackedDevicePose_t, unRenderPoseArrayCount: u32, pGamePoseArray: *mut TrackedDevicePose_t, unGamePoseArrayCount: u32, ) -> EVRCompositorError
Get the last set of poses returned by WaitGetPoses.
Sourcepub unsafe fn GetLastPoseForTrackedDeviceIndex(
self: Pin<&mut IVRCompositor>,
unDeviceIndex: u32,
pOutputPose: *mut TrackedDevicePose_t,
pOutputGamePose: *mut TrackedDevicePose_t,
) -> EVRCompositorError
pub unsafe fn GetLastPoseForTrackedDeviceIndex( self: Pin<&mut IVRCompositor>, unDeviceIndex: u32, pOutputPose: *mut TrackedDevicePose_t, pOutputGamePose: *mut TrackedDevicePose_t, ) -> EVRCompositorError
Interface for accessing last set of poses returned by WaitGetPoses one at a time. Returns VRCompositorError_IndexOutOfRange if unDeviceIndex not less than k_unMaxTrackedDeviceCount otherwise VRCompositorError_None. It is okay to pass NULL for either pose if you only want one of the values.
Sourcepub unsafe fn Submit(
self: Pin<&mut IVRCompositor>,
eEye: EVREye,
pTexture: *const Texture_t,
pBounds: *const VRTextureBounds_t,
nSubmitFlags: EVRSubmitFlags,
) -> EVRCompositorError
pub unsafe fn Submit( self: Pin<&mut IVRCompositor>, eEye: EVREye, pTexture: *const Texture_t, pBounds: *const VRTextureBounds_t, nSubmitFlags: EVRSubmitFlags, ) -> EVRCompositorError
Updated scene texture to display. If pBounds is NULL the entire texture will be used. If called from an OpenGL app, consider adding a glFlush after Submitting both frames to signal the driver to start processing, otherwise it may wait until the command buffer fills up, causing the app to miss frames.
OpenGL dirty state: glBindTexture
Return codes:
- IsNotSceneApplication (make sure to call VR_Init with VRApplicaiton_Scene)
- DoNotHaveFocus (some other app has taken focus)
- TextureIsOnWrongDevice (application did not use proper AdapterIndex - see IVRSystem.GetDXGIOutputInfo)
- SharedTexturesNotSupported (application needs to call CreateDXGIFactory1 or later before creating DX device)
- TextureUsesUnsupportedFormat (scene textures must be compatible with DXGI sharing rules - e.g. uncompressed, no mips, etc.)
- InvalidTexture (usually means bad arguments passed in)
- AlreadySubmitted (app has submitted two left textures or two right textures in a single frame - i.e. before calling WaitGetPoses again)
Sourcepub fn ClearLastSubmittedFrame(self: Pin<&mut IVRCompositor>)
pub fn ClearLastSubmittedFrame(self: Pin<&mut IVRCompositor>)
Clears the frame that was sent with the last call to Submit. This will cause the compositor to show the grid until Submit is called again.
Sourcepub fn PostPresentHandoff(self: Pin<&mut IVRCompositor>)
pub fn PostPresentHandoff(self: Pin<&mut IVRCompositor>)
Call immediately after presenting your app’s window (i.e. companion window) to unblock the compositor. This is an optional call, which only needs to be used if you can’t instead call WaitGetPoses immediately after Present. For example, if your engine’s render and game loop are not on separate threads, or blocking the render thread until 3ms before the next vsync would introduce a deadlock of some sort. This function tells the compositor that you have finished all rendering after having Submitted buffers for both eyes, and it is free to start its rendering work. This should only be called from the same thread you are rendering on.
Sourcepub unsafe fn GetFrameTiming(
self: Pin<&mut IVRCompositor>,
pTiming: *mut Compositor_FrameTiming,
unFramesAgo: u32,
) -> bool
pub unsafe fn GetFrameTiming( self: Pin<&mut IVRCompositor>, pTiming: *mut Compositor_FrameTiming, unFramesAgo: u32, ) -> bool
Returns true if timing data is filled it. Sets oldest timing info if nFramesAgo is larger than the stored history. Be sure to set timing.size = sizeof(Compositor_FrameTiming) on struct passed in before calling this function.
Sourcepub unsafe fn GetFrameTimings(
self: Pin<&mut IVRCompositor>,
pTiming: *mut Compositor_FrameTiming,
nFrames: u32,
) -> u32
pub unsafe fn GetFrameTimings( self: Pin<&mut IVRCompositor>, pTiming: *mut Compositor_FrameTiming, nFrames: u32, ) -> u32
Interface for copying a range of timing data. Frames are returned in ascending order (oldest to newest) with the last being the most recent frame. Only the first entry’s m_nSize needs to be set, as the rest will be inferred from that. Returns total number of entries filled out.
Sourcepub fn GetFrameTimeRemaining(self: Pin<&mut IVRCompositor>) -> f32
pub fn GetFrameTimeRemaining(self: Pin<&mut IVRCompositor>) -> f32
Returns the time in seconds left in the current (as identified by FrameTiming’s frameIndex) frame. Due to “running start”, this value may roll over to the next frame before ever reaching 0.0.
Sourcepub unsafe fn GetCumulativeStats(
self: Pin<&mut IVRCompositor>,
pStats: *mut Compositor_CumulativeStats,
nStatsSizeInBytes: u32,
)
pub unsafe fn GetCumulativeStats( self: Pin<&mut IVRCompositor>, pStats: *mut Compositor_CumulativeStats, nStatsSizeInBytes: u32, )
Fills out stats accumulated for the last connected application. Pass in sizeof( Compositor_CumulativeStats ) as second parameter.
Sourcepub fn FadeToColor(
self: Pin<&mut IVRCompositor>,
fSeconds: f32,
fRed: f32,
fGreen: f32,
fBlue: f32,
fAlpha: f32,
bBackground: bool,
)
pub fn FadeToColor( self: Pin<&mut IVRCompositor>, fSeconds: f32, fRed: f32, fGreen: f32, fBlue: f32, fAlpha: f32, bBackground: bool, )
Fades the view on the HMD to the specified color. The fade will take fSeconds, and the color values are between 0.0 and 1.0. This color is faded on top of the scene based on the alpha parameter. Removing the fade color instantly would be FadeToColor( 0.0, 0.0, 0.0, 0.0, 0.0 ). Values are in un-premultiplied alpha space.
Sourcepub fn GetCurrentFadeColor<'a>(
self: Pin<&'a mut IVRCompositor>,
bBackground: bool,
) -> impl New<Output = HmdColor_t> + 'a
pub fn GetCurrentFadeColor<'a>( self: Pin<&'a mut IVRCompositor>, bBackground: bool, ) -> impl New<Output = HmdColor_t> + 'a
Get current fade color value.
Sourcepub fn FadeGrid(self: Pin<&mut IVRCompositor>, fSeconds: f32, bFadeGridIn: bool)
pub fn FadeGrid(self: Pin<&mut IVRCompositor>, fSeconds: f32, bFadeGridIn: bool)
Fading the Grid in or out in fSeconds
Sourcepub fn GetCurrentGridAlpha(self: Pin<&mut IVRCompositor>) -> f32
pub fn GetCurrentGridAlpha(self: Pin<&mut IVRCompositor>) -> f32
Get current alpha value of grid.
Sourcepub unsafe fn SetSkyboxOverride(
self: Pin<&mut IVRCompositor>,
pTextures: *const Texture_t,
unTextureCount: u32,
) -> EVRCompositorError
pub unsafe fn SetSkyboxOverride( self: Pin<&mut IVRCompositor>, pTextures: *const Texture_t, unTextureCount: u32, ) -> EVRCompositorError
Override the skybox used in the compositor (e.g. for during level loads when the app can’t feed scene images fast enough) Order is Front, Back, Left, Right, Top, Bottom. If only a single texture is passed, it is assumed in lat-long format. If two are passed, it is assumed a lat-long stereo pair.
Sourcepub fn ClearSkyboxOverride(self: Pin<&mut IVRCompositor>)
pub fn ClearSkyboxOverride(self: Pin<&mut IVRCompositor>)
Resets compositor skybox back to defaults.
Sourcepub fn CompositorBringToFront(self: Pin<&mut IVRCompositor>)
pub fn CompositorBringToFront(self: Pin<&mut IVRCompositor>)
Brings the compositor window to the front. This is useful for covering any other window that may be on the HMD and is obscuring the compositor window.
Sourcepub fn CompositorGoToBack(self: Pin<&mut IVRCompositor>)
pub fn CompositorGoToBack(self: Pin<&mut IVRCompositor>)
Pushes the compositor window to the back. This is useful for allowing other applications to draw directly to the HMD.
Sourcepub fn CompositorQuit(self: Pin<&mut IVRCompositor>)
pub fn CompositorQuit(self: Pin<&mut IVRCompositor>)
DEPRECATED: Tells the compositor process to clean up and exit. You do not need to call this function at shutdown. Under normal circumstances the compositor will manage its own life cycle based on what applications are running.
Sourcepub fn IsFullscreen(self: Pin<&mut IVRCompositor>) -> bool
pub fn IsFullscreen(self: Pin<&mut IVRCompositor>) -> bool
Return whether the compositor is fullscreen
Sourcepub fn GetCurrentSceneFocusProcess(self: Pin<&mut IVRCompositor>) -> u32
pub fn GetCurrentSceneFocusProcess(self: Pin<&mut IVRCompositor>) -> u32
Returns the process ID of the process that is currently rendering the scene
Sourcepub fn GetLastFrameRenderer(self: Pin<&mut IVRCompositor>) -> u32
pub fn GetLastFrameRenderer(self: Pin<&mut IVRCompositor>) -> u32
Returns the process ID of the process that rendered the last frame (or 0 if the compositor itself rendered the frame.) Returns 0 when fading out from an app and the app’s process Id when fading into an app.
Sourcepub fn CanRenderScene(self: Pin<&mut IVRCompositor>) -> bool
pub fn CanRenderScene(self: Pin<&mut IVRCompositor>) -> bool
Returns true if the current process has the scene focus
Sourcepub fn ShowMirrorWindow(self: Pin<&mut IVRCompositor>)
pub fn ShowMirrorWindow(self: Pin<&mut IVRCompositor>)
DEPRECATED: Opens the headset view (as either a window or docked widget depending on user’s preferences) that displays what the user sees in the headset.
Sourcepub fn HideMirrorWindow(self: Pin<&mut IVRCompositor>)
pub fn HideMirrorWindow(self: Pin<&mut IVRCompositor>)
DEPRECATED: Closes the headset view, either as a window or docked widget.
Sourcepub fn IsMirrorWindowVisible(self: Pin<&mut IVRCompositor>) -> bool
pub fn IsMirrorWindowVisible(self: Pin<&mut IVRCompositor>) -> bool
DEPRECATED: Returns true if the headset view (either as a window or docked widget) is shown.
Sourcepub fn CompositorDumpImages(self: Pin<&mut IVRCompositor>)
pub fn CompositorDumpImages(self: Pin<&mut IVRCompositor>)
Writes back buffer and stereo left/right pair from the application to a ‘screenshots’ folder in the SteamVR runtime root.
Sourcepub fn ShouldAppRenderWithLowResources(self: Pin<&mut IVRCompositor>) -> bool
pub fn ShouldAppRenderWithLowResources(self: Pin<&mut IVRCompositor>) -> bool
Let an app know it should be rendering with low resources.
Sourcepub fn ForceInterleavedReprojectionOn(
self: Pin<&mut IVRCompositor>,
bOverride: bool,
)
pub fn ForceInterleavedReprojectionOn( self: Pin<&mut IVRCompositor>, bOverride: bool, )
Override interleaved reprojection logic to force on.
Sourcepub fn ForceReconnectProcess(self: Pin<&mut IVRCompositor>)
pub fn ForceReconnectProcess(self: Pin<&mut IVRCompositor>)
Force reconnecting to the compositor process.
Sourcepub fn SuspendRendering(self: Pin<&mut IVRCompositor>, bSuspend: bool)
pub fn SuspendRendering(self: Pin<&mut IVRCompositor>, bSuspend: bool)
Temporarily suspends rendering (useful for finer control over scene transitions).
pub unsafe fn ReleaseMirrorTextureD3D11( self: Pin<&mut IVRCompositor>, pD3D11ShaderResourceView: *mut c_void, )
Sourcepub unsafe fn GetMirrorTextureGL(
self: Pin<&mut IVRCompositor>,
eEye: EVREye,
pglTextureId: *mut u32,
pglSharedTextureHandle: *mut *mut c_void,
) -> EVRCompositorError
pub unsafe fn GetMirrorTextureGL( self: Pin<&mut IVRCompositor>, eEye: EVREye, pglTextureId: *mut u32, pglSharedTextureHandle: *mut *mut c_void, ) -> EVRCompositorError
Access to mirror textures from OpenGL.
Sourcepub unsafe fn GetVulkanInstanceExtensionsRequired(
self: Pin<&mut IVRCompositor>,
pchValue: *mut c_char,
unBufferSize: u32,
) -> u32
pub unsafe fn GetVulkanInstanceExtensionsRequired( self: Pin<&mut IVRCompositor>, pchValue: *mut c_char, unBufferSize: u32, ) -> u32
[Vulkan Only] return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing null. The string will be a space separated list of-required instance extensions to enable in VkCreateInstance
Sourcepub unsafe fn GetVulkanDeviceExtensionsRequired(
self: Pin<&mut IVRCompositor>,
pPhysicalDevice: *mut VkPhysicalDevice_T,
pchValue: *mut c_char,
unBufferSize: u32,
) -> u32
pub unsafe fn GetVulkanDeviceExtensionsRequired( self: Pin<&mut IVRCompositor>, pPhysicalDevice: *mut VkPhysicalDevice_T, pchValue: *mut c_char, unBufferSize: u32, ) -> u32
[Vulkan only] return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing null. The string will be a space separated list of required device extensions to enable in VkCreateDevice
Sourcepub fn SetExplicitTimingMode(
self: Pin<&mut IVRCompositor>,
eTimingMode: EVRCompositorTimingMode,
)
pub fn SetExplicitTimingMode( self: Pin<&mut IVRCompositor>, eTimingMode: EVRCompositorTimingMode, )
[ Vulkan/D3D12 Only ] There are two purposes for SetExplicitTimingMode:
- To get a more accurate GPU timestamp for when the frame begins in Vulkan/D3D12 applications.
- (Optional) To avoid having WaitGetPoses access the Vulkan queue so that the queue can be accessed from another thread while WaitGetPoses is executing.
More accurate GPU timestamp for the start of the frame is achieved by the application calling SubmitExplicitTimingData immediately before its first submission to the Vulkan/D3D12 queue. This is more accurate because normally this GPU timestamp is recorded during WaitGetPoses. In D3D11, WaitGetPoses queues a GPU timestamp write, but it does not actually get submitted to the GPU until the application flushes. By using SubmitExplicitTimingData, the timestamp is recorded at the same place for Vulkan/D3D12 as it is for D3D11, resulting in a more accurate GPU time measurement for the frame.
Avoiding WaitGetPoses accessing the Vulkan queue can be achieved using SetExplicitTimingMode as well. If this is desired, the application should set the timing mode to Explicit_ApplicationPerformsPostPresentHandoff and MUST call PostPresentHandoff itself. If these conditions are met, then WaitGetPoses is guaranteed not to access the queue. Note that PostPresentHandoff and SubmitExplicitTimingData will access the queue, so only WaitGetPoses becomes safe for accessing the queue from another thread.
Sourcepub fn SubmitExplicitTimingData(
self: Pin<&mut IVRCompositor>,
) -> EVRCompositorError
pub fn SubmitExplicitTimingData( self: Pin<&mut IVRCompositor>, ) -> EVRCompositorError
[ Vulkan/D3D12 Only ] Submit explicit timing data. When SetExplicitTimingMode is true, this must be called immediately before the application’s first vkQueueSubmit (Vulkan) or ID3D12CommandQueue::ExecuteCommandLists (D3D12) of each frame. This function will insert a GPU timestamp write just before the application starts its rendering. This function will perform a vkQueueSubmit on Vulkan so must not be done simultaneously with VkQueue operations on another thread. Returns VRCompositorError_RequestFailed if SetExplicitTimingMode is not enabled.
Sourcepub fn IsMotionSmoothingEnabled(self: Pin<&mut IVRCompositor>) -> bool
pub fn IsMotionSmoothingEnabled(self: Pin<&mut IVRCompositor>) -> bool
Indicates whether or not motion smoothing is enabled by the user settings. If you want to know if motion smoothing actually triggered due to a late frame, check Compositor_FrameTiming m_nReprojectionFlags & VRCompositor_ReprojectionMotion instead.
Sourcepub fn IsMotionSmoothingSupported(self: Pin<&mut IVRCompositor>) -> bool
pub fn IsMotionSmoothingSupported(self: Pin<&mut IVRCompositor>) -> bool
Indicates whether or not motion smoothing is supported by the current hardware.
Sourcepub fn IsCurrentSceneFocusAppLoading(self: Pin<&mut IVRCompositor>) -> bool
pub fn IsCurrentSceneFocusAppLoading(self: Pin<&mut IVRCompositor>) -> bool
Indicates whether or not the current scene focus app is currently loading. This is inferred from its use of FadeGrid to explicitly fade to the compositor to cover up the fact that it cannot render at a sustained full framerate during this time.
Sourcepub unsafe fn SetStageOverride_Async(
self: Pin<&mut IVRCompositor>,
pchRenderModelPath: *const c_char,
pTransform: *const HmdMatrix34_t,
pRenderSettings: *const Compositor_StageRenderSettings,
nSizeOfRenderSettings: u32,
) -> EVRCompositorError
pub unsafe fn SetStageOverride_Async( self: Pin<&mut IVRCompositor>, pchRenderModelPath: *const c_char, pTransform: *const HmdMatrix34_t, pRenderSettings: *const Compositor_StageRenderSettings, nSizeOfRenderSettings: u32, ) -> EVRCompositorError
Override the stage model used in the compositor to replace the grid. RenderModelPath is a full path the an OBJ file to load. This file will be loaded asynchronously from disk and uploaded to the gpu by the runtime. Once ready for rendering, the VREvent StageOverrideReady will be sent. Use FadeToGrid to reveal. Call ClearStageOverride to free the associated resources when finished.
Sourcepub fn ClearStageOverride(self: Pin<&mut IVRCompositor>)
pub fn ClearStageOverride(self: Pin<&mut IVRCompositor>)
Resets the stage to its default user specified setting.
Sourcepub unsafe fn GetCompositorBenchmarkResults(
self: Pin<&mut IVRCompositor>,
pBenchmarkResults: *mut Compositor_BenchmarkResults,
nSizeOfBenchmarkResults: u32,
) -> bool
pub unsafe fn GetCompositorBenchmarkResults( self: Pin<&mut IVRCompositor>, pBenchmarkResults: *mut Compositor_BenchmarkResults, nSizeOfBenchmarkResults: u32, ) -> bool
Returns true if pBenchmarkResults is filled it. Sets pBenchmarkResults with the result of the compositor benchmark. nSizeOfBenchmarkResults should be set to sizeof(Compositor_BenchmarkResults)
Sourcepub unsafe fn GetLastPosePredictionIDs(
self: Pin<&mut IVRCompositor>,
pRenderPosePredictionID: *mut u32,
pGamePosePredictionID: *mut u32,
) -> EVRCompositorError
pub unsafe fn GetLastPosePredictionIDs( self: Pin<&mut IVRCompositor>, pRenderPosePredictionID: *mut u32, pGamePosePredictionID: *mut u32, ) -> EVRCompositorError
Returns the frame id associated with the poses last returned by WaitGetPoses. Deltas between IDs correspond to number of headset vsync intervals.
Sourcepub unsafe fn GetPosesForFrame(
self: Pin<&mut IVRCompositor>,
unPosePredictionID: u32,
pPoseArray: *mut TrackedDevicePose_t,
unPoseArrayCount: u32,
) -> EVRCompositorError
pub unsafe fn GetPosesForFrame( self: Pin<&mut IVRCompositor>, unPosePredictionID: u32, pPoseArray: *mut TrackedDevicePose_t, unPoseArrayCount: u32, ) -> EVRCompositorError
Get the most up-to-date predicted (or recorded - up to 100ms old) set of poses for a given frame id.
Trait Implementations§
Source§impl Drop for IVRCompositor
impl Drop for IVRCompositor
Source§fn drop(self: &mut IVRCompositor)
fn drop(self: &mut IVRCompositor)
Synthesized destructor.
Source§impl ExternType for IVRCompositor
impl ExternType for IVRCompositor
Source§impl MakeCppStorage for IVRCompositor
impl MakeCppStorage for IVRCompositor
Source§unsafe fn allocate_uninitialized_cpp_storage() -> *mut IVRCompositor
unsafe fn allocate_uninitialized_cpp_storage() -> *mut IVRCompositor
Source§unsafe fn free_uninitialized_cpp_storage(arg0: *mut IVRCompositor)
unsafe fn free_uninitialized_cpp_storage(arg0: *mut IVRCompositor)
impl UniquePtrTarget for IVRCompositor
impl VectorElement for IVRCompositor
impl WeakPtrTarget for IVRCompositor
Auto Trait Implementations§
impl !Freeze for IVRCompositor
impl RefUnwindSafe for IVRCompositor
impl !Send for IVRCompositor
impl !Sync for IVRCompositor
impl !Unpin for IVRCompositor
impl UnwindSafe for IVRCompositor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.