onAnimationFrame method
Implementation
void onAnimationFrame(double time, XRFrame frame ) {
pose = frame.getViewerPose( customReferenceSpace ?? referenceSpace );
xrFrame = frame;
if ( pose != null ) {
final views = pose?.views.toDart;
if ( glBaseLayer != null) {
renderer.setRenderTargetFramebuffer( newRenderTarget!, Framebuffer(glBaseLayer!.framebuffer));
renderer.setRenderTarget( newRenderTarget );
}
bool cameraXRNeedsUpdate = false;
// check if it's necessary to rebuild cameraXR's camera list
if ( views?.length != cameraXR.cameras.length ) {
cameraXR.cameras.length = 0;
cameraXRNeedsUpdate = true;
}
for (int i = 0; i < (views?.length ?? 0); i ++ ) {
final view = views![ i ];
XRViewport? viewport;
if ( glBaseLayer != null ) {
viewport = glBaseLayer!.getViewport( view );
}
else {
final glSubImage = glBinding?.getViewSubImage( glProjLayer!, view );
viewport = glSubImage?.viewport;
// For side-by-side projection, we only produce a single texture for both eyes.
if ( i == 0 ) {
renderer.setRenderTargetTextures(
newRenderTarget!,
glSubImage!.colorTexture,
glSubImage.depthStencilTexture
);
renderer.setRenderTarget( newRenderTarget );
}
}
Camera? camera = cameras[ i ];
if ( camera == null ) {
camera = PerspectiveCamera();
camera.layers.enable( i );
camera.viewport = Vector4();
cameras[ i ] = camera;
}
camera.matrix.copyFromUnknown( view.transform.matrix );
camera.matrix.decompose( camera.position, camera.quaternion, camera.scale );
camera.projectionMatrix.copyFromUnknown( view.projectionMatrix );
camera.projectionMatrixInverse.setFrom( camera.projectionMatrix ).invert();
camera.viewport?.setValues( viewport!.x, viewport.y, viewport.width, viewport.height );
if ( i == 0 ) {
cameraXR.matrix.setFrom( camera.matrix );
cameraXR.matrix.decompose( cameraXR.position, cameraXR.quaternion, cameraXR.scale );
}
if ( cameraXRNeedsUpdate == true ) {
cameraXR.cameras.add( camera );
}
}
final enabledFeatures = session?.enabledFeatures?.toDart;
final gpuDepthSensingEnabled = enabledFeatures != null &&
enabledFeatures.isNotEmpty &&
enabledFeatures.contains( 'depth-sensing' ) &&
session?.depthUsage == 'gpu-optimized';
if ( gpuDepthSensingEnabled && glBinding != null) {
final depthData = glBinding?.getDepthInformation( views![ 0 ] );
if ( depthData != null && depthData.isValid) {
depthSensing.init( renderer, depthData, session!.renderState );
}
}
}
for (int i = 0; i < controllers.length; i ++ ) {
final inputSource = controllerInputSources.isNotEmpty?controllerInputSources[ i ]:null;
final controller = controllers[ i ];
if ( inputSource != null && controller != null ) {
controller.update( inputSource, frame, customReferenceSpace ?? referenceSpace );
}
}
if ( onAnimationFrameCallback != null) onAnimationFrameCallback( time, frame );
if ( frame.detectedPlanes != null) {
dispatchEvent(Event( type: 'planesdetected', data: frame ));
}
xrFrame = null;
}