@@ -5,11 +5,12 @@ import World from "@/systems/World"
55export class SimCameraRenderer {
66 private _camera : THREE . PerspectiveCamera
77 private _renderTarget : THREE . WebGLRenderTarget
8- private _canvas : OffscreenCanvas
9- private _ctx : OffscreenCanvasRenderingContext2D
8+ private _canvas : OffscreenCanvas | HTMLCanvasElement
9+ private _ctx : OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D
1010 private _robot : MirabufSceneObject
1111 private _cameraPosition : THREE . Vector3
1212 private _cameraQuaternion : THREE . Quaternion
13+ private _useOffscreenCanvas : boolean
1314
1415 constructor ( robot : MirabufSceneObject , width : number = 640 , height : number = 480 ) {
1516 this . _robot = robot
@@ -24,9 +25,20 @@ export class SimCameraRenderer {
2425 format : THREE . RGBAFormat ,
2526 } )
2627
27- // Create canvas for frame capture
28- this . _canvas = new OffscreenCanvas ( width , height )
29- this . _ctx = this . _canvas . getContext ( "2d" ) !
28+ this . _useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'
29+
30+ if ( this . _useOffscreenCanvas ) {
31+ // Use OffscreenCanvas for better performance where available
32+ console . log ( '[Camera] Using OffscreenCanvas for camera rendering' )
33+ this . _canvas = new OffscreenCanvas ( width , height )
34+ this . _ctx = this . _canvas . getContext ( "2d" ) !
35+ } else {
36+ console . log ( '[Camera] OffscreenCanvas not available, using regular Canvas fallback' )
37+ this . _canvas = document . createElement ( 'canvas' )
38+ this . _canvas . width = width
39+ this . _canvas . height = height
40+ this . _ctx = this . _canvas . getContext ( "2d" ) !
41+ }
3042
3143 // Camera position relative to robot
3244 this . _cameraPosition = new THREE . Vector3 ( 0 , 0.5 , 0.2 ) // Mounted on robot
@@ -116,13 +128,37 @@ export class SimCameraRenderer {
116128 this . _ctx . putImageData ( imageData , 0 , 0 )
117129
118130 // Convert to JPEG blob
119- return this . _canvas . convertToBlob ( { type : "image/jpeg" , quality : 0.8 } )
131+ if ( this . _useOffscreenCanvas ) {
132+ return ( this . _canvas as OffscreenCanvas ) . convertToBlob ( { type : "image/jpeg" , quality : 0.8 } )
133+ } else {
134+ return new Promise ( ( resolve , reject ) => {
135+ ( this . _canvas as HTMLCanvasElement ) . toBlob (
136+ ( blob ) => {
137+ if ( blob ) {
138+ resolve ( blob )
139+ } else {
140+ reject ( new Error ( "Failed to convert canvas to blob" ) )
141+ }
142+ } ,
143+ "image/jpeg" ,
144+ 0.8
145+ )
146+ } )
147+ }
120148 }
121149
122150 public setResolution ( width : number , height : number ) {
123151 this . _renderTarget . setSize ( width , height )
124- this . _canvas . width = width
125- this . _canvas . height = height
152+
153+ // Update canvas size
154+ if ( this . _useOffscreenCanvas ) {
155+ this . _canvas = new OffscreenCanvas ( width , height )
156+ this . _ctx = this . _canvas . getContext ( "2d" ) !
157+ } else {
158+ this . _canvas . width = width
159+ this . _canvas . height = height
160+ }
161+
126162 this . _camera . aspect = width / height
127163 this . _camera . updateProjectionMatrix ( )
128164 }
0 commit comments