///|
extern "js" fn webgpu_begin_3d_ffi(
view_projection : FixedArray[Double],
position_x : Double,
position_y : Double,
position_z : Double,
target_x : Double,
target_y : Double,
target_z : Double,
up_x : Double,
up_y : Double,
up_z : Double,
fovy : Double,
near_z : Double,
far_z : Double,
orthographic : Double,
orthographic_width : Double,
orthographic_height : Double,
) -> Unit =
#| (viewProjection, px, py, pz, tx, ty, tz, ux, uy, uz, fovy, nearZ, farZ, orthographic, orthoWidth, orthoHeight) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.begin3d(viewProjection, px, py, pz, tx, ty, tz, ux, uy, uz, fovy, nearZ, farZ, orthographic, orthoWidth, orthoHeight);
#| }
#| }
///|
extern "js" fn webgpu_canvas_size_ffi() -> FixedArray[Double] =
#| () => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (!rt?.canvas) return [1, 1];
#| return [
#| Math.max(1, Math.floor(rt.canvas.width || 1)),
#| Math.max(1, Math.floor(rt.canvas.height || 1)),
#| ];
#| }
///|
extern "js" fn webgpu_end_3d() -> Unit =
#| () => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.end3d();
#| }
#| }
///|
extern "js" fn webgpu_set_lighting_3d_ffi(
light_uniform : FixedArray[Double],
directional_shadow_data : FixedArray[Double],
point_shadow_data : FixedArray[Double],
spot_shadow_data : FixedArray[Double],
directional_shadow_map_size : Double,
point_shadow_map_size : Double,
) -> Unit =
#| (lightUniform, directionalShadowData, pointShadowData, spotShadowData, directionalShadowMapSize, pointShadowMapSize) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (!rt) return;
#| const safeLightUniform = Array.isArray(lightUniform) ? lightUniform : [];
#| const safeDirectionalShadowMapSize = Math.max(1, Math.round(Number(directionalShadowMapSize) || 2048));
#| const safePointShadowMapSize = Math.max(1, Math.round(Number(pointShadowMapSize) || 1024));
#| rt.shadow3d = {
#| directional: new Float32Array(Array.isArray(directionalShadowData) ? directionalShadowData : []),
#| point: new Float32Array(Array.isArray(pointShadowData) ? pointShadowData : []),
#| spot: new Float32Array(Array.isArray(spotShadowData) ? spotShadowData : []),
#| directionalShadowMapSize: safeDirectionalShadowMapSize,
#| pointShadowMapSize: safePointShadowMapSize,
#| };
#| rt.lightUniform3d = new Float32Array(safeLightUniform);
#| }
///|
extern "js" fn webgpu_set_shadow_view_projection_3d_ffi(
directional_cascades : FixedArray[Double],
spot_matrices : FixedArray[Double],
point_matrices : FixedArray[Double],
) -> Unit =
#| (directionalCascades, spotMatrices, pointMatrices) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (!rt) return;
#| rt.shadowViewProjection3d = {
#| directional: new Float32Array(Array.isArray(directionalCascades) ? directionalCascades : []),
#| spot: new Float32Array(Array.isArray(spotMatrices) ? spotMatrices : []),
#| point: new Float32Array(Array.isArray(pointMatrices) ? pointMatrices : []),
#| };
#| }
///|
extern "js" fn webgpu_upload_lit_primitive_mesh_resource_ffi(
cache_key : String,
vertices : FixedArray[Double],
) -> Unit =
#| (cacheKey, vertices) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.uploadLitPrimitiveMeshResource(cacheKey, vertices);
#| }
#| }
///|
extern "js" fn webgpu_draw_lit_primitive_mesh_batch_3d_ffi(
cache_key : String,
retained_key : String,
instances : FixedArray[Double],
double_sided : Bool,
cast_shadows : Bool,
) -> Unit =
#| (cacheKey, retainedKey, instances, doubleSided, castShadows) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.pushLitPrimitiveMeshBatch3d(cacheKey, retainedKey, instances, doubleSided, castShadows);
#| }
#| }
///|
extern "js" fn webgpu_release_primitive_mesh_resource(
cache_key : String,
) -> Unit =
#| (cacheKey) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.releasePrimitiveMeshResource(cacheKey);
#| }
#| }
///|
extern "js" fn webgpu_release_retained_instance_buffer_3d(
retained_key : String,
) -> Unit =
#| (retainedKey) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.releaseRetainedInstanceBuffer3d(retainedKey);
#| }
#| }
///|
extern "js" fn webgpu_draw_colored_triangles_3d_ffi(
vertices : FixedArray[Double],
double_sided : Bool,
cast_shadows : Bool,
) -> Unit =
#| (vertices, doubleSided, castShadows) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.pushColoredTriangles3d(vertices, doubleSided, castShadows);
#| }
#| }
///|
extern "js" fn webgpu_draw_lines_3d_ffi(vertices : FixedArray[Double]) -> Unit =
#| (vertices) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.pushLines3d(vertices);
#| }
#| }
///|
extern "js" fn webgpu_draw_textured_triangles_3d_ffi(
base_path : String,
emissive_path : String,
metallic_roughness_path : String,
occlusion_path : String,
normal_path : String,
base_sampler_code : Int32,
emissive_sampler_code : Int32,
metallic_roughness_sampler_code : Int32,
occlusion_sampler_code : Int32,
normal_sampler_code : Int32,
vertices : FixedArray[Double],
double_sided : Bool,
cast_shadows : Bool,
) -> Unit =
#| (basePath, emissivePath, metallicRoughnessPath, occlusionPath, normalPath, baseSamplerCode, emissiveSamplerCode, metallicRoughnessSamplerCode, occlusionSamplerCode, normalSamplerCode, vertices, doubleSided, castShadows) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.pushTexturedTriangles3d(basePath, emissivePath, metallicRoughnessPath, occlusionPath, normalPath, baseSamplerCode, emissiveSamplerCode, metallicRoughnessSamplerCode, occlusionSamplerCode, normalSamplerCode, vertices, doubleSided, castShadows);
#| }
#| }
///|
extern "js" fn webgpu_draw_skybox_textured_triangles_3d_ffi(
base_path : String,
vertices : FixedArray[Double],
) -> Unit =
#| (basePath, vertices) => {
#| const rt = globalThis.__selene_webgpu_runtime;
#| if (rt) {
#| rt.pushSkyboxTexturedTriangles3d(basePath, vertices);
#| }
#| }
///|
pub extern "js" fn Audio::new(path : String) -> Audio =
#| (path) => {
#| const init = globalThis.__selene_init_audio_element || (
#| globalThis.__selene_init_audio_element = (audio) => {
#| if (audio.__seleneAudioInitialized) {
#| return audio;
#| }
#| audio.__seleneAudioInitialized = true;
#| audio.preload = 'auto';
#| audio.__selenePlayState = 0;
#| audio.__selenePlayAttemptEpoch = -1;
#| audio.addEventListener('playing', () => {
#| audio.__selenePlayState = 1;
#| });
#| audio.addEventListener('pause', () => {
#| if (!audio.ended) {
#| audio.__selenePlayState = 0;
#| }
#| });
#| audio.addEventListener('error', () => {
#| audio.__selenePlayState = 3;
#| });
#| return audio;
#| }
#| );
#| return init(new Audio(path));
#| }
///|
fn webgpu_begin_3d(
view_projection : Array[Double],
position_x : Double,
position_y : Double,
position_z : Double,
target_x : Double,
target_y : Double,
target_z : Double,
up_x : Double,
up_y : Double,
up_z : Double,
fovy : Double,
near_z : Double,
far_z : Double,
orthographic : Double,
orthographic_width : Double,
orthographic_height : Double,
) -> Unit {
webgpu_begin_3d_ffi(
FixedArray::from_array(view_projection[:]),
position_x,
position_y,
position_z,
target_x,
target_y,
target_z,
up_x,
up_y,
up_z,
fovy,
near_z,
far_z,
orthographic,
orthographic_width,
orthographic_height,
)
}
///|
fn webgpu_canvas_size() -> Array[Double] {
Array::from_fixed_array(webgpu_canvas_size_ffi())
}
///|
fn webgpu_set_lighting_3d(
light_uniform : Array[Double],
directional_shadow_data : Array[Double],
point_shadow_data : Array[Double],
spot_shadow_data : Array[Double],
directional_shadow_map_size : Double,
point_shadow_map_size : Double,
) -> Unit {
webgpu_set_lighting_3d_ffi(
FixedArray::from_array(light_uniform[:]),
FixedArray::from_array(directional_shadow_data[:]),
FixedArray::from_array(point_shadow_data[:]),
FixedArray::from_array(spot_shadow_data[:]),
directional_shadow_map_size,
point_shadow_map_size,
)
}
///|
fn webgpu_set_shadow_view_projection_3d(
directional_cascades : Array[Double],
spot_matrices : Array[Double],
point_matrices : Array[Double],
) -> Unit {
webgpu_set_shadow_view_projection_3d_ffi(
FixedArray::from_array(directional_cascades[:]),
FixedArray::from_array(spot_matrices[:]),
FixedArray::from_array(point_matrices[:]),
)
}
///|
fn webgpu_upload_lit_primitive_mesh_resource(
cache_key : String,
vertices : Array[Double],
) -> Unit {
webgpu_upload_lit_primitive_mesh_resource_ffi(
cache_key,
FixedArray::from_array(vertices[:]),
)
}
///|
fn webgpu_draw_lit_primitive_mesh_batch_3d(
cache_key : String,
retained_key : String,
instances : Array[Double],
double_sided : Bool,
cast_shadows : Bool,
) -> Unit {
webgpu_draw_lit_primitive_mesh_batch_3d_ffi(
cache_key,
retained_key,
FixedArray::from_array(instances[:]),
double_sided,
cast_shadows,
)
}
///|
fn webgpu_draw_colored_triangles_3d(
vertices : Array[Double],
double_sided : Bool,
cast_shadows : Bool,
) -> Unit {
webgpu_draw_colored_triangles_3d_ffi(
FixedArray::from_array(vertices[:]),
double_sided,
cast_shadows,
)
}
///|
fn webgpu_draw_lines_3d(vertices : Array[Double]) -> Unit {
webgpu_draw_lines_3d_ffi(FixedArray::from_array(vertices[:]))
}
///|
fn webgpu_draw_textured_triangles_3d(
base_path : String,
emissive_path : String,
metallic_roughness_path : String,
occlusion_path : String,
normal_path : String,
base_sampler_code : Int32,
emissive_sampler_code : Int32,
metallic_roughness_sampler_code : Int32,
occlusion_sampler_code : Int32,
normal_sampler_code : Int32,
vertices : Array[Double],
double_sided : Bool,
cast_shadows : Bool,
) -> Unit {
webgpu_draw_textured_triangles_3d_ffi(
base_path,
emissive_path,
metallic_roughness_path,
occlusion_path,
normal_path,
base_sampler_code,
emissive_sampler_code,
metallic_roughness_sampler_code,
occlusion_sampler_code,
normal_sampler_code,
FixedArray::from_array(vertices[:]),
double_sided,
cast_shadows,
)
}
///|
fn webgpu_draw_skybox_textured_triangles_3d(
base_path : String,
vertices : Array[Double],
) -> Unit {
webgpu_draw_skybox_textured_triangles_3d_ffi(
base_path,
FixedArray::from_array(vertices[:]),
)
}