diff --git a/src/assets.ts b/src/assets.ts new file mode 100644 index 0000000..af375a6 --- /dev/null +++ b/src/assets.ts @@ -0,0 +1,95 @@ +import type { RenderLevel } from './type'; + +/** + * 资源基类 + */ +export interface AssetBaseOptions { + /** + * 资源 ID + */ + id: string, + /** + * 资源类型 + */ + url: string, + /** + * 渲染等级 + * 如果没有设置,按照 B+ 处理 + */ + renderLevel?: RenderLevel, +} + +/** + * 纹理贴图属性 + */ +export interface Image extends AssetBaseOptions { + /** + * WebP 地址 + * 如果运行时支持 WebP,则优先使用 WebP + */ + webp?: string, + /** + * AVIF 地址 + * 如果运行时支持 AVIF,则优先使用 AVIF + * @since 2.0.0 + */ + avif?: string, + /** + * 是否使用 mipmap + * loader 发布压缩纹理的时候会根据此参数决定是否生成压缩纹理 + * @default false + */ + mipmap?: boolean, + /** + * 图片 Y 轴的方向,如果 Y 轴向上(与 OpenGL 相同)则为 1 + * 如果 Y 轴向下(与 OpenGL 相反)则为 -1,图片再绘制数据模板的时候需要翻转绘制 + * @default 1 + */ + oriY?: 1 | -1, +} + +/** + * 动态换图类型 + * @since 1.1.0 + */ +export enum BackgroundType { + video = 'video', + image = 'image', +} + +export interface TemplateContent { + /** + * 当 template 宽高和 image 不相同时,会对 template 进行缩放,使其和 image 相同。 + */ + width: number, + height: number, + // 绘制 canvas 的背景图片,替换掉原来的那张图片,如果没有就不替换 + background?: { + type: BackgroundType, + name: string, + url: string | HTMLImageElement, + }, +} + +export type TemplateVariables = Record; + +/** + * 模板贴图属性 + */ +export interface TemplateImage extends Image { + template: TemplateContent, +} + +/** + * 压缩贴图属性 + */ +export interface CompressedImage extends Image { + /** + * 压缩贴图地址 + */ + compressed: { + // 安卓 + astc?: string, + pvrtc?: string, + }, +} diff --git a/src/components.ts b/src/components.ts index 6989576..bcdfd2c 100644 --- a/src/components.ts +++ b/src/components.ts @@ -37,6 +37,8 @@ export enum DataType { TreeComponent = 'TreeComponent', AnimationComponent = 'AnimationComponent', SpineComponent = 'SpineComponent', + VideoComponent = 'VideoComponent', + AudioComponent = 'AudioComponent', // Non-EffectObject TimelineClip = 'TimelineClip', @@ -231,12 +233,6 @@ export interface ShaderData extends EffectsObjectData { properties?: string, } -export interface EffectComponentData extends ComponentData { - _priority: number, - materials: DataPath[], - geometry: DataPath, -} - export interface EffectsPackageData { fileSummary: FileSummary, exportObjects: EffectsObjectData[], diff --git a/src/image.ts b/src/image.ts deleted file mode 100644 index 745e484..0000000 --- a/src/image.ts +++ /dev/null @@ -1,142 +0,0 @@ -import type { RenderLevel } from './type'; -import type { BinaryPointer } from './binary'; -import type { DataType } from './components'; - -export interface TextureFormatOptions { - format?: GLenum, - internalFormat?: GLenum, - type?: GLenum, -} - -export interface TextureConfigOptionsBase { - generateMipmap?: boolean, - id?: string, - dataType?: DataType.Texture, - name?: string, - wrapS?: GLenum, - wrapT?: GLenum, - magFilter?: GLenum, - minFilter?: GLenum, - anisotropic?: number, - flipY?: boolean, - premultiplyAlpha?: boolean, - // when use ImageBitMap, the bitmap content will be closed after sent to GPU - keepImageSource?: boolean, -} - -export type SerializedTextureCubeMipmap = [ - TEXTURE_CUBE_MAP_POSITIVE_X: BinaryPointer, - TEXTURE_CUBE_MAP_NEGATIVE_X: BinaryPointer, - TEXTURE_CUBE_MAP_POSITIVE_Y: BinaryPointer, - TEXTURE_CUBE_MAP_NEGATIVE_Y: BinaryPointer, - TEXTURE_CUBE_MAP_POSITIVE_Z: BinaryPointer, - TEXTURE_CUBE_MAP_NEGATIVE_Z: BinaryPointer -]; - -export interface SerializedTexture2DImageSource extends TextureConfigOptionsBase, TextureFormatOptions { - target?: WebGLRenderingContext['TEXTURE_2D'], - source: number, -} - -export interface SerializedTexture2DMipmapSource extends TextureConfigOptionsBase, TextureFormatOptions { - target?: WebGLRenderingContext['TEXTURE_2D'], - mipmaps: BinaryPointer[], -} - -export interface SerializedTextureCube extends TextureConfigOptionsBase, TextureFormatOptions { - target: WebGLRenderingContext['TEXTURE_CUBE_MAP'], - mipmaps: SerializedTextureCubeMipmap[], -} - -export type SerializedTexture2D = SerializedTexture2DImageSource | SerializedTexture2DMipmapSource; - -export type SerializedTextureSource = SerializedTexture2D | SerializedTextureCube; - -export type TextureJSONOptions = SerializedTextureSource; - -export type TextureDefine = TextureJSONOptions; - -/** - * 动态换图类型 - * @since 1.1.0 - */ -export enum BackgroundType { - video = 'video', - image = 'image', -} - -export interface TemplateContent { - /** - * 当 template 宽高和 image 不相同时,会对 template 进行缩放,使其和 image 相同。 - */ - width: number, - height: number, - // 绘制 canvas 的背景图片,替换掉原来的那张图片,如果没有就不替换 - background?: { - type: BackgroundType, - name: string, - url: string | HTMLImageElement, - }, -} - -export type TemplateVariables = Record; - -/** - * 纹理贴图属性 - */ -export interface Image { - id: string, - /** - * 纹理贴图地址 - */ - url: string, - /** - * WebP 地址 - * 如果运行时支持 WebP,则优先使用 WebP - */ - webp?: string, - /** - * AVIF 地址 - * 如果运行时支持 AVIF,则优先使用 AVIF - * @since 2.0.0 - */ - avif?: string, - /** - * 纹理贴图渲染等级 - * 如果没有设置,按照 B+ 处理 - */ - renderLevel?: RenderLevel, - /** - * 是否使用 mipmap - * loader 发布压缩纹理的时候会根据此参数决定是否生成压缩纹理 - * @default false - */ - mipmap?: boolean, - /** - * 图片 Y 轴的方向,如果 Y 轴向上(与 OpenGL 相同)则为 1 - * 如果 Y 轴向下(与 OpenGL 相反)则为 -1,图片再绘制数据模板的时候需要翻转绘制 - * @default 1 - */ - oriY?: 1 | -1, -} - -/** - * 模板贴图属性 - */ -export interface TemplateImage extends Image { - template: TemplateContent, -} - -/** - * 压缩贴图属性 - */ -export interface CompressedImage extends Image { - /** - * 压缩贴图地址 - */ - compressed: { - // 安卓 - astc?: string, - pvrtc?: string, - }, -} diff --git a/src/index.ts b/src/index.ts index 99c185e..78f3acb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ export * from './type'; export * from './composition'; -export * from './image'; +export * from './texture'; export * from './constants'; export * from './number-expression'; export * from './scene'; @@ -17,6 +17,8 @@ export * from './item/sprite-item'; export * from './item/spine-item'; export * from './item/effect-item'; export * from './item/text-item'; +export * from './item/video-item'; +export * from './item/audio-item'; export * from './item/model'; export * from './vfx-item-data'; export * from './animation-clip-data'; @@ -26,3 +28,4 @@ export * from './components'; export * from './vfx-item-data'; export * from './buitin-object-guid'; export * from './timeline'; +export * from './assets'; diff --git a/src/item.ts b/src/item.ts index 50282e7..fb17a66 100644 --- a/src/item.ts +++ b/src/item.ts @@ -8,6 +8,8 @@ import type { ModelCameraItem, ModelLightItem, ModelMeshItem, ModelSkyboxItem, M import type { CameraItem } from './item/camera-item'; import type { CompositionItem } from './item/composition-item'; import type { TextItem } from './item/text-item'; +import type { VideoItem } from './item/video-item'; +import type { AudioItem } from './item/audio-item'; /** * Item 基类,无对应元素 @@ -20,6 +22,8 @@ export type Item = | InteractItem | CameraItem | TextItem + | VideoItem + | AudioItem | ModelMeshItem<'json'> | ModelSkyboxItem<'json'> | ModelTreeItem<'json'> diff --git a/src/item/audio-item.ts b/src/item/audio-item.ts new file mode 100644 index 0000000..f97069e --- /dev/null +++ b/src/item/audio-item.ts @@ -0,0 +1,49 @@ +import type { ComponentData, DataPath } from '../components'; +import type { ItemType } from '../type'; +import type { BaseItem } from './base-item'; + +/** + * 音频元素 + */ +export interface AudioItem extends BaseItem { + /** + * 元素类型(指定为 audio) + */ + type: ItemType.audio, + /** + * 音频元素基础属性 + */ + content: AudioComponentData, +} + +export interface AudioContentOptions { + /** + * 音频链接,索引到 scene 中的 audios 数组 + */ + audio: DataPath, + /** + * 音频播放速度 + * @default 1 + */ + playbackRate?: number, + /** + * 是否静音播放 + * @default false + */ + muted?: boolean, + /** + * 音频音量大小 + * @default 1 + */ + volume?: number, +} + +/** + * 音频组件属性 + */ +export interface AudioComponentData extends ComponentData { + /** + * 音频元素基础属性 + */ + options: AudioContentOptions, +} diff --git a/src/item/effect-item.ts b/src/item/effect-item.ts index 426362b..47ee3a9 100644 --- a/src/item/effect-item.ts +++ b/src/item/effect-item.ts @@ -1,3 +1,4 @@ +import type { ComponentData, DataPath } from '../components'; import type { ItemType, PositionOverLifetime, RotationOverLifetime, SizeOverLifetime } from '../type'; import type { BaseItem, EndBehavior } from './base-item'; @@ -35,3 +36,9 @@ export interface EffectContent { */ positionOverLifetime?: PositionOverLifetime, } + +export interface EffectComponentData extends ComponentData { + _priority: number, + materials: DataPath[], + geometry: DataPath, +} diff --git a/src/item/video-item.ts b/src/item/video-item.ts new file mode 100644 index 0000000..30a2272 --- /dev/null +++ b/src/item/video-item.ts @@ -0,0 +1,88 @@ +import type { ComponentData, DataPath } from '../components'; +import type { RGBAColorValue } from '../number-expression'; +import type { + SizeOverLifetime, RotationOverLifetime, PositionOverLifetime, ColorOverLifetime, + InteractBehavior, RendererOptions, ItemType, +} from '../type'; +import type { BaseItem, EndBehavior } from './base-item'; + +/** + * 视频元素 + */ +export interface VideoItem extends BaseItem { + /** + * 元素类型(指定为 video) + */ + type: ItemType.video, + /** + * 视频元素渲染信息 + */ + content: VideoComponentData, + endBehavior: EndBehavior, +} + +export interface VideoContentOptions { + /** + * 元素基础颜色 + * @default [255,255,255,255] + */ + startColor?: RGBAColorValue, + /** + * 视频链接,索引到 scene 中的 videos 数组 + */ + video: DataPath, + /** + * 视频播放速度 + * @default 1 + */ + playbackRate?: number, + /** + * 是否静音播放 + * @default false + */ + muted?: boolean, + /** + * 视频音量大小 + * @default 1 + */ + volume?: number, +} + +/** + * 视频组件属性 + */ +export interface VideoComponentData extends ComponentData { + /** + * 视频元素基础属性 + */ + options: VideoContentOptions, + /** + * 视频元素材质渲染属性 + */ + renderer: RendererOptions, + /** + * 视频元素大小变化属性 + */ + sizeOverLifetime?: SizeOverLifetime, + /** + * 视频元素旋转变化属性 + */ + rotationOverLifetime?: RotationOverLifetime, + /** + * 视频元素位置变化属性 + */ + positionOverLifetime?: PositionOverLifetime, + /** + * 视频元素色彩变化属性 + */ + colorOverLifetime?: ColorOverLifetime, + /** + * 视频元素交互 + */ + interaction?: { + /** + * 交互行为 + */ + behavior: InteractBehavior, + }, +} diff --git a/src/scene.ts b/src/scene.ts index c8d9af1..79b03c8 100644 --- a/src/scene.ts +++ b/src/scene.ts @@ -1,12 +1,13 @@ import type { Composition, CompositionData } from './composition'; import type { SpineResource } from './item/spine-item'; import type { PlayerVersion, Shape } from './type'; -import type { TemplateImage, Image, CompressedImage, TextureDefine } from './image'; +import type { TextureDefine } from './texture'; import type { FontBase, FontDefine } from './text'; import type { BinaryFile } from './binary'; import type { ComponentData, EffectsObjectData, GeometryData, MaterialData, ShaderData } from './components'; import type { VFXItemData } from './vfx-item-data'; import type { AnimationClipData } from './animation-clip-data'; +import type { TemplateImage, Image, CompressedImage, AssetBaseOptions } from './assets'; /** * runtime 2.0 之前的场景信息 @@ -110,6 +111,7 @@ export interface JSONScene { * JSON 版本 * * 3.0 EC 改造、移除滤镜元素 + * 3.1 音视频 */ version: string, /** @@ -157,10 +159,16 @@ export interface JSONScene { * 数据模板下掉可以不要 FontBase[] */ fonts?: FontBase[] | FontDefine[], - // /** - // * spine 资源 - // */ - // spines?: SpineResource[], + /** + * 视频资源 + * @since 2.0.0 + */ + videos?: AssetBaseOptions[], + /** + * 音频资源 + * @since 2.0.0 + */ + audios?: AssetBaseOptions[], /** * 二进制文件地址 */ diff --git a/src/texture.ts b/src/texture.ts new file mode 100644 index 0000000..8199798 --- /dev/null +++ b/src/texture.ts @@ -0,0 +1,56 @@ +import type { BinaryPointer } from './binary'; +import type { DataType } from './components'; + +export interface TextureFormatOptions { + format?: GLenum, + internalFormat?: GLenum, + type?: GLenum, +} + +export interface TextureConfigOptionsBase { + generateMipmap?: boolean, + id?: string, + dataType?: DataType.Texture, + name?: string, + wrapS?: GLenum, + wrapT?: GLenum, + magFilter?: GLenum, + minFilter?: GLenum, + anisotropic?: number, + flipY?: boolean, + premultiplyAlpha?: boolean, + // when use ImageBitMap, the bitmap content will be closed after sent to GPU + keepImageSource?: boolean, +} + +export type SerializedTextureCubeMipmap = [ + TEXTURE_CUBE_MAP_POSITIVE_X: BinaryPointer, + TEXTURE_CUBE_MAP_NEGATIVE_X: BinaryPointer, + TEXTURE_CUBE_MAP_POSITIVE_Y: BinaryPointer, + TEXTURE_CUBE_MAP_NEGATIVE_Y: BinaryPointer, + TEXTURE_CUBE_MAP_POSITIVE_Z: BinaryPointer, + TEXTURE_CUBE_MAP_NEGATIVE_Z: BinaryPointer +]; + +export interface SerializedTexture2DImageSource extends TextureConfigOptionsBase, TextureFormatOptions { + target?: WebGLRenderingContext['TEXTURE_2D'], + source: number, +} + +export interface SerializedTexture2DMipmapSource extends TextureConfigOptionsBase, TextureFormatOptions { + target?: WebGLRenderingContext['TEXTURE_2D'], + mipmaps: BinaryPointer[], +} + +export interface SerializedTextureCube extends TextureConfigOptionsBase, TextureFormatOptions { + target: WebGLRenderingContext['TEXTURE_CUBE_MAP'], + mipmaps: SerializedTextureCubeMipmap[], +} + +export type SerializedTexture2D = SerializedTexture2DImageSource | SerializedTexture2DMipmapSource; + +export type SerializedTextureSource = SerializedTexture2D | SerializedTextureCube; + +export type TextureJSONOptions = SerializedTextureSource; + +export type TextureDefine = TextureJSONOptions; diff --git a/src/type.ts b/src/type.ts index a73277b..29d2d30 100644 --- a/src/type.ts +++ b/src/type.ts @@ -572,6 +572,14 @@ export enum ItemType { * 节点元素 */ node = 'node', + /** + * 视频元素 + */ + video = 'video', + /** + * 音频元素 + */ + audio = 'audio', } /**