@@ -5,11 +5,12 @@ import World from "@/systems/World"
5
5
export class SimCameraRenderer {
6
6
private _camera : THREE . PerspectiveCamera
7
7
private _renderTarget : THREE . WebGLRenderTarget
8
- private _canvas : OffscreenCanvas
9
- private _ctx : OffscreenCanvasRenderingContext2D
8
+ private _canvas : OffscreenCanvas | HTMLCanvasElement
9
+ private _ctx : OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D
10
10
private _robot : MirabufSceneObject
11
11
private _cameraPosition : THREE . Vector3
12
12
private _cameraQuaternion : THREE . Quaternion
13
+ private _useOffscreenCanvas : boolean
13
14
14
15
constructor ( robot : MirabufSceneObject , width : number = 640 , height : number = 480 ) {
15
16
this . _robot = robot
@@ -24,9 +25,20 @@ export class SimCameraRenderer {
24
25
format : THREE . RGBAFormat ,
25
26
} )
26
27
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
+ }
30
42
31
43
// Camera position relative to robot
32
44
this . _cameraPosition = new THREE . Vector3 ( 0 , 0.5 , 0.2 ) // Mounted on robot
@@ -116,13 +128,37 @@ export class SimCameraRenderer {
116
128
this . _ctx . putImageData ( imageData , 0 , 0 )
117
129
118
130
// 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
+ }
120
148
}
121
149
122
150
public setResolution ( width : number , height : number ) {
123
151
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
+
126
162
this . _camera . aspect = width / height
127
163
this . _camera . updateProjectionMatrix ( )
128
164
}
0 commit comments