diff --git a/.eslintignore b/.eslintignore index ba715aa1c5f..fa24a7e1440 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,4 @@ *.jsb.ts **/*.ems.ts -cocos/core/gfx/webgpu/**/* +cocos/gfx/webgpu/**/* cocos/webgpu/**/* \ No newline at end of file diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 9eb97b5cfcf..340c1880447 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -124,3 +124,13 @@ rules: allowNumber: true, allowBoolean: true }] + + '@typescript-eslint/type-annotation-spacing': warn + + # We choose to use style `... as foo` since it's more common. + # In the other hand, angle bracket style can be ambiguous with j/tsx syntax. + # For example, https://babeljs.io/docs/en/babel-plugin-transform-typescript#istsx + # forbids angle bracket style if `isTSX` is enabled. + '@typescript-eslint/consistent-type-assertions': [error, { + assertionStyle: 'as' + }] diff --git a/.github/workflows/interface-check-report.js b/.github/workflows/interface-check-report.js deleted file mode 100644 index fc3a7582967..00000000000 --- a/.github/workflows/interface-check-report.js +++ /dev/null @@ -1,20 +0,0 @@ -const ps = require('path'); -const fs = require('fs'); - -const interfaceDiffPath = ps.join(__dirname, '../../interface-diff.txt'); -let reportContent = fs.readFileSync(interfaceDiffPath, 'utf8'); - -if (reportContent.includes('@')) { - reportContent = reportContent.split('\n').slice(3).join('\n'); - reportContent = `## Interface Check Report -\`\`\`diff -! WARNING this pull request has changed these public interfaces: - -${reportContent} -\`\`\` -`; -} else { - reportContent = `## Interface Check Report -This pull request does not change any public interfaces !`; -} -fs.writeFileSync(interfaceDiffPath, reportContent, 'utf8'); diff --git a/.github/workflows/native-bindings.yml b/.github/workflows/native-bindings.yml index 975b0e7643b..e5d478c5ee5 100644 --- a/.github/workflows/native-bindings.yml +++ b/.github/workflows/native-bindings.yml @@ -6,6 +6,7 @@ on: paths: - 'templates/**' - 'native/**' + - 'package.json' jobs: generate-jsb: @@ -18,24 +19,20 @@ jobs: EXT_VERSION=`node ./.github/workflows/get-native-external-version.js` git clone --branch $EXT_VERSION --depth 1 https://github.com/cocos/cocos-engine-external native/external rm -rf native/external/.git - - uses: nttld/setup-ndk@v1 - id: setup-ndk - with: - ndk-version: r21e - add-to-path: false - name: Generate Bindings run: | cd ./native/tools/swig-config node genbindings.js git status - - name: Update builtin-res - env: - ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} + - name: Update auto-gen source files run: | cd native npm install -g typescript sh utils/generate_compile_commands_android.sh + echo "Generating DebugInfos ... " cmake --build ./build --target builtin-res + echo "Generating cocos-version.h ... " + node ./cmake/scripts/engine-version.js - name: Create Pull Request uses: fish9167/create-pull-request@v3 diff --git a/.github/workflows/native-compile-linux.yml b/.github/workflows/native-compile-linux.yml index e0699443394..e14046f2c68 100644 --- a/.github/workflows/native-compile-linux.yml +++ b/.github/workflows/native-compile-linux.yml @@ -3,6 +3,7 @@ name: Linux on: pull_request: paths: + - '.github/workflows/native-compile-linux.yml' - 'templates/**' - 'native/**' @@ -36,7 +37,7 @@ jobs: sudo apt install ninja-build -y - name: Compile env: - COCOS_ENGINE_DEV: 1 + COCOS_ENGINE_DEV: 0 run: | NATIVE_ROOT=$GITHUB_WORKSPACE/native echo "Compiling Linux ... " @@ -56,4 +57,4 @@ jobs: cd build-linux cmake ../ -GNinja -DRES_DIR=$RES_DIR -DCOCOS_X_PATH=$NATIVE_ROOT set +e - cmake --build . \ No newline at end of file + cmake --build . diff --git a/.github/workflows/native-generated-pr.yml b/.github/workflows/native-generated-pr.yml index e468ce26572..a93ef034f14 100644 --- a/.github/workflows/native-generated-pr.yml +++ b/.github/workflows/native-generated-pr.yml @@ -6,13 +6,16 @@ name: Assign Generated PR # paths: # - 'native/cocos/bindings/auto/**' -on: pull_request_target +#on: pull_request_target +on: pull_request jobs: auto-assign: if: (contains(github.event.pull_request.body, 'Automated PR to genbindings')) runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - uses: actions/checkout@v2 - name: Update assignees @@ -36,8 +39,13 @@ jobs: # ${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/assignees \ # -d "{\"assignees\":[\"${SRC_MERGER}\"]}" # exit 0 - - name: Assignment - uses: OperationsYU/auto-assignment@v1 + # - name: Assignment + # uses: OperationsYU/auto-assignment@v1 + # with: + # token: ${{ secrets.LABEL_TOKEN }} + # users: '["${{steps.merger.outputs.SRC_MERGER}}"]' + - name: Notify the merger of previous commit + uses: mshick/add-pr-comment@v2 with: - token: ${{ secrets.LABEL_TOKEN }} - users: '["${{steps.merger.outputs.SRC_MERGER}}"]' \ No newline at end of file + message: | + @${{steps.merger.outputs.SRC_MERGER}} please review \ No newline at end of file diff --git a/.github/workflows/native-linter-android.yml b/.github/workflows/native-linter-android.yml index 58403783ca0..a00f6a78cc9 100644 --- a/.github/workflows/native-linter-android.yml +++ b/.github/workflows/native-linter-android.yml @@ -26,6 +26,10 @@ jobs: # Checks out a copy of your repository on the ubuntu-latest machine - name: Checkout code uses: actions/checkout@v2 + - name: Install CMake & Clang Tidy + run: | + sudo apt update --fix-missing + sudo apt install -y cmake llvm clang-tidy-11 - name: Download external run: | EXT_VERSION=`node ./.github/workflows/get-native-external-version.js` @@ -71,9 +75,6 @@ jobs: skipedDebug: - added|modified|deleted: '**' - exclude: 'native/cocos/editor-support/**' - - name: Install CMake & Clang Tidy - run: | - sudo apt install -y cmake llvm clang-tidy-11 - name: Generate Compile database shell: bash diff --git a/.github/workflows/run_test_cases.yml b/.github/workflows/run_test_cases.yml index 5c378912b15..d5cf046cfb0 100644 --- a/.github/workflows/run_test_cases.yml +++ b/.github/workflows/run_test_cases.yml @@ -72,6 +72,32 @@ jobs: git branch ${{ steps.parse_pr.outputs.pr_base_ref }} git fetch origin pull/${{ steps.get_pr.outputs.pr_number }}/head:pull-${{ steps.get_pr.outputs.pr_number }} git merge --ff -s recursive --no-verify -m "PR Test" origin/${{ steps.parse_pr.outputs.pr_base_ref }} pull-${{ steps.get_pr.outputs.pr_number }} + + - name: Download external libraries + shell: bash + run: | + set -x + EXT_VERSION=`node ./.github/workflows/get-native-external-version.js` + PRECLONE_EXTERNAL="E:/preclone/cocos-engine-external" + if [ ! -d $PRECLONE_EXTERNAL ]; then + mkdir -p $PRECLONE_EXTERNAL + git clone https://github.com/cocos/cocos-engine-external $PRECLONE_EXTERNAL + else + echo "directory $PRECLONE_EXTERNAL is ready" + fi + if [ ! -d native/external ]; then + mkdir native/external + fi + git -C $PRECLONE_EXTERNAL reset --hard + git -C $PRECLONE_EXTERNAL fetch --all --prune + git -C $PRECLONE_EXTERNAL archive --format=tar $EXT_VERSION | tar -C native/external -xf - + - name: Generate bindings + run: | + cd ./native/tools/swig-config + echo "Create auto-generated jsbinding glue codes." + node genbindings.js && + git status + - name: npm install run: | npm -v @@ -159,6 +185,33 @@ jobs: git branch ${{ steps.parse_pr.outputs.pr_base_ref }} git fetch origin pull/${{ steps.get_pr.outputs.pr_number }}/head:pull-${{ steps.get_pr.outputs.pr_number }} git merge --ff -s recursive --no-verify -m "PR Test" origin/${{ steps.parse_pr.outputs.pr_base_ref }} pull-${{ steps.get_pr.outputs.pr_number }} + - name: Download external libraries + shell: bash + run: | + set -x + EXT_VERSION=`node ./.github/workflows/get-native-external-version.js` + PRECLONE_EXTERNAL="/Users/admin/Documents/actions-runner/preclone/cocos-engine-external" + if [ ! -d $PRECLONE_EXTERNAL ]; then + echo "create directory $PRECLONE_EXTERNAL" + # remove all sub-folders + rm -rf /Users/admin/Documents/actions-runner/preclone + mkdir -p $PRECLONE_EXTERNAL + git clone https://github.com/cocos/cocos-engine-external $PRECLONE_EXTERNAL + else + echo "directory $PRECLONE_EXTERNAL is ready" + fi + if [ ! -d native/external ]; then + mkdir native/external + fi + git -C $PRECLONE_EXTERNAL reset --hard + git -C $PRECLONE_EXTERNAL fetch --all --prune + git -C $PRECLONE_EXTERNAL archive --format=tar $EXT_VERSION | tar -C native/external -xf - + - name: Generate bindings + run: | + cd ./native/tools/swig-config + echo "Create auto-generated jsbinding glue codes." + node genbindings.js && + git status - name: npm install run: | npm -v diff --git a/.github/workflows/web-build.yml b/.github/workflows/web-build.yml index ca410269a77..17112e9b1c8 100644 --- a/.github/workflows/web-build.yml +++ b/.github/workflows/web-build.yml @@ -18,7 +18,7 @@ jobs: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) strategy: matrix: - node-version: [12.x] + node-version: [14.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/.github/workflows/web-check_version.yml b/.github/workflows/web-check_version.yml index fdfa953cf28..21e85d82fcc 100644 --- a/.github/workflows/web-check_version.yml +++ b/.github/workflows/web-check_version.yml @@ -11,6 +11,9 @@ concurrency: jobs: Check_package_version: runs-on: ubuntu-latest + + permissions: read-all + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) steps: diff --git a/.github/workflows/web-interface-check.yml b/.github/workflows/web-interface-check.yml deleted file mode 100644 index 979b53ff413..00000000000 --- a/.github/workflows/web-interface-check.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Interface check - -#on: push -on: [pull_request_target] - -# github.head_ref is only defined on pull_request events -concurrency: - group: ${{ github.workflow }}-${{ github.actor }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - interface_check: - if: - (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) - runs-on: ubuntu-latest - steps: - - name: clone REPO - run: | - git config --global user.name "test" - git config --global user.email "test@test.com" - git clone https://github.com/cocos-creator/engine.git - - - name: checkout BASE branch - working-directory: ./engine - run: | - git fetch origin ${{ github.base_ref }} - git checkout -b ${{ github.base_ref }}_BASE remotes/origin/${{ github.base_ref }} - git branch - - - name: npm install BASE branch - working-directory: ./engine - run: | - npm install --ignore-scripts - - - name: build BASE declaration - working-directory: ./engine - run: | - npm run build-declaration - cp ./bin/.declarations/cc.d.ts ../cc_base.d.ts - - - name: clear dependencies - working-directory: ./engine - run: | - git checkout . - git clean -xfd - npm cache clean --force - ls -la - - - name: merge HEAD branch - working-directory: ./engine - run: | - git remote add HEAD_REPO https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git - git fetch HEAD_REPO ${{ github.head_ref }} - git merge remotes/HEAD_REPO/${{ github.head_ref }} - - - name: npm install HEAD branch - working-directory: ./engine - run: | - npm install --ignore-scripts - - - name: build HEAD declaration - working-directory: ./engine - run: | - npm run build-declaration - - - uses: LouisBrunner/diff-action@v0.1.2 - with: - old: ./cc_base.d.ts - new: ./engine/bin/.declarations/cc.d.ts - mode: addition - tolerance: worse - output: ./engine/interface-diff.txt - - - name: optimize interface check report - working-directory: ./engine - run: | - cat ./interface-diff.txt - node ./.github/workflows/interface-check-report.js - - - uses: marocchino/sticky-pull-request-comment@v2 - with: - path: ./engine/interface-diff.txt diff --git a/.github/workflows/web-npm_test.yml b/.github/workflows/web-npm_test.yml index e745221ac54..0adc0bdaac4 100644 --- a/.github/workflows/web-npm_test.yml +++ b/.github/workflows/web-npm_test.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: '12.13' + node-version: '14.19' - name: install gulp run: | diff --git a/@types/editor-extends.d.ts b/@types/editor-extends.d.ts index 174adb210f2..48b89c7c219 100644 --- a/@types/editor-extends.d.ts +++ b/@types/editor-extends.d.ts @@ -51,6 +51,8 @@ interface EditorExtendsComponent { interface EditorExtendsAsset { queryAssetInfo(uuid: string, callback: Function): any; getAssetInfoFromUrl(url: string): EditorAssetInfo; + saveDataToImage(buffer: Uint8Array | null, width: number, height: number, sceneName: string, fileName: string): any; + bakeReflectionProbe(files: string[], isHDR: boolean, sceneName:string, probeID: number, callback: Function): any } interface EditorExtendsUuid { diff --git a/@types/jsb.d.ts b/@types/jsb.d.ts index ad7bc45a326..f6fc6b1f8a0 100644 --- a/@types/jsb.d.ts +++ b/@types/jsb.d.ts @@ -10,6 +10,8 @@ */ declare namespace jsb { + let window: any; + type AccelerationXYZ = number; type AccelerationIncludingGravityXYZ = number; type RotationRateAlpha = number; @@ -52,6 +54,8 @@ declare namespace jsb { export interface MouseEvent { x: number, y: number, + xDelta: number | undefined, + yDelta: number | undefined, button: number, windowId: number, } @@ -105,6 +109,7 @@ declare namespace jsb { export let onHandlePoseInput: (infoList: PoseInfo[]) => void | undefined; export let onHMDPoseInput: (infoList: PoseInfo[]) => void | undefined; + export let onHandheldPoseInput: (infoList: PoseInfo[]) => void | undefined; export interface KeyboardEvent { altKey: boolean; @@ -185,7 +190,7 @@ declare namespace jsb { /** * Get PCM header without pcm data. if you want to get pcm data, use getOriginalPCMBuffer instead */ - export function getPCMHeader (url: string) : PCMHeader; + export function getPCMHeader (url: string): PCMHeader; /** * Get PCM Data in decode format for example Int16Array, the format information is written in PCMHeader. * @param url: file relative path, for example player._path @@ -194,6 +199,27 @@ declare namespace jsb { export function getOriginalPCMBuffer (url: string, channelID: number): ArrayBuffer | undefined; } + class NativePOD { + underlyingData(): ArrayBuffer; + _data(): TypedArray; + __data: TypedArray; + } + + export class Color extends NativePOD { + } + export class Quat extends NativePOD { + } + export class Vec2 extends NativePOD { + } + export class Vec3 extends NativePOD { + } + export class Vec4 extends NativePOD { + } + + export class Mat3 extends NativePOD { + } + export class Mat4 extends NativePOD { + } export interface ManifestAsset { md5: string; path: string; @@ -313,3 +339,27 @@ declare namespace jsb { setEventCallback (eventCallback: (event: EventAssetsManager) => void): void; } } + +declare namespace ns { + + class NativePOD { + underlyingData(): ArrayBuffer; + _arraybuffer(): ArrayBuffer; + } + export class Line extends jsb.NativePOD { + } + export class Plane extends jsb.NativePOD { + } + export class Ray extends jsb.NativePOD { + } + export class Triangle extends jsb.NativePOD { + } + export class Sphere extends jsb.NativePOD { + } + export class AABB extends jsb.NativePOD { + } + export class Capsule extends jsb.NativePOD { + } + export class Frustum extends jsb.NativePOD { + } +} diff --git a/@types/pal/input.d.ts b/@types/pal/input.d.ts index 08b0b644c1a..8b6bfba8495 100644 --- a/@types/pal/input.d.ts +++ b/@types/pal/input.d.ts @@ -273,6 +273,17 @@ declare module 'pal/input' { */ public get buttonRightStick (): InputSourceButton; + /** + * @en The button Options + * @zh 选项按键 + */ + public get buttonOptions (): InputSourceButton; + /** + * @en The button Start + * @zh 开始按键 + */ + public get buttonStart (): InputSourceButton; + /** * @en The position Left hand * @zh 左手位置 @@ -358,4 +369,26 @@ declare module 'pal/input' { */ public get headMiddleOrientation (): InputSourceOrientation; } + + type HandheldCallback = (res: import('cocos/input/types').EventHandheld) => void; + /** + * Class designed for Handheld input. + */ + export class HandheldInputDevice { + /** + * Register the handheld event callback. + * @engineInternal + */ + public _on (eventType: import('cocos/input/types/event-enum').InputEventType, callback: HandheldCallback, target?: any); + /** + * @en The position handheld + * @zh 手持设备相机位置 + */ + public get handheldPosition (): InputSourcePosition; + /** + * @en The orientation handheld + * @zh 手持设备相机方向 + */ + public get handheldOrientation (): InputSourceOrientation; + } } diff --git a/@types/pal/minigame.d.ts b/@types/pal/minigame.d.ts index 54fe041bc8d..83bb7a3acd6 100644 --- a/@types/pal/minigame.d.ts +++ b/@types/pal/minigame.d.ts @@ -23,7 +23,7 @@ declare module 'pal/minigame' { * @returns {SafeArea} An interface displaying the data of safe area, including 'top', 'bottom', 'left', 'right', 'width' and 'height'. */ getSafeArea(): SafeArea; - triggerGC(): void; + triggerGC?(): void; getBatteryInfoSync(): BatteryInfo; exitMiniProgram? (): void; diff --git a/@types/pal/screen-adapter.d.ts b/@types/pal/screen-adapter.d.ts index c570c0f5fb6..827b199637e 100644 --- a/@types/pal/screen-adapter.d.ts +++ b/@types/pal/screen-adapter.d.ts @@ -16,7 +16,12 @@ declare module 'pal/screen-adapter' { * Determine whether the game frame exact fits the screen. * Now it only works on Web platform. */ - exactFitScreen: boolean, + exactFitScreen: boolean; + + /** + * Determine whether use headless renderer, which means do not support some screen operations. + */ + isHeadlessMode: boolean; } class ScreenAdapter { diff --git a/@types/pal/system-info.d.ts b/@types/pal/system-info.d.ts index 9cf22ccffaa..4cb322b7afe 100644 --- a/@types/pal/system-info.d.ts +++ b/@types/pal/system-info.d.ts @@ -40,6 +40,7 @@ declare module 'pal/system-info' { public get browserType (): BrowserType; public get browserVersion (): string; public get isXR (): boolean; + public init (): Promise ; public hasFeature (feature: Feature): boolean; public getBatteryLevel (): number; @@ -47,8 +48,14 @@ declare module 'pal/system-info' { public openURL (url: string): void; public now (): number; public restartJSVM (): void; - + /* + * Trigger to exit the game + */ public close (): void; + /* + * Free the native's resources + */ + public exit(): void; on (event: PalSystemEvent, cb: (...args: any)=>void, target?: any): void; off (event: PalSystemEvent, cb?: (...args: any)=>void, target?: any): void; diff --git a/CHANGELOG.txt b/CHANGELOG.txt deleted file mode 100644 index ea43954e0f5..00000000000 --- a/CHANGELOG.txt +++ /dev/null @@ -1,952 +0,0 @@ -ChangeLog: - -Cocos2d-x v3.8 @ September.6 2015 - - [NEW] spine: Supported Spine runtime 2.3 (Both native and web engine) - [NEW] Animate: Added Animate's getCurrentFrameIndex function - [NEW] network: Upgrade SocketIO support to v1.x - - [REFINE] web: Avoid re-bake the content when the parent node's position get changed - [REFINE] web: Added GameNodeObjectData and GameLayerObjectData in JSON parser - [REFINE] web: Updated skeleton animation to the latest version - [REFINE] web: Optimized resources automatic loading in JSON parser - [REFINE] web: Avoid cc.loader resource loading being terminated while encounter errors - [REFINE] web: Throw new Error object instead of error message string - [REFINE] web: Move setDepthTest to renderer - [REFINE] web: Added BlendFuncFrame parser - [REFINE] web: Permitted webp image loading on Chrome - [REFINE] web: Suspended the video player when the browser is minimized - - [FIX] web: Fixed a bug that VideoPlayer remove event throw error - [FIX] web: Fixed Armature position error in studio JSON parser - [FIX] web: Fixed default clearColor error in director - [FIX] web: Fixed rotation value parsing error in the timeline parser - [FIX] web: Fixed a bug that nested animation may be affected by outer animation - [FIX] web: Made LabelAtlas ignoring invalid characters and updating correctly the content size - [FIX] web: Fixed a bug that VideoPlayer remove event throw error - [FIX] web: Fixed a bug that cc.director.setNotificationNode(null) doesn't take effect - [FIX] web: Fixed texture rect update issue while changing sprite frame - [FIX] web: Fixed effect issue in ActionGrid and NodeGrid - [FIX] web: Fixed logic issue in Menu's _onTouchCancelled function - [FIX] web: Fixed MenuItem crash when normal image is null - [FIX] web: Fixed incomplete fadeout effects - [FIX] web: Fixed issue that return value of cc.screen.fullScreen is not boolean - [FIX] web: Fixed a bug that SkeletonNode is not drawing children - - [TEST] web: Rewrote testcase for stencil depth mask in RenderTextureTest - [TEST] web: Improved renderTexture stencilDepth test - [TEST] web: Fixed abnormal effects in effectsTest - [TEST] web: Fixed invisiable testcase of effects - -Cocos2d-x v3.7.1 @ August.12 2015 - [HIGHLIGHT] studio: Added new skeleton animation support and JSON parser for cocos v2.3.2 beta - - [NEW] Node: Added getNodeToParentTransform with selected ancestor - [NEW] web: Added cc.director.setClearColor and support transparent background - [NEW] web: Added Animate's getCurrentFrameIndex function - - [REFINE] studio: Optimized JSON parser's performance by removing audio play - [REFINE] studio: Optimized editor related extension data to a component instead of hosting in _userObject - [REFINE] web: Improved color/opacity manipulations in MenuItems - - [FIX] studio: Fixed ccs.Skin construction issue in JSON parser - [FIX] web: Fixed an issue that loading process won't trigger callback problem - [FIX] web: Fixed a bug where not resetting cc.Audio._ignoreEnded when replaying a sound caused it to stay in a "playing" state - [FIX] web: cc.ScrollView and cc.TableView: added check for parent visibility in onTouchBegan method - [FIX] web: Fixed TurnPageDown effect - [FIX] web: Fixed Cocos Studio parser issue that all elements are missing while the timeline action contains rotation - -Cocos2d-x v3.7 Final @ July 20 2015 - [REFINE] web: Add compatible Uint16Array defintion - - [FIX] web: Fixed url check regular expression not supporting localhost issue - [FIX] web: Fixed issue that sprite doesn't update texture rect correctly - -Cocos2d-x v3.7 RC1 @ July 14 2015 - [REFINE] Improved localStorage warning when disabled - - [FIX] Fixed a bug that SingleNode's color isn't set - [FIX] studio: Fixed a bug of JSON parser that texture address is wrong - [FIX] Fixed MenuItems' color/opacity setter issue with child nodes - [FIX] Fixed page view's layout issue for JSON parser - [FIX] Add ttc loader and prevent the pure digital fonts is invalid - [FIX] Fixed Float32Array initialization - [FIX] Fixed a bug that layout background is missing - [FIX] Fixed a bug that ObjectExtensionData miss setCustomProperty and getCustomProperty function - -Cocos2d-x v3.7 RC0 @ July 1 2015 - -* The json loader of Cocos Studio will automatically load dependencies resources -* SIMD.js optimization for kazmath functions (from Intel) -* Deleted the redundant variables defined and log informations in ccui.RichText -* Allowed timeline animations with only one frame -* Improved property declaration of cc.Texture2D - -* Bug fixes: - 1. Fixed positionType error of particle system in timeline parser - 2. Fixed setAnimationName issue while the property is undefined in timeline parser - 3. Fixed `cc.TMXObjectGroup#objectNamed` not returning the result bug - 4. Fixed TransitionSlideX callback sequence issue - 5. Fixed issue in music end event - 6. Fixed bug that LayerColor's color will disappear when update transform after being baked - 7. Fixed `inverse` function bug of `cc.math.Matrix4` - 8. Fixed the webaudio's invalid loop attribute bug for chrome 42 - 9. Fixed crash when character not found into BMP font - 10. Fixed spine's js parser issue by avoid NaN duration - 11. Fixed LabelTTF multiline detection - 12. Fixed issue in ccui.Widget#getScale - 13. Fixed texture is not updated in some cases - 14. PlayMusic should not use the search path (timeline 2.x) - 15. Fixed bug of loading path of resources - 16. Premultiply texture's alpha for png by default to fix Cocos Studio render issues - 17. Fixed cache update issue of Layout after bake - 18. Fixed isBaked returning undefined issue - 19. Made CCProgressTimerCanvasRenderCmd to properly show colorized sprites - 20. Fixed attributes being reset issue while baked cache canvas' size changed - 21. Fixed texture does not rotate bug of ccui.LoadingBar - 22. Fixed color not being set issue in timeline parser - 23. Fixed custom easing animation bug - 24. Fixed return empty texture2d bug when adding image with same url multiple times - 25. Fixed actiontimeline can not step to last frame issue when loop play - 26. Fixed the prompt can not be used in iOS wechat 6.2 - 27. Fixed restoring of sprite's color issue - 28. Fixed Uint8Array initialize issue - 29. Fixed cc.TextFieldTTF Delegate memory leaks - 30. Fixed sorted result is wrong in cc.eventManager (_sortEventListenersOfSceneGraphPriorityDes) - 31. Fixed BinaryLoader issue on IE11 - 32. Fixed the sprite's texture bug when frequently change the color - 33. Fixed an issue that action will result in automatic termination - 34. Fixed ScrollView initWithViewSize issue - -Cocos2d-JS v3.6 @ April 29 2015 - -* Added GAF web runtime to the web engine, the native support will be merged in future version. -* Synchronised Cocos2d-x v3.6. - -* Bug fixes: - 1. Fixed a bug of Cocos Studio parser that it doesn't parse correctly the outline of text widget and button widget. - 2. Fixed a bug of Cocos Studio parser that it doesn't support inner action correctly. - 3. Fixed a bug of Cocos Studio parser that `ccui.Text`'s content size is set incorrectly. - 4. Fixed a bug of Cocos Studio parser that `ccui.Layout`'s background color is set incorrectly. - 5. Fixed a bug of `cc.Node`'s `removeAllChildren` that it doesn't notify the renderer to update. - 6. Fixed a bug of audio system that the resume of music may start from the beginning. - 7. Fixed a bug that sprite's `setTexture` fails to update its content size. - 8. Fixed a bug that Scale9Sprite's children doesn't get transformed recursively. - 9. Fixed constant naming issue of `ccs.FrameEaseType`. - 10. Fixed `cc.LoaderScene.preload` API inconsistency between web engine and native engine. - 11. Fixed a bug that `ccui.Slider` doesn't act correctly when it's scaled. - 12. Fixed a bug that `ccui.Button` renders incorrectly when scale9sprite option enabled. - 13. Fixed circular invocation issue in `cc.Sprite`'s canvas render command. - -Cocos2d-JS v3.6 Beta @ April 22 2015 - -* Improved TMX transform to support RotationX and RotationY. -* Refactored Spine skeleton render command. -* Added checks to prevent issues when `cc.Node.WebGLRenderCmd` is not exist. -* Improved iOS browsers detection. -* Added getter setter function for `cc.MotionStreak`'s stroke property. -* Improved the detection of render mode. -* Upgraded Action Timeline and parser for the latest version of Cocos editor. -* Added `enumerateChildren` function for `cc.Node`. -* Make `cc.Scale9Sprite` support unpreloaded texture. -* Added `cc.sys.isObjectValid` to detect whether an object is still valid (in web and native engine). - -* Bug fixes: - 1. Fixed a bug that `cc.Scheduler`'s `scheduleOnce` runs multiply times. - 2. Fixed a bug of `cc.Scheduler`'s `pauseAllTargetsWithMinPriority`. - 3. Fixed a bug of `cc.eventManager` that its event listeners' order is incorrect when some nodes haven't been added to the scene graph or have been removed from parent without cleanup. - 4. Fixed a bug of `cc.LabelTTF` that `enableShadow` doesn't work. - 5. Fixed a bug of `cc.LabelTTF` that `setColor` doesn't set shadow color under Canvas render mode. - 6. Fixed a bug that stopped audios can be resume after invoking pause on them. - 7. Fixed a bug that `ccui.LoadingBar`'s texture renders incorrectly without preload. - 8. Fixed a bug that cocos builder's callback doesn't get invoked. - 9. Fixed a bug that TMX objects' position is incorrect when content scale factor is modified. - 10. Fixed a mistaken usage of `cc.isObject` in `cc.Sprite` implementation. - 11. Fixed a bug that position type haven't been copied in `cc.ParticleSystem`'s `clone` function. - 12. Fixed some undefined parameter check issues in `cc.Node`. - 13. Fixed a bug that setter for `scaleY` of `cc.EditBox` is incorrect. - 14. Fixed a bug of `cc.SkeletonAnimation` that its canvas render command doesn't work correctly. - 15. Fixed a parsing issue for the width of `cc.LabelBMFont`. - 16. Fixed `ccs.TweenType`'s constants naming issue. - 17. Fixed a bug that the spine skeleton may be rendered under the unsupported mode. - 18. Fixed a bug when setting `cc.ParticleSystem`'s blend function in the ActionTimeline parser. - 19. Added check to prevent issues that functions may not exist in the ActionTimeline parser. - 20. Fixed a typo of `ccs.displayFactory`. - 21. Fixed a bug of `cc.Node.setPosition` that parameter check is incorrect. - -Cocos2d-JS v3.5 @ April 1 2015 - -* Upgraded Cocos Studio parser to support Cocos Studio v2.2. -* Upgraded Spine support to v2.1, added spine test case with FFD. FFD is supported in native but not in web, both engine can parse the new version file correctly, but the web engine will ignore FFD informations. -* Replaced '==' with '===' for better performance. -* Added `path` parameter in `ccs.load` to support modifying cocostudio project resource path. -* Added animationList to Cocostudio ActionTimeline to support playing animation by name. -* Made ParticleSystem support creation from an map object. -* Added missing functions to `cc.Grid3D` and `cc.PageTurn3D`. -* Added tip message functions to `cc.TextFieldTTF` for mobile browser. -* Added a function `cc.sys.openURL`. -* Disabled retina display by default for better performance. -* Added Bower support. -* Updated `cc.sys.OS_XXX` informations for supported systems. - -* Bug fixes: - 1. Fixed a bug of chipmunk.js that it doesn't work under closure compiler advanced mode. - 2. Fixed a bug of Cocos Studio parser that widget didn't set its layout component. - 3. Fixed grammatical mistakes in cocostudio parser logs. - 4. Fixed memory leak issue in `cc.LabelBMFont`. - 5. Fixed a bug of `cc.Scale9Sprite` that its `updateDisplayColor` doesn't take effect. - 6. Fixed a bug of Cocos Studio parser that `cc.Scale9Sprite` doesn't display correctly if its texture isn't preloaded. - 7. Fixed a bug of `cc.MenuItemSprite` that the construction will fail when parameter `selectedSprite` is a Scale9Sprite instance. - 8. Fixed a bug of Cocos Studio parser that the background color of `ccui.Layout` can't be parsed correctly. - 9. Fixed a bug of `cc.ClippingNode` that it doesn't work when set `inverted` to true in Canvas Mode. - 10. Fixed a bug of `ccs.Armature` that its name was modified to animation name when loading from json files. - 11. Fixed a bug of `ccui.PageView` that it cancel child touch during movment of page view. - 12. Fixed a bug of `cc.Scheduler` that its parameter `repeat` is invalid in schedule function. - 13. Fixed a bug of `cc.Scheduler` that `unschedule` function may fail. - -Cocos2d-JS v3.4 Beta0 @ March 19 2015 - -* Added Windows Phone 8.0 platform support. -* Upgraded SpiderMonkey to v33, greatly improved JS object garbage collection and performance. -* Bound 3D modules including camera, light, sprite 3d, animation 3d, billboard, etc. -* Improved `cc.FontDefinition` & `ccui.RichText` in the web engine. -* Added gradient stops feature to `cc.LayerGradient` [Web exclusive]. -* Upgraded `cc.Scheduler` in the web engine with Cocos2d-x v3.4 implementation. -* Added a loading screen when scripts are loading. -* Improved performance by replacing `Object.defineProperties` with `cc.defineGetterSetter`. -* Supported loading sprite frames from json object. -* Refactored math library to improve web engine performance. -* Removed some variables from `cc` namespace to improve web engine performance. -* Added the Firefox OS Web manifest to support Firefox OS apps. -* Added `cocos` attr to the script element in templates. -* Moved loading.js to res folder for Cocos Console release mode. - -* Bug fixes: - 1. Added `getSpriteFrame` to `cc.Sprite` to fix API inconsistency. - 2. Added `getObject` to `cc.TMXObjectGroup` to fix API inconsistency. - 3. Added `addImageAsync` to `cc.textureCache` to fix API inconsistency. - 4. Fixed a bug of `cc.text` that its default font name is incorrect. - 5. Fixed a bug of `ccui.PageView` that its `getPage` doesn't work. - 6. Fixed a bug of `ccui.ImageView` that its `loadTexture` doesn't work while it's invoked multiple times at the same frame. - 7. Fixed a bug of `ccui` that its load event callbacks have some mistakes. - 8. Fixed a bug of `cc.Layer` that its bake function doesn't work when the layer has a parent node. - 9. Fixed typos in `cc.ClippingNode.WebGLRenderCmd` and `cc.ParticleSystem.WebGLRenderCmd` creation. - 10. Fixed a bug of `cc.Sprite` in `setTextureRect`. - 11. Fixed a bug of `cc.Screen`. - 12. Fixed a bug of `cc.view` that it doesn't work on iOS 8.1.2. - 13. Fixed a bug of cc.DrawNode that its lineWidth is always to default value when set linewidth to zero. - 14. Fixed a bug in hack for particles performance on canvas. - 15. Fixed a bug of `cc.audioEngine` that it doesn't work after minified/compiled. - 16. Fixed a bug in `CCBoot.js` that WebGL is not activated in web view of iOS 8. - 17. Fixed a bug of `cc.CheckBox` that its position is incorrect when its texture isn't preloaded. - 18. Fixed a bug of `cc.TMXLayer` that it stops to work after `setTileGID` called. - 19. Fixed a bug of Cocos parser 2.x that it doesn't set widget's LayoutComponent. - 20. Fixed a bug of `cc.isObject` that it considered function as an object. - -Cocos2d-JS v3.3 @ Feb.9, 2015 - -* Upgraded spine runtime to support the latest version and updated its test case. -* Added an option "noCache" for debugging on browsers. -* Set the default value of `cc.ParticleSystem`'s draw mode to texture mode. -* Added message to `ccs.load` when loading armature json file. -* Improved particle system test case. - -* Bug fixes: - 1. Fixed a bug of `cc.Sprite` that its `setSpriteFrame` doesn't work when sprite frame's `rotated` property is true. - 2. Fixed a bug of `cc.ClippingNode` when its stencil is `cc.Node` object in canvas mode. - 3. Fixed a ccui bug that the position of widgets is incorrect after loaded v2.x json file with `ccs.load`. - 4. Fixed a bug of `cc.PhysicsSprite` that `setIgnoreBodyRotation` function doesn't work. - 5. Fixed a bug of `ccui.Button` that setting pressed texture doesn't work when scale9 enabled. - 6. Fixed a bug of `ccui.ScrollView` that its `dir` property is null when passing `DIR_NONE` as `direction` in `_endRecordSlidAction` function. - -Cocos2d-JS v3.3 RC0 @ Feb.1, 2015 - -* Added web exclusive functions: `_getFontStyle`, `_setFontStyle`, `_getFontWeight` and `_setFontWeight` APIs to `cc.LabelTTF`. -* Observed orientation change event on mobile for resolution policy adaptation. - -* Bug fixes: - 1. Fixed Cocos Studio JSON parser's issues for parsing nested animation. - 2. Fixed Cocos Studio JSON parser's parameters parsing issues. - 3. Fixed Cocos Studio JSON parser's issue for parsing layer. - 4. Fixed Cocos Studio JSON action parser's issues. - 5. Fixed Cocos Studio JSON parser's issue for parsing Scale9Sprite. - 6. Fixed Cocos Studio JSON parser's issues caused by parsing process order. - 7. Fixed Cocos Studio JSON parser's issue for parsing loading bar's direction. - 8. Fixed UI layout system issues. - 9. Fixed `cc.EditBox`'s position issue under certain resolution policies. - 10. Fixed `ccui.ListView`'s issue for setting direction. - 11. Fixed an issue of `cc.Tween` that its `_currentPercent` is incorrect in `updateHandler` function. - 12. Fixed an issue of `ccui.Button` that its state is incorrect in `_onPressStateChangedToNormal`. - 13. Fixed an issue of `cc.ArmatureAnimation`'s `setMovementEventCallFunc`. - 14. Fixed an issue of `cc.Sequence` action when it's repeated. - 15. Fixed `_anchorPointInPoints` usage issue. - 16. Fixed an issue of `cc.GLProgram` that it doesn't work on some devices which didn't support highp float precision. - 17. Fixed an issue of fade actions that they don't work when duration is 0. - 18. Fixed `onended` callback issue of audio engine on iOS. - 19. Fixed Cocos Builder's parser issue for auto playing animations. - 20. Added a message to `ccs.Armature` that it doesn't support adding widget as its child. - 21. Improved test cases for stability. - -Cocos2d-JS v3.3 Beta @ Jan.24, 2015 - -* Added Cocos Studio v2.x parser and refactored 1.x parser. -* Upgraded new flow layout UI system in web engine. -* Refactored `load` events of texture2d, sprite and so on to be more intuitive. -* Added JavaScript file loader. -* Allowed set texture to null in `cc.Sprite`. -* Added full test cases for Cocos Studio v2.x parser and the new flow layout UI system. -* Upgraded MoonWarriors sample's UI and graphic design. - -* Bug fixes: - 1. Fixed a bug of Cocos2d UI, their focus event has been supported. - 2. Fixed a buf of `ccui.Widget` that its percent position doesn't work. - 3. Fixed a bug of `ccs.Armature` that its position doesn't update in visit on WebGL render mode. - 4. Fixed a bug of `cc.Sprite` that its `setTextureRect` function doesn't work when `setColor` invoked. - 5. Fixed a bug of `cc.PhysicsSprite` that its position is incorrect. - 6. Fixed a bug of `ccs.Bone` that its `setOpacity` and `setColor` doesn't work. - 7. Fixed a bug of `cc.LabelBMFont` that its word wrap doesn't work. - 8. Fixed a bug of `cc.sys` that it gets the incorrect OS type when system is Linux. - 9. Fixed a bug of `cc.audioEngine` that its loading path is incorrect. - 10. Fixed a bug of `ccui.Widget` that it can't touch when it's reused. - 11. Fixed a bug of UI system that the `setNormalizedPosition` doesn't work. - 12. Fixed a bug of `cc.ActionInterval` that its `_times` conflict with `cc.Blink`. - 13. Fixed release texture issue in canvas mode. - 14. Fixed a bug of `ccs.actionManager` that its `getActionByName` doesn't work. - 15. Fixed a bug of `cc.Sprite` that it can't draw without texture on WebGL mode. - 16. Fixed a bug of `cc.audioEngine` that it doesn't work on baidu browser. - 17. Fixed a bug of `cc.EditBox` that its position is incorrect on Canvas Mode and its string value is wrong when PlaceHolder is showing. - 18. Fixed a bug of `cc.loader` that its `loadImg` function doesn't work when image is accessed cross origin. - 19. Fixed a bug of `ccui.TextField` that its `contentSize` is incorrect in text field event. - -Cocos2d-JS v3.2 @ Dec.29, 2014 - -* Replaced `transform` function with `setTransform` function under canvas render mode for better performance. -* Added a timer in `cc.audioEngine` to check audio element loading event, prevent the loading process being stucked when load audio file failed. -* Added some new browser types to `cc.sys`. -* Added some audio resource loading codes to ensure compatibility with Wechat browser. -* Added check for WebAudio support to ensure compatibility. - -* Bug fixes: - 1. Fixed an issue that `cc.InputManager` doesn't trigger touch event on chrome mobile emulator. - 2. Fixed an issue that `cc.game.setFrameRate` doesn't work. - 3. Fixed an issue that `cc.view` can't remove resize event listener. - 4. Fixed an issue that `cc.EventManager` didn't set register flag to false when a listener is removed. - 5. Fixed an issue that `cc.audioEngine` doesn't play some audios on some iOS devices. - 6. Fixed an issue of ccui controls that their `setColor` doesn't work when cascade color is enabled. - 7. Fixed an issue that `ccs.Armature`'s `setColor` doesn't work in canvas render mode. - 8. Fixed an issue that `ccs.Armature` crashes when adding a child to it. - 9. Fixed an issue that `cc.SpriteBatchNode`'s status is incorrect in WebGL render mode. - 10. Fixed an issue of `cc.Layer` that its position is incorrect under bake mode. - 11. Fixed an issue of `ccui.RichText` that its `setContentSize` doesn't work. - 12. Fixed an issue of `cc.LabelTTF` that its `setColor` doesn't work when cascade color is enabled. - 13. Fixed an issue of spine that its skeletons position is incorrect when scaleX equals to -1 and scaleY equals to 1. - 14. Fixed `sp.Skeleton`'s API inconsistence by renaming `boundingBox` to `getBoundingBox`. - 15. Removed all usages of deprecated create functions in the test cases. - -Cocos2d-JS v3.2 RC0 @ Dec.11, 2014 - -* Refactoration of web engine by separating the render logic, the arthictecture level refactoration is now completed and brounght great performance improvement. -* Refactoration of web engine's resolution adaptation and audio engine with polyfilled adaptation logics for different devices and browsers. This ensures better compatibility and better extensibility for future needs. -* Added `setRotation` method to `ccui.ImageView`. -* Added a function that fill sprite with repeated texture in Canvas mode. -* Added `setLineHeight` method to `cc.LabelTTF`. -* Added `dumpAudioInfo` to `cc.audioEngine` for debugging purpose on mobile browser. -* Removed Cocos Studio's Protobuffer support from the framework. -* Added an outline shader sample. - -* Bug fixes: - 1. Fixed an issue of `cc.Sprite` that its rendering is incorrect without texture. - 2. Fixed an issue of `cc.ClippingNode` that its stencil drawing is incorrect on Canvas Mode. - 3. Fixed an issue of `TextFieldReader` that it will throw an error when 'areaWidth' and 'areaHeight' equal to zero. - 4. Fixed an issue of `ccui.CheckBox` that its getSelectedState doesn't return its state. - 5. Fixed an issue of `cc.LabelTTF` that it doesn't update the string when its string become to empty string. - 6. Fixed an issue of `cc.ParticleSystem` that it can't change its texture mode and shape type in Canvas mode. - 7. Fixed an issue of `cc.Layer`'s bake function that its position is incorrect when cc.view's scale isn't 1. - 8. Fixed an issue of `ccs.ArmatureAnimation`'s `setMovementEventCallFunc` and `setFrameEventCallFunc`. - 9. Fixed an issue of `console.log` that it isn't a funtion on IE9. - 10. Fixed an issue of `CSLoader` that it will add duplicate resources to sprite frame cache. - 11. Fixed an issue of `cc.ProgressTimer` that its setColor is not taking effect. - 12. Fixed an issue of `cc.loader` that it will throw an error when loading a remote texture. - 13. Upgrade html5 version chipmunk to the latest release. - -Cocos2d-JS-v3.1 @ Oct.22, 2014 - -* Released Facebook Integration for Cocos2d-JS v1.0, all APIs have been significantly polished and stabilized. Improved test cases for Facebook with more features demonstrated. -* Upgraded Cocos2d-x to v3.3 rc0 -* Supported Cocos Studio v2.0 including Timeline animation support and proto buffers format support for both web engine and JSB engine. -* Refactored load event of texture, sprite frame and sprite for better maintainability. -* Refactored `cc.rendererCanvas` for improving performance. -* Moved the `CC_Texture0` definition of fragment shader to cc.GLProgram to ensure compatibility with JSB. -* Added normalized position functions to cc.Node. -* Refactored the constructor of Cocos Studio's classes and deprecated all create functions. -* Refactored Cocos Studio reader for better maintainability. -* Improved Facebook SDK. -* Modified `cc.ProgressTo`'s behavior, its progression didn't reset to zero when the progression is 100. -* Changed `ccui.Widget`'s default anchor point to (0, 0) in widget reader. -* Removed all deprecated create function usage in engine and in the test cases. - -* Bug fixes: - 1. Fixed an issue of `cc.UILayout` that its scissor mode didn't work. - 2. Fixed an issue of `ccui.TextBMFont` that its 'string' property setting was incorrect. - 3. Fixed an issue of `cc.DrawNode` that its element's position was incorrect in Canvas mode. - 4. Fixed an issue of `cc.Layer` that its bake function didn't work in new renderer. - 5. Fixed an issue of `cc.Scale9Sprite` that its cached canvas size was incorrect. - 6. Fixed an issue of `cc.Director` that its position was incorrect when calling `setProjection` in new renderer. - 7. Fixed an issue of `cc.view` that the reinitialization logic of frame size was incorrect. - 8. Fixed incorrect usage of `cc.progressTo` in progress action test. - 9. Fixed an issue of CocosNodeTest for the new renderer. - 10. Fixed minor issues in test cases. - -* Known Issues: - 1. `jsb.AssetsManager` doesn't work on windows due to a bug in libcurl - -Cocos2d-JS v3.1 beta @ Oct.13, 2014 - -* Refactoration of the web engine with new renderer on the architecture level, optimization is under going. -* Released Facebook SDK for Cocos2d-JS beta2, its API have been significantly improved and stablized. -* Upgraded MoonWarriors sample with new set of graphical assets. -* Automatically enabled WebGL on iOS 8 safari. -* Upgraded chipmunk.js to the newest version. -* Supported setting color of shadow for `cc.LabelTTF`. -* Added `getTitleRenderer` function to ccui.Button. -* Supported Coco Studio timeline animation. -* Set the default value of LabelAtlas's `cascadeOpacityEnabled` and `cascadeColorEnabled` to true. -* Added a listener of texture to `cc.Sprite#setTexture` when the texture hasn't loaded. -* Activated `cc.pool` for all kind of objects. -* Added query test for chipmunk and added necessary JavaScript bindings. - -* Bugs fix: - 1. Fixed a bug of `cc.ComponentContainer` that a 'if' statement behavior is incorrect. - 2. Fixed a bug of `cc.Scale9Sprite` that the behavior of Canvas and WebGL is different. - 3. Fixed a bug of `cc.EventListener` that its pause state should set to true. - 4. Fixed a bug of `cc.ParticleSystem` that it should apply canvas scaling on canvas rendering mode. - 5. Fixed a bug of CCBoot.js that `cc.loader` should add a condition to check whether `crossOrign` property is undefined on IE9 and IE10. - 6. Fixed a bug of `ccui.Widget` that its `setPosition` function's behavior is incorrect. - 7. Fixed a bug of `ccui.LoadingBar` that its `barRenderer` should add to protected children array. - 8. Fixed a bug of `cc.Texture2D` that its `TEXTURE_MAG_FILTER` should set to LINEAR. - 9. Fixed a bug of `cc.TMXMapInfo` that its doesn't parse `rotation` property. - -Cocos2d-JS-v3.0 Final @ Sep.10, 2014 - -* Facebook SDK Beta2: Added `appRequest` API. -* Facebook SDK Beta2: Added permission request in `login` API, removed `requestPermission` API. -* Facebook SDK Beta2: Renamed `request` API to `api`. -* Facebook SDK Beta2: Renamed `publishInstall` API to `activateApp`. -* Added getter and setter function for browser's density dpi: `cc.view.setTargetDensityDPI`, `cc.view.getTargetDensityDPI`. -* Added some type check functions. -* Added audio support for wechat browser. -* Added setPlaceHolderColor and setTextColor to ccui.TextField. -* Added API reference for Cocos Studio extension. - -* Bugs fix: - 1. Fixed an issue of `cc.Menu` that its item's touch priority is different than cc.eventManager. - 2. Fixed an issue of `cc.view` that its NO_BORDER mode doesn't work correctly. - 3. Fixed an issue of `cc.LabelBMFont` that its content size is different than JSB. - 4. Fixed an issue of `cc.LabelBMFont` that its `setColor` is invalid on some mobile devices. - 5. Fixed an issue of `cc.PageView` that it can't receive TOUCH_CANCEL event. - 6. Fixed an issue of `cc.loader` that it can't load cross origin textures. - 7. Fixed an issue that Facebook SDK Web's `appRequest` wraps info parameter incorrectly. - 8. Fixed an issue of ccui widgets' `addEventListener` that it doesn't accept function's target as parameter. - -Cocos2d-JS-v3.0 RC3 @ Aug.29, 2014 - -* Facebook SDK Beta: Unified the callback parameters for different platform. -* Facebook SDK Beta: Added payment API on Web platform. -* Facebook SDK Beta: Supported app request and share open graph API on Web platform. -* Facebook SDK Beta: Remove plugin configuration for Facebook SDK to simplify the usage. -* Facebook SDK Beta: Added test case for new features and improve all test cases. -* Cocos Console: Improved web compile with `--advanced` tag. -* Improved Cocos2d-JS inline docs to provide a better API reference document. -* Refactored cc.game for maintainability. -* Refactored cc.async to simplify and improve the usage. -* Added `cc.formatStr` for string formatting, for example: `cc.formatStr("a: %d, b: %b", a, b)`. -* Refactored cc.log to support formatted string. -* Refactored cc.pool's `hasObj` to `hasObject` and `removeObj` to `removeObject`. -* Added some state check to cc.audioEngine. -* Refactored sprite's blend function to support more features on Canvas. -* Refactored `cc.textureCache.textureForKey` to `cc.textureCache.getTextureForKey`, `cc.TMXTilemap#propertiesForGID` to `cc.TMXTilemap#getPropertiesForGID` to follow the standard API naming style. -* Detected mouse event on touch screen tablets. -* Support new construction for cc.PhysicsDebugNode and deprecated `cc.PhysicsDebugNode.create` -* Made cc.Texture2D's setTexParameters supports two types of parameters. -* Added test case for remote image loading. - -* Bugs fix: - 1. Fixed an issue of tilemap that it can't runAction in canvas render mode. - 2. Fixed an issue of cc.eventManager that its removeListeners' codes are unreachable. - 3. Fixed an issue of cc.EditBox that its position is incorrect. - 4. Fixed an issue of cc.WebAudio that its stopped state is incorrect. - 5. Fixed an issue of cc.audioEngine that it doesn't work on firefox after it compiled with advanced mode. - 6. Fixed an issue of ccs.Bone that it doesn't update color and opacity correctly. - 7. Fixed an issue of ccs.Armature that its setShaderProgram doesn't work. - 8. Fixed cc.Sprite and cc.Scale9Sprite's issue so that their texture loads incorrectly. - 9. Fixed an issue of ccui.LoadingBar that its setPercent is invalid. - 10. Fixed an issue of Armature reader that it can't parse isTween property. - 11. Fixed an issue of ccui.PageView that its getTouchBeganPosition returns incorrect value. - 12. Fixed an issue of ccui.ImageView that its setColor doesn't work. - 13. Fixed an issue of cc.RenderTexture that it doesn't support parameter depthStencilFormat. - 14. Fixed an issue of ccs.ArmatureAnimation.setSpeedScale. - 15. Fixed an issue of cc.Scale9Sprite that it has a line on iOS device. - 16. Fixed CCProgressTimer draw on canvas with colorized sprite - 17. Fixed an issue of cc.game that its frameRate setter is invalid. - 18. Fixed an issue of cc.loader that its callback state is incorrect. - -Cocos2d-html5-v3.0 RC2 @ Aug.8, 2014 - -* Refactored Cocos UI for more stable and friendly user experience. -* Upgraded Cocostudio reader to support version 1.2 - 1.5.x. -* Upgraded Cocostudio Armature animation from Cocos2d-x v3.2. -* Added back 2.x createWithXXX functions and deprecate all create/createWithXXX functions. -* Merged cc.NodeRGBA and cc.LayerRGBA to cc.Node. -* Fixed ctor functions bugs to support new construction. -* Refactored cc.Sprite's setColor to improve its performance. -* Renamed CCAffineTransform.js's functions to lowercase started functions. -* Upgraded cc.Scale9Sprite from Cocos2d-x 3.2. -* Improved cc.LabelTTF's line break algorithms to support multi-languages. -* Made cc.RenderTexture's beginWithClear accept color value from 0-255. -* Improved implementation of all Actions lower case alias creation functions. -* Added lower case creation functions for 3d actions and progress actions. -* Added cc.sys.platform API for detecting platform. -* Upgraded HelloWorld project with v3.0 APIs. - -* Bugs fix: - 1. Fixed a bug of cc.WebAudio that sourceNode's playbackState is invalid on some browsers. - 2. Fixed a bug of cc.MenuItemToggle that callback is not correctly initialized when using new construction. - 3. Fixed a bug of ccui.Layout that its clipping area is incorrect. - 4. Fixed a bug of requestAnimFrame that it doesn't work after re-focus WeChat browser on Samsung mobile. - 5. Fixed a bug of CCBoot.js that bind function is undefined in Safari for iOS 5.1. - 6. Fixed a bug in cc.layer's bake function that its position is incorrect when cc.view is scaled. - 7. Fixed a bug of cc.LayerMultiplex. - 8. Fixed a bug of cc.TMXLayer that it can't display all map image when its type is hexagonal. - 9. Fixed a transform error in ccs.TransformHelp. - 10. Fixed a bug of cc.ControlSwitch. - 11. Fixed image format constant inconsistence. - 12. Fixed a bug of ccui.Widget that it is invisible after popScene. - 13. Correct behavior of cc.TransitionSlideInB and cc.TransitionSlideInT. - 14. Fixed bugs of ccui.Widget and ccui.Text's clone functions. - - -Cocos2d-html5-v3.0 RC0 @ July.3, 2014 -* Added Facebook SDK plugin into Pluginx extension. -* Refactoration of gui system `ccui` for better performance, usage and maintainbility. -* Added `bake` function to `cc.Layer` to support layer baking. -* Added object pool extension: `cc.pool`. -* Added new easing functions: bezier action, quadratic actions, quartic actions, quintic actions, circle actions, cubic actions. -* Made `cc.loader` continue the counter process even if a resource failed to be loaded. -* Supported multiple property objects in `cc.Class.extend` function. -* Refactored `ccui.Widget`'s `getLeftInParent`, `getBottomInParent`, `getRightInParent`, `getTopInParent` to `getLeftBoundary`, `getBottomBoundary`, `getRightBoundary`, `getTopBoundary`. -* Refactored `cc.FadeIn.create(duration, toOpacity)` to `cc.FadeIn.create(duration)`. -* Refactroed all string access functions in `ccui` extension to `setString` and `getString`. -* Added `getContentSize` and `setContentSize` in `ccui` extension. -* Changed the default alpha value of `cc.Color` from `undefined` to 255. -* Made `cc.log` support formatted string. - -* Bugs fix: - 1. Fix bugs on creating sequence objcet or spawn object using new method. - 2. Fix a bug that `ccui.LoadingBar`'s `setPercent` function will crash when its texture is in a plist file and scale9Enabled is true. - 3. Fixed a bug of `cc.audioEngine` that it crashs when audio isn't correctly loaded and its duration is infinity. - 4. Correction of the calculation of `cc.visibleRect`. - 5. Fix `cc.Skin`'s bounding box calculation for canvas rendering. - 6. Fix an issue that `cc.TextureCache` doesn't handle loaded texture in some case. - 7. Fix an issue that texture rect could be zero sized in `initWithFile` function of `cc.Sprite`. - 8. Fix a bug on inverted ClippingNode with DrawNode as stencil in Canvas render mode. - 9. Fix a bug that `cc.SpriteFrame` didn't support initialization with texture name parameter. - 10. Fix a bug on `ccs.ArmatureAnimation`'s loop parameter. - 11. Fix a bug that `cc.JumpTo`'s `_delta` position calculation is incorrect. - 12. Fix a bug of `cc._audioLoader` that it doesn't work when it failed to load an audio file. - -Cocos2d-html5-v3.0 beta @ May.23, 2014 - -* Refactored actions to make it more friendly and easy-to-use. -* Integrated Spine skeleton animation feature. -* Renamed constants of ProgressTimer, Scale9Sprite, TMXLayerInfo, Node, ParticleSystem for maintainability. -* Modified mouseMove event behavior of cc.inputManager to compatible with Cocos2d-x -* Modified cc.game.run to receive a canvas id as parameter. -* Added local audio file playing from 'file://' origin. -* Added local images file displaying from 'file://' origin. -* Refactored cc.TMXLayer's setTileAt etc functions to support point or x,y as their parameters. -* Added a check to cc.Sprite and cc.SpriteFrame to avoid its texture rect out of bounds. -* Added a check to cc.SpriteFrame to avoid cc.loader release invalid sprite frame file. -* Made cc.Touch return copies of point. -* Made the default of cc.Color alpha value is 255 to avoid cc.Sprite's setColor is invalid. -* Optimized cc.Node.sortAllChildren for better performance. -* Added warning of cc.Texture2D if it has an invalid texture. - -* Bugs fix: - 1. Fixed a bug of cc.winSize that it returns incorrect value when using setDesignResolution. - 2. Added a check to cc._setup to avoid double invocation. - 3. Fixed a bug of cc.TMXMapInfo that its tile's property id is incorrect. - 4. Fixed a bug of cc.Scale9Sprite that its CascadeColor and CascadeOpacity are invalid. - 5. Fixed a bug of ccs.UILoadingBar which its barRendererScaleChangedWithSize is incorrect. - 6. Added some forgotten files to build.xml for minimize core. - 7. Corrected a mistake of renderMode default value in CCBoot.js. - 8. Fixed a bug of ccui.Layout's draw function that its scaleX, scaleY value is incorrect. - 9. Fixed a bug of cc.Audio's stopMusic function. - 10. Fixed a bug of TextureCache that it can't remove image's event handler. - 11. Fixed ClippingNode's DrawNode stencil bug on Canvas. - 12. Fixed a typo 'cc.radiansToDegress' function to 'cc.radiansToDegrees'. - 13. Fixed a bug of ccui.ImageView that its setSize is invalid when the picture without pre-load. - 14. Fixed a bug of cc.ParticleSystem that it throws a error when create from CocosBuilder. - 15. Fixed a bug of cc.LabelAtlas that it can't display its children. - 16. Fixed a bug of cc.fontLoader that it can't load custom font. - 17. Fixed a bug of ccui.Widget that its setOpacity is invalid. - 18. Fixed a bug of cc.Node that it transform value is incorrect when a node skew to a special value. - -Cocos2d-html5-v3.0 alpha2 @ April.14, 2014 - -* Minimized the size of core from 254k to 113k after google closure advanced compiling -* Made cc.DrawNode support some DrawingPrimitive's drawing function on WebGL mode -* Added undefined checking in cc.loader for better performance. -* cc.Sprite supports creating a sprite through external URL. -* Added the warning information to notice developers that their project.json cannot be loaded or parsed. -* Added retina display support to cc.Editbox. -* cc.Node's pauseSchedulerAndActions and resumeSchedulerAndActions are deprecated, please use pause and resume instead. -* Added render mode checking to 3D action classes. -* Added SocketIO -* Sync cc.eventManager to the latest version of Cocos2d-x v3.0 Stable. -* ccui.Layout's doLayout function has been set to private function "_doLayout" -* Made actions extendable directly via ctor -* Added null callback check in cc.textureCache.addImage -* Fixed the API inconsistence of ccs.ArmatureAnimation.play -* Fixed compatibility and performance for ctor -* Renamed all Uppercase functions to lowercase in CCMacro -* Added necessary GL constants in H5 -* Fixed CONSTANTS inconsistence between h5 and JSB - -* Bugs fix: - 1. Fixed ccs.comAttribute API incompatible issue - 2. Fixed a bug of Cocostudio's data reader that getting isTween value is incorrect when the attribute value is false. - 3. Fixed a bug of Sprite that it doesn't work when its texture doesn't preload and its parent is a SpriteBatchNode - 4. Fixed a bug in CCBoot.js that console.error is invalid on firefox. - 5. Fixed some comment errors of framework. - 6. Fixed a bug of cc.LabelBMFont that it's multiline works incorrectly. - 7. Fixed a bug that Touches event doesn't work in release mode on IE browser. - 8. Fixed a bug that cc.winSize has not been reset after cc.view.setDesignResolutionSize. - 9. Fixed typo in ccui.Widget.TOUCH_BEGAN - 10. Fixed a bug of cc.MenuItemSprite.create that - 11. Fixed a bug of cc.loader that it need to set value before call the callback. - 12. Fixed a bug of cc.log that it doesn't work in IE9 - 13. Fixed IE incompatible issue with __lookupGetter__ - 14. Fixed a mistake of cc.Node that it return a reference of _position in getPosition - 15. Fixed a bug of cc.ClippingNode that its _super is undefined - 16. Fixed a bug of inputManager's touch event in IE browser - -* Known Issues: - 1. EventListener is not extendable. - - -Cocos2d-html5-v3.0 alpha @ March.15, 2014 - -* Refactor some properties of all rendering classes with getter setter for providing javascript user friendly APIs. -* Provide `attr` function for cc.Node and its descendants to permit modify multiple properties at the same time with a key-value object. -* Refactor foundational data structures for better maintainability. -* Add event manager to cocos2d-html5, all events are dispatched via cc.eventManager to event listener. -* Refactor cc.Application to cc.game. -* Refactor singleton Classes to javascript object. -* Refactor all createWithXXX functions into unified create function with different parameters. -* Use `moduleConfig.json` to config the paths of engine scripts. -* `cocos2d.js` is replaced with `project.json`. -* Refactoring cc.loader. -* CocoStudio GUI updated to 3.0, and ccs prefix of UI widgets have been changed to ccui. -* CocoStudio v1.3.0 has been supported in v3.0. -* richText has been supported in v3.0. -* Use `cc.BuilderReader.registerController` to register controller of ccb. -* Add `cc.path` to handle operations of file path. -* Add `cc.async` to handle async operations. -* Add cc.NodeGrid in v3.0. -* Replace `replaceWithScene` and `runWithScene` with `runScene`. -* move sys.xxx to cc.sys.xxx. -* Refactor CCEGLView.js for better maintainability. -* Refactor scheduler.js for better maintainability. -* Remove arguments.callee which is forbidden in ECMAScript strict mode. -* Refactor Array clean function for better performance. -* Refactor some functions about array operation. -* Refactor FadeIn/FadeOut to fix a bug that it always start from/to 255. -* Rewrite functions in CCNS.js with regex. -* Move CCFormatHelper and CCNS content into CCCommon.js. -* Refactor cc.Screen to support all browsers. -* Add retina display support for Apple devices to cc.view. -* Add "allLayers" function to cc.TMXTiledMap. -* Make cc.p and cc.size support two types of parameters. -* cc.DrawNode supports all functions of cc.DrawingPrimitive on Canvas mode. -* WebAudioEngine is supported on iOS now. -* Use event on cc.canvas to make full screen. -* Add a browser white list that support multiple audio playback at the same time. -* Removed in/hasOwnProperty usage in engine for better performance. -* Refactoring CCCommon.js, delete some unused functions, rename some functions for better maintainability. -* Add analytics plugin protocol ,Flurry plugin and ProtocolAds.js plugin protocol. -* Arguments length check replaced by undefined check for better performance. -* Fix legacy Function.prototype.bind support. - -* Bugs fix: - 1. Avoid CCLabelTTF enter in infinite loop while character's width larger than the dimension width - 2. Add jsDoc Flags to cc.NodeRGBA and cc.LayerRGBA - 3. Fixed a bug that Schedule doesn't restart when widget is re-added after being removed - 4. Correction of split logic in CCLabelTTF - 5. Fixed a bug that armature animation does not display correctly on canvas mode - 6. Correct gui widget clone functions - 7. Fixed a bug of cc.SpriteFrameCache that filePath is needed in `loadedFileNames` - 8. Add a condition check to avoid texture out of range bug - 9. Fixed a bug of cc.Editbox that its position is incorrect when its parent node isn't root node. - 10. Fixed a SimpleAudioEngine's state error. - 11. Fixed a bug of cc.TMXTileMap that its `_tileProperties` should be a dictionary object - 12. Fixed a bug of cc.DrawNode that it need to deep-copy verts in `drawPoly` - 13. Fixed a bug of UILabelBMFont that variable `_strStringValue` should be `_stringValue` - 14. Fixed a bug in SceneReader's `setPropertyFromJsonDict` function - 15. Fixed a bug when margin not set in ccs.Margin - 16. Fixed a bug of cc.TMXLayer that its `removeChild` works incorrectly. - -* Known Issues: - -Cocos2d-html5-v2.2.2 @ Dec.31, 2013 -* Resolution policy now act as a combination of cc.ContainerStrategy and cc.ContentStrategy so that user can beautifully customize its behavior. -* cc.LabelTTF's now support perfectly automatic line break with occidental and Chinese characters. -* cc.ClippingNode for canvas render mode is implemented. -* Refactored cc.Node and cc.Sprite by adding cc._PointConst and cc._SizeConst for better Performance. Now the performance of setPosition and getPosition is faster 65% than before. -* CCNode's setContentSize and setAnchorPoint support two types of parameters, more friendly and more efficient. setAnchorPoint(x,y) is faster 35% than setAnchorPoint(cc.p(x,y)). -* Added NPM support and adjusted folder structure. It supports modules customization, the mini HelloWorld is just 185KB when package all files into single file.Please visit NPM Guide for more details. -* Added SpriteFrameCache JSON format support. -* Added source map generating of Closure Compiler advance mode , please make sure your JDK version is 7.0 and up. -* Improved audio compatibility for mobile browser, added playing queue to solve the one audio restriction of some mobile browser. -* Refactoring TMXLayer for better performance. -* set cc.Rect's origin and size from public to private for compatibility with JSB. -* CocoStudio supports async image loading. -* cc.log supports printing object content to console -* Refactoring indexing of actionManager and Scheduler for better performance. -* ClippingNode supports some features on Canvas Mode. -* Migrated Armature to v2.2.2. -* Add callback function to CocoStudio action completion and refactoring it for better performance. -* CCBReader supports that CCControl can send action by all types of event. -* Add create function to cc.NodeRGBA -* Add jsdoc document to CocoStudio classes - -* Bugs fix: - 1. Fixed a bug of TMXLayer that it has thin lines at tile's border when EGLView's scale doesn't equal 1. - 2. Fixed bugs of LabelBMFont about updateDisplayedOpacity and multi-line is incorrect. - 3. Fixed a bug of LabelTTF that enter an infinite loop when setting special string and fontSize to it. - 4. Fixed a bug of NodeRGBA and LayerRGBA about updateDisplayedColor and updateDisplayedOpacity. - 5. Fixed a bug of ProgressTimer that it can't change color and opacity when calling setColor and setOpacity directly. - 6. Fixed a bug of cc.ProgressTimer that it has a blink when its reverseDirection equals false and type equals cc.PROGRESS_TIMER_TYPE_RADIAL. - 7. Some Loaders need modify their default value to adapt CocosBuilder that CocosBuilder ignores some two properties object like cc.Point when all the properties equals to zero. - 8. Fixed a bug of Fixed a bug of TMXTileMap that its getProperty doesn't work. - 9. Fixed a bug of ActionInterval that it throws error when its target doesn't have RGBAProtocol property. - 10. Fixed a bug of MenuItemSprite that it throws an error when create a MenuItemSprite object with cc.Node. - 11. Fixed a bug of UIWidget that its container intercept touch event while they can't. - 12. Fixed a bug of ccs.UILayout about relative positioning. - 13. Fixed a bug of Armature that its nodeToParentTransformCanvas correct. - -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. ClipNodeTest effects varies in different browsers - 3. Stencil of cc.ClippingNode doesn't work well with WEBGL render mode, the stencil have the right size and shape but it masks the content with a monochrome mask. - -Cocos2d-html5-v2.2.1 @ Nov.19, 2013 -* CocoStudio is now supported on Cocos2d-html5. The GUI, scene and component modules have been added to it. -* cc.EGLView and most render classes have been re-written to adapt multiple resolution resources in-order to optimize performance on mobile browsers. -* Refactored cc.LabelTTF, now its contentSize and position is correct for labels which has defined stroke and shadow. -* Corrected the behavior of "CascadeColorEnabled" and "CascadeOpacityEnabled" for cc.NodeRGBA and cc.LayerRGBA. -* All cc.Assert has being replaced, and more arguments checking and log information have added to engine's function. -* Added cc.Screen to engine, it uses to enter/exit FullScreen mode. -* Added cc.VisibleRect to engine, it provides nine points of game view for positioning. -* cc.WebAudioEngine now works perfectly on chrome. -* CocoStudio's namespace changes to 'ccs' now, and the other module's namespace will be renamed and support NPM in next version. -* cc.rect now accepts more types of parameters on JSB and HTML5 now, for example: cc.rect(1,1,1,1) and cc.rect(aRect), and cc.rect(cc.p(1,1),cc.size(10,10)); -* Optimized cc.Node's getBoundingBoxToWorld for better Performance. -* Modified the _sequenceCompleted method in CCBAnimation, it can set the next sequence in callback now. -* Improved the maintainability for _drawSceneForWebGL and _drawSceneForCanvas. -* ParticleExamples has been refactored for JSB. -* HelloHTML5World's CircleSprite has been removed, because it doesn't work on JSB. - -* Bugs fix: - 1. Fixed a Scale9Sprite's bug that setCapInsets is invalid. - 2. Fixed a bug that prevents the game to run on Chrome 31 WebGL mode. - 3. Fixed a bug of LabelTTF that doesn't work on Baidu browser. - 4. Fixed a bug of Sprite that it shouldn't to set transform dirty when setting color or opacity. - 5. Fixed a bug that cc.EditBox's setFontSize is invalid. - 6. Fixed a bug that Particles doesn't work when search path in FileUtils was set. - 7. Fixed a bug of Scale9Sprite that it throws an error when _scale9Image is null. - 8. Fixed a bug of LayerGradient that it shows wrong size when setting content size. - 9. It should listen to the method "onLoad" in cc.FileUtils when the browser isn't IE. - -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. ClipNodeTest effects varies in different browsers - -Cocos2d-html5-v2.2 @ Sep.19, 2013 -* Improved Sprite, Node, LabelTTF class define from separated code to combined code for maintainability, now it is clean and clear -* added a new sample game "Fruit attack" which works great on PC browsers, mobile browsers, and can even be run natively as an android and iOS app with JSB -* cc.Sprite and its subClasses's texture has been replaced from DOM element to cc.Texture2D on Canvas mode -* Improved cc.Texture2d for direct using without pre-loading image resources, you don't need to wait resources loading when create a new scene or layers -* Migrated CCBReader and GUI to Cocos2d-x 2.1.4 -* Improved update function of Action, and avoid using temporary object, it is good for GC and performance -* Modified LabelTTF's rendering from direct drawing to pre-rendering for performance, 100% faster than before on mobile browser -* Fixed APIs of HTML5 according to JSB for compatibility, e.g. cc.ParticleSystemQuad has merged into cc.ParticleSystem, please check it on upgrade guide v2.1.5 to v2.2(http://www.cocos2d-x.org/wiki/Upgrade_Guide_from_Cocos2d-html5_v215_to_v22) -* Added Hiding url address bar for mobile browser, please check the template and hello world -* Re-writed Canvas Mode of RenderTexture to adapt WebGL interface -* Added frame event, collider and blend type supporting for Armature. Now Armature supports two tools:1.CocoStudio(windows,http://www.cocostudio.org),2.DragonBones(flash, https://github.com/2youyouo2/SkeletonAnimationDesignPanel) -* Set auto render mode default value to canvas in mobile browsers and WebGL in desktop browsers - -* Bug fix: -1. Fixed cc.Sprite's displayFrame returns wrong value on Canvas mode. -2. Fixed cc.LabelBMFont is very slow when calling setString -3. Fixed a bug of CCBReader that cc.ControlButton doesn't work when its controller is _jsControlled -4. Fixed a bug of cc.TextureCache that the status of texture is wrong in callback -5. Fixed a bug of cc.Scale9Sprite that its contentSize is wrong when call setCapInsets -6. Fixed a bug of cc.TableView's that contentSize is wrong when change datasource -7. Fixed a bug of cc.Sprite that its children also follow fliped when it was fliped -8. Fixed cc.Node's nodeToWorldTransform returns wrong value on Canvas Mode -9. Fixed a bug of cc.LayerColor that represent incorrect opacity passed into init method -10. Stop listening and remove the event for HtmlImageElement object onload -11. Fixed cc.ProgressTimer display wrong when its sprite was flipped -12. Fixed some bugs for actions that set their object property through reference when initiating actions. - -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. ClipNodeTest effects varies in different browsers - -Cocos2d-html5-v2.1.5 @ July.24, 2013 -* Ported engine API to keep the same as Cocos2d-x v2.1.4 API -* Optimized John Resig's inheritance pattern (cc.Class.extend) with advanced property initialization. -* Implemented the rest of extensions features according to Cocos2d-x v2.1.4 -* Integrated Armature module -* Rewrote CCGrid, CCMotionStreak , CCProgressTimer with TypeArray -* Optimized performance for actions -* Optimized performance for MoonWarriors and CocosDragonJS - -* Bug fix: - 1. Fixed cc.EditBox Dom Element position issue when EGLView is set - 2. Fixed cc.EGLView adjustSize bug - 3. Fixed the bug of cc.ParticleBatchNode that it doesn't hide particles after particle life has expired when calling stopSystem() - 4. Fixed a bug that LabelTTF dimension behavior doesn't support height=0 - 5. Fixed line height for multiline LabelTTF and overlapping pixels in Scale9Sprite on Canvas browsers - 6. Fixed a bug of cc.SimpleAudioEngine that unloading effect doesn't work -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. ClipNodeTest effects varies in different browsers - 3. nodeToParentTransform in cc.Node returns wrong value on Canvas mode - -Cocos2d-html5-v2.1.4 @ Jun.12, 2013 -* Added support for multiple resources loading. This mechanic is the same as cocos2d-x now -* Optimised "Performance Tests -> Sprites Test", and increased its benchmark to 220%! -* Migrated audio (CocosDenshion) API to keep the same as Cocos2d JS API -* Added auto test for NodeTests and TilemapTests -* Changed CCTextureCache member functions such as addImage(path), addImageAysnc(path), removeTextureForKey(key) from using relative path to absolute path -* Added support for particle batch node - -* Bug fix: - 1. Fixed preLoading issue on iOS 5.1.1 - 2. Fixed cc.Menu / cc.MenuItemImage remaining touchable issue after replaceScene - 3. Fixed Box2d and chipmunk path error for single engine file mode - 4. Fixed cc.EditBox Dom Element position issue when cc.EditBox skewed - 5. Fixed cc.ScrollView position issue when it's parent node moved - 6. Fixed cc.TouchDispatcher can't touch issue when WebPage has been scrolled on Firefox or IE -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. ClipNodeTest effects varies in different browsers - -Cocos2d-html5-v2.1.3 @ May.1, 2013 -* CCEditbox now implemented for WebGL and JSB -* Updated CCBReader to latest version -* Performance optimization on Firefox 20% -* Added render mode flag to switch between WebGL and canvas2d -* Added support for Tizen -* Now able to load embedded texture file in a plist -* EGLView now works if canvas is placed inside another DOM element -* Added a Simulator which can be found in MoonWarriors Directory - -* Bug fix: - 1. Preloading on some mobile browsers - 2. CCLoader for WebGL - 3. ccNode memory leak -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. Particle System has some weird behavior when load from CCBReader - 3. RenderTextureTest RenderTextureIssue937 & Issue1464 doesn't work properly - 4. ClipNodeTest effects varies in different browsers - - -Cocos2d-html5-v2.1.2-beta @ Mar.20, 2013 -* WebGL rendering mode implemented - blazing fast on supported browsers -* Added many WegGL test to testbed -* cc.Loader now supports multiple stage preloading - all tests now preload by multi resource groups -* Now warns the user if their browser does not support html5 -* cc.Node now uses transform matrix - better performance -* Accelerometer implemented - Also works on Javascript binding (JSB) for Cocos2d-x & Cocos2d-iPhone -* Supports MP4 and M4a Audio format now -* Designer resolution for multi resolution support - Also works on Javascript binding for Cocos2d-x -* Faster Particle - thanks to Ivo Wetzel -* Bug fixes: - 1. File utility fixed - 2. Audio support bug fixed - 3. Removed some trailing coma which prevents blocks closure compiler - 4. Local storage bug fixed - 5. cc.MenuItemImage and cc.MenuItemToggle bugs fixed - 6. Fixed compatibility with some UIWebView - 7. Fixed rounding errors on ease actions -* Known Issues: - 1. Effect Advanced Lens3D doesn't work - 2. particle system can't load texture from plist - 3. EditBox doesn't work on WebGL mode - 4. Particle System has some weird behavior when load from CCBReader - 5. RenderTextureTest RenderTextureIssue937 & Issue1464 doesn't work properly - 6. ClipNodeTest effects varies in different browsers - -Cocos2d-html5-v2.1.1 @ Jan.28, 2013 -* Fixed bugs -* Added mouse button to MouseDispatcher, supports right-click -* Changed preload audio type from "bgm" and "effect" to "sound" -* Added "Sys" class for system capabilities -* Improved cc.BuilderReader to support .ccbi extension auto-completion -* Improved TMXXMLParser to support XML, CSV and zlib compression -* Changed cc.Time.gettimeofdayCocos2d to Date.now which is more javascript friendly. -* Added support for stackable actions - -Cocos2d-html5-v2.1.0 @ Dec.4, 2012 -* Improved cc.Class and add Release Mode -* All tests and games can now be run on Cocos2d-html5, Cocos2d-iPhone and Cocos2d-x -* Added support for google.base -* Added support for CocosBuilder and Bone Animation -* Updated API for Javascript Binding -* Integrated Chipmunk physical engine and chipmunk tests -* Added physicsDebugNode, physicsSprite, drawNode -* Built cocos2d-js-tests repo for tests -* Fixed support for mouse/touch/keyboard -* Fixed bugs -* Added WaterMelon with me and CocosDragon games for sample -* Added Edit Box for input - -Cocos2d-html5-v2.0.0 @ Aug.28, 2012 -* Updated API to Cocos2d-x V2.0 -* Updated template and directory name -* Improved JS files loader -* Added support for Dom rendering -* Updated JSDoc comments and shell -* Added TileMap property process and flip -* Improved BMFont -* Added Actions spline paths and cc.AnimationFrame -* Added support for multi-touch -* Added mini-framework for Dom manipulation -* Changed cc.Animation, cc.AudioEngine, cc.LableTTF and cc.Sprite API - - -Cocos2d-html5-v0.5.0-alpha2 @ Jun.18, 2012 -* Changed API, use "create" to construct all objects -* Fixed naming of variables -* Added JSDoc comments and shell -* Fixed Dom Menu flicker bug -* Changed code for closure compiler Advance optional -* Added version control - -Cocos2d-html5-v0.5.0-alpha @ May.28, 2012 -* supports canvas and Dom Menu -* part of test cases were added and tested in chrome -* porting from cocos2d-x is not finished -* files must load from http server - -Cocos2d-html5-v0.1.0 @ Jan.29, 2012 -* Build the directory structure of Engine -* cocos2d-html5 first version -* more details: http://www.cocos2d-x.org/ - - - - diff --git a/EngineErrorMap.md b/EngineErrorMap.md index 38b97f6e37e..46162067f52 100644 --- a/EngineErrorMap.md +++ b/EngineErrorMap.md @@ -1838,6 +1838,7 @@ We don't currently support conversion of \`CubicSplineQuatValue\`. Instancing/Batching enabled for non-baked skinning model '%s', this may result in unexpected rendering artifacts. Consider turning it off in the material if you do not intend to do this. ### 3937 + Previous error occurred when instantiating animation clip %s on node %s. ### 3938 @@ -1938,6 +1939,10 @@ Can not add a page without UITransform. Can not set the scroll view content when it hasn't UITransform or its parent hasn't UITransform. +### 4303 + +The %s scrollBar on the '%s' node is not available, please check it. + ### 4400 Invalid RichText img tag! The sprite frame name can't be found in the ImageAtlas! @@ -3206,6 +3211,14 @@ GeometryRenderer: too many lines. GeometryRenderer: too many triangles. +### 12010 + +PassUtils: illegal uniform handle, accessing uniform at offset %d + +### 12011 + +Pass: setUniform is invoked with incompatible uniform data type for binding %d, expected type is %s + ### 12100 The font size is too big to be fitted into texture atlas. Please switch to other label cache modes or choose a smaller font size. @@ -3314,4 +3327,8 @@ The asset replacing failed, can not found override asset('%s') for '%s' ### 16301 -node '%s' doesn't have any ModelRenderer component, this component will not work. please add ModelRenderer component first \ No newline at end of file +node '%s' doesn't have any ModelRenderer component, this component will not work. please add ModelRenderer component first + +### 16302 + +There is no reflection probe in the scene or no probe is near the current object. No reflection probe will take effect on this object. Please create a new reflection probe or move existing ones closer. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000000..bc24fb9700a --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +MIT License + +Copyright (c) 2013-2016 Chukong Technologies Inc. +Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. + +http://www.cocos.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 694ce7f32e3..4bcfc70986c 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,6 @@ forks - - version - license @@ -31,7 +27,7 @@ **Cocos Creator is the new generation of game development tool in Cocos family, it brings a complete set of 3D and 2D features while providing an intuitive, low cost and collaboration friendly workflow to game developers.** Cocos Engine is the runtime framework for Cocos Creator editor. -![image](https://www.cocos.com/wp-content/uploads/2022/08/13f41f1c975e8255fdc06f59597b9546-7.png) +![image](./ui.png) Cocos Creator inherited many good qualities and cool features from its previous versions, such as high performance low level C++ implementation, intuitive editor, cross-platform support. It supports native platforms, web platforms and rapidly expanding instant gaming platforms, including Windows, Mac, iOS, Android, HarmonyOS, Web, Facebook Instant Games, WeChat Mini Game and TikTok Mini Games. diff --git a/cc.config.json b/cc.config.json index 55852cf3b4a..2d88b38337a 100644 --- a/cc.config.json +++ b/cc.config.json @@ -5,7 +5,6 @@ "base": { "modules": ["base"], "dependentAssets": [ - "ff9be190-20a4-4e48-b68c-76e3c7cff085", "970b0598-bcb0-4714-91fb-2e81440dccd8", "bcd64cc6-2dd9-43f6-abbe-66318d332032", "d930590d-bb92-4cc8-8bd1-23cd027f9edf", @@ -19,6 +18,9 @@ "gfx-webgl2": { "modules": ["gfx-webgl2"] }, + "gfx-empty": { + "modules": ["gfx-empty"] + }, "3d": { "modules": ["3d"], "dependentAssets": [ @@ -27,7 +29,8 @@ "5d45aa00-e064-4938-b314-4265f0c2258c", "28d6d6b8-3f66-4a73-9795-17a0852ba2d4", "ec8106fe-05bf-4e94-943c-e0d3b7bb5e45", - "620b6bf3-0369-4560-837f-2a2c00b73c26" + "620b6bf3-0369-4560-837f-2a2c00b73c26", + "2df0a40b-26c2-47ce-be0d-4d3cd4164737" ] }, "animation": { @@ -121,6 +124,7 @@ "debug-renderer": { "modules": [], "dependentAssets": [ + "ff9be190-20a4-4e48-b68c-76e3c7cff085", "0835f102-5471-47a3-9a76-01c07ac9cdb2", "b5475517-23b9-4873-bc1a-968d96616081", "0ed97c56-390e-4dd1-96b7-e7f2d93a98ed", @@ -133,6 +137,12 @@ "video": { "modules": ["video"] }, + "xr": { + "modules": ["xr"] + }, + "light-probe": { + "modules": [ "light-probe" ] + }, "terrain": { "modules": ["terrain"], "dependentAssets": ["1d08ef62-a503-4ce2-8b9a-46c90873f7d3"] @@ -157,6 +167,10 @@ }, "dragon-bones": { "modules": ["dragon-bones"], + "dependentAssets":[ + "c27215d8-6835-4b68-bfbb-bdeac6100c04", + "b5d6115f-0370-4d7c-aad3-c194cc71cf98" + ], "dependentModules": ["2d"] }, "marionette": { @@ -165,15 +179,16 @@ "MARIONETTE": true } }, - "xr": { - "modules": ["xr"] - }, - "ar": { - "modules": ["ar"], - "dependentModules": ["xr"] - }, "custom-pipeline": { "modules": ["custom-pipeline"] + }, + "websocket": { + "modules": [], + "isNativeOnly": true + }, + "websocket-server": { + "modules": [], + "isNativeOnly": true } }, "moduleOverrides": [{ @@ -201,6 +216,7 @@ "overrides": { "cocos/rendering/index.ts": "cocos/rendering/index.jsb.ts", "cocos/rendering/render-pipeline.ts": "cocos/rendering/render-pipeline.jsb.ts", + "cocos/rendering/render-stage.ts": "cocos/rendering/render-stage.jsb.ts", "cocos/rendering/geometry-renderer.ts": "cocos/rendering/geometry-renderer.jsb.ts", "cocos/rendering/custom/index.ts": "cocos/rendering/custom/index.jsb.ts", "cocos/render-scene/core/native-pools.ts": "cocos/render-scene/core/native-pools.jsb.ts", @@ -214,6 +230,7 @@ "cocos/render-scene/core/render-scene.ts": "cocos/render-scene/core/render-scene.jsb.ts", "cocos/render-scene/scene/submodel.ts": "cocos/render-scene/scene/submodel.jsb.ts", "cocos/render-scene/scene/index.ts": "cocos/render-scene/scene/index.jsb.ts", + "cocos/render-scene/scene/reflection-probe.ts": "cocos/render-scene/scene/reflection-probe.jsb.ts", "cocos/2d/renderer/native-2d.ts": "cocos/2d/renderer/native-2d.jsb.ts", "cocos/gfx/base/pipeline-state.ts": "cocos/gfx/base/pipeline-state.jsb.ts", "cocos/gfx/index.ts": "cocos/gfx/index.jsb.ts", @@ -245,14 +262,16 @@ "cocos/3d/models/morph-model.ts": "cocos/3d/models/morph-model.jsb.ts", "cocos/3d/models/skinning-model.ts": "cocos/3d/models/skinning-model.jsb.ts", "cocos/3d/models/baked-skinning-model.ts": "cocos/3d/models/baked-skinning-model.jsb.ts", - "cocos/3d/misc/create-mesh.ts": "cocos/3d/misc/create-mesh.jsb.ts" + "cocos/3d/misc/create-mesh.ts": "cocos/3d/misc/create-mesh.jsb.ts", + "cocos/gi/light-probe/light-probe.ts": "cocos/gi/light-probe/light-probe.jsb.ts", + "cocos/gi/light-probe/delaunay.ts": "cocos/gi/light-probe/delaunay.jsb.ts" } }, { "test": "context.buildTimeConstants && context.buildTimeConstants.WEBGPU", "isVirtualModule": false, "overrides": { - "cocos/core/gfx/index.ts": "cocos/core/gfx/index.ems.ts" + "cocos/gfx/index.ts": "cocos/gfx/index.ems.ts" } }, { @@ -372,6 +391,12 @@ "ccGlobal": true, "internal": false }, + "TAOBAO": { + "comment": "Running in the taobao creative app.", + "type": "boolean", + "value": false, + "internal": false + }, "BYTEDANCE": { "comment": "Running in the ByteDance's mini game.", "type": "boolean", @@ -481,7 +506,7 @@ "MINIGAME": { "comment": "Running in mini game.", "type": "boolean", - "value": "$WECHAT || $BAIDU || $XIAOMI || $ALIPAY || $BYTEDANCE", + "value": "$WECHAT || $BAIDU || $XIAOMI || $ALIPAY || $TAOBAO || $BYTEDANCE", "ccGlobal": true, "internal": false }, @@ -524,18 +549,22 @@ "type": "boolean", "value": false, "internal": true - }, - "XR_ENV": { - "comment": "Running in environment where using XR.\n- 0 CLOSE\n- 1 XR\n- 2 WEB_XR", - "type": "number", - "value": 0, - "internal": false - }, - "XR_TYPE": { - "comment": "Different types in the XR environment.\n- 0 OFF\n- 1 VR\n- 2 AR", - "type": "number", - "value": 0, - "internal": false } + }, + + "optimizeDecorators": { + "fieldDecorators": [ + "property", "serializable", "formerlySerializedAs", "editorOnly", "uniquelyReferenced", + "type", "override", "executeInEditMode", "menu", "playOnFocus", "inspector", "icon", "help", + "editable", "visible", "readOnly", "displayName", "tooltip", "group", "range", "rangeMin", + "rangeMax", "rangeStep", "slide", "displayOrder", "unit", "radian", "multiline", "disallowAnimation", + "requireComponent", "executionOrder", "disallowMultiple", "allowReplicated", "ccclass" + ], + + "editorDecorators": [ + "executeInEditMode", "menu", "playOnFocus", "inspector", "icon", "help", "editable", "visible", + "readOnly", "displayName", "tooltip", "group", "range", "rangeMin", "rangeMax", "rangeStep", "slide", + "displayOrder", "unit", "radian", "multiline", "disallowAnimation" + ] } } diff --git a/cc.config.schema.json b/cc.config.schema.json index 2446166f914..6a1d2d194ac 100644 --- a/cc.config.schema.json +++ b/cc.config.schema.json @@ -52,12 +52,17 @@ "type": "object" }, "type": "array" + }, + "optimizeDecorators": { + "$ref": "#/definitions/IOptimizeDecorators", + "description": "The decorators to be optimize when build engine." } }, "required": [ "features", "includes", - "constants" + "constants", + "optimizeDecorators" ], "type": "object" }, @@ -72,11 +77,30 @@ "additionalProperties": false, "description": "An engine feature.", "properties": { + "dependentAssets": { + "description": "List of uuid that the feature depend on.", + "items": { + "type": "string" + }, + "type": "array" + }, + "dependentModules": { + "description": "List of module that the feature depend on.", + "items": { + "type": "string" + }, + "type": "array" + }, "intrinsicFlags": { "additionalProperties": {}, "description": "Flags to set when this feature is enabled.", "type": "object" }, + "isNativeOnly": { + "default": false, + "description": "Whether it is a native only feature, default is false.", + "type": "boolean" + }, "modules": { "description": "Modules to be included in this feature in their IDs. The ID of a module is its relative path(no extension) under /exports/.", "items": { @@ -138,6 +162,30 @@ ], "type": "object" }, + "IOptimizeDecorators": { + "additionalProperties": false, + "properties": { + "editorDecorators": { + "description": "The decorators which should be removed directly when they only work in Cocos Creator editor.", + "items": { + "type": "string" + }, + "type": "array" + }, + "fieldDecorators": { + "description": "The decorators which should be optimized when they only decorate class fields.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "fieldDecorators", + "editorDecorators" + ], + "type": "object" + }, "IndexConfig": { "additionalProperties": false, "properties": { diff --git a/cocos/2d/assembler/graphics/helper.ts b/cocos/2d/assembler/graphics/helper.ts index 076bb7d43aa..cfa60109431 100644 --- a/cocos/2d/assembler/graphics/helper.ts +++ b/cocos/2d/assembler/graphics/helper.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/2d/assembler/graphics/index.ts b/cocos/2d/assembler/graphics/index.ts index 8777cbc63a1..069e7b975b8 100644 --- a/cocos/2d/assembler/graphics/index.ts +++ b/cocos/2d/assembler/graphics/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/2d/assembler/graphics/types.ts b/cocos/2d/assembler/graphics/types.ts index 5028c19c04b..1ade132c5b5 100644 --- a/cocos/2d/assembler/graphics/types.ts +++ b/cocos/2d/assembler/graphics/types.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,7 +23,7 @@ THE SOFTWARE. */ -import { ccenum } from '../../../core/value-types/enum'; +import { ccenum } from '../../../core'; /** * @en Enum for LineCap. diff --git a/cocos/2d/assembler/graphics/webgl/earcut.ts b/cocos/2d/assembler/graphics/webgl/earcut.ts index b1a68828778..bb865e70559 100644 --- a/cocos/2d/assembler/graphics/webgl/earcut.ts +++ b/cocos/2d/assembler/graphics/webgl/earcut.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -36,8 +35,7 @@ class Aim { public next: Aim | null = null; // z-order curve value - // public z = null; - public z = 0; + public z: number = null as any; // previous and next nodes in z-order public prevZ: Aim | null = null; diff --git a/cocos/2d/assembler/graphics/webgl/graphics-assembler.ts b/cocos/2d/assembler/graphics/webgl/graphics-assembler.ts index a397147dac4..24795ee5c0b 100644 --- a/cocos/2d/assembler/graphics/webgl/graphics-assembler.ts +++ b/cocos/2d/assembler/graphics/webgl/graphics-assembler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ import { JSB } from 'internal:constants'; -import { Color, Vec3 } from '../../../../core/math'; +import { Color, Vec3 } from '../../../../core'; import { IAssembler } from '../../../renderer/base'; import { MeshRenderData } from '../../../renderer/render-data'; import { IBatcher } from '../../../renderer/i-batcher'; diff --git a/cocos/2d/assembler/graphics/webgl/impl.ts b/cocos/2d/assembler/graphics/webgl/impl.ts index 3e171534c59..d04c2b50526 100644 --- a/cocos/2d/assembler/graphics/webgl/impl.ts +++ b/cocos/2d/assembler/graphics/webgl/impl.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { JSB } from 'internal:constants'; -import { Color, Vec2 } from '../../../../core/math'; +import { Color, Vec2 } from '../../../../core'; import { Graphics } from '../../../components'; import { MeshRenderData } from '../../../renderer/render-data'; import { RenderDrawInfoType } from '../../../renderer/render-draw-info'; diff --git a/cocos/2d/assembler/graphics/webgl/index.ts b/cocos/2d/assembler/graphics/webgl/index.ts index 73f4a19c222..1a060e49757 100644 --- a/cocos/2d/assembler/graphics/webgl/index.ts +++ b/cocos/2d/assembler/graphics/webgl/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,8 +27,6 @@ import { IAssemblerManager } from '../../../renderer/base'; import { Graphics } from '../../../components'; import { graphicsAssembler as graphics } from './graphics-assembler'; -export { earcut } from './earcut'; - const graphicsAssemblerManager: IAssemblerManager = { getAssembler (sprite: UIRenderer) { return graphics; diff --git a/cocos/2d/assembler/index.ts b/cocos/2d/assembler/index.ts index 13d45196c74..6cabce4a673 100644 --- a/cocos/2d/assembler/index.ts +++ b/cocos/2d/assembler/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/2d/assembler/label/bmfont.ts b/cocos/2d/assembler/label/bmfont.ts index fcfe388d51c..78431f155a0 100644 --- a/cocos/2d/assembler/label/bmfont.ts +++ b/cocos/2d/assembler/label/bmfont.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,8 +23,7 @@ */ import { SpriteFrame } from '../../assets/sprite-frame'; -import * as js from '../../../core/utils/js'; -import { Color, Rect } from '../../../core/math'; +import { Color, Rect, js } from '../../../core'; import { IBatcher } from '../../renderer/i-batcher'; import { Label } from '../../components/label'; import { IAssembler } from '../../renderer/base'; @@ -40,7 +38,9 @@ const tempColor = new Color(255, 255, 255, 255); */ export const bmfont: IAssembler = { createData (comp: Label) { - return comp.requestRenderData(); + const renderData = comp.requestRenderData(); + renderData.resize(0, 0); + return renderData; }, fillBuffers (comp: Label, renderer: IBatcher) { diff --git a/cocos/2d/assembler/label/bmfontUtils.ts b/cocos/2d/assembler/label/bmfontUtils.ts index 17540ccd529..b6b879343a7 100644 --- a/cocos/2d/assembler/label/bmfontUtils.ts +++ b/cocos/2d/assembler/label/bmfontUtils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,10 +23,10 @@ */ import { JSB } from 'internal:constants'; -import { BitmapFont, IConfig, FontLetterDefinition, FontAtlas } from '../../assets/bitmap-font'; +import { IConfig, FontLetterDefinition, FontAtlas } from '../../assets/bitmap-font'; import { SpriteFrame } from '../../assets/sprite-frame'; import { isUnicodeCJK, isUnicodeSpace } from '../../utils/text-utils'; -import { Rect, Size, Vec2 } from '../../../core/math'; +import { Rect, Size, Vec2 } from '../../../core'; import { HorizontalTextAlignment, VerticalTextAlignment, Label, Overflow, CacheMode } from '../../components/label'; import { UITransform } from '../../framework/ui-transform'; import { LetterAtlas, shareLabelInfo } from './font-utils'; diff --git a/cocos/2d/assembler/label/font-utils.ts b/cocos/2d/assembler/label/font-utils.ts index 821123f1ff6..4fa6dae451b 100644 --- a/cocos/2d/assembler/label/font-utils.ts +++ b/cocos/2d/assembler/label/font-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { FontAtlas } from '../../assets/bitmap-font'; -import { Color } from '../../../core/math'; +import { Color, macro, warnID } from '../../../core'; import { ImageAsset, Texture2D } from '../../../asset/assets'; import { PixelFormat } from '../../../asset/assets/asset-enum'; import { BufferTextureCopy } from '../../../gfx'; import { safeMeasureText, BASELINE_RATIO, MIDDLE_RATIO, getBaselineOffset } from '../../utils/text-utils'; import { director, Director } from '../../../game/director'; -import { macro, warnID } from '../../../core'; +import { ccwindow } from '../../../core/global-exports'; export interface ISharedLabelData { canvas: HTMLCanvasElement; @@ -51,7 +50,7 @@ export class CanvasPool { let data = this.pool.pop(); if (!data) { - const canvas = document.createElement('canvas'); + const canvas = ccwindow.document.createElement('canvas'); const context = canvas.getContext('2d'); data = { canvas, @@ -133,7 +132,7 @@ class LetterTexture { constructor (char: string, labelInfo: ILabelInfo) { this.char = char; this.labelInfo = labelInfo; - this.hash = char.charCodeAt(0) + labelInfo.hash; + this.hash = `${char.charCodeAt(0)}${labelInfo.hash}`; } public updateRenderData () { diff --git a/cocos/2d/assembler/label/index.ts b/cocos/2d/assembler/label/index.ts index c466369f85b..7335dc3e4c7 100644 --- a/cocos/2d/assembler/label/index.ts +++ b/cocos/2d/assembler/label/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,7 +26,6 @@ import { BitmapFont } from '../../assets'; import { Label } from '../../components'; import { IAssemblerManager } from '../../renderer/base'; import { bmfont } from './bmfont'; -import { CanvasPool } from './font-utils'; import { letter } from './letter'; import { ttf } from './ttf'; @@ -55,7 +53,6 @@ export { ttf, bmfont, letter, - CanvasPool, }; Label.Assembler = labelAssembler; diff --git a/cocos/2d/assembler/label/letter-font.ts b/cocos/2d/assembler/label/letter-font.ts index 3df91d01021..79ef6b4b3d5 100644 --- a/cocos/2d/assembler/label/letter-font.ts +++ b/cocos/2d/assembler/label/letter-font.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ -import { mixin } from '../../../core/utils/js'; +import { js } from '../../../core'; import { Label, LabelOutline } from '../../components'; import { bmfontUtils } from './bmfontUtils'; import { shareLabelInfo, LetterAtlas, computeHash } from './font-utils'; @@ -34,7 +33,7 @@ const _isBold = false; let _shareAtlas: LetterAtlas | null = null; -export const letterFont = mixin(bmfontUtils, { +export const letterFont = js.mixin(bmfontUtils, { getAssemblerData () { if (!_shareAtlas) { _shareAtlas = new LetterAtlas(_atlasWidth, _atlasHeight); diff --git a/cocos/2d/assembler/label/letter.ts b/cocos/2d/assembler/label/letter.ts index cb1d79b4735..f40029ca058 100644 --- a/cocos/2d/assembler/label/letter.ts +++ b/cocos/2d/assembler/label/letter.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,13 +22,12 @@ THE SOFTWARE. */ -import { addon } from '../../../core/utils/js'; +import { js, Color } from '../../../core'; import { IBatcher } from '../../renderer/i-batcher'; import { Label } from '../../components/label'; import { fillMeshVertices3D } from '../utils'; import { bmfont } from './bmfont'; import { letterFont } from './letter-font'; -import { Color } from '../../../core/math/color'; const tempColor = new Color(255, 255, 255, 255); @@ -39,7 +37,9 @@ const tempColor = new Color(255, 255, 255, 255); */ export const letter = { createData (comp: Label) { - return comp.requestRenderData(); + const renderData = comp.requestRenderData(); + renderData.resize(0, 0); + return renderData; }, fillBuffers (comp: Label, renderer: IBatcher) { @@ -56,4 +56,4 @@ export const letter = { appendQuad: bmfont.appendQuad, }; -addon(letter, letterFont); +js.addon(letter, letterFont); diff --git a/cocos/2d/assembler/label/ttf.ts b/cocos/2d/assembler/label/ttf.ts index 8784886f6d2..f1de2e6fd2b 100644 --- a/cocos/2d/assembler/label/ttf.ts +++ b/cocos/2d/assembler/label/ttf.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,8 +27,7 @@ * @module ui-assembler */ -import * as js from '../../../core/utils/js'; -import { Color } from '../../../core/math'; +import { Color, js } from '../../../core'; import { IBatcher } from '../../renderer/i-batcher'; import { Label } from '../../components/label'; import { IAssembler } from '../../renderer/base'; diff --git a/cocos/2d/assembler/label/ttfUtils.ts b/cocos/2d/assembler/label/ttfUtils.ts index 2d27b82f592..2338f7da12a 100644 --- a/cocos/2d/assembler/label/ttfUtils.ts +++ b/cocos/2d/assembler/label/ttfUtils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,12 +26,10 @@ import { JSB } from 'internal:constants'; import { SpriteFrame } from '../../assets'; import { Texture2D } from '../../../asset/assets'; import { fragmentText, safeMeasureText, getBaselineOffset, BASELINE_RATIO } from '../../utils/text-utils'; -import { Color, Size, Vec2, Rect } from '../../../core/math'; +import { Color, Size, Vec2, Rect, logID, cclegacy } from '../../../core'; import { HorizontalTextAlignment, Label, LabelOutline, VerticalTextAlignment, LabelShadow } from '../../components'; import { ISharedLabelData, LetterRenderTexture } from './font-utils'; -import { logID } from '../../../core/platform/debug'; import { UITransform } from '../../framework/ui-transform'; -import { legacyCC } from '../../../core/global-exports'; import { dynamicAtlasManager } from '../../utils/dynamic-atlas/atlas-manager'; import { BlendFactor } from '../../../gfx'; import { WrapMode } from '../../../asset/assets/asset-enum'; @@ -341,11 +338,11 @@ export const ttfUtils = { if (comp.renderData) { comp.renderData.textureDirty = true; } - if (legacyCC.director.root && legacyCC.director.root.batcher2D) { + if (cclegacy.director.root && cclegacy.director.root.batcher2D) { if (JSB) { - legacyCC.director.root.batcher2D._releaseDescriptorSetCache(tex.getGFXTexture(), tex.getGFXSampler()); + cclegacy.director.root.batcher2D._releaseDescriptorSetCache(tex.getGFXTexture(), tex.getGFXSampler()); } else { - legacyCC.director.root.batcher2D._releaseDescriptorSetCache(tex.getHash()); + cclegacy.director.root.batcher2D._releaseDescriptorSetCache(tex.getHash()); } } } diff --git a/cocos/2d/assembler/sprite/bar-filled.ts b/cocos/2d/assembler/sprite/bar-filled.ts index 88b566464fd..8c9c816e6a5 100644 --- a/cocos/2d/assembler/sprite/bar-filled.ts +++ b/cocos/2d/assembler/sprite/bar-filled.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,12 +22,11 @@ THE SOFTWARE. */ -import { Mat4 } from '../../../core/math'; +import { Mat4, errorID } from '../../../core'; import { IRenderData, RenderData } from '../../renderer/render-data'; import { IBatcher } from '../../renderer/i-batcher'; import { Sprite } from '../../components'; import { IAssembler } from '../../renderer/base'; -import { errorID } from '../../../core/platform/debug'; import { dynamicAtlasManager } from '../../utils/dynamic-atlas/atlas-manager'; import { StaticVBChunk } from '../../renderer/static-vb-accessor'; diff --git a/cocos/2d/assembler/sprite/index.ts b/cocos/2d/assembler/sprite/index.ts index ba2f9b2d0ea..024db3aea74 100644 --- a/cocos/2d/assembler/sprite/index.ts +++ b/cocos/2d/assembler/sprite/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/2d/assembler/sprite/radial-filled.ts b/cocos/2d/assembler/sprite/radial-filled.ts index 340227efbe8..d41dbc35662 100644 --- a/cocos/2d/assembler/sprite/radial-filled.ts +++ b/cocos/2d/assembler/sprite/radial-filled.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,7 +24,7 @@ import { JSB } from 'internal:constants'; import { SpriteFrame } from '../../assets'; -import { Mat4, Vec2 } from '../../../core/math'; +import { Mat4, Vec2 } from '../../../core'; import { IRenderData, RenderData } from '../../renderer/render-data'; import { IBatcher } from '../../renderer/i-batcher'; import { Sprite, UIOpacity } from '../../components'; diff --git a/cocos/2d/assembler/sprite/simple.ts b/cocos/2d/assembler/sprite/simple.ts index 0fb769c9660..10703f267ec 100644 --- a/cocos/2d/assembler/sprite/simple.ts +++ b/cocos/2d/assembler/sprite/simple.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/2d/assembler/sprite/sliced.ts b/cocos/2d/assembler/sprite/sliced.ts index c1a4bef45a8..1019806a5e9 100644 --- a/cocos/2d/assembler/sprite/sliced.ts +++ b/cocos/2d/assembler/sprite/sliced.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ -import { Color, Mat4, Vec3 } from '../../../core/math'; +import { Color, Mat4, Vec3 } from '../../../core'; import { IRenderData, RenderData } from '../../renderer/render-data'; import { IBatcher } from '../../renderer/i-batcher'; import { Sprite } from '../../components'; diff --git a/cocos/2d/assembler/sprite/tiled.ts b/cocos/2d/assembler/sprite/tiled.ts index ddc847da74e..79a961ede69 100644 --- a/cocos/2d/assembler/sprite/tiled.ts +++ b/cocos/2d/assembler/sprite/tiled.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,8 +23,8 @@ */ import { JSB } from 'internal:constants'; -import { IUV, SpriteFrame } from '../../assets'; -import { Mat4, Vec3, Color } from '../../../core/math'; +import { IUV, SpriteFrame } from '../../assets/sprite-frame'; +import { Mat4, Vec3, Color } from '../../../core'; import { IRenderData, RenderData } from '../../renderer/render-data'; import { IBatcher } from '../../renderer/i-batcher'; import { Sprite } from '../../components/sprite'; @@ -35,13 +34,13 @@ import { StaticVBChunk } from '../../renderer/static-vb-accessor'; const m = new Mat4(); -let origin:IUV; -let leftInner:IUV; -let rightInner:IUV; -let rightOuter:IUV; -let bottomInner:IUV; -let topInner:IUV; -let topOuter:IUV; +let origin: IUV; +let leftInner: IUV; +let rightInner: IUV; +let rightOuter: IUV; +let bottomInner: IUV; +let topInner: IUV; +let topOuter: IUV; let tempRenderDataLength = 0; const tempRenderData: IRenderData[] = []; let QUAD_INDICES; @@ -358,8 +357,8 @@ export const tiled: IAssembler = { let coefV = 0; const hRepeat = centerWidth === 0 ? sizableWidth : sizableWidth / centerWidth; const vRepeat = centerHeight === 0 ? sizableHeight : sizableHeight / centerHeight; - const tempXVerts :any = []; - const tempYVerts :any = []; + const tempXVerts: any = []; + const tempYVerts: any = []; for (let yIndexUV = 0; yIndexUV < row; ++yIndexUV) { if (sizableHeight > centerHeight) { diff --git a/cocos/2d/assembler/utils.ts b/cocos/2d/assembler/utils.ts index 0ebd53b9759..edd862d5284 100644 --- a/cocos/2d/assembler/utils.ts +++ b/cocos/2d/assembler/utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Color, Mat4 } from '../../core/math'; +import { Color, Mat4, clamp } from '../../core'; import { RenderData } from '../renderer/render-data'; import { IBatcher } from '../renderer/i-batcher'; import { Node } from '../../scene-graph/node'; import { FormatInfos } from '../../gfx'; -import { clamp } from '../../core'; const m = new Mat4(); diff --git a/cocos/2d/assets/bitmap-font.ts b/cocos/2d/assets/bitmap-font.ts index ecbda85704a..f83bbae5514 100644 --- a/cocos/2d/assets/bitmap-font.ts +++ b/cocos/2d/assets/bitmap-font.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,9 +26,7 @@ import { ccclass, type, serializable, editable } from 'cc.decorator'; import { Font } from './font'; import { SpriteFrame } from './sprite-frame'; -import { legacyCC } from '../../core/global-exports'; -import { js } from '../../core/utils'; -import { warn } from '../../core/platform/debug'; +import { cclegacy, js, warn } from '../../core'; export interface IConfig { [key: string]: any; @@ -105,19 +102,22 @@ export class FontAtlas { */ @ccclass('cc.BitmapFont') export class BitmapFont extends Font { + /** + * @deprecated since v3.7.0, Useless Code. + */ @serializable @editable public fntDataStr = ''; /** - * @en [[SpriteFrame]] of the bitmap font + * @en [[SpriteFrame]] of the bitmap font. * @zh 位图字体所使用的精灵。 */ @type(SpriteFrame) public spriteFrame: SpriteFrame | null = null; /** - * @en The font size + * @en The font size. * @zh 文字尺寸。 */ @serializable @@ -125,13 +125,16 @@ export class BitmapFont extends Font { public fontSize = -1; /** - * @en Font configuration + * @en Font configuration. * @zh 字体配置。 */ @serializable @editable public fntConfig: IConfig | null = null; + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public declare fontDefDictionary: FontAtlas; onLoaded () { @@ -166,4 +169,4 @@ export class BitmapFont extends Font { } } -legacyCC.BitmapFont = BitmapFont; +cclegacy.BitmapFont = BitmapFont; diff --git a/cocos/2d/assets/font.ts b/cocos/2d/assets/font.ts index 44d54ee8cc7..2f7ac8a7bf0 100644 --- a/cocos/2d/assets/font.ts +++ b/cocos/2d/assets/font.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ import { ccclass } from 'cc.decorator'; import { Asset } from '../../asset/assets'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @en Class for Font handling. @@ -36,4 +35,4 @@ import { legacyCC } from '../../core/global-exports'; export class Font extends Asset { } -legacyCC.Font = Font; +cclegacy.Font = Font; diff --git a/cocos/2d/assets/index.ts b/cocos/2d/assets/index.ts index 23f063af1da..3f5cb48518d 100644 --- a/cocos/2d/assets/index.ts +++ b/cocos/2d/assets/index.ts @@ -1,4 +1,26 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ export * from './sprite-frame'; export { SpriteAtlas } from './sprite-atlas'; diff --git a/cocos/2d/assets/label-atlas.ts b/cocos/2d/assets/label-atlas.ts index 339c480c182..dfe886a86f6 100644 --- a/cocos/2d/assets/label-atlas.ts +++ b/cocos/2d/assets/label-atlas.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ import { ccclass } from 'cc.decorator'; import { BitmapFont } from './bitmap-font'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @en Class for LabelAtlas handling. * @zh 艺术数字字体资源类。 @@ -36,4 +35,4 @@ import { legacyCC } from '../../core/global-exports'; export class LabelAtlas extends BitmapFont { } -legacyCC.LabelAtlas = LabelAtlas; +cclegacy.LabelAtlas = LabelAtlas; diff --git a/cocos/2d/assets/sprite-atlas.ts b/cocos/2d/assets/sprite-atlas.ts index a8a7bfb0408..b77ac7cac31 100644 --- a/cocos/2d/assets/sprite-atlas.ts +++ b/cocos/2d/assets/sprite-atlas.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,10 +25,9 @@ import { EDITOR, TEST } from 'internal:constants'; import { ccclass, serializable, editable } from 'cc.decorator'; -import * as js from '../../core/utils/js'; import { Asset } from '../../asset/assets'; import { SpriteFrame } from './sprite-frame'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy, js } from '../../core'; interface ISpriteAtlasSerializeData{ name: string; @@ -48,14 +46,18 @@ interface ISpriteFrameList { */ @ccclass('cc.SpriteAtlas') export class SpriteAtlas extends Asset { + /** + * @en All sprite frames in the sprite atlas. + * @zh 精灵图集中的所有精灵。 + */ @serializable @editable public spriteFrames: ISpriteFrameList = js.createMap(); /** * @en Get the [[Texture2D]] asset of the atlas. - * @zh 获取精灵图集的贴图。请注意,由于结构调整优化,在 v1.1 版本之前,此函数的返回值为 imageAsset,在 v1.1 版本之后修正为 texture,想要获取 imageAsset 可使用 getTexture().image 获取 - * @returns The texture2d asset + * @zh 获取精灵图集的贴图。 + * @returns @en The texture2d asset. @zh 二维贴图资源。 */ public getTexture () { const keys = Object.keys(this.spriteFrames); @@ -71,8 +73,8 @@ export class SpriteAtlas extends Asset { * @en Gets the [[SpriteFrame]] correspond to the given key in sprite atlas. * @zh 根据键值获取精灵。 * - * @param key The SpriteFrame name - * @returns The SpriteFrame asset + * @param key @en The SpriteFrame name. @zh 精灵名字。 + * @returns @en The SpriteFrame asset. @zh 精灵资源。 */ public getSpriteFrame (key: string) { const sf = this.spriteFrames[key]; @@ -88,7 +90,7 @@ export class SpriteAtlas extends Asset { /** * @en Returns all sprite frames in the sprite atlas. * @zh 获取精灵图集所有精灵。 - * @returns All sprite frames + * @returns @en All sprite frames. @zh 所有的精灵资源。 */ public getSpriteFrames () { const frames: Array = []; @@ -138,4 +140,4 @@ export class SpriteAtlas extends Asset { } } -legacyCC.SpriteAtlas = SpriteAtlas; +cclegacy.SpriteAtlas = SpriteAtlas; diff --git a/cocos/2d/assets/sprite-frame.ts b/cocos/2d/assets/sprite-frame.ts index 8fee066ea58..dec42f4be97 100644 --- a/cocos/2d/assets/sprite-frame.ts +++ b/cocos/2d/assets/sprite-frame.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -27,18 +27,16 @@ import { ccclass } from 'cc.decorator'; import { EDITOR, TEST, BUILD } from 'internal:constants'; -import { Mat4, Rect, Size, Vec2, Vec3, Vec4 } from '../../core/math'; +import { Mat4, Rect, Size, Vec2, Vec3, Vec4, cclegacy, errorID, warnID, js } from '../../core'; import { Asset } from '../../asset/assets/asset'; import { TextureBase } from '../../asset/assets/texture-base'; -import { legacyCC } from '../../core/global-exports'; import { ImageAsset, ImageSource } from '../../asset/assets/image-asset'; import { Texture2D } from '../../asset/assets/texture-2d'; -import { errorID, warnID } from '../../core/platform/debug'; import { dynamicAtlasManager } from '../utils/dynamic-atlas/atlas-manager'; -import { js } from '../../core/utils/js'; import { Mesh } from '../../3d/assets/mesh'; import { createMesh } from '../../3d/misc'; import { Attribute, AttributeName, Format, PrimitiveMode } from '../../gfx'; +import { ccwindow } from '../../core/global-exports'; const INSET_LEFT = 0; const INSET_TOP = 1; @@ -52,6 +50,9 @@ enum MeshType { POLYGON = 1, // Todo: Polygon mode need add } +/** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ export interface IUV { u: number; v: number; @@ -101,22 +102,22 @@ interface ISpriteFrameOriginal { } /** - * @en Information object interface for initialize a [[SpriteFrame]] asset - * @zh 用于初始化 [[SpriteFrame]] 资源的对象接口描述 + * @en Information object interface for initialize a [[SpriteFrame]] asset. + * @zh 用于初始化 [[SpriteFrame]] 资源的对象接口描述。 */ interface ISpriteFrameInitInfo { /** - * @en The texture of the sprite frame, could be `TextureBase` - * @zh 贴图对象资源,可以是 `TextureBase` 类型 + * @en The texture of the sprite frame, could be `TextureBase`. + * @zh 贴图对象资源,可以是 `TextureBase` 类型。 */ texture?: TextureBase; /** - * @en The original size of the sprite frame + * @en The original size of the sprite frame. * @zh 精灵帧原始尺寸。 */ originalSize?: Size; /** - * @en The rect of the sprite frame in atlas texture + * @en The rect of the sprite frame in atlas texture. * @zh 精灵帧裁切矩形。 */ rect?: Rect; @@ -158,7 +159,7 @@ interface ISpriteFrameInitInfo { */ isRotate?: boolean; /** - * @en Whether the uv is flipped + * @en Whether the uv is flipped. * @zh 是否转置 UV。 */ isFlipUv?: boolean; @@ -168,17 +169,17 @@ const temp_uvs: IUV[] = [{ u: 0, v: 0 }, { u: 0, v: 0 }, { u: 0, v: 0 }, { u: 0, /** * @en - * A `SpriteFrame` support several types + * A `SpriteFrame` support several types. * 1. Rectangle sprite frame * 2. Sliced 9 sprite frame * 3. Mesh sprite frame * It mainly contains:
- * - texture: A `TextureBase` that will be used by render process
- * - rectangle: A rectangle of the texture - * - Sliced 9 border insets: The distance of each side from the internal rect to the sprite frame rect - * - vertices: Vertex list for the mesh type sprite frame - * - uv: The quad uv - * - uvSliced: The sliced 9 uv + * - texture: A `TextureBase` that will be used by render process.
+ * - rectangle: A rectangle of the texture. + * - Sliced 9 border insets: The distance of each side from the internal rect to the sprite frame rect. + * - vertices: Vertex list for the mesh type sprite frame. + * - uv: The quad uv. + * - uvSliced: The sliced 9 uv. * * @zh * 精灵帧资源。 @@ -189,10 +190,10 @@ const temp_uvs: IUV[] = [{ u: 0, v: 0 }, { u: 0, v: 0 }, { u: 0, v: 0 }, { u: 0, * 它主要包含下列数据:
* - 纹理:会被渲染流程使用的 `TextureBase` 资源。
* - 矩形:在纹理中的矩形区域。 - * - 九宫格信息:九宫格的内部矩形四个边距离 SpriteFrame 外部矩形的距离 - * - 网格信息:网格类型精灵帧的所有顶点列表 - * - uv: 四边形 UV - * - uvSliced: 九宫格 UV + * - 九宫格信息:九宫格的内部矩形四个边距离 SpriteFrame 外部矩形的距离。 + * - 网格信息:网格类型精灵帧的所有顶点列表。 + * - uv: 四边形 UV。 + * - uvSliced: 九宫格 UV。 * 可通过 `SpriteFrame` 获取该组件。 * * @example @@ -242,9 +243,11 @@ const temp_uvs: IUV[] = [{ u: 0, v: 0 }, { u: 0, v: 0 }, { u: 0, v: 0 }, { u: 0, @ccclass('cc.SpriteFrame') export class SpriteFrame extends Asset { /** - * @en Create a SpriteFrame object by an image asset or an native image asset - * @zh 通过 Image 资源或者平台相关 Image 对象创建一个 SpriteFrame 对象 - * @param imageSourceOrImageAsset ImageAsset or ImageSource, ImageSource support HTMLCanvasElement HTMLImageElement IMemoryImageSource + * @en Create a SpriteFrame object by an image asset or an native image asset. + * @zh 通过 Image 资源或者平台相关 Image 对象创建一个 SpriteFrame 资源。 + * @param imageSourceOrImageAsset @en ImageAsset or ImageSource, ImageSource could be HTMLCanvasElement, HTMLImageElement, IMemoryImageSource. + * @zh 图像资源或图像原始图像源,图像原始图像源支持 HTMLCanvasElement HTMLImageElement IMemoryImageSource 三种资源。 + * @returns @en SpriteFrame asset. @zh 精灵资源。 */ public static createWithImage (imageSourceOrImageAsset: ImageSource | ImageAsset) { const img = imageSourceOrImageAsset instanceof ImageAsset ? imageSourceOrImageAsset : new ImageAsset(imageSourceOrImageAsset); @@ -256,8 +259,8 @@ export class SpriteFrame extends Asset { } /** - * @en uv update event - * @zh uv 更新事件 + * @en uv update event. + * @zh uv 更新事件。 */ public static EVENT_UV_UPDATED = 'uv_updated'; public static MeshType = MeshType; @@ -416,8 +419,8 @@ export class SpriteFrame extends Asset { } /** - * @en The texture of the sprite frame, could be `TextureBase` - * @zh 贴图对象资源,可以是 `TextureBase` 类型 + * @en The texture of the sprite frame, could be `TextureBase`. + * @zh 贴图对象资源,可以是 `TextureBase` 类型。 */ get texture () { return this._texture; @@ -437,7 +440,7 @@ export class SpriteFrame extends Asset { } /** - * @en The uuid of the atlas asset, if exist + * @en The uuid of the atlas asset, if exists. * @zh 图集资源的 uuid。 */ get atlasUuid () { @@ -449,24 +452,27 @@ export class SpriteFrame extends Asset { } /** - * @en The pixel width of the sprite frame - * @zh 精灵帧的像素宽度 + * @en The pixel width of the sprite frame. + * @zh 精灵帧的像素宽度。 */ get width () { return this._texture.width; } /** - * @en The pixel height of the sprite frame - * @zh 精灵帧的像素高度 + * @en The pixel height of the sprite frame. + * @zh 精灵帧的像素高度。 */ get height () { return this._texture.height; } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ set _textureSource (value: TextureBase) { // Optimization for build - if (window.Build) { + if (globalThis.Build) { this._texture = value; return; } @@ -477,8 +483,8 @@ export class SpriteFrame extends Asset { } /** - * @en Whether flip the uv in X direction - * @zh 延 X 轴方向, 翻转 UV + * @en Whether flip the uv in X direction. + * @zh 沿 X 轴方向, 翻转 UV。 */ get flipUVX () { return this._isFlipUVX; @@ -490,8 +496,8 @@ export class SpriteFrame extends Asset { } /** - * @en Whether flip the uv in Y direction - * @zh 延 Y 轴方向, 翻转 UV + * @en Whether flip the uv in Y direction. + * @zh 沿 Y 轴方向, 翻转 UV。 */ get flipUVY () { return this._isFlipUVY; @@ -502,6 +508,10 @@ export class SpriteFrame extends Asset { this._calculateUV(); } + /** + * @en Sets whether sprite can be packed into dynamic atlas. + * @zh 设置精灵是否允许参与自动合图。 + */ get packable () { return this._packable; } @@ -509,57 +519,64 @@ export class SpriteFrame extends Asset { this._packable = value; } + /** + * @en Original information before packed to dynamic atlas, includes texture, width, height. It's null before being packed to dynamic atlas. + * @zh 精灵自动合图之前的原始 texture 和宽高信息。在参与自动合图之前此值为 null。 + */ get original () { return this._original; } /** - * @en Number of pixels corresponding to unit size in world space (pixels per meter) - * @zh 世界空间中的单位大小对应的像素数量(像素每米) + * @en Number of pixels corresponding to unit size in world space (pixels per unit). + * @zh 世界空间中的单位大小对应的像素数量(像素每单位)。 */ get pixelsToUnit () { return this._pixelsToUnit; } /** - * @en Local origin position when generating the mesh - * @zh 生成 mesh 时本地坐标原点位置 + * @en Local origin position when generating the mesh. + * @zh 生成 mesh 时本地坐标原点位置。 */ get pivot () { return this._pivot; } /** - * @en mesh information, you should call the [[ensureMeshData]] function before using it - * @zh mesh 信息,你应该在使用它之前调用 [[ensureMeshData]] 函数来确保其可用 + * @en mesh information, you should call the [[ensureMeshData]] function before using it. + * @zh mesh 信息,你应该在使用它之前调用 [[ensureMeshData]] 函数来确保其可用。 */ get mesh () { return this._mesh; } /** - * @internal + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. */ get trimmedBorder () { return this._trimmedBorder; } /** - * @en Vertex list for the mesh type sprite frame - * @zh 网格类型精灵帧的所有顶点列表 + * @en Vertex list for the mesh type sprite frame. + * @zh 网格类型精灵帧的所有顶点列表。 */ public vertices: IVertices | null = null; /** - * @en UV for quad vertices - * @zh 矩形的顶点 UV + * @en UV for quad vertices. + * @zh 矩形的顶点 UV。 */ public uv: number[] = []; - public unbiasUV:number[] = []; + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ + public unbiasUV: number[] = []; /** - * @en UV for sliced 9 vertices + * @en UV for sliced 9 vertices. * @zh 九宫格的顶点 UV。 */ public uvSliced: IUV[] = []; @@ -633,7 +650,7 @@ export class SpriteFrame extends Asset { * @zh * 返回是否已加载精灵帧。 * - * @deprecated since v3.3 + * @deprecated since v3.3, Useless Code. */ public textureLoaded () { return !!this.texture; @@ -644,7 +661,7 @@ export class SpriteFrame extends Asset { * Returns whether the sprite frame is rotated in the texture. * @zh * 获取 SpriteFrame 是否旋转。 - * @deprecated since v1.2, please use [[rotated]] instead + * @deprecated since v1.2, please use [[rotated]] instead. */ public isRotated () { return this._rotated; @@ -655,8 +672,8 @@ export class SpriteFrame extends Asset { * Set whether the sprite frame is rotated in the texture. * @zh * 设置 SpriteFrame 是否旋转。 - * @param value - * @deprecated since v1.2, please use [[rotated]] instead + * @param rotated @en rotated. @zh 是否旋转。 + * @deprecated since v1.2, please use [[rotated]] instead. */ public setRotated (rotated: boolean) { this.rotated = rotated; @@ -667,7 +684,9 @@ export class SpriteFrame extends Asset { * If it's an atlas texture, a transparent pixel area is proposed for the actual mapping of the current texture. * @zh 获取 SpriteFrame 的纹理矩形区域。 * 如果是一个 atlas 的贴图,则为当前贴图的实际剔除透明像素区域。 - * @deprecated since v1.2, please use [[rect]] + * @param out @en The output rect. @zh 输出的矩形区域。 + * @returns @en The rect. @zh 矩形区域。 + * @deprecated since v1.2, please use [[rect]]. */ public getRect (out?: Rect) { if (out) { @@ -681,7 +700,8 @@ export class SpriteFrame extends Asset { /** * @en Sets the rect of the sprite frame in the texture. * @zh 设置 SpriteFrame 的纹理矩形区域。 - * @deprecated since v1.2, please use [[rect]] + * @param rect @en The new rect. @zh 想要设置的 rect。 + * @deprecated since v1.2, please use [[rect]]. */ public setRect (rect: Rect) { this.rect = rect; @@ -690,7 +710,9 @@ export class SpriteFrame extends Asset { /** * @en Returns the original size before trimmed. * @zh 获取修剪前的原始大小。 - * @deprecated since v1.2, please use [[originalSize]] + * @param out @en The output original size. @zh 输出的原始大小。 + * @returns @en The original size. @zh 原始大小。 + * @deprecated since v1.2, please use [[originalSize]]. */ public getOriginalSize (out?: Size) { if (out) { @@ -704,17 +726,18 @@ export class SpriteFrame extends Asset { /** * @en Sets the original size before trimmed. * @zh 设置修剪前的原始大小。 - * @param size The new original size - * @deprecated since v1.2, please use [[originalSize]] + * @param size @en The new original size. @zh 新设置的原始大小。 + * @deprecated since v1.2, please use [[originalSize]]. */ public setOriginalSize (size: Size) { this.originalSize = size; } /** - * @en Returns the offset of the frame + * @en Gets the offset of the frame. * @zh 获取偏移量。 - * @param out The output offset object + * @param out @en The output offset object. @zh 输出的偏移量。 + * @returns @en The offset object. @zh 偏移量。 * @deprecated since v1.2, please use [[offset]] */ public getOffset (out?: Vec2) { @@ -727,9 +750,9 @@ export class SpriteFrame extends Asset { } /** - * @en Sets the offset of the frame + * @en Sets the offset of the frame. * @zh 设置偏移量。 - * @param offset The new offset + * @param offset @en The new offset. @zh 新设置的偏移量。 * @deprecated since v1.2, please use [[offset]] */ public setOffset (offset: Vec2) { @@ -737,41 +760,46 @@ export class SpriteFrame extends Asset { } /** - * @en Gets the related GFX [[gfx.Texture]] resource - * @zh 获取渲染贴图的 GFX 资源 + * @en Gets the related GFX [[gfx.Texture]] resource. + * @zh 获取渲染贴图的 GFX 资源。 + * @returns @en Gfx Texture resource. @zh GFX 贴图资源。 */ public getGFXTexture () { return this._texture.getGFXTexture(); } /** - * @en Gets the sampler resource of its texture - * @zh 贴图资源的采样器 + * @en Gets the GFX sampler of its texture. + * @zh 贴图资源的采样器。 + * @returns @en The GFX sampler resource. @zh GFX贴图采样器。 */ public getGFXSampler () { return this._texture.getGFXSampler(); } /** - * @en Gets the hash of its texture - * @zh 贴图资源的哈希值 + * @en Gets the hash of its texture. + * @zh 贴图资源的哈希值。 + * @returns @en Texture`s hash. @zh 贴图哈希值。 */ public getHash () { return this._texture.getHash(); } /** - * @en Gets the sampler hash of its texture - * @zh 贴图资源的采样器哈希值 + * @en Gets the sampler hash of its texture. + * @zh 贴图资源的采样器哈希值。 + * @returns @en Sampler`s hash. @zh 采样器哈希值。 */ public getSamplerInfo () { return this._texture.getSamplerInfo(); } /** - * @en Resets the sprite frame data + * @en Resets the sprite frame data. * @zh 重置 SpriteFrame 数据。 - * @param info SpriteFrame initialization information + * @param info @en SpriteFrame initialization information. @zh SpriteFrame 初始化信息。 + * @param clearData @en Clear Data before initialization. @zh 是否在初始化前清空原有数据。 */ public reset (info?: ISpriteFrameInitInfo, clearData = false) { let calUV = false; @@ -839,9 +867,10 @@ export class SpriteFrame extends Asset { } /** - * @en Check whether the rect of the sprite frame is out of the texture boundary + * @en Check whether the rect of the sprite frame is out of the texture boundary. * @zh 判断精灵计算的矩形区域是否越界。 - * @param texture + * @param texture @en Texture resources for sprite frame. @zh SpriteFrame 的贴图资源。 + * @returns @en Out of the texture boundary or not. @zh 矩形区域是否越界。 */ public checkRect (texture: TextureBase) { const rect = this._rect; @@ -886,8 +915,8 @@ export class SpriteFrame extends Asset { } /** - * @en Make sure the mesh is available, you should call it before using the mesh - * @zh 确保 mesh 可用,你应该在使用 mesh 之前调用它 + * @en Make sure the mesh is available, you should call it before using the mesh. + * @zh 确保 mesh 可用,你应该在使用 mesh 之前调用它。 */ public ensureMeshData () { if (this._mesh) return; @@ -1244,8 +1273,9 @@ export class SpriteFrame extends Asset { this._packable = false; return; } + const CanvasElement = ccwindow.HTMLCanvasElement; - if (texture.image && texture.image instanceof HTMLCanvasElement) { + if (texture.image && texture.image instanceof CanvasElement) { this._packable = true; } } @@ -1376,6 +1406,10 @@ export class SpriteFrame extends Asset { } } + /** + * @en clone a sprite frame. + * @zh 克隆当前 sprite frame。 + */ public clone (): SpriteFrame { const sp = new SpriteFrame(); const v = this.vertices; @@ -1435,10 +1469,21 @@ export class SpriteFrame extends Asset { } } + /** + * @en complete loading callback. + * @zh 加载完成回调。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public onLoaded () { this._calcTrimmedBorder(); } + /** + * @en default init. + * @zh 默认初始化。 + * @param uuid @en Asset uuid. @zh 资源 uuid。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public initDefault (uuid?: string) { super.initDefault(uuid); const texture = new Texture2D(); @@ -1447,6 +1492,12 @@ export class SpriteFrame extends Asset { this._calculateUV(); } + /** + * @en Check whether the sprite frame is validate. + * @zh 检查当前 sprite frame 对象是否是有效的。 + * @returns @en validate or not. @zh 是否有效。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public validate () { return this._texture && this._rect && this._rect.width !== 0 && this._rect.height !== 0; } @@ -1586,4 +1637,4 @@ export class SpriteFrame extends Asset { } } -legacyCC.SpriteFrame = SpriteFrame; +cclegacy.SpriteFrame = SpriteFrame; diff --git a/cocos/2d/assets/ttf-font.ts b/cocos/2d/assets/ttf-font.ts index 6e1c7ad23ee..f5ca236d547 100644 --- a/cocos/2d/assets/ttf-font.ts +++ b/cocos/2d/assets/ttf-font.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,9 +24,8 @@ */ import { ccclass, string, override, serializable } from 'cc.decorator'; -import { extname } from '../../core/utils/path'; +import { path, cclegacy } from '../../core'; import { Font } from './font'; -import { legacyCC } from '../../core/global-exports'; /** * @en Class for TTFFont asset. @@ -58,13 +56,19 @@ export class TTFFont extends Font { */ @override get _nativeDep () { - return { uuid: this._uuid, __nativeName__: this._native, ext: extname(this._native), __isNative__: true }; + return { uuid: this._uuid, __nativeName__: this._native, ext: path.extname(this._native), __isNative__: true }; } + /** + * @en default init. + * @zh 默认初始化。 + * @param uuid @en Asset uuid. @zh 资源 uuid。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public initDefault (uuid?: string) { this._fontFamily = 'Arial'; super.initDefault(uuid); } } -legacyCC.TTFFont = TTFFont; +cclegacy.TTFFont = TTFFont; diff --git a/cocos/2d/components/deprecated.ts b/cocos/2d/components/deprecated.ts index 037a4e834c7..0e8eb00bceb 100644 --- a/cocos/2d/components/deprecated.ts +++ b/cocos/2d/components/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mask, MaskType } from './mask'; import { Label } from './label'; @@ -32,30 +31,28 @@ import { UIMeshRenderer } from './ui-mesh-renderer'; import { Graphics } from './graphics'; import { UIStaticBatch } from './ui-static-batch'; import { UIOpacity } from './ui-opacity'; -import { js } from '../../core/utils/js'; -import { legacyCC } from '../../core/global-exports'; -import { replaceProperty } from '../../core/utils'; +import { js, cclegacy, replaceProperty } from '../../core'; /** * Alias of [[Mask]] * @deprecated Since v1.2 */ export { Mask as MaskComponent }; -legacyCC.MaskComponent = Mask; +cclegacy.MaskComponent = Mask; js.setClassAlias(Mask, 'cc.MaskComponent'); /** * Alias of [[Label]] * @deprecated Since v1.2 */ export { Label as LabelComponent }; -legacyCC.LabelComponent = Label; +cclegacy.LabelComponent = Label; js.setClassAlias(Label, 'cc.LabelComponent'); /** * Alias of [[LabelOutline]] * @deprecated Since v1.2 */ export { LabelOutline as LabelOutlineComponent }; -legacyCC.LabelOutlineComponent = LabelOutline; +cclegacy.LabelOutlineComponent = LabelOutline; js.setClassAlias(LabelOutline, 'cc.LabelOutlineComponent'); /** @@ -63,28 +60,28 @@ js.setClassAlias(LabelOutline, 'cc.LabelOutlineComponent'); * @deprecated Since v1.2 */ export { RichText as RichTextComponent }; -legacyCC.RichTextComponent = RichText; +cclegacy.RichTextComponent = RichText; js.setClassAlias(RichText, 'cc.RichTextComponent'); /** * Alias of [[Sprite]] * @deprecated Since v1.2 */ export { Sprite as SpriteComponent }; -legacyCC.SpriteComponent = Sprite; +cclegacy.SpriteComponent = Sprite; js.setClassAlias(Sprite, 'cc.SpriteComponent'); /** * Alias of [[UIMeshRenderer]] * @deprecated Since v1.2 */ export { UIMeshRenderer as UIModelComponent }; -legacyCC.UIModelComponent = UIMeshRenderer; +cclegacy.UIModelComponent = UIMeshRenderer; js.setClassAlias(UIMeshRenderer, 'cc.UIModelComponent'); /** * Alias of [[Graphics]] * @deprecated Since v1.2 */ export { Graphics as GraphicsComponent }; -legacyCC.GraphicsComponent = Graphics; +cclegacy.GraphicsComponent = Graphics; js.setClassAlias(Graphics, 'cc.GraphicsComponent'); /** * Alias of [[UIStaticBatch]] diff --git a/cocos/2d/components/graphics.ts b/cocos/2d/components/graphics.ts index 7b91f87187a..e36d97e8f0a 100644 --- a/cocos/2d/components/graphics.ts +++ b/cocos/2d/components/graphics.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,7 +28,7 @@ import { JSB } from 'internal:constants'; import { builtinResMgr } from '../../asset/asset-manager'; import { InstanceMaterialType, UIRenderer } from '../framework/ui-renderer'; import { director } from '../../game/director'; -import { Color } from '../../core/math'; +import { Color, warnID, cclegacy } from '../../core'; import { scene } from '../../render-scene'; import { IAssembler } from '../renderer/base'; import { IBatcher } from '../renderer/i-batcher'; @@ -38,8 +37,6 @@ import { Impl } from '../assembler/graphics/webgl/impl'; import { RenderingSubMesh } from '../../asset/assets'; import { Format, PrimitiveMode, Attribute, Device, BufferUsageBit, BufferInfo, MemoryUsageBit, deviceManager } from '../../gfx'; import { vfmtPosColor, getAttributeStride, getComponentPerVertex } from '../renderer/vertex-format'; -import { legacyCC } from '../../core/global-exports'; -import { warnID } from '../../core/platform/debug'; import { NativeUIModelProxy } from '../renderer/native-2d'; import { RenderEntity, RenderEntityType } from '../renderer/render-entity'; @@ -56,7 +53,7 @@ const stride = getAttributeStride(attributes); * Graphics component. * * @zh - * 自定义图形类 + * 自定义图形类。 */ @ccclass('cc.Graphics') @help('i18n:cc.Graphics') @@ -203,20 +200,6 @@ export class Graphics extends UIRenderer { this._color.set(value); } - get srcBlendFactor () { - return this._srcBlendFactor; - } - - set srcBlendFactor (value) { - } - - get dstBlendFactor () { - return this._dstBlendFactor; - } - - set dstBlendFactor (value) { - } - public static LineJoin = LineJoin; public static LineCap = LineCap; public impl: Impl | null = null; @@ -243,7 +226,10 @@ export class Graphics extends UIRenderer { private _graphicsUseSubMeshes: RenderingSubMesh[] = []; //nativeObj - protected declare _graphicsNativeProxy:NativeUIModelProxy; + protected declare _graphicsNativeProxy: NativeUIModelProxy; + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get graphicsNativeProxy () { return this._graphicsNativeProxy; } @@ -283,7 +269,7 @@ export class Graphics extends UIRenderer { public onDestroy () { this._sceneGetter = null; if (JSB) { - this.graphicsNativeProxy.destroy(); + this._graphicsNativeProxy.destroy(); this.model = null; } else { if (this.model) { @@ -635,6 +621,9 @@ export class Graphics extends UIRenderer { } } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public activeSubModel (idx: number) { if (!this.model) { warnID(4500, this.node.name); @@ -733,6 +722,9 @@ export class Graphics extends UIRenderer { } } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public updateRenderer () { super.updateRenderer(); if (JSB) { @@ -755,4 +747,4 @@ export class Graphics extends UIRenderer { } } -legacyCC.Graphics = Graphics; +cclegacy.Graphics = Graphics; diff --git a/cocos/2d/components/index.ts b/cocos/2d/components/index.ts index 791ca68e3ff..0d3f86a0c21 100644 --- a/cocos/2d/components/index.ts +++ b/cocos/2d/components/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './label'; export { Mask } from './mask'; diff --git a/cocos/2d/components/label-outline.ts b/cocos/2d/components/label-outline.ts index 48f3e448096..d90473ad87b 100644 --- a/cocos/2d/components/label-outline.ts +++ b/cocos/2d/components/label-outline.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,9 +25,8 @@ import { ccclass, help, executionOrder, menu, tooltip, requireComponent, executeInEditMode, serializable } from 'cc.decorator'; import { Component } from '../../scene-graph/component'; -import { Color } from '../../core/math'; +import { Color, cclegacy } from '../../core'; import { Label } from './label'; -import { legacyCC } from '../../core/global-exports'; /** * @en @@ -129,4 +127,4 @@ export class LabelOutline extends Component { } } -legacyCC.LabelOutline = LabelOutline; +cclegacy.LabelOutline = LabelOutline; diff --git a/cocos/2d/components/label-shadow.ts b/cocos/2d/components/label-shadow.ts index f8dba9663cd..f8308c1fc63 100644 --- a/cocos/2d/components/label-shadow.ts +++ b/cocos/2d/components/label-shadow.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,12 +25,12 @@ import { ccclass, help, executionOrder, menu, tooltip, requireComponent, executeInEditMode, serializable } from 'cc.decorator'; import { Component } from '../../scene-graph/component'; -import { Color, Vec2 } from '../../core/math'; +import { Color, Vec2 } from '../../core'; import { Label } from './label'; /** - * @en Shadow effect for Label component, only for system fonts or TTF fonts - * @zh 用于给 Label 组件添加阴影效果,只能用于系统字体或 ttf 字体 + * @en Shadow effect for Label component, only for system fonts or TTF fonts. + * @zh 用于给 Label 组件添加阴影效果,只能用于系统字体或 ttf 字体。 * @example * import { Node, Label, LabelShadow } from 'cc'; * // Create a new node and add label components. @@ -83,7 +82,7 @@ export class LabelShadow extends Component { /** * @en - * Offset between font and shadow + * Offset between font and shadow. * * @zh * 字体与阴影的偏移。 @@ -106,10 +105,10 @@ export class LabelShadow extends Component { /** * @en - * A non-negative float specifying the level of shadow blur + * A non-negative float specifying the level of shadow blur. * * @zh - * 阴影的模糊程度 + * 阴影的模糊程度。 * * @example * ```ts diff --git a/cocos/2d/components/label.ts b/cocos/2d/components/label.ts index a578451a0e9..5f1d0bfd2a8 100644 --- a/cocos/2d/components/label.ts +++ b/cocos/2d/components/label.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,16 +28,14 @@ import { BYTEDANCE, EDITOR, JSB } from 'internal:constants'; import { minigame } from 'pal/minigame'; import { BitmapFont, Font, SpriteFrame } from '../assets'; import { ImageAsset, Texture2D } from '../../asset/assets'; -import { ccenum } from '../../core/value-types/enum'; +import { ccenum, cclegacy, Color } from '../../core'; import { IBatcher } from '../renderer/i-batcher'; import { FontAtlas } from '../assets/bitmap-font'; import { CanvasPool, ISharedLabelData, LetterRenderTexture } from '../assembler/label/font-utils'; import { InstanceMaterialType, UIRenderer } from '../framework/ui-renderer'; import { TextureBase } from '../../asset/assets/texture-base'; import { PixelFormat } from '../../asset/assets/asset-enum'; -import { legacyCC } from '../../core/global-exports'; import { BlendFactor } from '../../gfx'; -import { Color } from '../../core'; const tempColor = Color.WHITE.clone(); /** @@ -100,7 +97,7 @@ ccenum(VerticalTextAlignment); /** * @en Enum for Overflow. * - * @zh 文本超载类型。 + * @zh 文本溢出行为类型。 */ export enum Overflow { /** @@ -163,23 +160,6 @@ export enum CacheMode { ccenum(CacheMode); -/** - * @zh - * Type 类型。 - */ -/** - * @zh - * TTF字体。 - */ -/** - * @zh - * 位图字体。 - */ -/** - * @zh - * 系统字体。 - */ - /** * @en * The Label Component. @@ -192,12 +172,32 @@ ccenum(CacheMode); @executionOrder(110) @menu('2D/Label') export class Label extends UIRenderer { + /** + * @en Enum for horizontal text alignment. + * + * @zh 文本横向对齐类型。 + */ public static HorizontalAlign = HorizontalTextAlignment; + /** + * @en Enum for vertical text alignment. + * + * @zh 文本垂直对齐类型。 + */ public static VerticalAlign = VerticalTextAlignment; + /** + * @en Enum for label overflow mode. + * + * @zh 文本溢出行为类型。 + */ public static Overflow = Overflow; + /** + * @en Enum for cache mode. + * + * @zh 文本图集缓存类型。 + */ public static CacheMode = CacheMode; /** - * @internal + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. */ public static _canvasPool = CanvasPool.getInstance(); @@ -600,18 +600,30 @@ export class Label extends UIRenderer { this.markForUpdateRenderData(); } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get spriteFrame () { return this._texture; } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get ttfSpriteFrame () { return this._ttfSpriteFrame; } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get assemblerData () { return this._assemblerData; } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get fontAtlas () { return this._fontAtlas; } @@ -742,6 +754,11 @@ export class Label extends UIRenderer { super.onDestroy(); } + /** + * @en update render data. + * @zh 更新渲染相关数据。 + * @param force @en Whether to force an immediate update. @zh 是否立马强制更新渲染数据。 + */ public updateRenderData (force = false) { if (force) { this._flushAssembler(); @@ -765,6 +782,9 @@ export class Label extends UIRenderer { this.markForUpdateRenderData(); } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setEntityColor (color: Color) { if (JSB) { if (this._font instanceof BitmapFont) { @@ -887,4 +907,4 @@ export class Label extends UIRenderer { } } -legacyCC.Label = Label; +cclegacy.Label = Label; diff --git a/cocos/2d/components/mask.ts b/cocos/2d/components/mask.ts index f7265c3f172..31096feb0c0 100644 --- a/cocos/2d/components/mask.ts +++ b/cocos/2d/components/mask.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,12 +25,9 @@ import { ccclass, help, executionOrder, menu, tooltip, displayOrder, type, visible, serializable, range, slide, executeInEditMode } from 'cc.decorator'; import { JSB } from 'internal:constants'; -import { clamp, Color, Mat4, Vec2, Vec3 } from '../../core/math'; -import { ccenum } from '../../core/value-types/enum'; +import { clamp, Color, Mat4, Vec2, Vec3, warnID, cclegacy, ccenum } from '../../core'; import { Graphics } from './graphics'; import { TransformBit } from '../../scene-graph/node-enum'; -import { warnID } from '../../core'; -import { legacyCC } from '../../core/global-exports'; import { Stage } from '../renderer/stencil-manager'; import { NodeEventProcessor } from '../../scene-graph/node-event-processor'; import { MaskMode } from '../renderer/render-entity'; @@ -164,9 +160,9 @@ export class Mask extends Component { /** * @en - * Reverse mask + * Reverse mask. * @zh - * 反向遮罩 + * 反向遮罩。 */ @displayOrder(14) @tooltip('i18n:mask.inverted') @@ -264,6 +260,10 @@ export class Mask extends Component { } } + /** + * @en Rendering component for providing stencil buffer information. + * @zh 用于提供 stencil buffer 信息的渲染组件。 + */ get subComp () { return this._graphics || this._sprite; } @@ -303,10 +303,6 @@ export class Mask extends Component { this.node.on(NodeEventType.SIZE_CHANGED, this._nodeStateChange, this); } - /** - * @zh - * 图形内容重塑。 - */ public onRestore () { this._changeRenderType(); this._updateGraphics(); @@ -323,9 +319,9 @@ export class Mask extends Component { } /** - * Hit test with point in World Space. - * - * @param worldPt point in World Space. + * @en Hit test with point in World Space. + * @zh 世界空间中的点击测试。 + * @param worldPt @en point in World Space. @zh 世界空间中的点击点。 */ public isHit (worldPt: Vec2) { const uiTrans = this.node._uiProps.uiTransformComp!; @@ -670,4 +666,4 @@ export class Mask extends Component { NodeEventProcessor._maskComp = Mask; -legacyCC.Mask = Mask; +cclegacy.Mask = Mask; diff --git a/cocos/2d/components/rich-text.ts b/cocos/2d/components/rich-text.ts index 31d1ea350ef..8bd1e2e37c6 100644 --- a/cocos/2d/components/rich-text.ts +++ b/cocos/2d/components/rich-text.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,19 +27,15 @@ import { ccclass, executeInEditMode, executionOrder, help, menu, tooltip, multil import { DEBUG, DEV, EDITOR } from 'internal:constants'; import { Font, SpriteAtlas, TTFFont, SpriteFrame } from '../assets'; import { EventTouch } from '../../input/types'; -import { assert, warnID } from '../../core/platform'; +import { assert, warnID, Color, Vec2, CCObject, cclegacy, js } from '../../core'; import { BASELINE_RATIO, fragmentText, isUnicodeCJK, isUnicodeSpace, getEnglishWordPartAtFirst, getEnglishWordPartAtLast } from '../utils/text-utils'; import { HtmlTextParser, IHtmlTextParserResultObj, IHtmlTextParserStack } from '../utils/html-text-parser'; -import Pool from '../../core/utils/pool'; -import { Color, Vec2 } from '../../core/math'; import { Node } from '../../scene-graph'; import { CacheMode, HorizontalTextAlignment, Label, VerticalTextAlignment } from './label'; import { LabelOutline } from './label-outline'; import { Sprite } from './sprite'; import { UITransform } from '../framework'; -import { legacyCC } from '../../core/global-exports'; import { Component } from '../../scene-graph/component'; -import { CCObject } from '../../core'; import { NodeEventType } from '../../scene-graph/node-event'; const _htmlTextParser = new HtmlTextParser(); @@ -50,11 +45,11 @@ const RichTextChildImageName = 'RICHTEXT_Image_CHILD'; /** * 富文本池。
*/ -const labelPool = new Pool((seg: ISegment) => { +const labelPool = new js.Pool((seg: ISegment) => { if (DEV) { assert(!seg.node.parent, 'Recycling node\'s parent should be null!'); } - if (!legacyCC.isValid(seg.node)) { + if (!cclegacy.isValid(seg.node)) { return false; } else { const outline = seg.node.getComponent(LabelOutline); @@ -65,11 +60,11 @@ const labelPool = new Pool((seg: ISegment) => { return true; }, 20); -const imagePool = new Pool((seg: ISegment) => { +const imagePool = new js.Pool((seg: ISegment) => { if (DEV) { assert(!seg.node.parent, 'Recycling node\'s parent should be null!'); } - return legacyCC.isValid(seg.node) as boolean; + return cclegacy.isValid(seg.node) as boolean; }, 10); // @@ -239,10 +234,10 @@ export class RichText extends Component { /** * @en - * Custom System font of RichText + * Custom System font of RichText. * * @zh - * 富文本定制系统字体 + * 富文本定制系统字体。 */ @tooltip('i18n:richtext.font_family') get fontFamily () { @@ -430,7 +425,17 @@ export class RichText extends Component { } } } + /** + * @en Enum for horizontal text alignment. + * + * @zh 文本横向对齐类型。 + */ public static HorizontalAlign = HorizontalTextAlignment; + /** + * @en Enum for vertical text alignment. + * + * @zh 文本垂直对齐类型。 + */ public static VerticalAlign = VerticalTextAlignment; @serializable @@ -1284,4 +1289,4 @@ export class RichText extends Component { } } -legacyCC.RichText = RichText; +cclegacy.RichText = RichText; diff --git a/cocos/2d/components/sprite.ts b/cocos/2d/components/sprite.ts index a0f790d7abf..2d7c6fa36f6 100644 --- a/cocos/2d/components/sprite.ts +++ b/cocos/2d/components/sprite.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,16 +27,13 @@ import { ccclass, help, executionOrder, menu, tooltip, displayOrder, type, range import { BUILD, EDITOR } from 'internal:constants'; import { SpriteAtlas } from '../assets/sprite-atlas'; import { SpriteFrame } from '../assets/sprite-frame'; -import { Vec2 } from '../../core/math'; -import { ccenum } from '../../core/value-types/enum'; -import { clamp } from '../../core/math/utils'; +import { Vec2, cclegacy, ccenum, clamp } from '../../core'; import { IBatcher } from '../renderer/i-batcher'; import { UIRenderer, InstanceMaterialType } from '../framework/ui-renderer'; import { PixelFormat } from '../../asset/assets/asset-enum'; import { TextureBase } from '../../asset/assets/texture-base'; import { Material, RenderTexture } from '../../asset/assets'; import { NodeEventType } from '../../scene-graph/node-event'; -import { legacyCC } from '../../core/global-exports'; /** * @en @@ -390,6 +386,10 @@ export class Sprite extends UIRenderer { } } + /** + * @en Grayscale mode. + * @zh 是否以灰度模式渲染。 + */ @editable @displayOrder(5) @tooltip('i18n:sprite.gray_scale') @@ -435,9 +435,25 @@ export class Sprite extends UIRenderer { } } + /** + * @en Enum for fill type. + * @zh 填充类型。 + */ public static FillType = FillType; + /** + * @en Enum for sprite type. + * @zh Sprite 类型。 + */ public static Type = SpriteType; + /** + * @en Sprite's size mode, including trimmed size, raw size, and none. + * @zh 精灵尺寸调整模式。 + */ public static SizeMode = SizeMode; + /** + * @en Event types for sprite. + * @zh sprite 的事件类型。 + */ public static EventType = EventType; @serializable @@ -505,9 +521,8 @@ export class Sprite extends UIRenderer { * If there is no atlas, the switch fails. * * @zh - * 精灵图集内的精灵替换 - * - * @returns + * 选取使用精灵图集中的其他精灵。 + * @param name @en Name of the spriteFrame to switch. @zh 要切换的 spriteFrame 名字。 */ public changeSpriteFrameFromAtlas (name: string) { if (!this._atlas) { @@ -518,6 +533,9 @@ export class Sprite extends UIRenderer { this.spriteFrame = sprite; } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public changeMaterialForDefine () { let texture; const lastInstanceMaterialType = this._instanceMaterialType; @@ -688,4 +706,4 @@ export class Sprite extends UIRenderer { } } -legacyCC.Sprite = Sprite; +cclegacy.Sprite = Sprite; diff --git a/cocos/2d/components/ui-mesh-renderer.ts b/cocos/2d/components/ui-mesh-renderer.ts index 515500d4ba0..b1e93011255 100644 --- a/cocos/2d/components/ui-mesh-renderer.ts +++ b/cocos/2d/components/ui-mesh-renderer.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -31,12 +30,11 @@ import { RenderPriority } from '../../rendering/define'; import { IBatcher } from '../renderer/i-batcher'; import { Stage } from '../renderer/stencil-manager'; import { Component } from '../../scene-graph/component'; -import { legacyCC } from '../../core/global-exports'; import { NativeUIModelProxy } from '../renderer/native-2d'; import { uiRendererManager } from '../framework/ui-renderer-manager'; import { RenderEntity, RenderEntityType } from '../renderer/render-entity'; import { MeshRenderData, RenderData } from '../renderer/render-data'; -import { assert } from '../../core'; +import { assert, cclegacy } from '../../core'; import { RenderDrawInfoType } from '../renderer/render-draw-info'; /** @@ -63,6 +61,10 @@ export class UIMeshRenderer extends Component { } } + /** + * @en Get the model component on this node + * @zh 获取同节点的 model 组件 + */ public get modelComponent () { return this._modelComponent; } @@ -71,8 +73,7 @@ export class UIMeshRenderer extends Component { //nativeObj private declare _UIModelNativeProxy: NativeUIModelProxy; - protected declare _renderEntity : RenderEntity; - private modelCount = 0; + protected declare _renderEntity: RenderEntity; public _dirtyVersion = -1; public _internalId = -1; @@ -126,6 +127,7 @@ export class UIMeshRenderer extends Component { * @zh 渲染数据组装程序,这个方法会在所有子节点数据组装之前更新并组装当前组件的渲染数据到 UI 的顶点数据缓冲区中。 * 一般在 UI 渲染流程中调用,用于组装所有的渲染数据到顶点数据缓冲区。 * 注意:不要手动调用该函数,除非你理解整个流程。 + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. */ public _render (render: IBatcher) { if (this._modelComponent) { @@ -143,12 +145,18 @@ export class UIMeshRenderer extends Component { return false; } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public fillBuffers (render: IBatcher) { if (this.enabled) { this._render(render); } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ // Native updateAssembler public updateRenderer () { if (JSB) { @@ -157,13 +165,13 @@ export class UIMeshRenderer extends Component { const models = this._modelComponent._collectModels(); // @ts-expect-error: UIMeshRenderer do not attachToScene this._modelComponent._detachFromScene(); // JSB - if (models.length !== this.modelCount) { - for (let i = this.modelCount; i < models.length; i++) { - this._uploadRenderData(i); - this._UIModelNativeProxy.updateModels(models[i]); - } + // clear models + this._UIModelNativeProxy.clearModels(); + this._renderEntity.clearDynamicRenderDrawInfos(); + for (let i = 0; i < models.length; i++) { + this._uploadRenderData(i); + this._UIModelNativeProxy.updateModels(models[i]); } - this.modelCount = models.length; this._UIModelNativeProxy.attachDrawInfo(); } } @@ -194,10 +202,7 @@ export class UIMeshRenderer extends Component { public update () { if (JSB) { if (this._modelComponent) { - const models = this._modelComponent._collectModels(); - if (models.length !== this.modelCount) { - this.markForUpdateRenderData(); - } + this.markForUpdateRenderData(); } } this._fitUIRenderQueue(); @@ -227,16 +232,28 @@ export class UIMeshRenderer extends Component { } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ // interface public markForUpdateRenderData (enable = true) { uiRendererManager.markDirtyRenderer(this); } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public stencilStage: Stage = Stage.DISABLED; + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setNodeDirty () { } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setTextureDirty () { } @@ -244,6 +261,9 @@ export class UIMeshRenderer extends Component { return (this.enabled && this._modelComponent !== null); } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ get renderEntity () { if (DEBUG) { assert(this._renderEntity, 'this._renderEntity should not be invalid'); @@ -252,9 +272,12 @@ export class UIMeshRenderer extends Component { } protected _renderData: RenderData | null = null; + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ get renderData () { return this._renderData; } } -legacyCC.UIMeshRenderer = UIMeshRenderer; +cclegacy.UIMeshRenderer = UIMeshRenderer; diff --git a/cocos/2d/components/ui-opacity.ts b/cocos/2d/components/ui-opacity.ts index a6d75ebe9fa..96a36be5a83 100644 --- a/cocos/2d/components/ui-opacity.ts +++ b/cocos/2d/components/ui-opacity.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, disallowMultiple, editable, executeInEditMode, executionOrder, help, menu, serializable, tooltip } from 'cc.decorator'; import { JSB } from 'internal:constants'; import { Component } from '../../scene-graph/component'; -import { clampf } from '../../core/utils/misc'; +import { misc } from '../../core'; import { UIRenderer } from '../framework/ui-renderer'; import { Node } from '../../scene-graph'; @@ -63,7 +62,7 @@ export class UIOpacity extends Component { if (this._opacity === value) { return; } - value = clampf(value, 0, 255); + value = misc.clampf(value, 0, 255); this._opacity = value; this.node._uiProps.localOpacity = value / 255; diff --git a/cocos/2d/components/ui-static-batch.ts b/cocos/2d/components/ui-static-batch.ts index 91f767eb5ae..987a3c363dc 100644 --- a/cocos/2d/components/ui-static-batch.ts +++ b/cocos/2d/components/ui-static-batch.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -45,6 +44,10 @@ import { director } from '../../game'; * 该组件放在所有需要被静态合批的节点对象的根节点上,子节点放置对象必须是精灵和文本,其余对象不参与静态合批。 * 用户必须通过手动方式启用收集静态合批数据[[markAsDirty]],否则合批方式仍然采用动态合批(采集数据的流程相同)。此后渲染的内容是采用收集到的合批渲染数据,子节点的任何修改将不再有效。 * 注意:子节点下不要放置 Mask,Graphics,以及 UI 模型或者粒子之类对象,否则会在启用完静态合批后跳过渲染。 + * + * @deprecated Since v3.4.1, We have adopted a new rendering batching policy in v3.4.1, + * which will result in an effective performance improvement for normal dynamic batching components, + * so manual management with the UIStaticBatch component is no longer recommended and will be removed in the future */ @ccclass('cc.UIStaticBatch') @help('i18n:cc.UIStaticBatch') diff --git a/cocos/2d/event/index.ts b/cocos/2d/event/index.ts index e849abf2454..37c0fa287ee 100644 --- a/cocos/2d/event/index.ts +++ b/cocos/2d/event/index.ts @@ -1 +1,25 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import './pointer-event-dispatcher'; diff --git a/cocos/2d/event/pointer-event-dispatcher.ts b/cocos/2d/event/pointer-event-dispatcher.ts index 0616b9cdbd8..8439612830c 100644 --- a/cocos/2d/event/pointer-event-dispatcher.ts +++ b/cocos/2d/event/pointer-event-dispatcher.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,7 +26,7 @@ import { Node } from '../../scene-graph/node'; import { Input, input } from '../../input'; import { Event, EventMouse, EventTouch } from '../../input/types'; import { DispatcherEventType, NodeEventProcessor } from '../../scene-graph/node-event-processor'; -import { js } from '../../core/utils/js'; +import { js } from '../../core'; import { InputEventType } from '../../input/types/event-enum'; import { EventDispatcherPriority, IEventDispatcher } from '../../input/input'; diff --git a/cocos/2d/framework/canvas.ts b/cocos/2d/framework/canvas.ts index 073702881b6..c37be72094d 100644 --- a/cocos/2d/framework/canvas.ts +++ b/cocos/2d/framework/canvas.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,13 +28,9 @@ import { ccclass, help, disallowMultiple, executeInEditMode, import { EDITOR } from 'internal:constants'; import { Camera } from '../../misc/camera-component'; import { Widget } from '../../ui/widget'; -import { Vec3 } from '../../core/math'; +import { Vec3, screen, Enum, cclegacy, visibleRect } from '../../core'; import { view } from '../../ui/view'; -import { legacyCC } from '../../core/global-exports'; -import { Enum } from '../../core/value-types/enum'; -import visibleRect from '../../core/platform/visible-rect'; import { RenderRoot2D } from './render-root-2d'; -import { screen } from '../../core'; import { NodeEventType } from '../../scene-graph/node-event'; const _worldPos = new Vec3(); @@ -89,6 +84,10 @@ export class Canvas extends RenderRoot2D { } } + /** + * @en The camera component that will be aligned with this canvas + * @zh 将与此 canvas 对齐的相机组件 + */ @type(Camera) @tooltip('i18n:canvas.camera') get cameraComponent () { @@ -103,6 +102,10 @@ export class Canvas extends RenderRoot2D { this._onResizeCamera(); } + /** + * @en Align canvas with screen + * @zh 是否使用屏幕对齐画布 + */ @tooltip('i18n:canvas.align') get alignCanvasWithScreen () { return this._alignCanvasWithScreen; @@ -114,12 +117,6 @@ export class Canvas extends RenderRoot2D { this._onResizeCamera(); } - // /** - // * @zh - // * 当前激活的画布组件,场景同一时间只能有一个激活的画布。 - // */ - // public static instance: Canvas | null = null; - @type(Camera) protected _cameraComponent: Camera | null = null; @serializable @@ -177,12 +174,12 @@ export class Canvas extends RenderRoot2D { if (EDITOR) { // Constantly align canvas node in edit mode - legacyCC.director.on(legacyCC.Director.EVENT_AFTER_UPDATE, this._fitDesignResolution!, this); + cclegacy.director.on(cclegacy.Director.EVENT_AFTER_UPDATE, this._fitDesignResolution!, this); // In Editor can not edit these attrs. // (Position in Node, contentSize in uiTransform) // (anchor in uiTransform, but it can edit, this is different from cocos creator) - this._objFlags |= legacyCC.Object.Flags.IsPositionLocked | legacyCC.Object.Flags.IsSizeLocked | legacyCC.Object.Flags.IsAnchorLocked; + this._objFlags |= cclegacy.Object.Flags.IsPositionLocked | cclegacy.Object.Flags.IsSizeLocked | cclegacy.Object.Flags.IsAnchorLocked; } else { // In Editor dont need resized camera when scene window resize this.node.on(NodeEventType.TRANSFORM_CHANGED, this._thisOnCameraResized); @@ -207,7 +204,7 @@ export class Canvas extends RenderRoot2D { super.onDestroy(); if (EDITOR) { - legacyCC.director.off(legacyCC.Director.EVENT_AFTER_UPDATE, this._fitDesignResolution!, this); + cclegacy.director.off(cclegacy.Director.EVENT_AFTER_UPDATE, this._fitDesignResolution!, this); } else { this.node.off(NodeEventType.TRANSFORM_CHANGED, this._thisOnCameraResized); } @@ -238,4 +235,4 @@ export class Canvas extends RenderRoot2D { } } -legacyCC.Canvas = Canvas; +cclegacy.Canvas = Canvas; diff --git a/cocos/2d/framework/deprecated-1.2.0.ts b/cocos/2d/framework/deprecated-1.2.0.ts index fa046b78937..efd61906a13 100644 --- a/cocos/2d/framework/deprecated-1.2.0.ts +++ b/cocos/2d/framework/deprecated-1.2.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { deprecateModuleExportedName } from '../../core/utils/x-deprecated'; +import { deprecateModuleExportedName } from '../../core'; deprecateModuleExportedName({ RenderComponent: { diff --git a/cocos/2d/framework/deprecated-3.0.0.ts b/cocos/2d/framework/deprecated-3.0.0.ts index 33415e7524c..27c0aaf8179 100644 --- a/cocos/2d/framework/deprecated-3.0.0.ts +++ b/cocos/2d/framework/deprecated-3.0.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { deprecateModuleExportedName } from '../../core/utils/x-deprecated'; +import { deprecateModuleExportedName } from '../../core'; deprecateModuleExportedName({ UIRenderable: { diff --git a/cocos/2d/framework/deprecated-3.6.0.ts b/cocos/2d/framework/deprecated-3.6.0.ts index 16a6220d62f..e10115c7887 100644 --- a/cocos/2d/framework/deprecated-3.6.0.ts +++ b/cocos/2d/framework/deprecated-3.6.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { deprecateModuleExportedName } from '../../core/utils/x-deprecated'; +import { deprecateModuleExportedName } from '../../core'; deprecateModuleExportedName({ Renderable2D: { newName: 'UIRenderer', since: '3.6.0', - removed: true, + removed: false, }, }); diff --git a/cocos/2d/framework/deprecated.ts b/cocos/2d/framework/deprecated.ts index 69223363d98..960a813b7a9 100644 --- a/cocos/2d/framework/deprecated.ts +++ b/cocos/2d/framework/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/no-unsafe-return */ -import { markAsWarning, removeProperty, replaceProperty } from '../../core/utils'; +import { markAsWarning, removeProperty, replaceProperty, js, Color, cclegacy } from '../../core'; import { UIComponent } from './ui-component'; import { UITransform } from './ui-transform'; import { UIRenderer } from './ui-renderer'; import { Canvas } from './canvas'; -import { js } from '../../core/utils/js'; -import { legacyCC } from '../../core/global-exports'; -import { Color } from '../../core/math/color'; removeProperty(UIComponent.prototype, 'UIComponent', [ { @@ -130,7 +126,7 @@ markAsWarning(UITransform.prototype, 'UITransform.prototype', [ * @deprecated Since v1.2 */ export { UITransform as UITransformComponent }; -legacyCC.UITransformComponent = UITransform; +cclegacy.UITransformComponent = UITransform; js.setClassAlias(UITransform, 'cc.UITransformComponent'); /** @@ -150,7 +146,7 @@ js.setClassAlias(UIRenderer, 'cc.RenderComponent'); * @deprecated Since v1.2 */ export { Canvas as CanvasComponent }; -legacyCC.CanvasComponent = Canvas; +cclegacy.CanvasComponent = Canvas; js.setClassAlias(Canvas, 'cc.CanvasComponent'); /** @@ -158,5 +154,5 @@ js.setClassAlias(Canvas, 'cc.CanvasComponent'); * @deprecated Since v3.6 */ export { UIRenderer as Renderable2D }; -legacyCC.internal.Renderable2D = UIRenderer; +cclegacy.internal.Renderable2D = UIRenderer; js.setClassAlias(UIRenderer, 'cc.Renderable2D'); diff --git a/cocos/2d/framework/index.ts b/cocos/2d/framework/index.ts index acc838ba808..2ebd077990c 100644 --- a/cocos/2d/framework/index.ts +++ b/cocos/2d/framework/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/2d/framework/render-root-2d.ts b/cocos/2d/framework/render-root-2d.ts index 73322c6ee75..faacc9441c4 100644 --- a/cocos/2d/framework/render-root-2d.ts +++ b/cocos/2d/framework/render-root-2d.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,9 +25,13 @@ import { ccclass, disallowMultiple, executeInEditMode, executionOrder, menu, requireComponent } from 'cc.decorator'; import { Component } from '../../scene-graph/component'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { UITransform } from './ui-transform'; +/** + * @en The entry node for 2D object data collection, all 2D rendering objects need to be rendered under the RenderRoot node. + * @zh 2D 对象数据收集的入口节点,所有的 2D渲染对象需在 RenderRoot 节点下才可以被渲染。 + */ @ccclass('cc.RenderRoot2D') @executionOrder(100) @menu('2D/RenderRoot2D') @@ -37,14 +40,14 @@ import { UITransform } from './ui-transform'; @executeInEditMode export class RenderRoot2D extends Component { public onEnable () { - legacyCC.director.root!.batcher2D.addScreen(this); + cclegacy.director.root!.batcher2D.addScreen(this); } public onDisable () { - legacyCC.director.root!.batcher2D.removeScreen(this); + cclegacy.director.root!.batcher2D.removeScreen(this); } public onDestroy () { - legacyCC.director.root!.batcher2D.removeScreen(this); + cclegacy.director.root!.batcher2D.removeScreen(this); } } diff --git a/cocos/2d/framework/sprite-renderer.ts b/cocos/2d/framework/sprite-renderer.ts index f2982c1ec7e..84cd1b71f0e 100644 --- a/cocos/2d/framework/sprite-renderer.ts +++ b/cocos/2d/framework/sprite-renderer.ts @@ -1,14 +1,14 @@ /* - Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -25,8 +25,7 @@ import { ccclass, executeInEditMode, executionOrder, help, menu, serializable, type, visible } from 'cc.decorator'; import { builtinResMgr } from '../../asset/asset-manager'; import { Material } from '../../asset/assets'; -import { Color, Vec2 } from '../../core'; -import { legacyCC } from '../../core/global-exports'; +import { Color, Vec2, cclegacy } from '../../core'; import { ModelLocalBindings } from '../../rendering/define'; import { Model } from '../../render-scene/scene'; import { Root } from '../../root'; @@ -51,8 +50,8 @@ enum SpriteMode { @executeInEditMode export class SpriteRenderer extends ModelRenderer { /** - * @en The spriteFrame that the component should render - * @zh 该组件应渲染的 spriteFrame + * @en The spriteFrame that the component should render. + * @zh 该组件应渲染的 spriteFrame。 */ @type(SpriteFrame) get spriteFrame () { @@ -79,8 +78,8 @@ export class SpriteRenderer extends ModelRenderer { } /** - * @en Rendering model of the component - * @zh 该组件的渲染模型 + * @en Rendering model of the component. + * @zh 该组件的渲染模型。 */ get model () { return this._model; @@ -134,7 +133,7 @@ export class SpriteRenderer extends ModelRenderer { public onDestroy () { if (this._model) { - legacyCC.director.root.destroyModel(this._model); + cclegacy.director.root.destroyModel(this._model); this._model = null; this._models.length = 0; } @@ -163,7 +162,7 @@ export class SpriteRenderer extends ModelRenderer { } protected _createModel () { - const model = this._model = (legacyCC.director.root as Root).createModel(Model); + const model = this._model = (cclegacy.director.root as Root).createModel(Model); model.visFlags = this.visibility; model.node = model.transform = this.node; this._models.length = 0; diff --git a/cocos/2d/framework/ui-component.ts b/cocos/2d/framework/ui-component.ts index ae9b35bc1b3..80ea93a6bc7 100644 --- a/cocos/2d/framework/ui-component.ts +++ b/cocos/2d/framework/ui-component.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,10 +31,10 @@ import { Stage } from '../renderer/stencil-manager'; /** * @en Legacy 2D base class for rendering component, please use [[UIRenderer]] instead. - * This component will setup NodeUIProperties.uiComp in its owner [[Node]] + * This component will setup NodeUIProperties.uiComp in its owner [[Node]]. * @zh 旧的 2D 渲染组件基类,请使用 [[UIRenderer]] 替代。 * 这个组件会设置 [[Node]] 上的 NodeUIProperties.uiComp。 - * @deprecated since v3.4.1 + * @deprecated since v3.4.1, please use [[UIRenderer]] instead. */ @ccclass('cc.UIComponent') @requireComponent(UITransform) @@ -72,18 +71,31 @@ export class UIComponent extends Component { * @zh 后置渲染数据组装程序,它会在所有子节点的渲染数据组装完成后被调用。 * 它可能会组装额外的渲染数据到顶点数据缓冲区,也可能只是重置一些渲染状态。 * 注意:不要手动调用该函数,除非你理解整个流程。 + * @deprecated since v3.4.1, please use [[UIRenderer]] instead. */ public postUpdateAssembler (render: IBatcher) { } + /** + * @deprecated since v3.4.1, please use [[UIRenderer]] instead. + */ public markForUpdateRenderData (enable = true) { } - public stencilStage : Stage = Stage.DISABLED; + /** + * @deprecated since v3.4.1, please use [[UIRenderer]] instead. + */ + public stencilStage: Stage = Stage.DISABLED; + /** + * @deprecated since v3.4.1, please use [[UIRenderer]] instead. + */ public setNodeDirty () { } + /** + * @deprecated since v3.4.1, please use [[UIRenderer]] instead. + */ public setTextureDirty () { } } diff --git a/cocos/2d/framework/ui-renderer-manager.ts b/cocos/2d/framework/ui-renderer-manager.ts index 3d598477d8c..3971749e97a 100644 --- a/cocos/2d/framework/ui-renderer-manager.ts +++ b/cocos/2d/framework/ui-renderer-manager.ts @@ -1,6 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { DEBUG } from 'internal:constants'; -import { assert } from '../../core/platform/debug'; -import { js } from '../../core/utils/js'; +import { assert, js } from '../../core'; import { UIMeshRenderer } from '../components'; import { UIRenderer } from './ui-renderer'; diff --git a/cocos/2d/framework/ui-renderer.ts b/cocos/2d/framework/ui-renderer.ts index bbf736601a2..cc5e26b4631 100644 --- a/cocos/2d/framework/ui-renderer.ts +++ b/cocos/2d/framework/ui-renderer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,8 +27,7 @@ import { ccclass, executeInEditMode, requireComponent, tooltip, type, displayOrder, serializable, override, visible, displayName, disallowAnimation, } from 'cc.decorator'; -import { Color } from '../../core/math'; -import { ccenum } from '../../core/value-types/enum'; +import { Color, assert, ccenum, cclegacy } from '../../core'; import { builtinResMgr } from '../../asset/asset-manager'; import { Material } from '../../asset/assets'; import { BlendFactor } from '../../gfx'; @@ -40,12 +38,10 @@ import { Node } from '../../scene-graph'; import { TransformBit } from '../../scene-graph/node-enum'; import { UITransform } from './ui-transform'; import { Stage } from '../renderer/stencil-manager'; -import { legacyCC } from '../../core/global-exports'; import { NodeEventType } from '../../scene-graph/node-event'; import { Renderer } from '../../misc/renderer'; import { RenderEntity, RenderEntityType } from '../renderer/render-entity'; import { uiRendererManager } from './ui-renderer-manager'; -import { assert } from '../../core'; import { RenderDrawInfoType } from '../renderer/render-draw-info'; import { director } from '../../game'; @@ -121,16 +117,19 @@ export class UIRenderer extends Renderer { * @en The blend factor enums * @zh 混合模式枚举类型 * @see [[gfx.BlendFactor]] + * @internal */ public static BlendState = BlendFactor; /** * @en The render data assembler * @zh 渲染数据组装器 + * @internal */ public static Assembler: IAssemblerManager = null!; /** * @en The post render data assembler * @zh 后置渲染数据组装器 + * @internal */ public static PostAssembler: IAssemblerManager | null = null; @@ -201,21 +200,21 @@ export class UIRenderer extends Renderer { protected _renderData: RenderData | null = null; /** - * @internal + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. */ get renderData () { return this._renderData; } /** - * @internal + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. */ get useVertexOpacity () { return this._useVertexOpacity; } /** - * @internal + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. * @en The component stencil stage (please do not any modification directly on this object) * @zh 组件模板缓冲状态 (注意:请不要直接修改它的值) */ @@ -254,19 +253,26 @@ export class UIRenderer extends Renderer { protected _instanceMaterialType = -1; protected _srcBlendFactorCache = BlendFactor.SRC_ALPHA; protected _dstBlendFactorCache = BlendFactor.ONE_MINUS_SRC_ALPHA; + /** - * @internal + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. */ public _dirtyVersion = -1; /** - * @internal + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. */ public _internalId = -1; + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ get batcher () { return director.root!.batcher2D; } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ get renderEntity () { if (DEBUG) { assert(this._renderEntity, 'this._renderEntity should not be invalid'); @@ -351,7 +357,7 @@ export class UIRenderer extends Renderer { /** * @en Request new render data object. * @zh 请求新的渲染数据对象。 - * @return The new render data + * @return @en The new render data. @zh 新的渲染数据。 */ public requestRenderData (drawInfoType = RenderDrawInfoType.COMP) { const data = RenderData.add(); @@ -373,7 +379,9 @@ export class UIRenderer extends Renderer { this._renderData = null; } - // test code: to replace prev part updateAssembler + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public updateRenderer () { if (this._assembler) { this._assembler.updateRenderData(this); @@ -382,7 +390,9 @@ export class UIRenderer extends Renderer { this._renderEntity.enabled = this._renderFlag; } - // test code: to replace after part updateAssembler + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public fillBuffers (render: IBatcher) { if (this._renderFlag) { this._render(render); @@ -420,7 +430,9 @@ export class UIRenderer extends Renderer { protected updateMaterial () { if (this._customMaterial) { - this.setMaterial(this._customMaterial, 0); + if (this.getMaterial(0) !== this._customMaterial) { + this.setMaterial(this._customMaterial, 0); + } return; } const mat = this._updateBuiltinMaterial(); @@ -445,6 +457,9 @@ export class UIRenderer extends Renderer { } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ // for common public static setEntityColorDirtyRecursively (node: Node, dirty: boolean) { const render = node._uiProps.uiComp as UIRenderer; @@ -462,18 +477,27 @@ export class UIRenderer extends Renderer { } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setEntityColor (color: Color) { if (JSB) { this._renderEntity.color = color; } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setEntityOpacity (opacity: number) { if (JSB) { this._renderEntity.localOpacity = opacity; } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setEntityEnabled (enabled: boolean) { if (JSB) { this._renderEntity.enabled = enabled; @@ -555,12 +579,18 @@ export class UIRenderer extends Renderer { protected _flushAssembler?(): void; + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setNodeDirty () { if (this.renderData) { this.renderData.nodeDirty = true; } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setTextureDirty () { if (this.renderData) { this.renderData.textureDirty = true; @@ -574,4 +604,4 @@ export class UIRenderer extends Renderer { } } -legacyCC.internal.UIRenderer = UIRenderer; +cclegacy.internal.UIRenderer = UIRenderer; diff --git a/cocos/2d/framework/ui-transform.ts b/cocos/2d/framework/ui-transform.ts index 3312438b998..cc4ca5295a7 100644 --- a/cocos/2d/framework/ui-transform.ts +++ b/cocos/2d/framework/ui-transform.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,13 +25,9 @@ import { ccclass, help, executeInEditMode, executionOrder, menu, tooltip, displayOrder, serializable, disallowMultiple } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; import { Component, Node } from '../../scene-graph'; -import { Mat4, Rect, Size, Vec2, Vec3 } from '../../core/math'; -import { AABB } from '../../core/geometry'; +import { Mat4, Rect, Size, Vec2, Vec3, geometry, warnID, visibleRect, approx, EPSILON } from '../../core'; import { Director, director } from '../../game/director'; -import { warnID } from '../../core/platform/debug'; import { NodeEventType } from '../../scene-graph/node-event'; -import visibleRect from '../../core/platform/visible-rect'; -import { approx, EPSILON } from '../../core/math/utils'; import { IMask } from '../../scene-graph/node-event-processor'; import { Mask } from '../components/mask'; @@ -67,7 +62,6 @@ export class UITransform extends Component { */ @displayOrder(0) @tooltip('i18n:ui_transform.content_size') - // @constget get contentSize (): Readonly { return this._contentSize; } @@ -92,6 +86,12 @@ export class UITransform extends Component { this._markRenderDataDirty(); } + /** + * @en + * component width. + * @zh + * 组件宽度。 + */ get width () { return this._contentSize.width; } @@ -116,6 +116,12 @@ export class UITransform extends Component { this._markRenderDataDirty(); } + /** + * @en + * component height. + * @zh + * 组件高度。 + */ get height () { return this._contentSize.height; } @@ -164,6 +170,13 @@ export class UITransform extends Component { this._markRenderDataDirty(); } + /** + * @en + * The x-axis anchor of the node. + * + * @zh + * 锚点位置的 X 坐标。 + */ get anchorX () { return this._anchorPoint.x; } @@ -178,6 +191,13 @@ export class UITransform extends Component { this._markRenderDataDirty(); } + /** + * @en + * The y-axis anchor of the node. + * + * @zh + * 锚点位置的 Y 坐标。 + */ get anchorY () { return this._anchorPoint.y; } @@ -199,7 +219,7 @@ export class UITransform extends Component { * * @zh * 渲染先后顺序,按照广度渲染排列,按同级节点下进行一次排列。 - * @deprecated + * @deprecated Since v3.1 */ get priority () { return this._priority; @@ -279,14 +299,14 @@ export class UITransform extends Component { * @zh * 设置节点 UI Transform 的原始大小,不受该节点是否被缩放或者旋转的影响。 * - * @param size - The size of the UI transformation. + * @param size @en The size of the UI transform. @zh UI Transform 的 Size 大小。 * @example * ```ts * import { Size } from 'cc'; * node.setContentSize(new Size(100, 100)); * ``` */ - public setContentSize(size: Size) : void; + public setContentSize(size: Size): void; /** * @en @@ -295,15 +315,15 @@ export class UITransform extends Component { * @zh * 设置节点 UI Transform 的原始大小,不受该节点是否被缩放或者旋转的影响。 * - * @param width - The width of the UI transformation. - * @param height - The height of the UI transformation. + * @param width @en The width of the UI transform. @zh UI Transform 的宽。 + * @param height @en The height of the UI transform. @zh UI Transform 的高。 * @example * ```ts * import { Size } from 'cc'; * node.setContentSize(100, 100); * ``` */ - public setContentSize(width: number, height: number) : void; + public setContentSize(width: number, height: number): void; public setContentSize (size: Size | number, height?: number) { const locContentSize = this._contentSize; @@ -448,7 +468,7 @@ export class UITransform extends Component { * @zh 屏幕空间中的点击测试。 * @en Hit test with point in Screen Space. * - * @param screenPoint point in Screen Space. + * @param screenPoint @en point in Screen Space. @zh 屏幕坐标中的点。 */ public hitTest (screenPoint: Vec2, windowId = 0) { const w = this._contentSize.width; @@ -579,13 +599,13 @@ export class UITransform extends Component { /** * @en - * Returns a "local" axis aligned bounding box of the node.
+ * Returns an axis aligned bounding box of this node in local space coordinate.
* The returned box is relative only to its parent. * * @zh * 返回父节坐标系下的轴向对齐的包围盒。 * - * @return - 节点大小的包围盒 + * @returns @en An axis aligned bounding box of this node in local space coordinate. @zh 本地坐标系下的包围盒。 * @example * ```ts * const boundingBox = uiTransform.getBoundingBox(); @@ -607,14 +627,14 @@ export class UITransform extends Component { /** * @en - * Returns a "world" axis aligned bounding box of the node.
+ * Returns an axis aligned bounding box of this node in world space coordinate.
* The bounding box contains self and active children's world bounding box. * * @zh * 返回节点在世界坐标系下的对齐轴向的包围盒(AABB)。 * 该边框包含自身和已激活的子节点的世界边框。 * - * @returns - 返回世界坐标系下包围盒。 + * @returns @en An axis aligned bounding box of this node in world space coordinate. @zh 世界坐标系下包围盒。 * @example * ```ts * const newRect = uiTransform.getBoundingBoxToWorld(); @@ -622,8 +642,8 @@ export class UITransform extends Component { */ public getBoundingBoxToWorld () { if (this.node.parent) { - this.node.parent.getWorldMatrix(_worldMatrix); - return this.getBoundingBoxTo(_worldMatrix); + const m = this.node.parent.getWorldMatrix(); + return this.getBoundingBoxTo(m); } return this.getBoundingBox(); } @@ -637,7 +657,8 @@ export class UITransform extends Component { * * @param parentMat @en The parent node matrix. * @zh 父节点矩阵。 - * @returns + * @returns @en The minimum bounding box containing the current bounding box and its child nodes. + * @zh 包含当前节点包围盒及其子节点包围盒的最小包围盒。 */ public getBoundingBoxTo (parentMat: Mat4) { Mat4.fromRTS(_matrix, this.node.getRotation(), this.node.getPosition(), this.node.getScale()); @@ -654,7 +675,7 @@ export class UITransform extends Component { rect.transformMat4(_worldMatrix); // query child's BoundingBox - if (!this.node.children) { + if (!this.node.children || this.node.children.length === 0) { return rect; } @@ -679,9 +700,11 @@ export class UITransform extends Component { * Compute the corresponding aabb in world space for raycast. * * @zh - * 计算出此 UI_2D 节点在世界空间下的 aabb 包围盒 + * 计算出此 UI_2D 节点在世界空间下的 aabb 包围盒。 + * @param out @en The out object of aabb bounding box of the node in world space. @zh 输出节点在世界空间下的 aabb 包围盒。 + * @returns @en The aabb bounding box of the node in world space. @zh 节点在世界空间下的 aabb 包围盒。 */ - public getComputeAABB (out?: AABB) { + public getComputeAABB (out?: geometry.AABB) { const width = this._contentSize.width; const height = this._contentSize.height; _rect.set( @@ -698,10 +721,10 @@ export class UITransform extends Component { const h = _rect.height / 2; const l = 0.001; if (out != null) { - AABB.set(out, px, py, pz, w, h, l); + geometry.AABB.set(out, px, py, pz, w, h, l); return out; } else { - return new AABB(px, py, pz, w, h, l); + return new geometry.AABB(px, py, pz, w, h, l); } } @@ -734,7 +757,7 @@ export class UITransform extends Component { private static _sortChildrenSibling (node) { const siblings = node.children; if (siblings) { - siblings.sort((a:Node, b:Node) => { + siblings.sort((a: Node, b: Node) => { const aComp = a._uiProps.uiTransformComp; const bComp = b._uiProps.uiTransformComp; const ca = aComp ? aComp._priority : 0; @@ -746,6 +769,10 @@ export class UITransform extends Component { } } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + * @engineInternal + */ public static _sortSiblings () { UITransform.priorityChangeNodeMap.forEach((node, ID) => { UITransform._sortChildrenSibling(node); @@ -755,6 +782,10 @@ export class UITransform extends Component { UITransform.priorityChangeNodeMap.clear(); } + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + * @engineInternal + */ public static _cleanChangeMap () { UITransform.priorityChangeNodeMap.clear(); } diff --git a/cocos/2d/index.ts b/cocos/2d/index.ts index 4a43401e4a1..296768138a7 100644 --- a/cocos/2d/index.ts +++ b/cocos/2d/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { - CanvasPool, graphicsAssembler, labelAssembler, spriteAssembler, - earcut, } from './assembler'; import { RenderData, MeshRenderData } from './renderer/render-data'; import { MeshBuffer } from './renderer/mesh-buffer'; import { StencilManager } from './renderer/stencil-manager'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import './event'; import './renderer/batcher-2d'; @@ -49,18 +46,16 @@ export * from './utils'; export { MeshBuffer, StencilManager, - CanvasPool, - spriteAssembler, - labelAssembler, - graphicsAssembler, - earcut, + spriteAssembler, // use less + labelAssembler, // use less + graphicsAssembler, // use less }; -legacyCC.UI = { - MeshBuffer, - spriteAssembler, - graphicsAssembler, - labelAssembler, +cclegacy.UI = { + MeshBuffer, // use less + spriteAssembler, // use less + graphicsAssembler, // use less + labelAssembler, // use less RenderData, MeshRenderData, }; diff --git a/cocos/2d/renderer/base.ts b/cocos/2d/renderer/base.ts index b7d67976490..20312364a90 100644 --- a/cocos/2d/renderer/base.ts +++ b/cocos/2d/renderer/base.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -30,10 +29,16 @@ import { UIRenderer } from '../framework/ui-renderer'; +/** + * @internal + */ export interface IAssembler { [key: string]: any; } +/** + * @internal + */ export interface IAssemblerManager { getAssembler (component: UIRenderer): IAssembler; } diff --git a/cocos/2d/renderer/batcher-2d.ts b/cocos/2d/renderer/batcher-2d.ts index 4b8bbcd99e7..e00a2ac3553 100644 --- a/cocos/2d/renderer/batcher-2d.ts +++ b/cocos/2d/renderer/batcher-2d.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,27 +22,23 @@ THE SOFTWARE. */ -import { JSB } from 'internal:constants'; +import { DEBUG, JSB } from 'internal:constants'; import { Camera, Model } from '../../render-scene/scene'; import type { UIStaticBatch } from '../components/ui-static-batch'; import { Material } from '../../asset/assets/material'; import { RenderRoot2D, UIRenderer } from '../framework'; import { Texture, Device, Attribute, Sampler, DescriptorSetInfo, Buffer, BufferInfo, BufferUsageBit, MemoryUsageBit, DescriptorSet, InputAssembler, deviceManager, PrimitiveMode } from '../../gfx'; -import { Pool } from '../../core/memop'; -import { CachedArray } from '../../core/memop/cached-array'; +import { CachedArray, Pool, Mat4, cclegacy, assertIsTrue, assert } from '../../core'; import { Root } from '../../root'; import { Node } from '../../scene-graph'; import { Stage, StencilManager } from './stencil-manager'; import { DrawBatch2D } from './draw-batch'; -import { legacyCC } from '../../core/global-exports'; import { ModelLocalBindings, UBOLocal } from '../../rendering/define'; import { SpriteFrame } from '../assets'; import { TextureBase } from '../../asset/assets/texture-base'; -import { Mat4 } from '../../core/math'; import { IBatcher } from './i-batcher'; import { StaticVBAccessor } from './static-vb-accessor'; -import { assertIsTrue } from '../../core/data/utils/asserts'; import { getAttributeStride, vfmt, vfmtPosUvColor } from './vertex-format'; import { updateOpacity } from '../assembler/utils'; import { BaseRenderData, MeshRenderData } from './render-data'; @@ -58,6 +53,8 @@ const _dsInfo = new DescriptorSetInfo(null!); const m4_1 = new Mat4(); /** + * @en + * UI render flow * @zh * UI 渲染流程 */ @@ -124,12 +121,12 @@ export class Batcher2D implements IBatcher { // DescriptorSet Cache Map private _descriptorSetCache = new DescriptorSetCache(); - private _meshDataArray :MeshRenderData[] = []; + private _meshDataArray: MeshRenderData[] = []; // mask use - private _maskClearModel :Model | null = null; - private _maskClearMtl :Material | null = null; - private _maskModelMesh :RenderingSubMesh | null = null; + private _maskClearModel: Model | null = null; + private _maskClearMtl: Material | null = null; + private _maskModelMesh: RenderingSubMesh | null = null; constructor (private _root: Root) { this.device = _root.device; @@ -149,9 +146,9 @@ export class Batcher2D implements IBatcher { } this._batches.destroy(); - this._bufferAccessors.forEach((accessor: StaticVBAccessor) => { + for (const accessor of this._bufferAccessors.values()) { accessor.destroy(); - }); + } this._bufferAccessors.clear(); if (this._drawBatchPool) { @@ -163,7 +160,7 @@ export class Batcher2D implements IBatcher { StencilManager.sharedManager!.destroy(); if (this._maskClearModel && this._maskModelMesh) { - legacyCC.director.root.destroyModel(this._maskClearModel); + cclegacy.director.root.destroyModel(this._maskClearModel); this._maskModelMesh.destroy(); } if (this._maskClearMtl) { @@ -281,14 +278,15 @@ export class Batcher2D implements IBatcher { if (JSB) { this._nativeObj.uploadBuffers(); } else if (this._batches.length > 0) { - this._meshDataArray.forEach((rd) => { - rd.uploadBuffers(); - }); + const length = this._meshDataArray.length; + for (let i = 0; i < length; i++) { + this._meshDataArray[i].uploadBuffers(); + } - this._bufferAccessors.forEach((accessor: StaticVBAccessor) => { + for (const accessor of this._bufferAccessors.values()) { accessor.uploadBuffers(); accessor.reset(); - }); + } this._descriptorSetCache.update(); } @@ -308,12 +306,13 @@ export class Batcher2D implements IBatcher { this._drawBatchPool.free(batch); } // Reset buffer accessors - this._bufferAccessors.forEach((accessor: StaticVBAccessor) => { + for (const accessor of this._bufferAccessors.values()) { accessor.reset(); - }); - this._meshDataArray.forEach((rd) => { - rd.freeIAPool(); - }); + } + const length = this._meshDataArray.length; + for (let i = 0; i < length; i++) { + this._meshDataArray[i].freeIAPool(); + } this._meshDataArray.length = 0; this._staticVBBuffer = null; @@ -416,6 +415,9 @@ export class Batcher2D implements IBatcher { this._currDepthStencilStateStage = depthStencilStateStage; this._currLayer = comp.node.layer; if (frame) { + if (DEBUG) { + assert(frame.isValid, 'frame should not be invalid, it may have been released'); + } this._currTexture = frame.getGFXTexture(); this._currSampler = frame.getGFXSampler(); this._currTextureHash = frame.getHash(); @@ -556,7 +558,7 @@ export class Batcher2D implements IBatcher { dssHash = StencilManager.sharedManager!.getStencilHash(comp.stencilStage); } - const stamp = legacyCC.director.getTotalFrames(); + const stamp = cclegacy.director.getTotalFrames(); if (model) { model.updateTransform(stamp); model.updateUBOs(stamp); @@ -860,7 +862,7 @@ export class Batcher2D implements IBatcher { if (!this._maskClearModel) { this._maskClearMtl = builtinResMgr.get('default-clear-stencil'); - this._maskClearModel = legacyCC.director.root.createModel(scene.Model); + this._maskClearModel = cclegacy.director.root.createModel(scene.Model); const stride = getAttributeStride(vfmt); const gfxDevice: Device = deviceManager.gfxDevice; const vertexBuffer = gfxDevice.createBuffer(new BufferInfo( @@ -906,7 +908,7 @@ export class Batcher2D implements IBatcher { } const model = this._maskClearModel!; - const stamp = legacyCC.director.getTotalFrames(); + const stamp = cclegacy.director.getTotalFrames(); if (model) { model.updateTransform(stamp); model.updateUBOs(stamp); @@ -933,10 +935,7 @@ export class Batcher2D implements IBatcher { //sync mesh buffer to naive public syncMeshBuffersToNative (accId: number, buffers: MeshBuffer[]) { if (JSB) { - const nativeBuffers:NativeUIMeshBuffer[] = []; - buffers.forEach((x) => { - nativeBuffers.push(x.nativeObj); - }); + const nativeBuffers = buffers.map((buf) => buf.nativeObj); this._nativeObj.syncMeshBuffersToNative(accId, nativeBuffers); } } @@ -1052,7 +1051,7 @@ class DescriptorSetCache { } public getDescriptorSet (batch: DrawBatch2D): DescriptorSet { - const root = legacyCC.director.root; + const root = cclegacy.director.root; let hash; if (batch.useLocalData) { const caches = this._localDescriptorSetCache; @@ -1088,8 +1087,11 @@ class DescriptorSetCache { public update () { const caches = this._localDescriptorSetCache; + const length = caches.length; + if (length === 0) { return; } const uselessArray: number[] = []; - caches.forEach((value) => { + for (let i = 0; i < length; i++) { + const value = caches[i]; if (value.isValid()) { value.uploadLocalData(); } else { @@ -1097,7 +1099,7 @@ class DescriptorSetCache { const pos = caches.indexOf(value); uselessArray.push(pos); } - }); + } for (let i = uselessArray.length - 1; i >= 0; i--) { caches.splice(uselessArray[i], 1); } @@ -1105,9 +1107,11 @@ class DescriptorSetCache { public reset () { const caches = this._localDescriptorSetCache; - caches.forEach((value) => { + const length = caches.length; + for (let i = 0; i < length; i++) { + const value = caches[i]; this._localCachePool.free(value); - }); + } this._localDescriptorSetCache.length = 0; } @@ -1121,9 +1125,9 @@ class DescriptorSetCache { } public destroy () { - this._descriptorSetCache.forEach((value, key, map) => { + for (const value of this._descriptorSetCache.values()) { value.destroy(); - }); + } this._descriptorSetCache.clear(); this._dsCacheHashByTexture.clear(); this._localDescriptorSetCache.length = 0; @@ -1131,4 +1135,4 @@ class DescriptorSetCache { } } -legacyCC.internal.Batcher2D = Batcher2D; +cclegacy.internal.Batcher2D = Batcher2D; diff --git a/cocos/2d/renderer/buffer-accessor.ts b/cocos/2d/renderer/buffer-accessor.ts index a8044d6d54b..8ef1612a51e 100644 --- a/cocos/2d/renderer/buffer-accessor.ts +++ b/cocos/2d/renderer/buffer-accessor.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,7 +24,7 @@ import { Attribute, Device } from '../../gfx'; import type { MeshBuffer } from './mesh-buffer'; -import { getAttributeStride, getComponentPerVertex } from './vertex-format'; +import { getAttributeStride } from './vertex-format'; export class BufferAccessor { public get attributes (): Readonly { return this._attributes; } diff --git a/cocos/2d/renderer/deprecated.ts b/cocos/2d/renderer/deprecated.ts index fb79fba44a6..36ced8f1d73 100644 --- a/cocos/2d/renderer/deprecated.ts +++ b/cocos/2d/renderer/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import * as VertexFormat from './vertex-format'; import { Batcher2D } from './batcher-2d'; import { DrawBatch2D } from './draw-batch'; -import { markAsWarning, replaceProperty, removeProperty } from '../../core/utils/x-deprecated'; +import { markAsWarning, replaceProperty, removeProperty, warnID } from '../../core'; import { MeshBuffer } from './mesh-buffer'; import { MeshRenderData } from './render-data'; -import { warnID } from '../../core'; export { VertexFormat as UIVertexFormat }; diff --git a/cocos/2d/renderer/draw-batch.ts b/cocos/2d/renderer/draw-batch.ts index c497ff548bb..333bcbe654a 100644 --- a/cocos/2d/renderer/draw-batch.ts +++ b/cocos/2d/renderer/draw-batch.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Material } from '../../asset/assets/material'; import { Texture, Sampler, InputAssembler, DescriptorSet, Shader } from '../../gfx'; import { Node } from '../../scene-graph'; import { Model } from '../../render-scene/scene/model'; import { Layers } from '../../scene-graph/layers'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { Pass } from '../../render-scene/core/pass'; import { IBatcher } from './i-batcher'; @@ -115,7 +114,7 @@ export class DrawBatch2D { for (let i = 0; i < passes.length; i++) { if (!this._passes[i]) { - this._passes[i] = new Pass(legacyCC.director.root); + this._passes[i] = new Pass(cclegacy.director.root); } const mtlPass = passes[i]; const passInUse = this._passes[i]; diff --git a/cocos/2d/renderer/i-batcher.ts b/cocos/2d/renderer/i-batcher.ts index f1a7733c38c..f7b2c24eff4 100644 --- a/cocos/2d/renderer/i-batcher.ts +++ b/cocos/2d/renderer/i-batcher.ts @@ -1,7 +1,30 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { CachedArray } from '../../core'; import { TextureBase } from '../../asset/assets/texture-base'; -import { Device } from '../../gfx'; -import { Attribute } from '../../gfx/base/define'; +import { Device, Attribute } from '../../gfx'; import { Camera } from '../../render-scene/scene/camera'; import { Model } from '../../render-scene/scene/model'; import { SpriteFrame } from '../assets/sprite-frame'; diff --git a/cocos/2d/renderer/linear-buffer-accessor.ts b/cocos/2d/renderer/linear-buffer-accessor.ts index 8b26bd871f3..668e1489e4f 100644 --- a/cocos/2d/renderer/linear-buffer-accessor.ts +++ b/cocos/2d/renderer/linear-buffer-accessor.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,12 +22,10 @@ THE SOFTWARE. */ -import { InputAssembler, Device, Attribute } from '../../core/gfx'; +import { InputAssembler, Device, Attribute } from '../../gfx'; import { MeshBuffer } from './mesh-buffer'; import { BufferAccessor } from './buffer-accessor'; -import { assertID } from '../../core/platform/debug'; -import { assertIsNonNullable } from '../../core/data/utils/asserts'; -import { macro } from '../../core/platform/macro'; +import { assertID, macro, assertIsNonNullable } from '../../core'; export class LinearBufferAccessor extends BufferAccessor { public static IB_SCALE = 4; // ib size scale based on vertex count diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index c9f76463bf8..1d464e2894f 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,9 +25,7 @@ import { JSB } from 'internal:constants'; import { Device, BufferUsageBit, MemoryUsageBit, Attribute, Buffer, BufferInfo, InputAssembler, InputAssemblerInfo } from '../../gfx'; import { getAttributeStride } from './vertex-format'; -import { getError, warnID } from '../../core/platform/debug'; -import { sys } from '../../core'; -import { assertIsTrue } from '../../core/data/utils/asserts'; +import { sys, getError, warnID, assertIsTrue } from '../../core'; import { NativeUIMeshBuffer } from './native-2d'; interface IIARef { @@ -37,7 +34,7 @@ interface IIARef { indexBuffer: Buffer; } -export enum MeshBufferSharedBufferView{ +enum MeshBufferSharedBufferView { byteOffset, vertexOffset, indexOffset, @@ -45,15 +42,35 @@ export enum MeshBufferSharedBufferView{ count, } +/** + * @en Mesh buffer used for 2d rendering, used internally and not of concern to the user. + * @zh 2d 渲染使用的网格缓冲数据,内部使用,用户不须关心。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ export class MeshBuffer { + /** + * @en The vertex attributes of the buffer. + * @zh buffer 的顶点属性。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get attributes () { return this._attributes; } + /** + * @en Number of bytes in vertex format. + * @zh 顶点格式的字节数。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get vertexFormatBytes () { return this._vertexFormatBytes; } protected _byteOffset = 0; + /** + * @en byte offset. + * @zh 字节偏移量。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get byteOffset () { return this._byteOffset; } - set byteOffset (val:number) { + set byteOffset (val: number) { this._byteOffset = val; if (JSB) { this._sharedBuffer[MeshBufferSharedBufferView.byteOffset] = val; @@ -61,10 +78,15 @@ export class MeshBuffer { } protected _vertexOffset = 0; + /** + * @en Vertexes offset. + * @zh 顶点数偏移。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get vertexOffset () { return this._vertexOffset; } - set vertexOffset (val:number) { + set vertexOffset (val: number) { this._vertexOffset = val; if (JSB) { this._sharedBuffer[MeshBufferSharedBufferView.vertexOffset] = val; @@ -72,10 +94,15 @@ export class MeshBuffer { } protected _indexOffset = 0; + /** + * @en Indices offset. + * @zh 索引偏移。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get indexOffset () { return this._indexOffset; } - set indexOffset (val:number) { + set indexOffset (val: number) { this._indexOffset = val; if (JSB) { this._sharedBuffer[MeshBufferSharedBufferView.indexOffset] = val; @@ -83,10 +110,15 @@ export class MeshBuffer { } protected _dirty = false; + /** + * @en Dirty flag. + * @zh 脏标记。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get dirty () { return this._dirty; } - set dirty (val:boolean) { + set dirty (val: boolean) { this._dirty = val; if (JSB) { this._sharedBuffer[MeshBufferSharedBufferView.dirty] = val ? 1 : 0; @@ -94,18 +126,28 @@ export class MeshBuffer { } protected _floatsPerVertex = 0; + /** + * @en Float numbers per vertex. + * @zh 每顶点的浮点数长度。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get floatsPerVertex () { return this._floatsPerVertex; } - set floatsPerVertex (val:number) { + set floatsPerVertex (val: number) { this._floatsPerVertex = val; } protected _vData: Float32Array = null!; + /** + * @en Vertexes data. + * @zh 顶点数据。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get vData () { return this._vData; } - set vData (val:Float32Array) { + set vData (val: Float32Array) { this._vData = val; //还得看是否需要共享.buffer if (JSB) { @@ -114,10 +156,15 @@ export class MeshBuffer { } protected _iData: Uint16Array = null!; + /** + * @en Indices data. + * @zh 索引数据。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get iData () { return this._iData; } - set iData (val:Uint16Array) { + set iData (val: Uint16Array) { this._iData = val; if (JSB) { this._nativeObj.iData = val; @@ -135,23 +182,43 @@ export class MeshBuffer { private _nextFreeIAHandle = 0; //nativeObj - protected declare _nativeObj:NativeUIMeshBuffer; + protected declare _nativeObj: NativeUIMeshBuffer; + /** + * @en Native object. + * @zh 原生对象。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get nativeObj () { return this._nativeObj; } //sharedBuffer protected declare _sharedBuffer: Uint32Array; + /** + * @en Native shared buffer. + * @zh 原生共享缓冲。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get sharedBuffer () { return this._sharedBuffer; } + /** + * @en Initial native shared buffer. + * @zh 初始化原生共享缓冲。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public initSharedBuffer () { if (JSB) { this._sharedBuffer = new Uint32Array(MeshBufferSharedBufferView.count); } } + /** + * @en Synchronized native shared buffer. + * @zh 同步原生共享缓冲。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public syncSharedBufferToNative () { if (JSB) { this._nativeObj.syncSharedBufferToNative(this._sharedBuffer); @@ -166,6 +233,15 @@ export class MeshBuffer { this.syncSharedBufferToNative(); } + /** + * @en Initialize mesh buffer. + * @zh 初始化对象。 + * @param device @en The GFX device. @zh GFX设备。 + * @param attrs @en The vertex attributes of the buffer. @zh 缓冲区的顶点属性。 + * @param vFloatCount @en The vertexes float count. @zh 每顶点所需的 float 数量。 + * @param iCount @en The indices count. @zh 索引数量。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public initialize (device: Device, attrs: Attribute[], vFloatCount: number, iCount: number) { this._initVDataCount = vFloatCount; this._initIDataCount = iCount; @@ -186,6 +262,11 @@ export class MeshBuffer { } } + /** + * @en Reset state. + * @zh 重置状态。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public reset () { this._nextFreeIAHandle = 0; this.dirty = false; @@ -212,6 +293,11 @@ export class MeshBuffer { this._iaPool.length = 0; } + /** + * @en Set dirty flag. + * @zh 设置脏标签。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public setDirty () { this.dirty = true; } @@ -225,7 +311,11 @@ export class MeshBuffer { return false; } - //有返回值暂时没写 + /** + * @en require Free input assembler. + * @zh 请求可用的输入汇集器。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public requireFreeIA (device: Device) { if (this._iaPool.length <= this._nextFreeIAHandle) { this._iaPool.push(this.createNewIA(device)); @@ -234,7 +324,11 @@ export class MeshBuffer { return ia; } - //参数暂时没传 + /** + * @en recycle input assembler. + * @zh 回收输入汇集器。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public recycleIA (ia: InputAssembler) { const pool = this._iaPool; for (let i = 0; i < this._nextFreeIAHandle; ++i) { @@ -248,6 +342,11 @@ export class MeshBuffer { } } + /** + * @en check capacity. + * @zh 检查可分配余量。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public checkCapacity (vertexCount: number, indexCount: number) { const maxVertex = (this.vertexOffset + vertexCount) * this._floatsPerVertex; const maxIndex = this.indexOffset + indexCount; @@ -257,6 +356,11 @@ export class MeshBuffer { return true; } + /** + * @en Upload and update buffers data. + * @zh 上传更新缓冲内容。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public uploadBuffers () { if (this.byteOffset === 0 || !this._dirty) { return; @@ -295,7 +399,6 @@ export class MeshBuffer { this.dirty = false; } - //有返回值,暂时没原生化 private createNewIA (device: Device): IIARef { let ia; let vertexBuffers; diff --git a/cocos/2d/renderer/native-2d-empty.ts b/cocos/2d/renderer/native-2d-empty.ts index eb4c24f6a71..7a0f0dd81d0 100644 --- a/cocos/2d/renderer/native-2d-empty.ts +++ b/cocos/2d/renderer/native-2d-empty.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export const NativeRenderDrawInfo = undefined; export const NativeBatcher2d = undefined; diff --git a/cocos/2d/renderer/native-2d.jsb.ts b/cocos/2d/renderer/native-2d.jsb.ts index 4e1cf0a516a..75fac9c8365 100644 --- a/cocos/2d/renderer/native-2d.jsb.ts +++ b/cocos/2d/renderer/native-2d.jsb.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + // 2d declare const n2d: any; diff --git a/cocos/2d/renderer/native-2d.ts b/cocos/2d/renderer/native-2d.ts index 4e843f70e13..c6cabde2724 100644 --- a/cocos/2d/renderer/native-2d.ts +++ b/cocos/2d/renderer/native-2d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { Material } from '../../asset/assets'; import { Attribute, Device, Sampler, Texture } from '../../gfx'; import { Node } from '../../scene-graph'; @@ -99,6 +123,7 @@ export declare class NativeUIModelProxy { updateModels(model); attachDrawInfo(); attachNode(node); + clearModels(); } export declare class NativeStencilManager { diff --git a/cocos/2d/renderer/render-data.ts b/cocos/2d/renderer/render-data.ts index c6d80ddfd19..8944ec30ed9 100644 --- a/cocos/2d/renderer/render-data.ts +++ b/cocos/2d/renderer/render-data.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,19 +26,15 @@ import { DEBUG, JSB } from 'internal:constants'; import { director } from '../../game/director'; import { Material } from '../../asset/assets/material'; import { TextureBase } from '../../asset/assets/texture-base'; -import { Color } from '../../core/math'; -import { Pool, RecyclePool } from '../../core/memop'; -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; +import { Color, Pool, RecyclePool, murmurhash2_32_gc, assert, assertIsTrue } from '../../core'; import { SpriteFrame } from '../assets/sprite-frame'; import { UIRenderer } from '../framework/ui-renderer'; import { StaticVBAccessor, StaticVBChunk } from './static-vb-accessor'; import { getAttributeStride, vfmtPosUvColor } from './vertex-format'; import { Buffer, BufferInfo, BufferUsageBit, Device, Attribute, InputAssembler, InputAssemblerInfo, MemoryUsageBit } from '../../gfx'; -import { assertIsTrue } from '../../core/data/utils/asserts'; import { RenderDrawInfo, RenderDrawInfoType } from './render-draw-info'; import { Batcher2D } from './batcher-2d'; import { RenderEntity, RenderEntityType } from './render-entity'; -import { assert } from '../../core'; /** * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. diff --git a/cocos/2d/renderer/render-draw-info.ts b/cocos/2d/renderer/render-draw-info.ts index 032c78f4925..f118dcd6d4d 100644 --- a/cocos/2d/renderer/render-draw-info.ts +++ b/cocos/2d/renderer/render-draw-info.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { JSB } from 'internal:constants'; import { IRenderData } from './render-data'; import { NativeRenderDrawInfo } from './native-2d'; diff --git a/cocos/2d/renderer/render-entity.ts b/cocos/2d/renderer/render-entity.ts index 37dfc418d8b..d59200c0cc5 100644 --- a/cocos/2d/renderer/render-entity.ts +++ b/cocos/2d/renderer/render-entity.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { JSB } from 'internal:constants'; import { NativeRenderEntity } from './native-2d'; import { RenderDrawInfo } from './render-draw-info'; diff --git a/cocos/2d/renderer/static-vb-accessor.ts b/cocos/2d/renderer/static-vb-accessor.ts index bbafd08762f..9a759f22848 100644 --- a/cocos/2d/renderer/static-vb-accessor.ts +++ b/cocos/2d/renderer/static-vb-accessor.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,10 +26,7 @@ import { JSB } from 'internal:constants'; import { Device, Attribute } from '../../gfx'; import { MeshBuffer } from './mesh-buffer'; import { BufferAccessor } from './buffer-accessor'; -import { assertID, errorID } from '../../core/platform/debug'; -import { assertIsTrue } from '../../core/data/utils/asserts'; -import { Pool } from '../../core/memop/pool'; -import { macro } from '../../core/platform/macro'; +import { assertID, errorID, Pool, macro, assertIsTrue } from '../../core'; import { director } from '../../game'; interface IFreeEntry { @@ -147,6 +143,14 @@ export class StaticVBAccessor extends BufferAccessor { const buf = this._buffers[bufferId]; const iCount = indices.length; if (iCount) { + //make sure iData length enough + const needLength = buf.indexOffset + indices.length; + if (buf.iData.length < needLength) { + const expansionLength = Math.floor(1.25 * needLength); + const newIData = new Uint16Array(expansionLength); + newIData.set(buf.iData); + buf.iData = newIData; + } // Append index buffer buf.iData.set(indices, buf.indexOffset); buf.indexOffset += indices.length; @@ -305,7 +309,7 @@ export class StaticVBAccessor extends BufferAccessor { return this._buffers.length - 1; } - static generateID () : number { + static generateID (): number { return StaticVBAccessor.ID_COUNT++; } } diff --git a/cocos/2d/renderer/stencil-manager.ts b/cocos/2d/renderer/stencil-manager.ts index 72a7da6e7bd..8434fbf52cc 100644 --- a/cocos/2d/renderer/stencil-manager.ts +++ b/cocos/2d/renderer/stencil-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,7 +27,11 @@ import { Material } from '../../asset/assets'; import { UIRenderer } from '../framework/ui-renderer'; import { UIMeshRenderer } from '../components/ui-mesh-renderer'; -// Stage types +/** + * @en Stencil stage types enum. + * @zh 模板状态类型枚举。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ export enum Stage { // Stencil disabled DISABLED = 0, @@ -46,6 +49,11 @@ export enum Stage { ENTER_LEVEL_INVERTED = 6, } +/** + * @en Native stencil buffer format enum. + * @zh 原生模板缓冲格式枚举。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ export enum StencilSharedBufferView { stencilTest, func, @@ -58,6 +66,11 @@ export enum StencilSharedBufferView { count, } +/** + * @en Stencil state manager. + * @zh 模板状态管理器。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ export class StencilManager { public static sharedManager: StencilManager | null = null; private _maskStack: any[] = []; @@ -72,31 +85,61 @@ export class StencilManager { ref: 1, }; - private _stage:Stage = Stage.DISABLED; + private _stage: Stage = Stage.DISABLED; + /** + * @en Stencil stage. + * @zh 模板缓冲阶段。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get stage () { return this._stage; } - set stage (val:Stage) { + set stage (val: Stage) { this._stage = val; } + /** + * @en Stencil pattern. + * @zh 模板缓冲样式。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ get pattern () { return this._stencilPattern; } + /** + * @en Add mask nesting. + * @zh 添加mask嵌套。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public pushMask (mask: any) { this._maskStack.push(mask); } + /** + * @en clear stencil stage. + * @zh 清空模板状态。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public clear (comp: UIRenderer | UIMeshRenderer) { const isInverted = (comp.stencilStage !== Stage.ENTER_LEVEL); return isInverted ? Stage.CLEAR_INVERTED : Stage.CLEAR; } + /** + * @en Open stencil stage to enabled. + * @zh 开启模板状态。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public enableMask () { this.stage = Stage.ENABLED; } + /** + * @en exit stencil. + * @zh 退出模板状态。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public exitMask () { if (this._maskStack.length === 0) { // cc.errorID(9001); @@ -110,15 +153,25 @@ export class StencilManager { } } + /** + * @en Get write mask count. + * @zh 获取写入模板缓冲的位数。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public getWriteMask () { return 1 << (this._maskStack.length - 1); } + /** + * @en Get write mask count when exit. + * @zh 获取退出时模板缓冲的位数。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public getExitWriteMask () { return 1 << this._maskStack.length; } - public getStencilRef () { + private getStencilRef () { let result = 0; for (let i = 0; i < this._maskStack.length; ++i) { result += (0x00000001 << i); @@ -126,10 +179,20 @@ export class StencilManager { return result; } + /** + * @en Get mask nesting count. + * @zh 获取mask嵌套数量。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public getMaskStackSize () { return this._maskStack.length; } + /** + * @en Reset stencil stage. + * @zh 重置模板状态。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public reset () { // reset stack and stage this._maskStack.length = 0; @@ -146,6 +209,11 @@ export class StencilManager { private stencilStateMap = new Map(); private stencilStateMapWithDepth = new Map(); + /** + * @en Get stencil stage. + * @zh 获取模板状态。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public getStencilStage (stage: Stage, mat?: Material) { let key = 0; let depthTest = false; @@ -196,6 +264,11 @@ export class StencilManager { return depthStencilState; } + /** + * @en Get stencil hash. + * @zh 获取模板状态的哈希值。 + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public getStencilHash (stage: Stage) { return (stage << 8) | this._maskStack.length; } diff --git a/cocos/2d/renderer/vertex-format.ts b/cocos/2d/renderer/vertex-format.ts index de3db5628ae..b2b30689a70 100644 --- a/cocos/2d/renderer/vertex-format.ts +++ b/cocos/2d/renderer/vertex-format.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,7 +23,7 @@ */ import { AttributeName, Format, FormatInfos, Attribute } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @en Vertex format with vector 3 position attribute @@ -35,7 +34,7 @@ export const vfmt = [ ]; /** - * @en Vertex format with the following layout + * @en Vertex format with the following layout. * 1. Vector 3 position attribute (Float32) * 2. Vector 4 color attribute (Float32) * @zh 包含以下数据的顶点格式 @@ -63,6 +62,16 @@ export const vfmtPosUvColor = [ new Attribute(AttributeName.ATTR_COLOR, Format.RGBA32F), ]; +/** + * @en Vertex format with the following layout + * 1. Vector 3 position attribute (Float32) + * 2. Vector 2 uv attribute (Float32) + * 3. Byte 4 color attribute (Byte) + * @zh 包含以下数据的顶点格式 + * 1. 三维位置属性(Float32) + * 2. 二维贴图 UV 属性(Float32) + * 3. RGBA 颜色属性(Byte) + */ export const vfmtPosUvColor4B = [ new Attribute(AttributeName.ATTR_POSITION, Format.RGB32F), new Attribute(AttributeName.ATTR_TEX_COORD, Format.RG32F), @@ -79,7 +88,7 @@ export const vfmtPosUvColor4B = [ * 1. 三维位置属性(Float32) * 2. 二维贴图 UV 属性(Float32) * 3. 第一套 RGBA 颜色属性(Float32) - * 3. 第二套 RGBA 颜色属性(Float32) + * 4. 第二套 RGBA 颜色属性(Float32) */ export const vfmtPosUvTwoColor = [ new Attribute(AttributeName.ATTR_POSITION, Format.RGB32F), @@ -88,6 +97,18 @@ export const vfmtPosUvTwoColor = [ new Attribute(AttributeName.ATTR_COLOR2, Format.RGBA32F), ]; +/** + * @en Vertex format with the following layout + * 1. Vector 3 position attribute (Float32) + * 2. Vector 2 uv attribute (Float32) + * 3. First byte 4 color attribute (Byte) + * 4. Second byte 4 color attribute (Byte) + * @zh 包含以下数据的顶点格式 + * 1. 三维位置属性(Float32) + * 2. 二维贴图 UV 属性(Float32) + * 3. 第一套 RGBA 颜色属性(Byte) + * 4. 第二套 RGBA 颜色属性(Byte) + */ export const vfmtPosUvTwoColor4B = [ new Attribute(AttributeName.ATTR_POSITION, Format.RGB32F), new Attribute(AttributeName.ATTR_TEX_COORD, Format.RG32F), @@ -129,7 +150,7 @@ export function getAttributeStride (attrs: Attribute[]) { return count; } -legacyCC.internal.vfmtPosUvColor = vfmtPosUvColor; -legacyCC.internal.vfmtPosUvTwoColor = vfmtPosUvTwoColor; -legacyCC.internal.vfmtPosUvColor4B = vfmtPosUvColor4B; -legacyCC.internal.vfmtPosUvTwoColor4B = vfmtPosUvTwoColor4B; +cclegacy.internal.vfmtPosUvColor = vfmtPosUvColor; +cclegacy.internal.vfmtPosUvTwoColor = vfmtPosUvTwoColor; +cclegacy.internal.vfmtPosUvColor4B = vfmtPosUvColor4B; +cclegacy.internal.vfmtPosUvTwoColor4B = vfmtPosUvTwoColor4B; diff --git a/cocos/2d/utils/dynamic-atlas/atlas-manager.ts b/cocos/2d/utils/dynamic-atlas/atlas-manager.ts index dfba21e6575..7affddb9f7f 100644 --- a/cocos/2d/utils/dynamic-atlas/atlas-manager.ts +++ b/cocos/2d/utils/dynamic-atlas/atlas-manager.ts @@ -1,9 +1,30 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; -import { System } from '../../../core'; +import { System, macro, js, cclegacy } from '../../../core'; import { Filter } from '../../../asset/assets/asset-enum'; -import { legacyCC } from '../../../core/global-exports'; -import { macro } from '../../../core/platform'; -import { js } from '../../../core/utils/js'; import { Atlas } from './atlas'; import { director } from '../../../game'; @@ -35,10 +56,10 @@ export class DynamicAtlasManager extends System { if (value) { this.reset(); - legacyCC.director.on(legacyCC.Director.EVENT_BEFORE_SCENE_LAUNCH, this.beforeSceneLoad, this); + cclegacy.director.on(cclegacy.Director.EVENT_BEFORE_SCENE_LAUNCH, this.beforeSceneLoad, this); } else { this.reset(); - legacyCC.director.off(legacyCC.Director.EVENT_BEFORE_SCENE_LAUNCH, this.beforeSceneLoad, this); + cclegacy.director.off(cclegacy.Director.EVENT_BEFORE_SCENE_LAUNCH, this.beforeSceneLoad, this); } this._enabled = value; @@ -142,7 +163,7 @@ export class DynamicAtlasManager extends System { * @param spriteFrame the sprite frame that will be inserted in the atlas. */ public insertSpriteFrame (spriteFrame) { - if (EDITOR && !legacyCC.GAME_VIEW) return null; + if (EDITOR && !cclegacy.GAME_VIEW) return null; if (!this._enabled || this._atlasIndex === this._maxAtlasCount || !spriteFrame || spriteFrame._original) return null; @@ -241,7 +262,7 @@ export class DynamicAtlasManager extends System { * @param frame the sprite frame that will be packed in the dynamic atlas. */ public packToDynamicAtlas (comp, frame) { - if ((EDITOR && !legacyCC.GAME_VIEW) || !this._enabled) return; + if ((EDITOR && !cclegacy.GAME_VIEW) || !this._enabled) return; if (frame && !frame._original && frame.packable && frame.texture && frame.texture.width > 0 && frame.texture.height > 0) { const packedFrame = this.insertSpriteFrame(frame); @@ -252,8 +273,12 @@ export class DynamicAtlasManager extends System { } } +/** + * @en Dynamic Atlas Manager,use to auto merge sprite frame. + * @zh 动态合图管理器,用于引擎的自动合图功能。 + */ export const dynamicAtlasManager: DynamicAtlasManager = DynamicAtlasManager.instance = new DynamicAtlasManager(); director.registerSystem('dynamicAtlasManager', dynamicAtlasManager, 0); -legacyCC.internal.dynamicAtlasManager = dynamicAtlasManager; +cclegacy.internal.dynamicAtlasManager = dynamicAtlasManager; diff --git a/cocos/2d/utils/dynamic-atlas/atlas.ts b/cocos/2d/utils/dynamic-atlas/atlas.ts index 06e06be6534..dd8542545dc 100644 --- a/cocos/2d/utils/dynamic-atlas/atlas.ts +++ b/cocos/2d/utils/dynamic-atlas/atlas.ts @@ -1,8 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { PixelFormat } from '../../../asset/assets/asset-enum'; import { ImageAsset } from '../../../asset/assets/image-asset'; import { Texture2D } from '../../../asset/assets/texture-2d'; import { BufferTextureCopy } from '../../../gfx'; -import { legacyCC } from '../../../core/global-exports'; +import { cclegacy } from '../../../core'; import { SpriteFrame } from '../../assets/sprite-frame'; const space = 2; @@ -75,7 +99,7 @@ export class Atlas { return null; } - if (legacyCC.internal.dynamicAtlasManager.textureBleeding) { + if (cclegacy.internal.dynamicAtlasManager.textureBleeding) { // Smaller frame is more likely to be affected by linear filter if (width <= 8 || height <= 8) { this._texture.drawTextureAt(texture.image!, this._x - 1, this._y - 1); diff --git a/cocos/2d/utils/font-loader.ts b/cocos/2d/utils/font-loader.ts index e9e3e891b62..579de5d42fe 100644 --- a/cocos/2d/utils/font-loader.ts +++ b/cocos/2d/utils/font-loader.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,21 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { warnID } from '../../core/platform/debug'; +import { warnID } from '../../core'; import { safeMeasureText } from './text-utils'; -import { CompleteCallback, IDownloadParseOptions } from '../../asset/asset-manager/shared'; import downloader from '../../asset/asset-manager/downloader'; import factory from '../../asset/asset-manager/factory'; import { TTFFont } from '../assets/ttf-font'; +import { ccwindow } from '../../core/global-exports'; + +const ccdocument = ccwindow.document; interface IFontLoadHandle { fontFamilyName: string; refWidth: number; - onComplete: CompleteCallback; + onComplete: ((err: Error | null, data?: any | null) => void); startTime: number; } @@ -53,9 +54,9 @@ const useNativeCheck = (() => { let nativeCheck: boolean; return (): boolean => { if (nativeCheck === undefined) { - if ('FontFace' in window) { - const match = /Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent); - const safari10Match = /OS X.*Version\/10\..*Safari/.exec(window.navigator.userAgent) && /Apple/.exec(window.navigator.vendor); + if ('FontFace' in ccwindow) { + const match = /Gecko.*Firefox\/(\d+)/.exec(ccwindow.navigator.userAgent); + const safari10Match = /OS X.*Version\/10\..*Safari/.exec(ccwindow.navigator.userAgent) && /Apple/.exec(ccwindow.navigator.vendor); if (match) { nativeCheck = parseInt(match[1], 10) > 42; @@ -108,7 +109,7 @@ function checkFontLoaded () { } // refer to https://github.com/typekit/webfontloader/blob/master/src/core/nativefontwatchrunner.js -function nativeCheckFontLoaded (start: number, font: string, callback: CompleteCallback): void { +function nativeCheckFontLoaded (start: number, font: string, callback: ((err: Error | null, data?: any | null) => void)): void { const loader = new Promise((resolve, reject) => { const check = () => { const now = Date.now(); @@ -116,8 +117,7 @@ function nativeCheckFontLoaded (start: number, font: string, callback: CompleteC if (now - start >= _timeout) { reject(); } else { - // @ts-expect-error see https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts - document.fonts.load(`40px ${font}`).then((fonts) => { + (ccdocument as any).fonts.load(`40px ${font}`).then((fonts) => { if (fonts.length >= 1) { resolve(); } else { @@ -150,9 +150,8 @@ function nativeCheckFontLoaded (start: number, font: string, callback: CompleteC }); } -export function loadFont (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) { +export function loadFont (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) { const fontFamilyName = getFontFamily(url); - // Already loaded fonts if (_fontFaces[fontFamilyName]) { onComplete(null, fontFamilyName); @@ -160,7 +159,7 @@ export function loadFont (url: string, options: IDownloadParseOptions, onComplet } if (!_canvasContext) { - const labelCanvas = document.createElement('canvas'); + const labelCanvas = ccdocument.createElement('canvas'); labelCanvas.width = 100; labelCanvas.height = 100; _canvasContext = labelCanvas.getContext('2d'); @@ -171,7 +170,7 @@ export function loadFont (url: string, options: IDownloadParseOptions, onComplet const refWidth = safeMeasureText(_canvasContext!, _testString, fontDesc); // Setup font face style - const fontStyle = document.createElement('style'); + const fontStyle = ccdocument.createElement('style'); fontStyle.type = 'text/css'; let fontStr = ''; if (Number.isNaN(fontFamilyName)) { @@ -181,17 +180,17 @@ export function loadFont (url: string, options: IDownloadParseOptions, onComplet } fontStr += `url("${url}");`; fontStyle.textContent = `${fontStr}}`; - document.body.appendChild(fontStyle); + ccdocument.body.appendChild(fontStyle); // Preload font with div - const preloadDiv = document.createElement('div'); + const preloadDiv = ccdocument.createElement('div'); const divStyle = preloadDiv.style; divStyle.fontFamily = fontFamilyName; preloadDiv.innerHTML = '.'; divStyle.position = 'absolute'; divStyle.left = '-100px'; divStyle.top = '-100px'; - document.body.appendChild(preloadDiv); + ccdocument.body.appendChild(preloadDiv); if (useNativeCheck()) { nativeCheckFontLoaded(Date.now(), fontFamilyName, onComplete); @@ -228,7 +227,7 @@ export function getFontFamily (fontHandle: string): string { return fontFamilyName; } -function createFont (id: string, data: string, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createFont (id: string, data: string, options: Record, onComplete: ((err: Error | null, data?: TTFFont | null) => void)) { const out = new TTFFont(); out._nativeUrl = id; out._nativeAsset = data; diff --git a/cocos/2d/utils/html-text-parser.ts b/cocos/2d/utils/html-text-parser.ts index 237f1b88428..6b781c3b494 100644 --- a/cocos/2d/utils/html-text-parser.ts +++ b/cocos/2d/utils/html-text-parser.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,7 +24,7 @@ */ import { TEST } from 'internal:constants'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. @@ -34,7 +33,8 @@ const eventRegx = /^(click)(\s)*=|(param)(\s)*=/; const imageAttrReg = /(\s)*src(\s)*=|(\s)*height(\s)*=|(\s)*width(\s)*=|(\s)*align(\s)*=|(\s)*offset(\s)*=|(\s)*click(\s)*=|(\s)*param(\s)*=/; /** - * A utils class for parsing HTML texts. The parsed results will be an object array. + * @en A utils class for parsing HTML texts. The parsed results will be an object array. + * @zh 一个用于解析HTML文本的工具类。解析后的结果将是一个对象数组。 * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ export interface IHtmlTextParserResultObj{ @@ -43,6 +43,8 @@ export interface IHtmlTextParserResultObj{ } /** + * @en Html Text Parser Stack interface + * @zh Html 文本解析器接口 * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ export interface IHtmlTextParserStack{ @@ -63,6 +65,8 @@ export interface IHtmlTextParserStack{ } /** + * @en Html Text Parser Stack + * @zh Html 文本解析器 * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ export class HtmlTextParser { @@ -431,5 +435,5 @@ export class HtmlTextParser { } if (TEST) { - legacyCC._Test.HtmlTextParser = HtmlTextParser; + cclegacy._Test.HtmlTextParser = HtmlTextParser; } diff --git a/cocos/2d/utils/index.ts b/cocos/2d/utils/index.ts index e5a3541ba1a..0e63c451e81 100644 --- a/cocos/2d/utils/index.ts +++ b/cocos/2d/utils/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './font-loader'; export * from './html-text-parser'; -export * from './text-utils'; export { dynamicAtlasManager } from './dynamic-atlas/atlas-manager'; diff --git a/cocos/2d/utils/text-utils.ts b/cocos/2d/utils/text-utils.ts index 6c2fe47d363..b3e0eb15177 100644 --- a/cocos/2d/utils/text-utils.ts +++ b/cocos/2d/utils/text-utils.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ import { RUNTIME_BASED } from 'internal:constants'; import { minigame } from 'pal/minigame'; -import Pool from '../../core/utils/pool'; +import { js } from '../../core'; export const BASELINE_RATIO = 0.26; let _BASELINE_OFFSET = 0; @@ -64,7 +63,7 @@ interface ICacheNode { next: ICacheNode | null } -const pool = new Pool(2); +const pool = new js.Pool(2); pool.get = function () { return this._get() || { key: '', diff --git a/cocos/3d/assets/deprecated.ts b/cocos/3d/assets/deprecated.ts index b570e2fec1b..e539981fabf 100644 --- a/cocos/3d/assets/deprecated.ts +++ b/cocos/3d/assets/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { removeProperty, replaceProperty } from '../../core/utils'; +import { removeProperty, replaceProperty } from '../../core'; import { Mesh } from './mesh'; replaceProperty(Mesh.prototype, 'Mesh.prototype', [ diff --git a/cocos/3d/assets/index.ts b/cocos/3d/assets/index.ts index 233c1d6ce20..da00b2a5f85 100644 --- a/cocos/3d/assets/index.ts +++ b/cocos/3d/assets/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/3d/assets/mesh.jsb.ts b/cocos/3d/assets/mesh.jsb.ts index 1d73e394036..8f562b41fb5 100644 --- a/cocos/3d/assets/mesh.jsb.ts +++ b/cocos/3d/assets/mesh.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,8 +22,7 @@ THE SOFTWARE. */ import { ccclass, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; -import { Vec3 } from '../../core/math'; +import { cclegacy, Vec3 } from '../../core'; declare const jsb: any; @@ -149,20 +147,24 @@ Object.defineProperty(meshAssetProto, 'maxPosition', { }); meshAssetProto.onLoaded = function () { - // might be undefined - if (this._struct != undefined) { - this.setStruct(this._struct); + // might be undefined or null + const meshStruct = this._struct; + if (meshStruct) { + // Synchronize to native if the struct contains valid values. + if (meshStruct.vertexBundles.length !== 0 || meshStruct.primitives.length !== 0) { + this.setStruct(this._struct); + } } // Set to null to release memory in JS this._struct = null; originOnLoaded.apply(this); }; -legacyCC.Mesh = jsb.Mesh; +cclegacy.Mesh = jsb.Mesh; // handle meta data, it is generated automatically const MeshProto = Mesh.prototype; -serializable(MeshProto, '_struct'); -serializable(MeshProto, '_hash'); -serializable(MeshProto, '_allowDataAccess'); +serializable(MeshProto, '_struct', () => { return { vertexBundles: [], primitives: [] } }); +serializable(MeshProto, '_hash', () => 0); +serializable(MeshProto, '_allowDataAccess', () => true); ccclass('cc.Mesh')(Mesh); diff --git a/cocos/3d/assets/mesh.ts b/cocos/3d/assets/mesh.ts index 402ef0f4209..9341dda232f 100644 --- a/cocos/3d/assets/mesh.ts +++ b/cocos/3d/assets/mesh.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,20 +25,14 @@ import { ccclass, serializable } from 'cc.decorator'; import { Asset } from '../../asset/assets/asset'; import { IDynamicGeometry } from '../../primitive/define'; -import { assertIsTrue } from '../../core/data/utils/asserts'; import { BufferBlob } from '../misc/buffer-blob'; import { Skeleton } from './skeleton'; -import { AABB } from '../../core/geometry'; -import { legacyCC } from '../../core/global-exports'; -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; -import { sys } from '../../core/platform/sys'; -import { warnID } from '../../core/platform/debug'; +import { geometry, cclegacy, sys, warnID, Mat4, Quat, Vec3, assertIsTrue, murmurhash2_32_gc } from '../../core'; import { RenderingSubMesh } from '../../asset/assets'; import { Attribute, Device, Buffer, BufferInfo, AttributeName, BufferUsageBit, Feature, Format, FormatInfos, FormatType, MemoryUsageBit, PrimitiveMode, getTypedArrayConstructor, DrawInfo, FormatInfo, deviceManager, } from '../../gfx'; -import { Mat4, Quat, Vec3 } from '../../core/math'; import { Morph } from './morph'; import { MorphRendering, createMorphRendering } from './morph-rendering'; @@ -153,7 +146,7 @@ export declare namespace Mesh { * @en dynamic submesh bounds * @zh 动态子模型包围盒。 */ - bounds: AABB[]; + bounds: geometry.AABB[]; } /** @@ -344,7 +337,7 @@ export class Mesh extends Asset { private _renderingSubMeshes: RenderingSubMesh[] | null = null; - private _boneSpaceBounds: Map = new Map(); + private _boneSpaceBounds: Map = new Map(); private _jointBufferIndices: number[] | null = null; @@ -510,9 +503,9 @@ export class Mesh extends Asset { * @en update dynamic sub mesh geometry * @zh 更新动态子网格的几何数据 * @param primitiveIndex @en sub mesh index @zh 子网格索引 - * @param geometry @en sub mesh geometry data @zh 子网格几何数据 + * @param dynamicGeometry @en sub mesh geometry data @zh 子网格几何数据 */ - public updateSubMesh (primitiveIndex: number, geometry: IDynamicGeometry) { + public updateSubMesh (primitiveIndex: number, dynamicGeometry: IDynamicGeometry) { if (!this._struct.dynamic) { warnID(14200); return; @@ -524,29 +517,29 @@ export class Mesh extends Asset { } const buffers: Float32Array[] = []; - if (geometry.positions.length > 0) { - buffers.push(geometry.positions); + if (dynamicGeometry.positions.length > 0) { + buffers.push(dynamicGeometry.positions); } - if (geometry.normals && geometry.normals.length > 0) { - buffers.push(geometry.normals); + if (dynamicGeometry.normals && dynamicGeometry.normals.length > 0) { + buffers.push(dynamicGeometry.normals); } - if (geometry.uvs && geometry.uvs.length > 0) { - buffers.push(geometry.uvs); + if (dynamicGeometry.uvs && dynamicGeometry.uvs.length > 0) { + buffers.push(dynamicGeometry.uvs); } - if (geometry.tangents && geometry.tangents.length > 0) { - buffers.push(geometry.tangents); + if (dynamicGeometry.tangents && dynamicGeometry.tangents.length > 0) { + buffers.push(dynamicGeometry.tangents); } - if (geometry.colors && geometry.colors.length > 0) { - buffers.push(geometry.colors); + if (dynamicGeometry.colors && dynamicGeometry.colors.length > 0) { + buffers.push(dynamicGeometry.colors); } - if (geometry.customAttributes) { - for (let k = 0; k < geometry.customAttributes.length; k++) { - buffers.push(geometry.customAttributes[k].values); + if (dynamicGeometry.customAttributes) { + for (let k = 0; k < dynamicGeometry.customAttributes.length; k++) { + buffers.push(dynamicGeometry.customAttributes[k].values); } } @@ -580,11 +573,11 @@ export class Mesh extends Asset { if (primitive.indexView) { const indexView = primitive.indexView; const stride = indexView.stride; - const indexCount = (stride === 2) ? geometry.indices16!.length : geometry.indices32!.length; + const indexCount = (stride === 2) ? dynamicGeometry.indices16!.length : dynamicGeometry.indices32!.length; const updateSize = indexCount * stride; const dstBuffer = new Uint8Array(this._data.buffer, indexView.offset, updateSize); - const srcBuffer = (stride === 2) ? new Uint8Array(geometry.indices16!.buffer, geometry.indices16!.byteOffset, updateSize) - : new Uint8Array(geometry.indices32!.buffer, geometry.indices32!.byteOffset, updateSize); + const srcBuffer = (stride === 2) ? new Uint8Array(dynamicGeometry.indices16!.buffer, dynamicGeometry.indices16!.byteOffset, updateSize) + : new Uint8Array(dynamicGeometry.indices32!.buffer, dynamicGeometry.indices32!.byteOffset, updateSize); const indexBuffer = subMesh.indexBuffer!; assertIsTrue(indexCount <= info.maxSubMeshIndices, 'Too many indices.'); @@ -598,15 +591,15 @@ export class Mesh extends Asset { } // update bound - if (geometry.minPos && geometry.maxPos) { - const minPos = new Vec3(geometry.minPos.x, geometry.minPos.y, geometry.minPos.z); - const maxPos = new Vec3(geometry.maxPos.x, geometry.maxPos.y, geometry.maxPos.z); + if (dynamicGeometry.minPos && dynamicGeometry.maxPos) { + const minPos = new Vec3(dynamicGeometry.minPos.x, dynamicGeometry.minPos.y, dynamicGeometry.minPos.z); + const maxPos = new Vec3(dynamicGeometry.maxPos.x, dynamicGeometry.maxPos.y, dynamicGeometry.maxPos.z); if (!dynamic.bounds[primitiveIndex]) { - dynamic.bounds[primitiveIndex] = new AABB(); + dynamic.bounds[primitiveIndex] = new geometry.AABB(); } - AABB.fromPoints(dynamic.bounds[primitiveIndex], minPos, maxPos); + geometry.AABB.fromPoints(dynamic.bounds[primitiveIndex], minPos, maxPos); const subMin = new Vec3(); const subMax = new Vec3(); @@ -685,12 +678,12 @@ export class Mesh extends Asset { if (this._boneSpaceBounds.has(skeleton.hash)) { return this._boneSpaceBounds.get(skeleton.hash)!; } - const bounds: (AABB | null)[] = []; + const bounds: (geometry.AABB | null)[] = []; this._boneSpaceBounds.set(skeleton.hash, bounds); const valid: boolean[] = []; const { bindposes } = skeleton; for (let i = 0; i < bindposes.length; i++) { - bounds.push(new AABB(Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity)); + bounds.push(new geometry.AABB(Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity)); valid.push(false); } const { primitives } = this._struct; @@ -716,7 +709,7 @@ export class Mesh extends Asset { } for (let i = 0; i < bindposes.length; i++) { const b = bounds[i]!; - if (!valid[i]) { bounds[i] = null; } else { AABB.fromPoints(b, b.center, b.halfExtents); } + if (!valid[i]) { bounds[i] = null; } else { geometry.AABB.fromPoints(b, b.center, b.halfExtents); } } return bounds; } @@ -738,7 +731,7 @@ export class Mesh extends Asset { const vec3_temp = new Vec3(); const rotate = worldMatrix && new Quat(); - const boundingBox = worldMatrix && new AABB(); + const boundingBox = worldMatrix && new geometry.AABB(); if (rotate) { worldMatrix!.getRotation(rotate); } @@ -751,7 +744,7 @@ export class Mesh extends Asset { Vec3.multiplyScalar(boundingBox!.center, boundingBox!.center, 0.5); Vec3.subtract(boundingBox!.halfExtents, struct.maxPosition, struct.minPosition); Vec3.multiplyScalar(boundingBox!.halfExtents, boundingBox!.halfExtents, 0.5); - AABB.transform(boundingBox!, boundingBox!, worldMatrix); + geometry.AABB.transform(boundingBox!, boundingBox!, worldMatrix); Vec3.add(struct.maxPosition, boundingBox!.center, boundingBox!.halfExtents); Vec3.subtract(struct.minPosition, boundingBox!.center, boundingBox!.halfExtents); } @@ -897,7 +890,6 @@ export class Mesh extends Asset { // merge index buffer let idxCount = 0; let idxStride = 2; - let vertBatchCount = 0; let ibView: Uint8Array | Uint16Array | Uint32Array; let srcIBView: Uint8Array | Uint16Array | Uint32Array; let dstIBView: Uint8Array | Uint16Array | Uint32Array; @@ -912,6 +904,7 @@ export class Mesh extends Asset { vertexBundelIndices: prim.vertexBundelIndices, }; + let vertBatchCount = 0; for (const bundleIdx of prim.vertexBundelIndices) { vertBatchCount = Math.max(vertBatchCount, this._struct.vertexBundles[bundleIdx].view.count); } @@ -997,7 +990,7 @@ export class Mesh extends Asset { Vec3.multiplyScalar(boundingBox!.center, boundingBox!.center, 0.5); Vec3.subtract(boundingBox!.halfExtents, mesh._struct.maxPosition, mesh._struct.minPosition); Vec3.multiplyScalar(boundingBox!.halfExtents, boundingBox!.halfExtents, 0.5); - AABB.transform(boundingBox!, boundingBox!, worldMatrix); + geometry.AABB.transform(boundingBox!, boundingBox!, worldMatrix); Vec3.add(vec3_temp, boundingBox!.center, boundingBox!.halfExtents); Vec3.max(meshStruct.maxPosition, meshStruct.maxPosition, vec3_temp); Vec3.subtract(vec3_temp, boundingBox!.center, boundingBox!.halfExtents); @@ -1329,7 +1322,7 @@ export class Mesh extends Asset { this._data = globalEmptyMeshBuffer; } } -legacyCC.Mesh = Mesh; +cclegacy.Mesh = Mesh; function getOffset (attributes: Attribute[], attributeIndex: number) { let result = 0; diff --git a/cocos/3d/assets/morph-rendering.ts b/cocos/3d/assets/morph-rendering.ts index 02d40d996bf..73e16027077 100644 --- a/cocos/3d/assets/morph-rendering.ts +++ b/cocos/3d/assets/morph-rendering.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { AttributeName, Buffer, BufferUsageBit, Device, MemoryUsageBit, DescriptorSet, BufferInfo, FormatFeatureBit, Format, @@ -31,12 +30,9 @@ import { Texture2D } from '../../asset/assets/texture-2d'; import { ImageAsset } from '../../asset/assets/image-asset'; import { UBOMorph, UNIFORM_NORMAL_MORPH_TEXTURE_BINDING, UNIFORM_POSITION_MORPH_TEXTURE_BINDING, UNIFORM_TANGENT_MORPH_TEXTURE_BINDING } from '../../rendering/define'; -import { warn } from '../../core/platform/debug'; import { Morph, SubMeshMorph } from './morph'; -import { assertIsNonNullable, assertIsTrue } from '../../core/data/utils/asserts'; -import { log2, nextPow2 } from '../../core/math/bits'; +import { assertIsNonNullable, assertIsTrue, warn, bits, nextPow2, cclegacy } from '../../core'; import { IMacroPatch } from '../../render-scene'; -import { legacyCC } from '../../core/global-exports'; import { PixelFormat } from '../../asset/assets/asset-enum'; /** @@ -503,17 +499,17 @@ class MorphUniforms { public setWeights (weights: number[]) { assertIsTrue(weights.length === this._targetCount); for (let iWeight = 0; iWeight < weights.length; ++iWeight) { - this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_WEIGHTS + 4 * iWeight, weights[iWeight], legacyCC.sys.isLittleEndian); + this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_WEIGHTS + 4 * iWeight, weights[iWeight], cclegacy.sys.isLittleEndian); } } public setMorphTextureInfo (width: number, height: number) { - this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_DISPLACEMENT_TEXTURE_WIDTH, width, legacyCC.sys.isLittleEndian); - this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_DISPLACEMENT_TEXTURE_HEIGHT, height, legacyCC.sys.isLittleEndian); + this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_DISPLACEMENT_TEXTURE_WIDTH, width, cclegacy.sys.isLittleEndian); + this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_DISPLACEMENT_TEXTURE_HEIGHT, height, cclegacy.sys.isLittleEndian); } public setVerticesCount (count: number) { - this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_VERTICES_COUNT, count, legacyCC.sys.isLittleEndian); + this._localBuffer.setFloat32(UBOMorph.OFFSET_OF_VERTICES_COUNT, count, cclegacy.sys.isLittleEndian); } public commit () { @@ -632,7 +628,7 @@ function bestSizeToHavePixels (nPixels: number) { nPixels = 5; } const aligned = nextPow2(nPixels); - const epxSum = log2(aligned); + const epxSum = bits.log2(aligned); const h = epxSum >> 1; const w = (epxSum & 1) ? (h + 1) : h; return { diff --git a/cocos/3d/assets/morph.ts b/cocos/3d/assets/morph.ts index b17197a84ac..daa9c39cb01 100644 --- a/cocos/3d/assets/morph.ts +++ b/cocos/3d/assets/morph.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { AttributeName } from '../../gfx'; import { Mesh } from './mesh'; diff --git a/cocos/3d/assets/skeleton.jsb.ts b/cocos/3d/assets/skeleton.jsb.ts index e85a6f28c16..139ff9907ae 100644 --- a/cocos/3d/assets/skeleton.jsb.ts +++ b/cocos/3d/assets/skeleton.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,15 +23,13 @@ */ import { ccclass, type, serializable } from 'cc.decorator'; -import { CCString } from '../../core/data/utils/attribute'; -import { Mat4 } from '../../core/math'; +import { CCString, cclegacy, Mat4 } from '../../core'; import { DataPoolManager } from '../skeletal-animation/data-pool-manager'; import { Asset } from '../../asset/assets/asset'; -import { legacyCC } from '../../core/global-exports'; export const Skeleton = jsb.Skeleton; export type Skeleton = jsb.Skeleton; -legacyCC.Skeleton = Skeleton; +cclegacy.Skeleton = Skeleton; const skeletonProto: any = Skeleton.prototype; Object.defineProperty(skeletonProto, 'bindposes', { @@ -54,7 +51,7 @@ skeletonProto._ctor = function () { }; skeletonProto.destroy = function () { - (legacyCC.director.root?.dataPoolManager as DataPoolManager)?.releaseSkeleton(this); + (cclegacy.director.root?.dataPoolManager as DataPoolManager)?.releaseSkeleton(this); return Asset.prototype.destroy.call(this); }; @@ -66,7 +63,7 @@ skeletonProto.onLoaded = function () { // handle meta data, it is generated automatically const SkeletonProto = Skeleton.prototype; -type([CCString])(SkeletonProto, '_joints'); -type([Mat4])(SkeletonProto, '_bindposes'); -serializable(SkeletonProto, '_hash'); +type([CCString])(SkeletonProto, '_joints', () => []); +type([Mat4])(SkeletonProto, '_bindposes', () => []); +serializable(SkeletonProto, '_hash', () => 0); ccclass('cc.Skeleton')(Skeleton); \ No newline at end of file diff --git a/cocos/3d/assets/skeleton.ts b/cocos/3d/assets/skeleton.ts index a836a24c6cc..e3018244098 100644 --- a/cocos/3d/assets/skeleton.ts +++ b/cocos/3d/assets/skeleton.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,12 +23,9 @@ */ import { ccclass, type, serializable } from 'cc.decorator'; -import { CCString } from '../../core/data/utils/attribute'; -import { Mat4 } from '../../core/math'; -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; +import { CCString, Mat4, cclegacy, murmurhash2_32_gc } from '../../core'; import type { DataPoolManager } from '../skeletal-animation/data-pool-manager'; import { Asset } from '../../asset/assets/asset'; -import { legacyCC } from '../../core/global-exports'; /** * @en The skeleton asset. It stores the path related to [[SkinnedMeshRenderer.skinningRoot]] of all bones and its bind pose matrix. @@ -110,7 +106,7 @@ export class Skeleton extends Asset { } public destroy () { - (legacyCC.director.root?.dataPoolManager as DataPoolManager)?.releaseSkeleton(this); + (cclegacy.director.root?.dataPoolManager as DataPoolManager)?.releaseSkeleton(this); return super.destroy(); } @@ -124,4 +120,4 @@ export class Skeleton extends Asset { } } -legacyCC.Skeleton = Skeleton; +cclegacy.Skeleton = Skeleton; diff --git a/cocos/3d/framework/deprecated.ts b/cocos/3d/framework/deprecated.ts index dcc249d860f..aafe27f546b 100644 --- a/cocos/3d/framework/deprecated.ts +++ b/cocos/3d/framework/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { removeProperty } from '../../core/utils'; +import { removeProperty, js, cclegacy } from '../../core'; import { MeshRenderer } from './mesh-renderer'; -import { js } from '../../core/utils/js'; -import { legacyCC } from '../../core/global-exports'; removeProperty(MeshRenderer.prototype, 'MeshRenderer.prototype', [ { @@ -42,5 +39,5 @@ removeProperty(MeshRenderer.prototype, 'MeshRenderer.prototype', [ * @deprecated Since v1.2 */ export { MeshRenderer as ModelComponent }; -legacyCC.ModelComponent = MeshRenderer; +cclegacy.ModelComponent = MeshRenderer; js.setClassAlias(MeshRenderer, 'cc.ModelComponent'); diff --git a/cocos/3d/framework/index.ts b/cocos/3d/framework/index.ts index dc20bfbf3d4..05b122abc47 100644 --- a/cocos/3d/framework/index.ts +++ b/cocos/3d/framework/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,7 +23,7 @@ THE SOFTWARE. */ -export { MeshRenderer } from './mesh-renderer'; +export { MeshRenderer, ReflectionProbeType } from './mesh-renderer'; /** deprecated */ export * from './deprecated'; diff --git a/cocos/3d/framework/mesh-renderer.ts b/cocos/3d/framework/mesh-renderer.ts index 7c65415a75f..b1dd6b50f41 100644 --- a/cocos/3d/framework/mesh-renderer.ts +++ b/cocos/3d/framework/mesh-renderer.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -22,26 +22,25 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -import { ccclass, help, executeInEditMode, executionOrder, menu, tooltip, visible, type, - formerlySerializedAs, serializable, editable, disallowAnimation } from 'cc.decorator'; import { JSB } from 'internal:constants'; -import { Texture2D } from '../../asset/assets'; +import { displayOrder, group, range } from 'cc.decorator'; +import { Texture2D, TextureCube } from '../../asset/assets'; import { Material } from '../../asset/assets/material'; import { Mesh } from '../assets/mesh'; -import { Vec4 } from '../../core/math'; +import { Vec4, Enum, cclegacy, CCBoolean, CCFloat, assertIsTrue, _decorator, CCInteger, EventTarget, warnID } from '../../core'; import { scene } from '../../render-scene'; import { MorphModel } from '../models/morph-model'; import { Root } from '../../root'; -import { TransformBit } from '../../scene-graph/node-enum'; -import { Enum } from '../../core/value-types'; -import { builtinResMgr } from '../../asset/asset-manager'; +import { MobilityMode, TransformBit } from '../../scene-graph/node-enum'; import { ModelRenderer } from '../../misc/model-renderer'; import { MorphRenderingInstance } from '../assets/morph-rendering'; -import { legacyCC } from '../../core/global-exports'; -import { assertIsTrue } from '../../core/data/utils/asserts'; -import { CCFloat } from '../../core/data/utils/attribute'; -import { property } from '../../core/data/class-decorator'; +import { NodeEventType } from '../../scene-graph/node-event'; +import { Texture } from '../../gfx'; +import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; +import { settings, Settings } from '../../core/settings'; + +const { property, ccclass, help, executeInEditMode, executionOrder, menu, tooltip, visible, type, + formerlySerializedAs, serializable, editable, disallowAnimation } = _decorator; /** * @en Shadow projection mode. @@ -78,11 +77,51 @@ const ModelShadowReceivingMode = Enum({ }); /** - * @en Model's light map settings. - * @zh 模型光照图设置 + * @en Reflection probe type + * @zh 反射探针类型。 + */ +export enum ReflectionProbeType { + /** + * @en Use the default skybox. + * @zh 使用默认天空盒 + */ + NONE = 0, + /** + * @en Cubemap generate by probe + * @zh Probe烘焙的cubemap + */ + BAKED_CUBEMAP = 1, + /** + * @en Realtime planar reflection + * @zh 实时平面反射 + */ + PLANAR_REFLECTION = 2, +} + +/** + * @en Model's bake settings. + * @zh 模型烘焙设置 */ -@ccclass('cc.ModelLightmapSettings') -class ModelLightmapSettings { +@ccclass('cc.ModelBakeSettings') +class ModelBakeSettings extends EventTarget { + /** + * @en The event which will be triggered when the useLightProbe is changed. + * @zh useLightProbe属性修改时触发的事件 + */ + public static readonly USE_LIGHT_PROBE_CHANGED = 'use_light_probe_changed'; + + /** + * @en The event which will be triggered when the reflectionProbe is changed. + * @zh reflectionProbe 属性修改时触发的事件 + */ + public static readonly REFLECTION_PROBE_CHANGED = 'reflection_probe_changed'; + + /** + * @en The event which will be triggered when the bakeToReflectionProbe is changed. + * @zh bakeToReflectionProbe 属性修改时触发的事件 + */ + public static readonly BAKE_TO_REFLECTION_PROBE_CHANGED = 'bake_to_reflection_probe_changed'; + @serializable public texture: Texture2D|null = null; @serializable @@ -96,12 +135,26 @@ class ModelLightmapSettings { @serializable protected _lightmapSize = 64; + @serializable + protected _useLightProbe = false; + @serializable + protected _bakeToLightProbe = true; + + @serializable + protected _reflectionProbeType = ReflectionProbeType.NONE; + @serializable + protected _bakeToReflectionProbe = true; + @serializable + public _probeCubemap: TextureCube | null = null; + public _probePlanarmap: Texture | null = null; + /** * @en Whether the model is static and bake-able with light map. * Notice: the model's vertex data must have the second UV attribute to enable light map baking. * @zh 模型是否是静态的并可以烘培光照贴图。 * 注意:模型顶点数据必须包含第二套 UV 属性来支持光照贴图烘焙。 */ + @group({ id: 'LightMap', name: 'LightMapSettings', displayOrder: 0 }) @editable get bakeable () { return this._bakeable; @@ -115,6 +168,7 @@ class ModelLightmapSettings { * @en Whether to cast shadow in light map baking. * @zh 在光照贴图烘焙中是否投射阴影。 */ + @group({ id: 'LightMap', name: 'LightMapSettings' }) @editable get castShadow () { return this._castShadow; @@ -128,6 +182,7 @@ class ModelLightmapSettings { * @en Whether to receive shadow in light map baking. * @zh 在光照贴图烘焙中是否接受阴影。 */ + @group({ id: 'LightMap', name: 'LightMapSettings' }) @editable get receiveShadow () { return this._receiveShadow; @@ -141,7 +196,10 @@ class ModelLightmapSettings { * @en The lightmap size. * @zh 光照图大小。 */ + @group({ id: 'LightMap', name: 'LightMapSettings' }) @editable + @type(CCInteger) + @range([0, 1024]) get lightmapSize () { return this._lightmapSize; } @@ -149,6 +207,67 @@ class ModelLightmapSettings { set lightmapSize (val) { this._lightmapSize = val; } + + /** + * @en Whether to use light probe which provides indirect light to dynamic objects. + * @zh 模型是否使用光照探针,光照探针为动态物体提供间接光。 + */ + @group({ id: 'LightProbe', name: 'LightProbeSettings', displayOrder: 1 }) + @editable + @type(CCBoolean) + get useLightProbe () { + return this._useLightProbe; + } + + set useLightProbe (val) { + this._useLightProbe = val; + this.emit(ModelBakeSettings.USE_LIGHT_PROBE_CHANGED); + } + + /** + * @en Whether the model is used to calculate light probe + * @zh 模型是否用于计算光照探针 + */ + @group({ id: 'LightProbe', name: 'LightProbeSettings' }) + @editable + @type(CCBoolean) + get bakeToLightProbe () { + return this._bakeToLightProbe; + } + + set bakeToLightProbe (val) { + this._bakeToLightProbe = val; + } + + /** + * @en Used to set whether to use the reflection probe or set probe's type. + * @zh 用于设置是否使用反射探针或者设置反射探针的类型。 + */ + @group({ id: 'ReflectionProbe', name: 'ReflectionProbeSettings', displayOrder: 2 }) + @type(Enum(ReflectionProbeType)) + get reflectionProbe () { + return this._reflectionProbeType; + } + + set reflectionProbe (val) { + this._reflectionProbeType = val; + this.emit(ModelBakeSettings.REFLECTION_PROBE_CHANGED); + } + + /** + * @en Whether the model can be render by the reflection probe + * @zh 模型是否能被反射探针渲染 + */ + @group({ id: 'ReflectionProbe', name: 'ReflectionProbeSettings' }) + @type(CCBoolean) + get bakeToReflectionProbe () { + return this._bakeToReflectionProbe; + } + + set bakeToReflectionProbe (val) { + this._bakeToReflectionProbe = val; + this.emit(ModelBakeSettings.BAKE_TO_REFLECTION_PROBE_CHANGED); + } } /** @@ -175,13 +294,14 @@ export class MeshRenderer extends ModelRenderer { public static ShadowReceivingMode = ModelShadowReceivingMode; /** - * @en The settings for light map baking - * @zh 光照贴图烘焙的配置 + * @en The settings for GI baking, it was called lightmapSettings before + * @zh 全局光照烘焙的配置,以前名称为lightmapSettings */ @serializable @editable @disallowAnimation - public lightmapSettings = new ModelLightmapSettings(); + @displayOrder(3) + public bakeSettings = new ModelBakeSettings(this); @serializable protected _mesh: Mesh | null = null; @@ -198,6 +318,11 @@ export class MeshRenderer extends ModelRenderer { @serializable protected _shadowNormalBias = 0; + @serializable + protected _reflectionProbeId = -1; + + protected _reflectionProbeDataMap: Texture2D | null = null; + // @serializable private _subMeshShapesWeights: number[][] = []; @@ -207,7 +332,7 @@ export class MeshRenderer extends ModelRenderer { */ @type(CCFloat) @tooltip('i18n:model.shadow_bias') - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 0 } }) + @group({ id: 'DynamicShadow', name: 'DynamicShadowSettings', displayOrder: 2 }) @disallowAnimation get shadowBias () { return this._shadowBias; @@ -216,7 +341,7 @@ export class MeshRenderer extends ModelRenderer { set shadowBias (val) { this._shadowBias = val; this._updateShadowBias(); - this._onUpdateLocalShadowBias(); + this._onUpdateLocalShadowBiasAndProbeId(); } /** @@ -225,7 +350,7 @@ export class MeshRenderer extends ModelRenderer { */ @type(CCFloat) @tooltip('i18n:model.shadow_normal_bias') - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 1 } }) + @group({ id: 'DynamicShadow', name: 'DynamicShadowSettings' }) @disallowAnimation get shadowNormalBias () { return this._shadowNormalBias; @@ -234,7 +359,7 @@ export class MeshRenderer extends ModelRenderer { set shadowNormalBias (val) { this._shadowNormalBias = val; this._updateShadowNormalBias(); - this._onUpdateLocalShadowBias(); + this._onUpdateLocalShadowBiasAndProbeId(); } /** @@ -243,7 +368,7 @@ export class MeshRenderer extends ModelRenderer { */ @type(ModelShadowCastingMode) @tooltip('i18n:model.shadow_casting_model') - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 2 } }) + @group({ id: 'DynamicShadow', name: 'DynamicShadowSettings' }) @disallowAnimation get shadowCastingMode () { return this._shadowCastingMode; @@ -254,13 +379,32 @@ export class MeshRenderer extends ModelRenderer { this._updateCastShadow(); } + /** + * @en Is received direction Light. + * @zh 是否接收平行光光照。 + * @param visibility @en direction light visibility. @zh 方向光的可见性。 + */ + public onUpdateReceiveDirLight (visibility: number, forceClose = false) { + if (!this._model) { return; } + if (forceClose) { + this._model.receiveDirLight = false; + return; + } + if (this.node && ((visibility & this.node.layer) === this.node.layer) + || (visibility & this._model.visFlags)) { + this._model.receiveDirLight = true; + } else { + this._model.receiveDirLight = false; + } + } + /** * @en receive shadow. * @zh 实时光照下是否接受阴影。 */ @type(ModelShadowReceivingMode) @tooltip('i18n:model.shadow_receiving_model') - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 3 } }) + @group({ id: 'DynamicShadow', name: 'DynamicShadowSettings' }) @disallowAnimation get receiveShadow () { return this._shadowReceivingMode; @@ -278,6 +422,7 @@ export class MeshRenderer extends ModelRenderer { * 注意,设置时,所有形变目标的权重都将归零。 */ @type(Mesh) + @displayOrder(1) @tooltip('i18n:model.mesh') get mesh () { return this._mesh; @@ -296,6 +441,9 @@ export class MeshRenderer extends ModelRenderer { } this._updateCastShadow(); this._updateReceiveShadow(); + this._updateUseLightProbe(); + this._updateUseReflectionProbe(); + this._updateReceiveDirLight(); } /** @@ -339,6 +487,13 @@ export class MeshRenderer extends ModelRenderer { constructor () { super(); this._modelType = scene.Model; + + const highQualityMode = settings.querySettings(Settings.Category.RENDERING, 'highQualityMode'); + if (highQualityMode) { + this._shadowCastingMode = ModelShadowCastingMode.ON; + this.bakeSettings.castShadow = true; + this.bakeSettings.receiveShadow = true; + } } public onLoad () { @@ -352,6 +507,10 @@ export class MeshRenderer extends ModelRenderer { this._updateReceiveShadow(); this._updateShadowBias(); this._updateShadowNormalBias(); + this._updateUseLightProbe(); + this._updateBakeToReflectionProbe(); + this._updateUseReflectionProbe(); + this._updateReceiveDirLight(); } // Redo, Undo, Prefab restore, etc. @@ -364,10 +523,20 @@ export class MeshRenderer extends ModelRenderer { this._updateReceiveShadow(); this._updateShadowBias(); this._updateShadowNormalBias(); + this._updateUseLightProbe(); + this._updateBakeToReflectionProbe(); + this._updateUseReflectionProbe(); + this._updateReceiveDirLight(); } public onEnable () { super.onEnable(); + this.node.on(NodeEventType.MOBILITY_CHANGED, this.onMobilityChanged, this); + this.node.on(NodeEventType.LIGHT_PROBE_BAKING_CHANGED, this.onLightProbeBakingChanged, this); + this.bakeSettings.on(ModelBakeSettings.USE_LIGHT_PROBE_CHANGED, this.onUseLightProbeChanged, this); + this.bakeSettings.on(ModelBakeSettings.REFLECTION_PROBE_CHANGED, this.onReflectionProbeChanged, this); + this.bakeSettings.on(ModelBakeSettings.BAKE_TO_REFLECTION_PROBE_CHANGED, this.onBakeToReflectionProbeChanged, this); + if (!this._model) { this._updateModels(); } @@ -375,7 +544,12 @@ export class MeshRenderer extends ModelRenderer { this._updateReceiveShadow(); this._updateShadowBias(); this._updateShadowNormalBias(); - this._onUpdateLocalShadowBias(); + this._updateBakeToReflectionProbe(); + this._updateUseReflectionProbe(); + this._onUpdateLocalShadowBiasAndProbeId(); + this._updateUseLightProbe(); + this._updateReceiveDirLight(); + this._onUpdateReflectionProbeDataMap(); this._attachToScene(); } @@ -383,11 +557,16 @@ export class MeshRenderer extends ModelRenderer { if (this._model) { this._detachFromScene(); } + this.node.off(NodeEventType.MOBILITY_CHANGED, this.onMobilityChanged, this); + this.node.off(NodeEventType.LIGHT_PROBE_BAKING_CHANGED, this.onLightProbeBakingChanged, this); + this.bakeSettings.off(ModelBakeSettings.USE_LIGHT_PROBE_CHANGED, this.onUseLightProbeChanged, this); + this.bakeSettings.off(ModelBakeSettings.REFLECTION_PROBE_CHANGED, this.onReflectionProbeChanged, this); + this.bakeSettings.off(ModelBakeSettings.BAKE_TO_REFLECTION_PROBE_CHANGED, this.onBakeToReflectionProbeChanged, this); } public onDestroy () { if (this._model) { - legacyCC.director.root.destroyModel(this._model); + cclegacy.director.root.destroyModel(this._model); this._model = null; this._models.length = 0; } @@ -494,13 +673,70 @@ export class MeshRenderer extends ModelRenderer { * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _updateLightmap (lightmap: Texture2D|null, uOff: number, vOff: number, scale: number, lum: number) { - this.lightmapSettings.texture = lightmap; - this.lightmapSettings.uvParam.x = uOff; - this.lightmapSettings.uvParam.y = vOff; - this.lightmapSettings.uvParam.z = scale; - this.lightmapSettings.uvParam.w = lum; + this.bakeSettings.texture = lightmap; + this.bakeSettings.uvParam.x = uOff; + this.bakeSettings.uvParam.y = vOff; + this.bakeSettings.uvParam.z = scale; + this.bakeSettings.uvParam.w = lum; this._onUpdateLightingmap(); + this._updateReceiveDirLight(); + } + + public updateProbeCubemap (cubeMap: TextureCube | null, useDefaultTexture?: boolean) { + if (this.bakeSettings._probeCubemap && this.bakeSettings._probeCubemap === cubeMap) { + return; + } + this.bakeSettings._probeCubemap = cubeMap; + if (this.model !== null) { + let cubeMap = this.bakeSettings._probeCubemap; + if (!cubeMap && this.node.scene && !useDefaultTexture) { + cubeMap = this.node.scene._globals.skybox.envmap; + } + this.model.updateReflectionProbeCubemap(cubeMap); + } + } + public updateProbePlanarMap (planarMap: Texture | null) { + if (this.bakeSettings._probePlanarmap === planarMap) { + return; + } + this.bakeSettings._probePlanarmap = planarMap; + if (this.model !== null) { + this.model.updateReflectionProbePlanarMap(this.bakeSettings._probePlanarmap); + } + } + + public updateReflectionProbeDataMap (dataMap: Texture2D | null) { + this._reflectionProbeDataMap = dataMap; + if (this.model !== null) { + this.model.updateReflectionProbeDataMap(dataMap); + } + } + + public updateReflectionProbeId (probeId: number) { + this._reflectionProbeId = probeId; + if (this.model) { + this.model.reflectionProbeId = probeId; + } + this._onUpdateLocalShadowBiasAndProbeId(); + } + + protected _updateReflectionProbeTexture () { + if (this.model === null) return; + if (this.bakeSettings.reflectionProbe === ReflectionProbeType.BAKED_CUBEMAP) { + let cubeMap = this.bakeSettings._probeCubemap; + if (!cubeMap && this.node.scene) { + cubeMap = this.node.scene._globals.skybox.envmap; + } + this.model.updateReflectionProbeCubemap(cubeMap); + this.model.updateReflectionProbePlanarMap(null); + } else if (this.bakeSettings.reflectionProbe === ReflectionProbeType.PLANAR_REFLECTION) { + this.model.updateReflectionProbePlanarMap(this.bakeSettings._probePlanarmap); + this.model.updateReflectionProbeCubemap(null); + } else { + this.model.updateReflectionProbeCubemap(null); + this.model.updateReflectionProbePlanarMap(null); + } } protected _updateModels () { @@ -524,10 +760,32 @@ export class MeshRenderer extends ModelRenderer { } // Initialize lighting map before model initializing // because the lighting map will influence the model's shader - this._model.initLightingmap(this.lightmapSettings.texture, this.lightmapSettings.uvParam); + this._model.initLightingmap(this.bakeSettings.texture, this.bakeSettings.uvParam); + this._updateUseLightProbe(); this._updateModelParams(); this._onUpdateLightingmap(); - this._onUpdateLocalShadowBias(); + this._onUpdateLocalShadowBiasAndProbeId(); + this._updateUseReflectionProbe(); + this._updateReceiveDirLight(); + this._onUpdateReflectionProbeDataMap(); + } + } + + protected _updateReceiveDirLight () { + if (!this._model) { return; } + const scene = this.node.scene; + if (!scene || !scene.renderScene) { return; } + const mainLight = scene.renderScene.mainLight; + if (!mainLight) { return; } + const visibility = mainLight.visibility; + if (!mainLight.node) { return; } + if (mainLight.node.mobility === MobilityMode.Static + && (this.bakeSettings.texture || (this.node.scene.globals.lightProbeInfo.data + && this.node.scene.globals.lightProbeInfo.data.hasCoefficients() + && this._model.useLightProbe))) { + this.onUpdateReceiveDirLight(visibility, true); + } else { + this.onUpdateReceiveDirLight(visibility); } } @@ -541,7 +799,7 @@ export class MeshRenderer extends ModelRenderer { // derived classes should use a morph-able model type(i.e. model type derived from `MorphModel`). // So we should take care of the edge case. const modelType = (preferMorphOverPlain && this._modelType === scene.Model) ? MorphModel : this._modelType; - const model = this._model = (legacyCC.director.root as Root).createModel(modelType); + const model = this._model = (cclegacy.director.root as Root).createModel(modelType); model.visFlags = this.visibility; model.node = model.transform = this.node; this._models.length = 0; @@ -592,28 +850,37 @@ export class MeshRenderer extends ModelRenderer { protected _onUpdateLightingmap () { if (this.model !== null) { - this.model.updateLightingmap(this.lightmapSettings.texture, this.lightmapSettings.uvParam); + this.model.updateLightingmap(this.bakeSettings.texture, this.bakeSettings.uvParam); } this.setInstancedAttribute('a_lightingMapUVParam', [ - this.lightmapSettings.uvParam.x, - this.lightmapSettings.uvParam.y, - this.lightmapSettings.uvParam.z, - this.lightmapSettings.uvParam.w, + this.bakeSettings.uvParam.x, + this.bakeSettings.uvParam.y, + this.bakeSettings.uvParam.z, + this.bakeSettings.uvParam.w, ]); } - protected _onUpdateLocalShadowBias () { + protected _onUpdateLocalShadowBiasAndProbeId () { if (this.model !== null) { this.model.updateLocalShadowBias(); + this.model.updateReflectionProbeId(); } - this.setInstancedAttribute('a_localShadowBias', [ + this.setInstancedAttribute('a_localShadowBiasAndProbeId', [ this._shadowBias, this._shadowNormalBias, + this._reflectionProbeId, + 0.0, ]); } + protected _onUpdateReflectionProbeDataMap () { + if (this.model !== null) { + this.model.updateReflectionProbeDataMap(this._reflectionProbeDataMap); + } + } + protected _onMaterialModified (idx: number, material: Material | null) { if (!this._model || !this._model.inited) { return; } this._onRebuildPSO(idx, material || this._getBuiltinMaterial()); @@ -624,7 +891,9 @@ export class MeshRenderer extends ModelRenderer { this._model.isDynamicBatching = this._isBatchingEnabled(); this._model.setSubModelMaterial(idx, material); this._onUpdateLightingmap(); - this._onUpdateLocalShadowBias(); + this._onUpdateLocalShadowBiasAndProbeId(); + this._updateReflectionProbeTexture(); + this._onUpdateReflectionProbeDataMap(); } protected _onMeshChanged (old: Mesh | null) { @@ -680,6 +949,49 @@ export class MeshRenderer extends ModelRenderer { } } + protected onMobilityChanged () { + this._updateUseLightProbe(); + this._updateReceiveDirLight(); + } + + protected onLightProbeBakingChanged () { + this._updateReceiveDirLight(); + } + + protected onUseLightProbeChanged () { + this._updateUseLightProbe(); + } + + protected onReflectionProbeChanged () { + this._updateUseReflectionProbe(); + this._onUpdateLocalShadowBiasAndProbeId(); + if (this.bakeSettings.reflectionProbe === ReflectionProbeType.BAKED_CUBEMAP) { + cclegacy.internal.reflectionProbeManager.updateUseCubeModels(this._model); + if (!cclegacy.internal.reflectionProbeManager.getUsedReflectionProbe(this._model, ReflectionProbeType.BAKED_CUBEMAP)) { + warnID(16302); + } + } else if (this.bakeSettings.reflectionProbe === ReflectionProbeType.PLANAR_REFLECTION) { + cclegacy.internal.reflectionProbeManager.updateUsePlanarModels(this._model); + if (!cclegacy.internal.reflectionProbeManager.getUsedReflectionProbe(this._model, ReflectionProbeType.PLANAR_REFLECTION)) { + warnID(16302); + } + } + } + + protected onBakeToReflectionProbeChanged () { + this._updateBakeToReflectionProbe(); + } + + protected _updateUseLightProbe () { + if (!this._model) { return; } + const node = this.node; + if (this._mesh && node && node.mobility === MobilityMode.Movable && this.bakeSettings.useLightProbe) { + this._model.useLightProbe = true; + } else { + this._model.useLightProbe = false; + } + } + protected _isBatchingEnabled () { for (let i = 0; i < this._materials.length; ++i) { const mat = this._materials[i]; @@ -692,6 +1004,17 @@ export class MeshRenderer extends ModelRenderer { return false; } + protected _updateUseReflectionProbe () { + if (!this._model) return; + this._model.reflectionProbeType = this.bakeSettings.reflectionProbe; + this._updateReflectionProbeTexture(); + } + + protected _updateBakeToReflectionProbe () { + if (!this._model) { return; } + this._model.bakeToReflectionProbe = this.bakeSettings.bakeToReflectionProbe; + } + private _watchMorphInMesh () { if (this._morphInstance) { this._morphInstance.destroy(); diff --git a/cocos/3d/index.ts b/cocos/3d/index.ts index 2bbdca2893d..4dc501ba8ce 100644 --- a/cocos/3d/index.ts +++ b/cocos/3d/index.ts @@ -1,20 +1,19 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the 'Software'), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER @@ -32,6 +31,9 @@ export * from './framework'; export * from './lights'; export * from './skinned-mesh-renderer'; +export * from './lod'; +export * from './reflection-probe'; + export { utils, }; diff --git a/cocos/3d/lights/deprecated.ts b/cocos/3d/lights/deprecated.ts index e9c901cac8a..f23d390750a 100644 --- a/cocos/3d/lights/deprecated.ts +++ b/cocos/3d/lights/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,43 +20,41 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Light } from './light-component'; import { SpotLight } from './spot-light-component'; import { SphereLight } from './sphere-light-component'; import { DirectionalLight } from './directional-light-component'; -import { legacyCC } from '../../core/global-exports'; -import { js } from '../../core/utils/js'; -import { replaceProperty } from '../../core/utils/x-deprecated'; +import { cclegacy, js, replaceProperty } from '../../core'; /** * Alias of [[Light]] * @deprecated Since v1.2 */ export { Light as LightComponent }; -legacyCC.LightComponent = Light; +cclegacy.LightComponent = Light; js.setClassAlias(Light, 'cc.LightComponent'); /** * Alias of [[DirectionalLight]] * @deprecated Since v1.2 */ export { DirectionalLight as DirectionalLightComponent }; -legacyCC.DirectionalLightComponent = DirectionalLight; +cclegacy.DirectionalLightComponent = DirectionalLight; js.setClassAlias(DirectionalLight, 'cc.DirectionalLightComponent'); /** * Alias of [[SphereLight]] * @deprecated Since v1.2 */ export { SphereLight as SphereLightComponent }; -legacyCC.SphereLightComponent = SphereLight; +cclegacy.SphereLightComponent = SphereLight; js.setClassAlias(SphereLight, 'cc.SphereLightComponent'); /** * Alias of [[SpotLight]] * @deprecated Since v1.2 */ export { SpotLight as SpotLightComponent }; -legacyCC.SpotLightComponent = SpotLight; +cclegacy.SpotLightComponent = SpotLight; js.setClassAlias(SpotLight, 'cc.SpotLightComponent'); replaceProperty(SpotLight.prototype, 'SpotLight.prototype', [ diff --git a/cocos/3d/lights/directional-light-component.ts b/cocos/3d/lights/directional-light-component.ts index 55ce22caf61..fc61f873e52 100644 --- a/cocos/3d/lights/directional-light-component.ts +++ b/cocos/3d/lights/directional-light-component.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -23,16 +23,16 @@ THE SOFTWARE. */ -import { ccclass, range, slide, type, editable, visible, help, executeInEditMode, - menu, tooltip, serializable, formerlySerializedAs } from 'cc.decorator'; import { Light } from './light-component'; import { scene } from '../../render-scene'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy, clamp, warnID, CCBoolean, CCFloat, _decorator, settings, Settings, CCInteger } from '../../core'; import { Camera, PCFType, Shadows, ShadowType, CSMOptimizationMode, CSMLevel } from '../../render-scene/scene'; import { Root } from '../../root'; -import { property } from '../../core/data/class-decorator'; -import { CCBoolean, CCFloat } from '../../core/data/utils/attribute'; -import { clamp, warnID } from '../../core'; +import { MeshRenderer } from '../framework'; +import { director } from '../../game/director'; +import { rangeMin } from '../../core/data/decorators'; + +const { ccclass, menu, executeInEditMode, property, serializable, formerlySerializedAs, tooltip, help, visible, type, editable, slide, range } = _decorator; /** * @en The directional light component, only one real time directional light is permitted in one scene, it act as the main light of the scene. @@ -74,6 +74,13 @@ export class DirectionalLight extends Light { @serializable protected _csmOptimizationMode = CSMOptimizationMode.RemoveDuplicates; + @serializable + protected _csmAdvancedOptions = false; + @serializable + protected _csmLayersTransition = false; + @serializable + protected _csmTransitionRange = 0.05; + // fixed area properties @serializable protected _shadowFixedArea = false; @@ -92,8 +99,12 @@ export class DirectionalLight extends Light { * @zh 光源强度。 */ @tooltip('i18n:lights.illuminance') + @editable + @rangeMin(0) + @slide + @type(CCInteger) get illuminance () { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._illuminanceHDR; } else { @@ -101,7 +112,7 @@ export class DirectionalLight extends Light { } } set illuminance (val) { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._illuminanceHDR = val; this._light && (this._light.illuminanceHDR = this._illuminanceHDR); @@ -116,8 +127,8 @@ export class DirectionalLight extends Light { * @zh 是否启用实时阴影? */ @tooltip('i18n:lights.shadowEnabled') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 1 } }) @editable @type(CCBoolean) @@ -136,8 +147,8 @@ export class DirectionalLight extends Light { * @zh 实时阴影计算中的阴影 pcf 等级。 */ @tooltip('i18n:lights.shadowPcf') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 5 } }) @editable @type(PCFType) @@ -156,8 +167,8 @@ export class DirectionalLight extends Light { * @zh 实时阴影计算中的阴影纹理偏移值。 */ @tooltip('i18n:lights.shadowBias') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 6 } }) @editable @type(CCFloat) @@ -176,8 +187,8 @@ export class DirectionalLight extends Light { * @zh 实时阴影计算中的法线偏移。 */ @tooltip('i18n:lights.shadowNormalBias') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 7 } }) @editable @type(CCFloat) @@ -196,8 +207,8 @@ export class DirectionalLight extends Light { * @zh 实时阴影计算中的阴影颜色饱和度。 */ @tooltip('i18n:lights.shadowSaturation') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 8 } }) @editable @range([0.0, 1.0, 0.01]) @@ -220,8 +231,8 @@ export class DirectionalLight extends Light { */ @tooltip('i18n:lights.shadowDistance') @visible(function (this: DirectionalLight) { - return (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap && this._shadowFixedArea === false; }) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 9 } }) @@ -248,11 +259,12 @@ export class DirectionalLight extends Light { */ @tooltip('i18n:lights.shadowInvisibleOcclusionRange') @visible(function (this: DirectionalLight) { - return (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type - === ShadowType.ShadowMap && this._shadowFixedArea === false; + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type + === ShadowType.ShadowMap && this._shadowFixedArea === false + && this._csmAdvancedOptions; }) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 10 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 22 } }) @editable @tooltip('if shadow has been culled, increase this value to fix it') @range([0.0, 2000.0, 1.0]) @@ -273,7 +285,7 @@ export class DirectionalLight extends Light { * @zh 获取或者设置阴影层级 */ @visible(false) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 11 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 10 } }) @editable @tooltip('CSM Level') @slide @@ -295,11 +307,11 @@ export class DirectionalLight extends Light { */ @tooltip('i18n:lights.enableCSM') @visible(function (this: DirectionalLight) { - return (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap && this._shadowFixedArea === false; }) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 12 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 11 } }) @editable @tooltip('enable CSM') @slide @@ -320,7 +332,7 @@ export class DirectionalLight extends Light { * @zh 获取或者设置阴影层级系数 */ @visible(false) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 13 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 12 } }) @editable @tooltip('CSM Level ratio') @range([0.0, 1.0, 0.01]) @@ -343,7 +355,7 @@ export class DirectionalLight extends Light { * @internal */ @visible(false) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 14 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 13 } }) @editable @tooltip('CSM Performance Optimization Mode') @slide @@ -363,9 +375,9 @@ export class DirectionalLight extends Light { * @zh 实时阴影计算中是否使用固定区域阴影。 */ @tooltip('i18n:lights.shadowFixedArea') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 15 } }) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 14 } }) @editable @type(CCBoolean) get shadowFixedArea () { @@ -384,11 +396,11 @@ export class DirectionalLight extends Light { */ @tooltip('i18n:lights.shadowNear') @visible(function (this: DirectionalLight) { - return (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap && this._shadowFixedArea === true; }) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 16 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 15 } }) @editable @type(CCFloat) get shadowNear () { @@ -407,11 +419,11 @@ export class DirectionalLight extends Light { */ @tooltip('i18n:lights.shadowFar') @visible(function (this: DirectionalLight) { - return (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap && this._shadowFixedArea === true; }) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 17 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 16 } }) @editable @type(CCFloat) get shadowFar () { @@ -430,11 +442,11 @@ export class DirectionalLight extends Light { */ @tooltip('i18n:lights.shadowOrthoSize') @visible(function (this: DirectionalLight) { - return (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.enabled - && (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap && this._shadowFixedArea === true; }) - @property({ group: { name: 'DynamicShadowSettings', displayOrder: 18 } }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 17 } }) @type(CCFloat) get shadowOrthoSize () { return this._shadowOrthoSize; @@ -446,9 +458,79 @@ export class DirectionalLight extends Light { } } + /** + * @en Enabled shadow advanced options + * @zh 是否启用高级选项? + */ + @tooltip('i18n:lights.shadowAdvancedOptions') + @visible(function (this: DirectionalLight) { + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap + && this._csmLevel > CSMLevel.LEVEL_1; + }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 19 } }) + @editable + @type(CCBoolean) + get csmAdvancedOptions () { + return this._csmAdvancedOptions; + } + set csmAdvancedOptions (val) { + this._csmAdvancedOptions = val; + } + + /** + * @en Enabled csm layers transition + * @zh 是否启用级联阴影层级过渡? + */ + @tooltip('i18n:lights.csmLayersTransition') + @visible(function (this: DirectionalLight) { + return (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.enabled + && (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap + && this._csmLevel > CSMLevel.LEVEL_1 + && this._csmAdvancedOptions; + }) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 20 } }) + @editable + @type(CCBoolean) + get csmLayersTransition () { + return this._csmLayersTransition; + } + set csmLayersTransition (val) { + this._csmLayersTransition = val; + if (this._light) { this._light.csmLayersTransition = val; } + } + + /** + * @en get or set csm layers transition range + * @zh 获取或者设置级联阴影层级过渡范围? + */ + @tooltip('i18n:lights.csmTransitionRange') + @visible(false) + @property({ group: { name: 'DynamicShadowSettings', displayOrder: 21 } }) + @editable + @range([0.0, 0.1, 0.01]) + @slide + @type(CCFloat) + get csmTransitionRange () { + return this._csmTransitionRange; + } + set csmTransitionRange (val) { + this._csmTransitionRange = val; + if (this._light) { this._light.csmTransitionRange = val; } + } + constructor () { super(); this._lightType = scene.DirectionalLight; + + const highQualityMode = settings.querySettings(Settings.Category.RENDERING, 'highQualityMode'); + + if (highQualityMode) { + this._shadowPcf = PCFType.SOFT_2X; + this._shadowDistance = 50; + this.enableCSM = true; + this.staticSettings.castShadow = true; + } } protected _createLight () { @@ -471,6 +553,31 @@ export class DirectionalLight extends Light { this._light.csmLevel = this._csmLevel; this._light.csmLayerLambda = this._csmLayerLambda; this._light.csmOptimizationMode = this._csmOptimizationMode; + this._light.csmLayersTransition = this._csmLayersTransition; + this._light.csmTransitionRange = this._csmTransitionRange; + } + } + + protected _onUpdateReceiveDirLight () { + if (!this._light) { + return; + } + super._onUpdateReceiveDirLight(); + + const scene = director.getScene(); + if (!scene || !scene.renderScene) { + return; + } + if (scene.renderScene.mainLight !== this._light) { + return; + } + const models = scene.renderScene.models; + for (let i = 0; i < models.length; i++) { + const model = models[i]; + if (!model.node) continue; + const meshRender = model.node.getComponent(MeshRenderer); + if (!meshRender) continue; + meshRender.onUpdateReceiveDirLight(this._visibility); } } } diff --git a/cocos/3d/lights/index.ts b/cocos/3d/lights/index.ts index 67d85771f65..8e8c5dd108d 100644 --- a/cocos/3d/lights/index.ts +++ b/cocos/3d/lights/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,6 +27,8 @@ export { DirectionalLight } from './directional-light-component'; export { Light } from './light-component'; export { SphereLight } from './sphere-light-component'; export { SpotLight } from './spot-light-component'; +export { PointLight } from './point-light-component'; +export { RangedDirectionalLight } from './ranged-directional-light-component'; /** deprecated */ export * from './deprecated'; diff --git a/cocos/3d/lights/light-component.ts b/cocos/3d/lights/light-component.ts index 6a69a762abd..d9ea8268f63 100644 --- a/cocos/3d/lights/light-component.ts +++ b/cocos/3d/lights/light-component.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -25,11 +25,11 @@ import { ccclass, tooltip, range, slide, type, displayOrder, serializable, editable } from 'cc.decorator'; import { Component } from '../../scene-graph/component'; -import { Color, Vec3 } from '../../core/math'; -import { Enum } from '../../core/value-types'; +import { Color, Vec3, Enum, cclegacy } from '../../core'; import { scene } from '../../render-scene'; import { Root } from '../../root'; -import { legacyCC } from '../../core/global-exports'; +import { CAMERA_DEFAULT_MASK } from '../../rendering/define'; +import { Layers } from '../../scene-graph/layers'; const _color_tmp = new Vec3(); @@ -53,8 +53,6 @@ class StaticLightSettings { @serializable protected _editorOnly = false; @serializable - protected _bakeable = false; - @serializable protected _castShadow = false; /** @@ -81,19 +79,6 @@ class StaticLightSettings { this._baked = val; } - /** - * @en Whether the light is bake-able. - * @zh 光源是否可烘培。 - */ - @editable - get bakeable () { - return this._bakeable; - } - - set bakeable (val) { - this._bakeable = val; - } - /** * @en Whether the light will cast shadow during baking process. * @zh 光源在烘焙时是否投射阴影。 @@ -138,6 +123,8 @@ export class Light extends Component { protected _colorTemperature = 6550; @serializable protected _staticSettings: StaticLightSettings = new StaticLightSettings(); + @serializable + protected _visibility = CAMERA_DEFAULT_MASK; protected _type = scene.LightType.UNKNOWN; protected _lightType: typeof scene.Light; @@ -233,6 +220,22 @@ export class Light extends Component { } } + /** + * @en Visibility mask of the light, declaring a set of node layers that will be visible to this light. + * @zh 光照的可见性掩码,声明在当前光照中可见的节点层级集合。 + */ + @tooltip('i18n:lights.visibility') + @displayOrder(255) + @type(Layers.BitMask) + set visibility (vis: number) { + this._visibility = vis; + if (this._light) { this._light.visibility = vis; } + this._onUpdateReceiveDirLight(); + } + get visibility (): number { + return this._visibility; + } + constructor () { super(); this._lightType = scene.Light; @@ -256,18 +259,19 @@ export class Light extends Component { protected _createLight () { if (!this._light) { - this._light = (legacyCC.director.root as Root).createLight(this._lightType); + this._light = (cclegacy.director.root as Root).createLight(this._lightType); } this.color = this._color; this.useColorTemperature = this._useColorTemperature; this.colorTemperature = this._colorTemperature; this._light.node = this.node; this._light.baked = this.baked; + this._light.visibility = this.visibility; } protected _destroyLight () { if (this._light) { - legacyCC.director.root.recycleLight(this._light); + cclegacy.director.root.recycleLight(this._light); this._light = null; } } @@ -287,6 +291,12 @@ export class Light extends Component { case scene.LightType.SPOT: renderScene.addSpotLight(this._light as scene.SpotLight); break; + case scene.LightType.POINT: + renderScene.addPointLight(this._light as scene.PointLight); + break; + case scene.LightType.RANGED_DIRECTIONAL: + renderScene.addRangedDirLight(this._light as scene.RangedDirectionalLight); + break; default: break; } @@ -307,9 +317,17 @@ export class Light extends Component { case scene.LightType.SPOT: renderScene.removeSpotLight(this._light as scene.SpotLight); break; + case scene.LightType.POINT: + renderScene.removePointLight(this._light as scene.PointLight); + break; + case scene.LightType.RANGED_DIRECTIONAL: + renderScene.removeRangedDirLight(this._light as scene.RangedDirectionalLight); + break; default: break; } } } + + protected _onUpdateReceiveDirLight () {} } diff --git a/cocos/3d/lights/point-light-component.ts b/cocos/3d/lights/point-light-component.ts new file mode 100644 index 00000000000..39cac9097f2 --- /dev/null +++ b/cocos/3d/lights/point-light-component.ts @@ -0,0 +1,164 @@ +/* + Copyright (c) 2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ccclass, help, executeInEditMode, menu, tooltip, type, displayOrder, + serializable, formerlySerializedAs, editable, rangeMin, slide } from 'cc.decorator'; +import { scene } from '../../render-scene'; +import { Camera, LightType } from '../../render-scene/scene'; +import { Light, PhotometricTerm } from './light-component'; +import { CCFloat, CCInteger, cclegacy } from '../../core'; + +/** + * @en The point light component, multiple point lights can be added to one scene. + * @zh 点光源组件,场景中可以添加多个点光源。 + */ +@ccclass('cc.PointLight') +@help('i18n:cc.PointLight') +@menu('Light/PointLight') +@executeInEditMode +export class PointLight extends Light { + @serializable + @formerlySerializedAs('_luminance') + private _luminanceHDR = 1700 / scene.nt2lm(0.15); + @serializable + private _luminanceLDR = 1700 / scene.nt2lm(0.15) * Camera.standardExposureValue * Camera.standardLightMeterScale; + @serializable + private _term = PhotometricTerm.LUMINOUS_FLUX; + @serializable + private _range = 1; + + /** + * @en Luminous flux of the light. + * @zh 光通量。 + */ + @displayOrder(-1) + @tooltip('i18n:lights.luminous_flux') + @editable + @rangeMin(0) + @slide + @type(CCInteger) + get luminousFlux () { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + return this._luminanceHDR * scene.nt2lm(1.0); + } else { + return this._luminanceLDR; + } + } + set luminousFlux (val) { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + let result = 0; + if (isHDR) { + this._luminanceHDR = val / scene.nt2lm(1.0); + result = this._luminanceHDR; + } else { + this._luminanceLDR = val; + result = this._luminanceLDR; + } + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + this._light && ((this._light as scene.PointLight).luminance = result); + } + + /** + * @en Luminance of the light. + * @zh 光亮度。 + */ + @displayOrder(-1) + @tooltip('i18n:lights.luminance') + @editable + @rangeMin(0) + @slide + @type(CCInteger) + get luminance () { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + return this._luminanceHDR; + } else { + return this._luminanceLDR; + } + } + set luminance (val) { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + this._luminanceHDR = val; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + this._light && ((this._light as scene.PointLight).luminanceHDR = this._luminanceHDR); + } else { + this._luminanceLDR = val; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + this._light && ((this._light as scene.PointLight).luminanceLDR = this._luminanceLDR); + } + } + + /** + * @en The photometric term currently being used. + * @zh 当前使用的光度学计量单位。 + */ + @type(PhotometricTerm) + @displayOrder(-2) + @tooltip('i18n:lights.term') + @editable + @rangeMin(0) + @slide + @type(CCInteger) + get term (): number { + return this._term; + } + set term (val) { + this._term = val; + } + + /** + * @en Range of the light. + * @zh 光源范围。 + */ + @tooltip('i18n:lights.range') + @editable + @rangeMin(0) + @slide + @type(CCFloat) + get range () { + return this._range; + } + set range (val) { + this._range = val; + if (this._light) { (this._light as scene.PointLight).range = val; } + } + + constructor () { + super(); + this._lightType = scene.PointLight; + } + + protected _createLight () { + super._createLight(); + this._type = LightType.POINT; + this.range = this._range; + + if (this._light) { + (this._light as scene.PointLight).luminanceHDR = this._luminanceHDR; + (this._light as scene.PointLight).luminanceLDR = this._luminanceLDR; + } + } +} diff --git a/cocos/3d/lights/ranged-directional-light-component.ts b/cocos/3d/lights/ranged-directional-light-component.ts new file mode 100644 index 00000000000..e857ed781ea --- /dev/null +++ b/cocos/3d/lights/ranged-directional-light-component.ts @@ -0,0 +1,85 @@ +/* + Copyright (c) 2023 Xiamen Yaji Software Co., Ltd. + http://www.cocos2d-x.org + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Light } from './light-component'; +import { ccclass, help, property, menu, executeInEditMode, formerlySerializedAs, serializable, tooltip, editable, slide, type } from '../../core/data/class-decorator'; +import { Camera, LightType } from '../../render-scene/scene'; +import { scene } from '../../render-scene'; +import { CCInteger, cclegacy } from '../../core'; +import { rangeMin } from '../../core/data/decorators'; + +/** + * @en The ranged directional light component, Multiple ranged directional light sources are allowed in a scene. + * @zh 范围平行光光源组件,一个场景允许存在多个范围平行光光源。 + */ +@ccclass('cc.RangedDirectionalLight') +@help('i18n:cc.RangedDirectionalLight') +@menu('Light/RangedDirectionalLight') +@executeInEditMode +export class RangedDirectionalLight extends Light { + @property + @formerlySerializedAs('_illuminance') + private _illuminanceHDR = 65000; + + @serializable + private _illuminanceLDR = 65000 * Camera.standardExposureValue; + + /** + * @en The light source intensity. + * @zh 光源强度。 + */ + @tooltip('i18n:lights.illuminance') + @editable + @rangeMin(0) + @slide + @type(CCInteger) + get illuminance () { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + return this._illuminanceHDR; + } else { + return this._illuminanceLDR; + } + } + set illuminance (val) { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + this._illuminanceHDR = val; + this._light && ((this._light as scene.RangedDirectionalLight).illuminanceHDR = this._illuminanceHDR); + } else { + this._illuminanceLDR = val; + this._light && ((this._light as scene.RangedDirectionalLight).illuminanceLDR = this._illuminanceLDR); + } + } + + constructor () { + super(); + this._lightType = scene.RangedDirectionalLight; + } + + protected _createLight () { + super._createLight(); + this._type = LightType.RANGED_DIRECTIONAL; + if (this._light) { + (this._light as scene.RangedDirectionalLight).illuminanceHDR = this._illuminanceHDR; + (this._light as scene.RangedDirectionalLight).illuminanceLDR = this._illuminanceLDR; + } + } +} diff --git a/cocos/3d/lights/sphere-light-component.ts b/cocos/3d/lights/sphere-light-component.ts index f8e3cc7369c..2bf6d9d6a87 100644 --- a/cocos/3d/lights/sphere-light-component.ts +++ b/cocos/3d/lights/sphere-light-component.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -23,10 +23,11 @@ THE SOFTWARE. */ -import { ccclass, help, executeInEditMode, menu, tooltip, type, displayOrder, serializable, formerlySerializedAs } from 'cc.decorator'; +import { ccclass, help, executeInEditMode, menu, tooltip, type, displayOrder, serializable, formerlySerializedAs, + editable, slide, rangeMin } from 'cc.decorator'; import { scene } from '../../render-scene'; import { Light, PhotometricTerm } from './light-component'; -import { legacyCC } from '../../core/global-exports'; +import { CCFloat, CCInteger, cclegacy } from '../../core'; import { Camera } from '../../render-scene/scene'; import { Root } from '../../root'; @@ -60,8 +61,12 @@ export class SphereLight extends Light { */ @displayOrder(-1) @tooltip('i18n:lights.luminous_flux') + @editable + @rangeMin(0) + @slide + @type(CCInteger) get luminousFlux () { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._luminanceHDR * scene.nt2lm(this._size); } else { @@ -69,7 +74,7 @@ export class SphereLight extends Light { } } set luminousFlux (val) { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; let result = 0; if (isHDR) { this._luminanceHDR = val / scene.nt2lm(this._size); @@ -87,8 +92,12 @@ export class SphereLight extends Light { */ @displayOrder(-1) @tooltip('i18n:lights.luminance') + @editable + @rangeMin(0) + @slide + @type(CCInteger) get luminance () { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._luminanceHDR; } else { @@ -96,7 +105,7 @@ export class SphereLight extends Light { } } set luminance (val) { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._luminanceHDR = val; this._light && (this._light.luminanceHDR = this._luminanceHDR); @@ -113,6 +122,10 @@ export class SphereLight extends Light { @type(PhotometricTerm) @displayOrder(-2) @tooltip('i18n:lights.term') + @editable + @rangeMin(0) + @slide + @type(CCInteger) get term (): number { return this._term; } @@ -127,6 +140,10 @@ export class SphereLight extends Light { * 光源大小。 */ @tooltip('i18n:lights.size') + @editable + @rangeMin(0) + @slide + @type(CCFloat) get size () { return this._size; } @@ -142,6 +159,10 @@ export class SphereLight extends Light { * 光源范围。 */ @tooltip('i18n:lights.range') + @editable + @rangeMin(0) + @slide + @type(CCFloat) get range () { return this._range; } diff --git a/cocos/3d/lights/spot-light-component.ts b/cocos/3d/lights/spot-light-component.ts index e610a204b7a..8e456151f50 100644 --- a/cocos/3d/lights/spot-light-component.ts +++ b/cocos/3d/lights/spot-light-component.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -22,17 +22,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -import { ccclass, range, slide, type, editable, displayOrder, help, executeInEditMode, - menu, tooltip, serializable, formerlySerializedAs, visible } from 'cc.decorator'; -import { toRadian } from '../../core/math'; +import { toRadian, cclegacy, CCBoolean, CCFloat, _decorator } from '../../core'; import { scene } from '../../render-scene'; import { Light, PhotometricTerm } from './light-component'; -import { legacyCC } from '../../core/global-exports'; import { Root } from '../../root'; import { Camera, PCFType, ShadowType } from '../../render-scene/scene'; -import { property } from '../../core/data/class-decorator'; -import { CCBoolean, CCFloat } from '../../core/data/utils/attribute'; + +const { ccclass, range, slide, type, editable, displayOrder, help, executeInEditMode, + menu, tooltip, serializable, formerlySerializedAs, visible, property } = _decorator; /** * @en The spot light component, multiple spot lights can be added to one scene. @@ -83,7 +80,7 @@ export class SpotLight extends Light { @tooltip('i18n:lights.luminous_flux') @displayOrder(-1) get luminousFlux () { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._luminanceHDR * scene.nt2lm(this._size); } else { @@ -92,7 +89,7 @@ export class SpotLight extends Light { } set luminousFlux (val) { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; let result = 0; if (isHDR) { this._luminanceHDR = val / scene.nt2lm(this._size); @@ -111,7 +108,7 @@ export class SpotLight extends Light { @tooltip('i18n:lights.luminance') @displayOrder(-1) get luminance () { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._luminanceHDR; } else { @@ -120,7 +117,7 @@ export class SpotLight extends Light { } set luminance (val) { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._luminanceHDR = val; this._light && (this._light.luminanceHDR = this._luminanceHDR); @@ -200,7 +197,7 @@ export class SpotLight extends Light { * @zh 是否启用阴影? */ @tooltip('i18n:lights.shadowEnabled') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 1 } }) @editable @type(CCBoolean) @@ -219,7 +216,7 @@ export class SpotLight extends Light { * @zh 获取或者设置阴影 pcf 等级。 */ @tooltip('i18n:lights.shadowPcf') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 2 } }) @editable @type(PCFType) @@ -238,7 +235,7 @@ export class SpotLight extends Light { * @zh 阴影的深度偏移, 可以减弱跨像素导致的条纹状失真 */ @tooltip('i18n:lights.shadowBias') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 3 } }) @editable @type(CCFloat) @@ -257,7 +254,7 @@ export class SpotLight extends Light { * @zh 设置或者获取法线偏移。 */ @tooltip('i18n:lights.shadowNormalBias') - @visible(() => (legacyCC.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) + @visible(() => (cclegacy.director.root as Root).pipeline.pipelineSceneData.shadows.type === ShadowType.ShadowMap) @property({ group: { name: 'DynamicShadowSettings', displayOrder: 4 } }) @editable @type(CCFloat) diff --git a/cocos/xr/ar/ar-module-base.ts b/cocos/3d/lod/index.ts similarity index 70% rename from cocos/xr/ar/ar-module-base.ts rename to cocos/3d/lod/index.ts index 919904d8f16..3fdc71a2984 100644 --- a/cocos/xr/ar/ar-module-base.ts +++ b/cocos/3d/lod/index.ts @@ -1,14 +1,14 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. - http://www.cocos2d-x.org + http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -22,5 +22,4 @@ THE SOFTWARE. */ -export abstract class IARModule { -} +export { LOD, LODGroup } from './lodgroup-component'; diff --git a/cocos/3d/lod/lodgroup-component.ts b/cocos/3d/lod/lodgroup-component.ts new file mode 100644 index 00000000000..cd6cc75f9ce --- /dev/null +++ b/cocos/3d/lod/lodgroup-component.ts @@ -0,0 +1,641 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { EDITOR, JSB } from 'internal:constants'; +import { ccclass, editable, executeInEditMode, menu, serializable, type } from 'cc.decorator'; +import { Vec3, Mat4, geometry, CCInteger, CCFloat } from '../../core'; +import { Node } from '../../scene-graph/node'; +import { Component } from '../../scene-graph/component'; +import { MeshRenderer } from '../framework/mesh-renderer'; +import { Mesh } from '../assets/mesh'; +import { scene } from '../../render-scene'; +import { NodeEventType } from '../../scene-graph/node-event'; + +// Ratio of objects occupying the screen +const DEFAULT_SCREEN_OCCUPATION: number[] = [0.25, 0.125, 0.01]; + +export type ModelAddedCallback = () => void; +@ccclass('cc.LOD') +export class LOD { + // Minimum percentage of screen usage for the current lod in effect, range in [0, 1] + @serializable + protected _screenUsagePercentage = 1.0; + // Mesh renderers components contained in this LOD level. + @type([MeshRenderer]) + @serializable + protected _renderers: MeshRenderer[] = []; + // renderer internal LOD data block. + /** + * @engineInternal + */ + private _LODData: scene.LODData = new scene.LODData(); + + /** + * @engineInternal + */ + private _modelAddedCallback: ModelAddedCallback | null; + + constructor () { + this._LODData.screenUsagePercentage = this._screenUsagePercentage; + this._modelAddedCallback = null; + } + + /** + * @en Minimum percentage of screen usage for the current lod in effect, range in [0, 1] + * @zh 本层级生效时,占用屏幕的最小百分比, 取值范围[0, 1] + */ + @type(CCFloat) + get screenUsagePercentage (): number { return this._screenUsagePercentage; } + set screenUsagePercentage (val: number) { + this._screenUsagePercentage = val; + this._LODData.screenUsagePercentage = val; + } + + /** + * @en Get the list of [[MeshRenderer]] used by the current lod. + * @zh 获取当前lod使用的 [[MeshRenderer]] 列表 + */ + @type([MeshRenderer]) + get renderers (): readonly MeshRenderer[] { + return this._renderers; + } + + /** + * @en reset _renderers to meshList or [], LODData's model will be reset too. + * @zh 重置 _renderers 为 meshList或空数组, LODData上的model也会被重置 + */ + set renderers (meshList: readonly MeshRenderer[]) { + if (meshList === this._renderers) return; + let modelAdded = false; + this._renderers.length = 0; + this._LODData.clearModels(); + for (let i = 0; i < meshList.length; i++) { + this._renderers[i] = meshList[i]; + const model = meshList[i]?.model; + if (model) { + modelAdded = true; + this._LODData.addModel(model); + } + } + if (this._modelAddedCallback && modelAdded) { + this._modelAddedCallback(); + } + } + + /** + * @engineInternal + * @en Get the total number of all mesh's triangle. + * @zh 获取所有模型的三角形总数 + */ + @editable + @type([CCInteger]) + get triangleCount (): number[] { + const tris: number[] = []; + this._renderers.forEach((meshRenderer: MeshRenderer | null) => { + let count = 0; + if (meshRenderer && meshRenderer.mesh) { + const primitives = meshRenderer.mesh.struct.primitives; + primitives?.forEach((subMesh: Mesh.ISubMesh) => { + if (subMesh && subMesh.indexView) { + count += subMesh.indexView.count; + } + }); + } + tris.push(count / 3); + }); + return tris; + } + + /** + * @en Get the number of LOD. + * @zh 获取LOD的数量 + */ + get rendererCount (): number { return this._renderers.length; } + + /** + * @engineInternal + * @en Get internal LOD object. + */ + get lodData () { return this._LODData; } + + /** + * @engineInternal + */ + set modelAddedCallback (callback: ModelAddedCallback) { + this._modelAddedCallback = callback; + } + + /** + * @en Insert a [[MeshRenderer]] before specific index position. + * @zh 在指定的数组索引处插入一个[[MeshRenderer]] + * @param index @en The rendering array is indexed from 0. If - 1 is passed, it will be added to the end of the list. + * @zh renderers数组从0开始索引,若传递-1将会被添加到列表末尾。 + * @param renderer @en The mesh-renderer object. @zh [[MeshRenderer]] 对象 + * @returns @en The inserted [[MeshRenderer]] @zh 返回被插入的 [[MeshRenderer]] 对象 + */ + public insertRenderer (index: number, renderer: MeshRenderer): MeshRenderer { + // make sure insert at the tail of the list. + if (index < 0 || index > this._renderers.length) { + index = this._renderers.length; + } + this._renderers.splice(index, 0, renderer); + let modelAdded = false; + if (renderer.model) { + modelAdded = true; + this._LODData.addModel(renderer.model); + } + if (this._modelAddedCallback && modelAdded) { + this._modelAddedCallback(); + } + return renderer; + } + + /** + * @en Delete the [[MeshRenderer]] at specific index position. + * @zh 删除指定索引处的[[MeshRenderer]] + * @param index @en 0 indexed position in renderer array, when -1 is specified, the last element will be deleted. + * @zh _renderers从0开始索引,传递-1则最后一个元素会被删除。 + * @returns @en The deleted [[MeshRenderer]], or null if the specified index does not exist. @zh 如果指定索引处的对象存在,返回被删除对象否则返回null。 + */ + public deleteRenderer (index: number): MeshRenderer | null { + const renders = this._renderers.splice(index, 1); + const model = renders.length > 0 ? renders[0]?.model : null; + if (model) { + this._LODData.eraseModel(model); + } + + return renders[0]; + } + + /** + * @en Get the [[MeshRenderer]] at specific index position. + * @zh 获取指定索引处的[[MeshRenderer]] + * @param index @en Value range from 0 to _renderers's length. @zh 取值范围是[0, _renderers长度] + * @return @en Returns the [[MeshRenderer]] at the specified index, or null if the specified index does not exist. @zh 返回指定索引处的对象,若不存在则返回null。 + */ + public getRenderer (index: number): MeshRenderer | null { + return this._renderers[index] || null; + } + + /** + * @en Update the [[MeshRenderer]] at specific index position. + * @zh 更新指定索引处的 [[MeshRenderer]] + * @param index @en Value range from 0 to _renderers's length @zh 取值范围是 [0, _renderers数组长度] + */ + public setRenderer (index: number, renderer: MeshRenderer) { + if (index < 0 || index >= this.rendererCount) { + console.error('setRenderer to LOD error, index out of range'); + return; + } + this.deleteRenderer(index); + this.insertRenderer(index, renderer); + } +} + +@ccclass('cc.LODGroup') +@menu('Rendering/LOD Group') +@executeInEditMode +export class LODGroup extends Component { + /** + * @en Object reference point in local space, e.g. center of the bound volume for all LODs + */ + @serializable + protected _localBoundaryCenter: Vec3 = new Vec3(0, 0, 0); + + /** + * @en Object Size in local space, may be auto-calculated value from object bounding box or value from user input. + */ + @serializable + protected _objectSize = 0; + + /** + *@en The array of LODs + */ + @serializable + protected _LODs: LOD[] = []; + + /** + * @engineInternal + */ + protected _lodGroup = new scene.LODGroup(); + + private _eventRegistered = false; + + constructor () { + super(); + } + + /** + * @engineInternal + */ + set localBoundaryCenter (val: Vec3) { + this._localBoundaryCenter.set(val); + this._lodGroup.localBoundaryCenter = val; + } + + /** + * @en Obtain the center point of AABB composed of all models + * @zh 获取所有模型组成的AABB的中心点 + */ + get localBoundaryCenter (): Readonly { return this._localBoundaryCenter.clone(); } + + /** + * @en Obtain LOD level numbers. + * @zh 获取LOD层级数 + */ + get lodCount (): number { return this._LODs.length; } + + /** + * @en Set current AABB's size. + * @zh 设置当前包围盒的大小 + */ + @type(CCFloat) + set objectSize (val: number) { + this._objectSize = val; + this._lodGroup.objectSize = val; + } + + /** + * @en Get current AABB's size. + * @zh 获取当前包围盒的大小 + */ + get objectSize () { return this._objectSize; } + + /** + * @en Get LOD array config. + * @zh 获取 LOD 数组 + */ + @type([LOD]) + get LODs (): readonly LOD[] { + return this._LODs; + } + + /** + * @en Reset current LODs to new value. + * @ 重置 LODs 为当前新设置的值。 + */ + set LODs (valArray: readonly LOD[]) { + if (valArray === this._LODs) { + //_LODs maybe changed, we need to notify the scene to update. + this._updateDataToScene(); + return; + } + this._LODs.length = 0; + this.lodGroup.clearLODs(); + valArray.forEach((lod: LOD, index: number) => { + this.lodGroup.insertLOD(index, lod.lodData); + this._LODs[index] = lod; + lod.modelAddedCallback = this.onLodModelAddedCallback.bind(this); + }); + //_LODs has been changed, we need to notify the scene to update. + this._updateDataToScene(); + } + + /** + * @engineInternal + */ + get lodGroup () { return this._lodGroup; } + + private onLodModelAddedCallback () { + if (this.objectSize === 0) { + this.recalculateBounds(); + } + } + + /** + * @en Insert the [[LOD]] at specific index position, [[LOD]] will be inserted to the last position if index less than 0 or greater than lodCount. + * @zh 在指定索引处插入 [[LOD]], 若索引为负或超过lodCount,则在末尾添加 + * @param index @en location where lod is added. @zh lod被插入的位置 + * @param screenUsagePercentage @en The minimum screen usage percentage that the currently set lod starts to use, range in[0, 1]. + * @zh lod生效时的最低屏幕显示百分比要求,取值范围[0, 1] + * @param lod @en If this parameter is not set, it will be created by default. @zh 如果参数没传,则内部创建 + * @returns @en The new lod added. @zh 返回被添加的lod + */ + public insertLOD (index: number, screenUsagePercentage?: number, lod?: LOD): LOD { + if (index < 0 || index > this.lodCount) { + index = this.lodCount; + } + + if (!lod) { + lod = new LOD(); + } + lod.modelAddedCallback = this.onLodModelAddedCallback.bind(this); + if (!screenUsagePercentage) { + const preLod = this.getLOD(index - 1); + const nextLod = this.getLOD(index); + if (preLod && nextLod) { + screenUsagePercentage = (preLod.screenUsagePercentage + nextLod.screenUsagePercentage) / 2; + } else if (preLod && !nextLod) { // insert at last position + screenUsagePercentage = preLod.screenUsagePercentage / 2; + if (screenUsagePercentage > 0.01) { + screenUsagePercentage = 0.01; + } + } else if (nextLod && !preLod) { + //insert at first position + screenUsagePercentage = nextLod.screenUsagePercentage; + const curNextLOD = this.getLOD(index + 1); + nextLod.screenUsagePercentage = (screenUsagePercentage + (curNextLOD ? curNextLOD.screenUsagePercentage : 0)) / 2; + } else { //lod count is zero + screenUsagePercentage = DEFAULT_SCREEN_OCCUPATION[0]; + } + } + lod.screenUsagePercentage = screenUsagePercentage; + this._LODs.splice(index, 0, lod); + this._lodGroup.insertLOD(index, lod.lodData); + this._updateDataToScene(); + if (this.node) { + this._emitChangeNode(this.node); + } + return lod; + } + + /** + * @en Erase the [[LOD]] at specific index position. + * @zh 删除指定索引处的 [[LOD]] + * @param index @en Index of the erased lod, range in [0, lodCount]. @zh 被删除对象索引, 取值范围[0, lodCount] + * @returns @en Erased lod. @zh 被删除的对象 + */ + public eraseLOD (index: number): LOD | null { + if (index < 0 || index >= this.lodCount) { + console.warn('eraseLOD error, index out of range'); + return null; + } + const lod = this._LODs[index]; + if (!lod) { + console.warn('eraseLOD error, LOD not exist at specified index.'); + return null; + } + this._LODs.splice(index, 1); + this._lodGroup.eraseLOD(index); + this._updateDataToScene(); + this._emitChangeNode(this.node); + return lod; + } + + /** + * @en Get [[LOD]] at specific index position. + * @zh 获取指定索引处的 [[LOD]] + * @param index @en Range in [0, lodCount]. @zh 取值范围[0, lodCount] + * @returns @en Lod at specified index, or null. @zh 返回指定索引的lod或null + */ + public getLOD (index: number): LOD | null { + if (index < 0 || index >= this.lodCount) { + console.warn('getLOD error, index out of range'); + return null; + } + return this._LODs[index]; + } + + /** + * @en Update the [[LOD]] at specific index position. + * @zh 更新指定索引处的 [[LOD]] + * @param index, update lod at specified index. + * @param lod, the updated lod. + */ + public setLOD (index: number, lod: LOD) { + if (index < 0 || index >= this.lodCount) { + console.warn('setLOD error, index out of range'); + return; + } + this._LODs[index] = lod; + lod.modelAddedCallback = this.onLodModelAddedCallback.bind(this); + this.lodGroup.updateLOD(index, lod.lodData); + this._updateDataToScene(); + } + + /** + * @en Recalculate the bounding box, and the interface will recalculate the localBoundaryCenter and objectSize + * @zh 重新计算包围盒,该接口会更新 localBoundaryCenter 和 objectSize + */ + public recalculateBounds () { + function getTransformedBoundary (c: /* center */Vec3, e: /*extents*/Vec3, transform: Mat4): [Vec3, Vec3] { + let minPos: Vec3; + let maxPos: Vec3; + + const pts = new Array( + new Vec3(c.x - e.x, c.y - e.y, c.z - e.z), + new Vec3(c.x - e.x, c.y + e.y, c.z - e.z), + new Vec3(c.x + e.x, c.y + e.y, c.z - e.z), + new Vec3(c.x + e.x, c.y - e.y, c.z - e.z), + new Vec3(c.x - e.x, c.y - e.y, c.z + e.z), + new Vec3(c.x - e.x, c.y + e.y, c.z + e.z), + new Vec3(c.x + e.x, c.y + e.y, c.z + e.z), + new Vec3(c.x + e.x, c.y - e.y, c.z + e.z), + ); + + minPos = pts[0].transformMat4(transform); + maxPos = minPos.clone(); + for (let i = 1; i < 8; ++i) { + const pt = pts[i].transformMat4(transform); + minPos = Vec3.min(minPos, minPos, pt); + maxPos = Vec3.max(maxPos, maxPos, pt); + } + return [minPos, maxPos]; + } + + const minPos = new Vec3(); + const maxPos = new Vec3(); + let boundsMin: Vec3 | null = null; + let boundsMax: Vec3 = new Vec3(); + + for (let i = 0; i < this.lodCount; ++i) { + const lod = this.getLOD(i); + if (lod) { + for (let j = 0; j < lod.rendererCount; ++j) { + const renderer = lod.getRenderer(j); + if (!renderer) { + continue; + } + renderer.model?.updateWorldBound(); + let worldBounds = renderer.model?.worldBounds; + if (worldBounds) { + if (JSB) { + const center = worldBounds.center; + const halfExtents = worldBounds.halfExtents; + worldBounds = geometry.AABB.create(center.x, center.y, center.z, halfExtents.x, halfExtents.y, halfExtents.z); + } + worldBounds.getBoundary(minPos, maxPos); + + if (boundsMin) { + Vec3.min(boundsMin, boundsMin, minPos); + Vec3.max(boundsMax, boundsMax, maxPos); + } else { + boundsMin = minPos.clone(); + boundsMax = maxPos.clone(); + } + } + } + } + } + + if (boundsMin) { + // Transform world bounds to local space bounds + const boundsMin2 = boundsMin; + const c = new Vec3((boundsMax.x + boundsMin2.x) * 0.5, (boundsMax.y + boundsMin2.y) * 0.5, (boundsMax.z + boundsMin2.z) * 0.5); + const e = new Vec3((boundsMax.x - boundsMin2.x) * 0.5, (boundsMax.y - boundsMin2.y) * 0.5, (boundsMax.z - boundsMin2.z) * 0.5); + + const [minPos, maxPos] = getTransformedBoundary(c, e, this.node.worldMatrix.clone().invert()); + + // Set bounding volume center and extents in local space + c.set((maxPos.x + minPos.x) * 0.5, (maxPos.y + minPos.y) * 0.5, (maxPos.z + minPos.z) * 0.5); + e.set((maxPos.x - minPos.x) * 0.5, (maxPos.y - minPos.y) * 0.5, (maxPos.z - minPos.z) * 0.5); + + // Save the result + this.localBoundaryCenter = c; + this.objectSize = Math.max(e.x, e.y, e.z) * 2.0; + } else { + // No model exists, reset to default value + this.localBoundaryCenter = new Vec3(0, 0, 0); + this.objectSize = 0; + } + this._emitChangeNode(this.node); + } + + /** + * @en reset current objectSize to 1, and recalculate screenUsagePercentage. + * @zh 重置 objectSize 的大小为1,该接口会重新计算 screenUsagePercentage + */ + public resetObjectSize () { + if (this.objectSize === 1.0) return; + + if (this.objectSize === 0) { + this.objectSize = 1.0; + } + + // 1 will be new object size + const scale = 1.0 / this.objectSize; + // reset object size to 1 + this.objectSize = 1.0; + + for (let i = 0; i < this.lodCount; ++i) { + const lod = this.getLOD(i); + if (lod) { + lod.screenUsagePercentage *= scale; + } + } + this._emitChangeNode(this.node); + } + + /** + * @zh 强制使用某一级的LOD + * @en Force LOD level to use. + * lodLevel @en The LOD level to use. Passing lodLevel < 0 will return to standard LOD processing. @zh 要使用的LOD层级,为负数时使用标准的处理流程 + */ + public forceLOD (lodLevel: number) { + this.lodGroup.lockLODLevels(lodLevel < 0 ? [] : [lodLevel]); + } + + onLoad () { + this._lodGroup.node = this.node; + // objectSize maybe initialized from deserialize + this._lodGroup.objectSize = this._objectSize; + this._lodGroup.localBoundaryCenter = this._localBoundaryCenter; + if (!this._eventRegistered) { + this.node.on(NodeEventType.COMPONENT_REMOVED, this._onRemove, this); + this._eventRegistered = true; + } + this._constructLOD(); + } + + _onRemove (comp: Component) { + if (comp === this) { + this.onDisable(); + } + } + + private _constructLOD () { + // generate default lod for lodGroup + if (this.lodCount < 1) { + const size = DEFAULT_SCREEN_OCCUPATION.length; + for (let i = 0; i < size; i++) { + this.insertLOD(i, DEFAULT_SCREEN_OCCUPATION[i]); + } + } + } + + // Redo, Undo, Prefab restore, etc. + onRestore () { + this._constructLOD(); + if (this.enabledInHierarchy) { + this._attachToScene(); + } + } + + onEnable () { + this._attachToScene(); + if (this.objectSize === 0) { + this.recalculateBounds(); + } + + // cache lod for scene + if (this.lodCount > 0 && this._lodGroup.lodCount < 1) { + this._LODs.forEach((lod: LOD, index) => { + lod.lodData.screenUsagePercentage = lod.screenUsagePercentage; + const renderers = lod.renderers; + if (renderers !== null && renderers.length > 0) { + for (let i = 0; i < renderers.length; i++) { + const lodInstance = lod.lodData; + const renderer = renderers[i]; + if (lodInstance && renderer && renderer.model) { + lodInstance.addModel(renderer.model); + } + } + } + this._lodGroup.insertLOD(index, lod.lodData); + }); + } + } + + onDisable () { + this._detachFromScene(); + } + + private _attachToScene () { + if (this.node && this.node.scene) { + const renderScene = this._getRenderScene(); + if (this._lodGroup.scene) { + this._detachFromScene(); + } + renderScene.addLODGroup(this._lodGroup); + } + } + + private _detachFromScene () { + if (this._lodGroup.scene) { this._lodGroup.scene.removeLODGroup(this._lodGroup); } + } + + /** + * @engineInternal + */ + private _emitChangeNode (node: Node) { + if (EDITOR) { + // @ts-expect-error Because EditorExtends is Editor only + EditorExtends.Node.emit('change', node.uuid, node); + } + } + + private _updateDataToScene () { + this._detachFromScene(); + this._attachToScene(); + } +} diff --git a/cocos/3d/misc/batch-utils.ts b/cocos/3d/misc/batch-utils.ts index be019edbc40..778838be018 100644 --- a/cocos/3d/misc/batch-utils.ts +++ b/cocos/3d/misc/batch-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { MeshRenderer } from '../framework/mesh-renderer'; import { Mesh } from '../assets/mesh'; -import { Mat4 } from '../../core/math/mat4'; +import { Mat4 } from '../../core'; import { Node } from '../../scene-graph/node'; function checkMaterialisSame (comp1: MeshRenderer, comp2: MeshRenderer): boolean { diff --git a/cocos/3d/misc/buffer-blob.ts b/cocos/3d/misc/buffer-blob.ts index 9de7e3703bb..ecc97efe581 100644 --- a/cocos/3d/misc/buffer-blob.ts +++ b/cocos/3d/misc/buffer-blob.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export class BufferBlob { private _arrayBufferOrPaddings: Array = []; diff --git a/cocos/3d/misc/buffer.ts b/cocos/3d/misc/buffer.ts index 50b3deb1450..c1d83bcfd54 100644 --- a/cocos/3d/misc/buffer.ts +++ b/cocos/3d/misc/buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Format, FormatInfos, FormatType, FormatInfo } from '../../gfx'; -import { sys } from '../../core/platform/sys'; +import { sys } from '../../core'; const _typeMap: Record = { [FormatType.UNORM]: 'Uint', diff --git a/cocos/3d/misc/create-mesh.jsb.ts b/cocos/3d/misc/create-mesh.jsb.ts index a44849df3e8..5befbd46789 100644 --- a/cocos/3d/misc/create-mesh.jsb.ts +++ b/cocos/3d/misc/create-mesh.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,10 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { legacyCC } from "../../core/global-exports"; +import { cclegacy } from "../../core"; export const MeshUtils = jsb.MeshUtils; export const createMesh = MeshUtils.createMesh; export const createDynamicMesh = MeshUtils.createDynamicMesh; -legacyCC.MeshUtils = jsb.MeshUtils; +cclegacy.MeshUtils = jsb.MeshUtils; diff --git a/cocos/3d/misc/create-mesh.ts b/cocos/3d/misc/create-mesh.ts index 22d287d4d4b..3e59d58258a 100644 --- a/cocos/3d/misc/create-mesh.ts +++ b/cocos/3d/misc/create-mesh.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mesh } from '../assets/mesh'; import { AttributeName, Format, FormatInfos, PrimitiveMode, Attribute } from '../../gfx'; -import { Vec3 } from '../../core/math'; +import { Vec3 } from '../../core'; import { IGeometry, IDynamicGeometry, ICreateMeshOptions, ICreateDynamicMeshOptions } from '../../primitive/define'; import { writeBuffer } from './buffer'; import { BufferBlob } from './buffer-blob'; diff --git a/cocos/3d/misc/index.ts b/cocos/3d/misc/index.ts index 9ef690807ba..4e2c4f39d5f 100644 --- a/cocos/3d/misc/index.ts +++ b/cocos/3d/misc/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export { find } from '../../scene-graph/find'; export { toPPM } from './ppm'; diff --git a/cocos/3d/misc/joint-texture-sampler-info.ts b/cocos/3d/misc/joint-texture-sampler-info.ts index 7891c3fc394..37566b27ad8 100644 --- a/cocos/3d/misc/joint-texture-sampler-info.ts +++ b/cocos/3d/misc/joint-texture-sampler-info.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { Address, Filter, SamplerInfo } from '../../gfx'; export const jointTextureSamplerInfo = new SamplerInfo( diff --git a/cocos/3d/misc/ppm.ts b/cocos/3d/misc/ppm.ts index d87753b1d92..64c19d8490a 100644 --- a/cocos/3d/misc/ppm.ts +++ b/cocos/3d/misc/ppm.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @en diff --git a/cocos/3d/misc/read-mesh.ts b/cocos/3d/misc/read-mesh.ts index 4d5e2eefc27..e6d45c728cd 100644 --- a/cocos/3d/misc/read-mesh.ts +++ b/cocos/3d/misc/read-mesh.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mesh } from '../assets/mesh'; import { AttributeName, Format, FormatInfos } from '../../gfx'; diff --git a/cocos/3d/models/baked-skinning-model.jsb.ts b/cocos/3d/models/baked-skinning-model.jsb.ts index 9507db53a22..3ce1b9be9ea 100644 --- a/cocos/3d/models/baked-skinning-model.jsb.ts +++ b/cocos/3d/models/baked-skinning-model.jsb.ts @@ -1,13 +1,36 @@ -import { legacyCC } from '../../core/global-exports'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { cclegacy, geometry } from '../../core'; import { Skeleton } from '../assets/skeleton'; -import { AABB } from '../../core/geometry'; import { Mesh } from '../assets/mesh'; -import { Node } from '../../core/scene-graph/node' -import { AnimationClip } from "../../core"; +import { Node } from '../../scene-graph/node' +import { AnimationClip } from "../../animation"; import { IJointTextureHandle } from '../skeletal-animation/skeletal-animation-utils'; export const BakedSkinningModel = jsb.BakedSkinningModel; -legacyCC.BakedSkinningModel = jsb.BakedSkinningModel; +cclegacy.BakedSkinningModel = jsb.BakedSkinningModel; const MorphModel = jsb.MorphModel; const bakedSkinningModelProto: any = BakedSkinningModel.prototype; @@ -15,7 +38,7 @@ const bakedSkinningModelProto: any = BakedSkinningModel.prototype; bakedSkinningModelProto._ctor = function () { jsb.Model.prototype._ctor.call(this); this.uploadedAnim = undefined; - this._dataPoolManager = legacyCC.director.root.dataPoolManager; + this._dataPoolManager = cclegacy.director.root.dataPoolManager; const jointTextureInfo = new Float32Array(4); const animInfo = this._dataPoolManager.jointAnimationInfo.getData(); this._jointsMedium = { buffer: null, jointTextureInfo, animInfo, texture: null, boundsInfo: null }; @@ -52,7 +75,7 @@ bakedSkinningModelProto.uploadAnimation = function (anim: AnimationClip | null) this.setUploadedAnimForJS(!!anim); const resMgr = this._dataPoolManager; let texture: IJointTextureHandle | null = null; - let modelBounds: AABB | null = null; + let modelBounds: geometry.AABB | null = null; if (anim) { texture = resMgr.jointTexturePool.getSequencePoseTexture(this._skeleton, anim, this._mesh, this.transform); this._jointsMedium.boundsInfo = texture && texture.bounds.get(this._mesh.hash)!; diff --git a/cocos/3d/models/baked-skinning-model.ts b/cocos/3d/models/baked-skinning-model.ts index d6c77a245c2..7e82a939293 100644 --- a/cocos/3d/models/baked-skinning-model.ts +++ b/cocos/3d/models/baked-skinning-model.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ import type { AnimationClip } from '../../animation/animation-clip'; import { Mesh } from '../assets/mesh'; import { Skeleton } from '../assets/skeleton'; -import { AABB } from '../../core/geometry'; +import { geometry, cclegacy } from '../../core'; import { BufferUsageBit, MemoryUsageBit, Attribute, DescriptorSet, Buffer, BufferInfo } from '../../gfx'; import { INST_JOINT_ANIM_INFO, UBOSkinningAnimation, UBOSkinningTexture, UNIFORM_JOINT_TEXTURE_BINDING } from '../../rendering/define'; import { Node } from '../../scene-graph'; @@ -35,7 +34,6 @@ import type { DataPoolManager } from '../skeletal-animation/data-pool-manager'; import { ModelType } from '../../render-scene/scene/model'; import { IAnimInfo, IJointTextureHandle } from '../skeletal-animation/skeletal-animation-utils'; import { MorphModel } from './morph-model'; -import { legacyCC } from '../../core/global-exports'; import { jointTextureSamplerInfo } from '../misc/joint-texture-sampler-info'; import { SubModel } from '../../render-scene/scene'; @@ -44,7 +42,7 @@ interface IJointsInfo { jointTextureInfo: Float32Array; texture: IJointTextureHandle | null; animInfo: IAnimInfo; - boundsInfo: AABB[] | null; + boundsInfo: geometry.AABB[] | null; } const myPatches = [ @@ -75,7 +73,7 @@ export class BakedSkinningModel extends MorphModel { constructor () { super(); this.type = ModelType.BAKED_SKINNING; - this._dataPoolManager = legacyCC.director.root.dataPoolManager; + this._dataPoolManager = cclegacy.director.root.dataPoolManager; const jointTextureInfo = new Float32Array(4); const animInfo = this._dataPoolManager.jointAnimationInfo.getData(); this._jointsMedium = { buffer: null, jointTextureInfo, animInfo, texture: null, boundsInfo: null }; diff --git a/cocos/3d/models/morph-model.jsb.ts b/cocos/3d/models/morph-model.jsb.ts index 7313f51f35b..a7a31391ae5 100644 --- a/cocos/3d/models/morph-model.jsb.ts +++ b/cocos/3d/models/morph-model.jsb.ts @@ -1,4 +1,28 @@ -import { legacyCC } from "../../core/global-exports"; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { cclegacy } from "../../core"; export const MorphModel = jsb.MorphModel; -legacyCC.MorphModel = jsb.MorphModel; +cclegacy.MorphModel = jsb.MorphModel; diff --git a/cocos/3d/models/morph-model.ts b/cocos/3d/models/morph-model.ts index 5f89a741ab2..c6bdc8bde47 100644 --- a/cocos/3d/models/morph-model.ts +++ b/cocos/3d/models/morph-model.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Model } from '../../render-scene/scene/model'; import { MorphRenderingInstance } from '../assets/morph-rendering'; diff --git a/cocos/3d/models/skinning-model.jsb.ts b/cocos/3d/models/skinning-model.jsb.ts index 562cbbe46dd..cda78c947b5 100644 --- a/cocos/3d/models/skinning-model.jsb.ts +++ b/cocos/3d/models/skinning-model.jsb.ts @@ -1,4 +1,28 @@ -import { legacyCC } from "../../core/global-exports"; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { cclegacy } from "../../core"; export const SkinningModel = jsb.SkinningModel; -legacyCC.SkinningModel = jsb.SkinningModel; +cclegacy.SkinningModel = jsb.SkinningModel; diff --git a/cocos/3d/models/skinning-model.ts b/cocos/3d/models/skinning-model.ts index 4a1caf93def..c0586deb655 100644 --- a/cocos/3d/models/skinning-model.ts +++ b/cocos/3d/models/skinning-model.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,9 +26,8 @@ import { Material } from '../../asset/assets/material'; import { RenderingSubMesh } from '../../asset/assets/rendering-sub-mesh'; import { Mesh } from '../assets/mesh'; import { Skeleton } from '../assets/skeleton'; -import { AABB } from '../../core/geometry'; +import { geometry, Mat4, Vec3, warnID } from '../../core'; import { BufferUsageBit, MemoryUsageBit, DescriptorSet, Buffer, BufferInfo, Attribute, FormatFeatureBit, Format } from '../../gfx'; -import { Mat4, Vec3 } from '../../core/math'; import { UBOSkinning, UNIFORM_REALTIME_JOINT_TEXTURE_BINDING } from '../../rendering/define'; import { Node } from '../../scene-graph/node'; import { ModelType } from '../../render-scene/scene/model'; @@ -37,7 +35,6 @@ import { uploadJointData } from '../skeletal-animation/skeletal-animation-utils' import { MorphModel } from './morph-model'; import { deleteTransform, getTransform, getWorldMatrix, IJointTransform } from '../../animation/skeletal-animation-utils'; import { IMacroPatch, BatchingSchemes, Pass } from '../../render-scene'; -import { warnID } from '../../core/platform/debug'; import { director } from '../../game'; import { PixelFormat } from '../../asset/assets/asset-enum'; import { Texture2D, ImageAsset } from '../../asset/assets'; @@ -67,7 +64,7 @@ function getRelevantBuffers (outIndices: number[], outBuffers: number[], jointMa } interface IJointInfo { - bound: AABB; + bound: geometry.AABB; target: Node; bindpose: Mat4; transform: IJointTransform; @@ -80,7 +77,7 @@ const v3_max = new Vec3(); const v3_1 = new Vec3(); const v3_2 = new Vec3(); const m4_1 = new Mat4(); -const ab_1 = new AABB(); +const ab_1 = new geometry.AABB(); class RealTimeJointTexture { public static readonly WIDTH = 256; @@ -184,7 +181,7 @@ export class SkinningModel extends MorphModel { for (let i = 0; i < this._joints.length; i++) { const { bound, transform } = this._joints[i]; const worldMatrix = getWorldMatrix(transform, stamp); - AABB.transform(ab_1, bound, worldMatrix); + geometry.AABB.transform(ab_1, bound, worldMatrix); ab_1.getBoundary(v3_1, v3_2); Vec3.min(v3_min, v3_min, v3_1); Vec3.max(v3_max, v3_max, v3_2); @@ -192,7 +189,7 @@ export class SkinningModel extends MorphModel { const worldBounds = this._worldBounds; if (this._modelBounds && worldBounds) { - AABB.fromPoints(this._modelBounds, v3_min, v3_max); + geometry.AABB.fromPoints(this._modelBounds, v3_min, v3_max); // @ts-expect-error TS2445 this._modelBounds.transform(root._mat, root._pos, root._rot, root._scale, this._worldBounds); } diff --git a/cocos/3d/reflection-probe/index.ts b/cocos/3d/reflection-probe/index.ts new file mode 100644 index 00000000000..14914f0198a --- /dev/null +++ b/cocos/3d/reflection-probe/index.ts @@ -0,0 +1,25 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +export { ReflectionProbe } from './reflection-probe-component'; diff --git a/cocos/3d/reflection-probe/reflection-probe-component.ts b/cocos/3d/reflection-probe/reflection-probe-component.ts new file mode 100644 index 00000000000..74ef5ad9909 --- /dev/null +++ b/cocos/3d/reflection-probe/reflection-probe-component.ts @@ -0,0 +1,393 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { ccclass, executeInEditMode, menu, playOnFocus, serializable, tooltip, type, visible } from 'cc.decorator'; +import { EDITOR } from 'internal:constants'; +import { cclegacy, CCObject, Color, Enum, size, Vec3 } from '../../core'; + +import { TextureCube } from '../../asset/assets'; +import { scene } from '../../render-scene'; +import { CAMERA_DEFAULT_MASK } from '../../rendering/define'; +import { ReflectionProbeManager } from '../../rendering/reflection-probe-manager'; +import { Component } from '../../scene-graph/component'; +import { Layers } from '../../scene-graph/layers'; +import { Camera } from '../../misc/camera-component'; +import { Node, TransformBit } from '../../scene-graph'; +import { ProbeClearFlag, ProbeType } from '../../render-scene/scene/reflection-probe'; +import { absolute } from '../../physics/utils/util'; + +export enum ProbeResolution { + /** + * @zh 分辨率 256 * 256。 + * @en renderTexture resolution 256 * 256. + * @readonly + */ + Low_256x256 = 256, + + /** + * @zh 分辨率 512 * 512。 + * @en renderTexture resolution 512 * 512. + * @readonly + */ + Medium_512x512 = 512, + + /** + * @zh 分辨率 768 * 768 + * @en renderTexture resolution 768 * 768. + * @readonly + */ + High_768x768 = 768, +} +@ccclass('cc.ReflectionProbe') +@menu('Rendering/ReflectionProbe') +@executeInEditMode +@playOnFocus +export class ReflectionProbe extends Component { + protected static readonly DEFAULT_CUBE_SIZE: Readonly = new Vec3(1, 1, 1); + protected static readonly DEFAULT_PLANER_SIZE: Readonly = new Vec3(5, 0.5, 5); + protected readonly _lastSize = new Vec3(); + @serializable + protected _resolution = 256; + @serializable + protected _clearFlag = ProbeClearFlag.SKYBOX; + + @serializable + protected _backgroundColor = new Color(0, 0, 0, 255); + + @serializable + protected _visibility = CAMERA_DEFAULT_MASK; + + @serializable + protected _probeType = ProbeType.CUBE; + + @serializable + protected _cubemap: TextureCube | null = null; + + @serializable + protected readonly _size = new Vec3(1, 1, 1); + + @serializable + protected _sourceCamera: Camera | null = null; + + @serializable + private _probeId = -1; + + protected _probe: scene.ReflectionProbe | null = null; + + protected _previewSphere: Node | null = null; + protected _previewPlane: Node | null = null; + + protected _sourceCameraPos = new Vec3(0, 0, 0); + + /** + * @en + * Gets or sets the size of the box + * @zh + * 获取或设置包围盒的大小。 + */ + set size (value: Vec3) { + this._size.set(value); + absolute(this._size); + this.probe.size = this._size; + if (this.probe) { + ReflectionProbeManager.probeManager.onUpdateProbes(true); + ReflectionProbeManager.probeManager.updateProbeData(); + } + } + @type(Vec3) + get size () { + return this._size; + } + + /** + * @en Environment reflection or plane reflection. + * @zh 设置探针类型,环境反射或者平面反射 + */ + @type(Enum(ProbeType)) + set probeType (value: number) { + this.probe.probeType = value; + if (value !== this._probeType) { + const lastSize = this._size.clone(); + const lastSizeIsNoExist = Vec3.equals(this._lastSize, Vec3.ZERO); + this._probeType = value; + + if (this._probeType === ProbeType.CUBE) { + if (lastSizeIsNoExist) { + this._size.set(ReflectionProbe.DEFAULT_CUBE_SIZE); + } + this.probe.switchProbeType(value, null); + if (EDITOR) { + this._objFlags |= CCObject.Flags.IsRotationLocked; + } + ReflectionProbeManager.probeManager.clearPlanarReflectionMap(this.probe); + } else { + if (lastSizeIsNoExist) { + this._size.set(ReflectionProbe.DEFAULT_PLANER_SIZE); + } + if (EDITOR && this._objFlags & CCObject.Flags.IsRotationLocked) { + this._objFlags ^= CCObject.Flags.IsRotationLocked; + } + if (!this._sourceCamera) { + console.warn('the reflection camera is invalid, please set the reflection camera'); + } else { + this.probe.switchProbeType(value, this._sourceCamera.camera); + } + } + if (!lastSizeIsNoExist) { + this._size.set(this._lastSize); + } + this._lastSize.set(lastSize); + this.size = this._size; + } + } + get probeType () { + return this._probeType; + } + + /** + * @en set render texture size + * @zh 设置渲染纹理大小 + */ + @visible(function (this: ReflectionProbe) { return this.probeType === ProbeType.CUBE; }) + @type(Enum(ProbeResolution)) + set resolution (value: number) { + this._resolution = value; + this.probe.resolution = value; + } + + get resolution () { + return this._resolution; + } + + /** + * @en Clearing flags of the camera, specifies which part of the framebuffer will be actually cleared every frame. + * @zh 相机的缓冲清除标志位,指定帧缓冲的哪部分要每帧清除。 + */ + @type(Enum(ProbeClearFlag)) + set clearFlag (value: number) { + this._clearFlag = value; + this.probe.clearFlag = this._clearFlag; + } + get clearFlag () { + return this._clearFlag; + } + + /** + * @en Clearing color of the camera. + * @zh 相机的颜色缓冲默认值。 + */ + @visible(function (this: ReflectionProbe) { return this._clearFlag === ProbeClearFlag.SOLID_COLOR; }) + @type(Color) + set backgroundColor (val: Color) { + this._backgroundColor = val; + this.probe.backgroundColor = this._backgroundColor; + } + get backgroundColor () { + return this._backgroundColor; + } + + /** + * @en Visibility mask, declaring a set of node layers that will be visible to this camera. + * @zh 可见性掩码,声明在当前相机中可见的节点层级集合。 + */ + @type(Layers.BitMask) + @tooltip('i18n:camera.visibility') + get visibility () { + return this._visibility; + } + set visibility (val) { + this._visibility = val; + this.probe.visibility = this._visibility; + } + + /** + * @en The camera to render planar reflections, specified by the user + * @zh 需要渲染平面反射的相机,由用户指定 + */ + @visible(function (this: ReflectionProbe) { return this.probeType === ProbeType.PLANAR; }) + @type(Camera) + set sourceCamera (camera: Camera) { + this._sourceCamera = camera; + if (camera) { + this.visibility = camera.visibility; + this.clearFlag = camera.clearFlags; + this.backgroundColor = camera.clearColor; + if (this.probeType === ProbeType.PLANAR) { + this.probe.switchProbeType(this.probeType, camera.camera); + } + } + } + get sourceCamera () { + return this._sourceCamera!; + } + + set cubemap (val: TextureCube | null) { + this._cubemap = val; + this.probe.cubemap = val; + ReflectionProbeManager.probeManager.onUpdateProbes(true); + } + + get probe () { + return this._probe!; + } + + /** + * @en Reflection probe cube mode preview sphere + * @zh 反射探针cube模式的预览小球 + */ + set previewSphere (val: Node) { + this._previewSphere = val; + if (this.probe) { + this.probe.previewSphere = val; + if (this._previewSphere) { + ReflectionProbeManager.probeManager.updatePreviewSphere(this.probe); + } + } + } + + get previewSphere () { + return this._previewSphere!; + } + + /** + * @en Reflection probe planar mode preview plane + * @zh 反射探针Planar模式的预览平面 + */ + set previewPlane (val: Node) { + this._previewPlane = val; + if (this.probe) { + this.probe.previewPlane = val; + if (this._previewPlane) { + ReflectionProbeManager.probeManager.updatePreviewPlane(this.probe); + } + } + } + + get previewPlane () { + return this._previewPlane!; + } + + public onLoad () { + this._createProbe(); + } + + onEnable () { + if (this._probe) { + const probe = ReflectionProbeManager.probeManager.getProbeById(this._probeId); + if (probe !== null && probe !== this._probe) { + this._probeId = ReflectionProbeManager.probeManager.getNewReflectionProbeId(); + this._probe.updateProbeId(this._probeId); + } + ReflectionProbeManager.probeManager.register(this._probe); + ReflectionProbeManager.probeManager.onUpdateProbes(true); + this._probe.enable(); + } + } + onDisable () { + if (this._probe) { + ReflectionProbeManager.probeManager.unregister(this._probe); + this._probe.disable(); + } + } + + public start () { + if (this._sourceCamera && this.probeType === ProbeType.PLANAR) { + this.probe.renderPlanarReflection(this.sourceCamera.camera); + ReflectionProbeManager.probeManager.filterModelsForPlanarReflection(); + } + ReflectionProbeManager.probeManager.updateProbeData(); + } + + public onDestroy () { + if (this.probe) { + this.probe.destroy(); + } + } + + public update (dt: number) { + if (!this.probe) return; + if (EDITOR && !cclegacy.GAME_VIEW) { + if (this.probeType === ProbeType.PLANAR) { + const cameraLst: scene.Camera[] | undefined = this.node.scene.renderScene?.cameras; + if (cameraLst !== undefined) { + for (let i = 0; i < cameraLst.length; ++i) { + const camera: scene.Camera = cameraLst[i]; + if (camera.name === 'Editor Camera') { + this.probe.renderPlanarReflection(camera); + break; + } + } + } + } + + if (this.node.hasChangedFlags) { + this.probe.updateBoundingBox(); + } + if (this.node.hasChangedFlags & TransformBit.POSITION) { + ReflectionProbeManager.probeManager.onUpdateProbes(true); + ReflectionProbeManager.probeManager.updateProbeData(); + } + } + if (this.probeType === ProbeType.PLANAR && this.sourceCamera) { + if ((this.sourceCamera.node.hasChangedFlags & TransformBit.TRS) + || !this._sourceCameraPos.equals(this.sourceCamera.node.getWorldPosition())) { + this._sourceCameraPos = this.sourceCamera.node.getWorldPosition(); + this.probe.renderPlanarReflection(this.sourceCamera.camera); + } + } + } + + /** + * @en Clear the baked cubemap. + * @zh 清除烘焙的cubemap + */ + public clearBakedCubemap () { + this.cubemap = null; + ReflectionProbeManager.probeManager.updateBakedCubemap(this.probe); + ReflectionProbeManager.probeManager.updatePreviewSphere(this.probe); + } + + private _createProbe () { + if (this._probeId === -1 || ReflectionProbeManager.probeManager.exists(this._probeId)) { + this._probeId = ReflectionProbeManager.probeManager.getNewReflectionProbeId(); + } + this._probe = new scene.ReflectionProbe(this._probeId); + if (this._probe) { + const cameraNode = new Node('ReflectionProbeCamera'); + cameraNode.hideFlags |= CCObject.Flags.DontSave | CCObject.Flags.HideInHierarchy; + this.node.scene.addChild(cameraNode); + + this._probe.initialize(this.node, cameraNode); + if (this.enabled) { + ReflectionProbeManager.probeManager.register(this._probe); + } + this._probe.resolution = this._resolution; + this._probe.clearFlag = this._clearFlag; + this._probe.backgroundColor = this._backgroundColor; + this._probe.visibility = this._visibility; + this._probe.probeType = this._probeType; + this._probe.size = this._size; + this._probe.cubemap = this._cubemap!; + } + } +} diff --git a/cocos/3d/skeletal-animation/data-pool-manager.ts b/cocos/3d/skeletal-animation/data-pool-manager.ts index 899e6f68804..15f8fd616a2 100644 --- a/cocos/3d/skeletal-animation/data-pool-manager.ts +++ b/cocos/3d/skeletal-animation/data-pool-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import type { AnimationClip } from '../../animation/animation-clip'; import type { Skeleton } from '../assets'; import { Device } from '../../gfx'; import { JointAnimationInfo, JointTexturePool } from './skeletal-animation-utils'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; export class DataPoolManager { public jointTexturePool: JointTexturePool; @@ -52,4 +51,4 @@ export class DataPoolManager { } } -legacyCC.internal.DataPoolManager = DataPoolManager; +cclegacy.internal.DataPoolManager = DataPoolManager; diff --git a/cocos/3d/skeletal-animation/deprecated.ts b/cocos/3d/skeletal-animation/deprecated.ts index 86c3a8d4e28..1e394027d12 100644 --- a/cocos/3d/skeletal-animation/deprecated.ts +++ b/cocos/3d/skeletal-animation/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { js } from '../../core/utils/js'; -import { legacyCC } from '../../core/global-exports'; +import { js, cclegacy } from '../../core'; import { SkeletalAnimation } from './skeletal-animation'; /** * Alias of [[SkeletalAnimation]] * @deprecated Since v1.2 */ export { SkeletalAnimation as SkeletalAnimationComponent }; -legacyCC.SkeletalAnimationComponent = SkeletalAnimation; +cclegacy.SkeletalAnimationComponent = SkeletalAnimation; js.setClassAlias(SkeletalAnimation, 'cc.SkeletalAnimationComponent'); diff --git a/cocos/3d/skeletal-animation/index.ts b/cocos/3d/skeletal-animation/index.ts index bb11159cb2c..1d643c87afc 100644 --- a/cocos/3d/skeletal-animation/index.ts +++ b/cocos/3d/skeletal-animation/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './data-pool-manager'; diff --git a/cocos/3d/skeletal-animation/limits.ts b/cocos/3d/skeletal-animation/limits.ts index 13ef5fed276..04c066a2492 100644 --- a/cocos/3d/skeletal-animation/limits.ts +++ b/cocos/3d/skeletal-animation/limits.ts @@ -1,2 +1,26 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export const MAX_ANIMATION_LAYER = 32; diff --git a/cocos/3d/skeletal-animation/skeletal-animation-blending.ts b/cocos/3d/skeletal-animation/skeletal-animation-blending.ts index 23962555a9b..7cc74a36664 100644 --- a/cocos/3d/skeletal-animation/skeletal-animation-blending.ts +++ b/cocos/3d/skeletal-animation/skeletal-animation-blending.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { DEBUG } from 'internal:constants'; -import { Vec3, Quat } from '../../core/math'; +import { Vec3, Quat } from '../../core'; import { Node } from '../../scene-graph'; import { RuntimeBinding } from '../../animation/tracks/track'; -import { assertIsTrue } from '../../core/data/utils/asserts'; -import { MAX_ANIMATION_LAYER } from './limits'; export abstract class BlendStateBuffer< TNodeBlendState extends NodeBlendState, PropertyBlendState> = @@ -355,261 +351,6 @@ export class LegacyBlendStateBuffer extends BlendStateBuffer { - constructor (defaultValue: Readonly) { - Vec3.copy(this._defaultValue, defaultValue); - Vec3.copy(this.result, defaultValue); - } - - public refCount = 0; - - public result = new Vec3(); - - public blend (value: Readonly, weight: number): void { - this._accumulatedWeight = mixAveragedVec3( - this._clipBlendResult, - this._clipBlendResult, - this._accumulatedWeight, - value, - weight, - ); - } - - public commitLayerChange (weight: number) { - const { - result, - _clipBlendResult: clipBlendResult, - _accumulatedWeight: accumulatedWeight, - } = this; - if (accumulatedWeight < 1.0) { - this.blend(this._defaultValue, 1.0 - accumulatedWeight); - } - Vec3.lerp(result, result, clipBlendResult, weight); - Vec3.zero(this._clipBlendResult); - this._accumulatedWeight = 0.0; - } - - public reset () { - Vec3.copy(this.result, this._defaultValue); - } - - private _defaultValue = new Vec3(); - private _clipBlendResult = new Vec3(); - private _accumulatedWeight = 0.0; -} - -class LayeredQuatPropertyBlendState implements PropertyBlendState { - constructor (defaultValue: Readonly) { - Quat.copy(this._defaultValue, defaultValue); - Quat.copy(this.result, defaultValue); - } - - public refCount = 0; - - public result = new Quat(); - - public blend (value: Readonly, weight: number): void { - this._accumulatedWeight = mixAveragedQuat( - this._clipBlendResult, - this._clipBlendResult, - this._accumulatedWeight, - value, - weight, - ); - } - - public commitLayerChange (weight: number) { - const { - result, - _clipBlendResult: clipBlendResult, - _accumulatedWeight: accumulatedWeight, - } = this; - if (accumulatedWeight < 1.0) { - this.blend(this._defaultValue, 1.0 - accumulatedWeight); - } - Quat.slerp(result, result, clipBlendResult, weight); - Quat.identity(this._clipBlendResult); - this._accumulatedWeight = 0.0; - } - - public reset () { - Quat.copy(this.result, this._defaultValue); - } - - private _defaultValue = new Quat(); - private _clipBlendResult = new Quat(); - private _accumulatedWeight = 0.0; -} - -class LayeredNodeBlendState extends NodeBlendState { - public setLayerMask (layerIndex: number) { - this._layerMask &= ~(1 << layerIndex); - } - - public commitLayerChanges (layerIndex: number, weight: number) { - if (!(this._layerMask & (1 << layerIndex))) { - return; - } - const { _properties: { position, scale, rotation, eulerAngles } } = this; - if (position) { - position.commitLayerChange(weight); - } - if (scale) { - scale.commitLayerChange(weight); - } - if (rotation) { - rotation.commitLayerChange(weight); - } - if (eulerAngles) { - eulerAngles.commitLayerChange(weight); - } - } - - public apply (node: Node) { - // Layered buffer always enable all flags. - this._transformApplyFlags = TRANSFORM_APPLY_FLAGS_ALL; - - super.apply(node); - - const { _properties: { position, scale, rotation, eulerAngles } } = this; - - position?.reset(); - scale?.reset(); - rotation?.reset(); - eulerAngles?.reset(); - } - - protected _createVec3BlendState (currentValue: Readonly) { - return new LayeredVec3PropertyBlendState(currentValue); - } - - protected _createQuatBlendState (currentValue: Readonly) { - return new LayeredQuatPropertyBlendState(currentValue); - } - - private _layerMask = (~0 >>> 0); -} - -/** - * The blend state buffer is an internal facility - * used by Creator to implements animation blending. - * - * The workflow of a blend state buffer is described as following: - * - * - Create writers onto the buffer. - * - * Through `createWriter()`. - * - * - Set layer masks. - * - * Each layer should set its mask, if any. - * - * - Call the following steps in every buffer frame. - * - * - Change to layer: sample animation. - * - * The animations would write into the "clip blending buffer" - * through `BlendStateWriter` created by the buffer. - * The writing process can be weighted. The weight represents the contribution to the blending. - * Let's call this kind of blending "clip blending". - * - * - Commit layer changes. - * - * While all animations within the layer are sampled. The clip blending buffer holds - * the blend result of the layer. - * Then, a `commitLayerChanges()` call should be made to commit the changes to final result buffer, - * using another algorithm. Let's call this kind of blending "layer blending". - * - * - Apply. - * - * After ran above steps for all layers. An `apply()` call - * causes the final result buffer content flush into scene. - * - * The following demonstrates the algorithms used in "clip blending" and "layer blending", respectively. - * - * ### Algorithm used in clip blending and legacy animation system(i.e in cross fading). - * - * In short: the weights of samples are normalized, - * and the samples are scaled multiplied by their normalized weight, - * and then add up them all together. - * - * Let: - * - `N` be the count of samples to blend; - * - `v_n` be n-th sample's value; - * - `w_n` be n-th sample's weight; - * - `v_current` be current value. - * - `W_n` be the accumulated weights from 0 to n-th sample. - * - * The blend result after mix with n-th sample, denoted by `R_n`, is calculated as: - * - * ``` - * R_n = sum(i=0, n, v_i * (w_i / W_n)) - * = (R_(n-1) * W_(n-1) + v_n * w_n) / (W_(n-1) + w_n) - * ``` - * - * The final blend result produced in addition blend with current pose: - * - * ``` - * R_final = R_N * W_N + V_current * (1 - W_N) | if W_N < 1 - * R_final = R_N | Otherwise - * ``` - * - * ### Algorithm used in layer blending(Marionette animation system). - * - * In short: each layer is added onto previous content, - * the previous layer and itself are weighted by its weight. - * - * Let: - * - `N` be the count of samples to blend; - * - `V_n` be n-th sample's output; - * - `w_n` be n-th sample's weight; - * - `V_default` be the default pose. - * - * The blend result after mix with n-th sample, denoted by `R_n`, is calculated as: - * - * ``` - * R_0 = V_default * (1 - w_0) + V_0 * w_0 - * R_n = R_(n-1) * (1 - w_n) + V_n * w_n | if n ≠ 0 - * ``` - * - * The final blend result is simply the N-th result, or the default pose is no input samples: - * - * ``` - * R_final = R_N | if N ≠ 0 - * R_final = V_default | if N = 0 - * ``` - * ``` - */ -export class LayeredBlendStateBuffer extends BlendStateBuffer { - public setMask (layerIndex: number, excludeNodes: Set) { - if (DEBUG) { - checkLayerIndex(layerIndex); - } - this._nodeBlendStates.forEach((nodeBlendState, node) => { - if (excludeNodes.has(node)) { - nodeBlendState.setLayerMask(layerIndex); - } - }); - } - - public commitLayerChanges (layerIndex: number, weight: number) { - if (DEBUG) { - checkLayerIndex(layerIndex); - } - this._nodeBlendStates.forEach((nodeBlendState, node) => { - nodeBlendState.commitLayerChanges(layerIndex, weight); - }); - } - - protected createNodeBlendState () { - return new LayeredNodeBlendState(); - } -} - -function checkLayerIndex (layerIndex: number) { - assertIsTrue(layerIndex < MAX_ANIMATION_LAYER); -} - function mixAveragedVec3 (result: Vec3, previous: Readonly, accumulatedWeight: number, input: Readonly, weight: number) { const newSum = accumulatedWeight + weight; if (weight === 1.0 && !accumulatedWeight) { diff --git a/cocos/3d/skeletal-animation/skeletal-animation-data-hub.ts b/cocos/3d/skeletal-animation/skeletal-animation-data-hub.ts index 31e70c02057..20d5f119ff6 100644 --- a/cocos/3d/skeletal-animation/skeletal-animation-data-hub.ts +++ b/cocos/3d/skeletal-animation/skeletal-animation-data-hub.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,7 +24,7 @@ import { DataPoolManager } from './data-pool-manager'; import type { AnimationClip } from '../../animation/animation-clip'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { BAKE_SKELETON_CURVE_SYMBOL } from '../../animation/internal-symbols'; type BakeData = ReturnType; @@ -42,7 +41,7 @@ export class SkelAnimDataHub { let data = SkelAnimDataHub.pool.get(clip); if (!data || data.samples !== clip.sample) { // release outdated render data - if (data) { (legacyCC.director.root.dataPoolManager as DataPoolManager).releaseAnimationClip(clip); } + if (data) { (cclegacy.director.root.dataPoolManager as DataPoolManager).releaseAnimationClip(clip); } const frames = Math.ceil(clip.sample * clip.duration) + 1; const step = clip.sample; data = clip[BAKE_SKELETON_CURVE_SYMBOL](0, step, frames); diff --git a/cocos/3d/skeletal-animation/skeletal-animation-state.ts b/cocos/3d/skeletal-animation/skeletal-animation-state.ts index 909bc273b70..2492a96d3cf 100644 --- a/cocos/3d/skeletal-animation/skeletal-animation-state.ts +++ b/cocos/3d/skeletal-animation/skeletal-animation-state.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,14 +23,13 @@ */ import { JSB } from 'internal:constants'; -import { Mat4, Quat, Vec3 } from '../../core/math'; +import { Mat4, Quat, Vec3, cclegacy } from '../../core'; import { IAnimInfo, JointAnimationInfo } from './skeletal-animation-utils'; import { Node } from '../../scene-graph/node'; import type { AnimationClip } from '../../animation/animation-clip'; import { AnimationState } from '../../animation/animation-state'; import { SkeletalAnimation, Socket } from './skeletal-animation'; import { SkelAnimDataHub } from './skeletal-animation-data-hub'; -import { legacyCC } from '../../core/global-exports'; const m4_1 = new Mat4(); const m4_2 = new Mat4(); @@ -68,7 +66,7 @@ export class SkeletalAnimationState extends AnimationState { constructor (clip: AnimationClip, name = '') { super(clip, name); - this._animInfoMgr = legacyCC.director.root.dataPoolManager.jointAnimationInfo; + this._animInfoMgr = cclegacy.director.root.dataPoolManager.jointAnimationInfo; } public initialize (root: Node) { @@ -85,6 +83,18 @@ export class SkeletalAnimationState extends AnimationState { this.setUseBaked(baked); } + protected onPlay () { + super.onPlay(); + const baked = this._parent!.useBakedAnimation; + if (baked) { + this._animInfoMgr.switchClip(this._animInfo!, this.clip); + const users = this._parent!.getUsers(); + users.forEach((user) => { + user.uploadAnimation(this.clip); + }); + } + } + /** * @internal This method only friends to `SkeletalAnimation`. */ diff --git a/cocos/3d/skeletal-animation/skeletal-animation-utils.ts b/cocos/3d/skeletal-animation/skeletal-animation-utils.ts index d6fbcd05172..c61fb079c8d 100644 --- a/cocos/3d/skeletal-animation/skeletal-animation-utils.ts +++ b/cocos/3d/skeletal-animation/skeletal-animation-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,10 +28,9 @@ import { SkelAnimDataHub } from './skeletal-animation-data-hub'; import { getWorldTransformUntilRoot } from '../../animation/transform-utils'; import { Mesh } from '../assets/mesh'; import { Skeleton } from '../assets/skeleton'; -import { AABB } from '../../core/geometry'; +import { geometry, Mat4, Quat, Vec3 } from '../../core'; import { BufferUsageBit, Format, FormatInfos, MemoryUsageBit, Device, Buffer, BufferInfo, FormatFeatureBit } from '../../gfx'; -import { Mat4, Quat, Vec3 } from '../../core/math'; import { UBOSkinningAnimation } from '../../rendering/define'; import { Node } from '../../scene-graph'; import { ITextureBufferHandle, TextureBufferPool } from '../../render-scene/core/texture-buffer-pool'; @@ -114,7 +112,7 @@ export interface IJointTextureHandle { skeletonHash: number; readyToBeDeleted: boolean; handle: ITextureBufferHandle; - bounds: Map; + bounds: Map; animInfos?: IInternalJointAnimInfo[]; } @@ -124,7 +122,7 @@ const v3_min = new Vec3(); const v3_max = new Vec3(); const m4_1 = new Mat4(); const m4_2 = new Mat4(); -const ab_1 = new AABB(); +const ab_1 = new geometry.AABB(); export interface IChunkContent { skeleton: number; @@ -233,7 +231,7 @@ export class JointTexturePool { const mat = node ? getWorldTransformUntilRoot(node, skinningRoot, m4_1) : skeleton.inverseBindposes[j]; const bound = boneSpaceBounds[j]; if (bound) { - AABB.transform(ab_1, bound, mat); + geometry.AABB.transform(ab_1, bound, mat); ab_1.getBoundary(v3_3, v3_4); Vec3.min(v3_min, v3_min, v3_3); Vec3.max(v3_max, v3_max, v3_4); @@ -243,8 +241,8 @@ export class JointTexturePool { uploadJointData(textureBuffer, offset, node ? mat : Mat4.IDENTITY, j === 0); } } - const bounds = [new AABB()]; texture.bounds.set(mesh.hash, bounds); - AABB.fromPoints(bounds[0], v3_min, v3_max); + const bounds = [new geometry.AABB()]; texture.bounds.set(mesh.hash, bounds); + geometry.AABB.fromPoints(bounds[0], v3_min, v3_max); if (buildTexture) { this._pool.update(texture.handle, textureBuffer.buffer); this._textureBuffers.set(hash, texture); @@ -288,9 +286,9 @@ export class JointTexturePool { textureBuffer = new Float32Array(bufSize); buildTexture = true; } else { texture.refCount++; } const boneSpaceBounds = mesh.getBoneSpaceBounds(skeleton); - const bounds: AABB[] = []; texture.bounds.set(mesh.hash, bounds); + const bounds: geometry.AABB[] = []; texture.bounds.set(mesh.hash, bounds); for (let f = 0; f < frames; f++) { - bounds.push(new AABB(Inf, Inf, Inf, -Inf, -Inf, -Inf)); + bounds.push(new geometry.AABB(Inf, Inf, Inf, -Inf, -Inf, -Inf)); } for (let f = 0, offset = 0; f < frames; f++) { const bound = bounds[f]; @@ -312,7 +310,7 @@ export class JointTexturePool { const boneSpaceBound = boneSpaceBounds[j]; if (boneSpaceBound) { const transform = bindposeCorrection ? Mat4.multiply(m4_2, mat, bindposeCorrection) : mat; - AABB.transform(ab_1, boneSpaceBound, transform); + geometry.AABB.transform(ab_1, boneSpaceBound, transform); ab_1.getBoundary(v3_3, v3_4); Vec3.min(bound.center, bound.center, v3_3); Vec3.max(bound.halfExtents, bound.halfExtents, v3_4); @@ -322,7 +320,7 @@ export class JointTexturePool { uploadJointData(textureBuffer, offset, transformValid ? m4_1 : Mat4.IDENTITY, j === 0); } } - AABB.fromPoints(bound, bound.center, bound.halfExtents); + geometry.AABB.fromPoints(bound, bound.center, bound.halfExtents); } if (buildTexture) { this._pool.update(texture.handle, textureBuffer.buffer); @@ -489,8 +487,9 @@ export class JointAnimationInfo { public switchClip (info: IAnimInfo, clip: AnimationClip | null) { info.currentClip = clip; - info.data[0] = -1; + info.data[0] = 0; // reset default frame 0 info.buffer.update(info.data); + info.data[0] = -1; // reset frame index to -1. sampleCurves will calculate frame to 0. info.dirty = false; if (JSB) { info.dirtyForJSB[0] = 0; diff --git a/cocos/3d/skeletal-animation/skeletal-animation.ts b/cocos/3d/skeletal-animation/skeletal-animation.ts index 4d9a4fe5b81..f9a71ec4e68 100644 --- a/cocos/3d/skeletal-animation/skeletal-animation.ts +++ b/cocos/3d/skeletal-animation/skeletal-animation.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,7 +26,7 @@ import { ccclass, executeInEditMode, executionOrder, help, menu, tooltip, type, serializable, editable, } from 'cc.decorator'; import { SkinnedMeshRenderer } from '../skinned-mesh-renderer'; -import { Mat4 } from '../../core/math'; +import { Mat4, cclegacy, js, assertIsTrue } from '../../core'; import { DataPoolManager } from './data-pool-manager'; import { Node } from '../../scene-graph/node'; import { AnimationClip } from '../../animation/animation-clip'; @@ -35,10 +34,7 @@ import { Animation } from '../../animation/animation-component'; import { SkelAnimDataHub } from './skeletal-animation-data-hub'; import { SkeletalAnimationState } from './skeletal-animation-state'; import { getWorldTransformUntilRoot } from '../../animation/transform-utils'; -import { legacyCC } from '../../core/global-exports'; -import { js } from '../../core/utils/js'; import type { AnimationState } from '../../animation/animation-state'; -import { assertIsTrue } from '../../core/data/utils/asserts'; import { getGlobalAnimationManager } from '../../animation/global-animation-manager'; /** @@ -180,7 +176,7 @@ export class SkeletalAnimation extends Animation { public onDestroy () { super.onDestroy(); - (legacyCC.director.root.dataPoolManager as DataPoolManager).jointAnimationInfo.destroy(this.node.uuid); + (cclegacy.director.root.dataPoolManager as DataPoolManager).jointAnimationInfo.destroy(this.node.uuid); getGlobalAnimationManager().removeSockets(this.node, this._sockets); this._removeAllUsers(); } @@ -233,7 +229,7 @@ export class SkeletalAnimation extends Animation { */ public querySockets () { const animPaths = (this._defaultClip && Object.keys(SkelAnimDataHub.getOrExtract(this._defaultClip).joints).sort() - .reduce((acc, cur) => (cur.startsWith(acc[acc.length - 1]) ? acc : (acc.push(cur), acc)), [] as string[])) || []; + .reduce((acc, cur) => (cur.startsWith(`${acc[acc.length - 1]}/`) ? acc : (acc.push(cur), acc)), [] as string[])) || []; if (!animPaths.length) { return ['please specify a valid default animation clip first']; } const out: string[] = []; for (let i = 0; i < animPaths.length; i++) { diff --git a/cocos/3d/skinned-mesh-renderer/deprecated.ts b/cocos/3d/skinned-mesh-renderer/deprecated.ts index f4780bd92d7..9d703ce26a5 100644 --- a/cocos/3d/skinned-mesh-renderer/deprecated.ts +++ b/cocos/3d/skinned-mesh-renderer/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,30 +20,29 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { SkinnedMeshRenderer } from './skinned-mesh-renderer'; import { SkinnedMeshBatchRenderer, SkinnedMeshUnit } from './skinned-mesh-batch-renderer'; -import { js } from '../../core/utils/js'; -import { legacyCC } from '../../core/global-exports'; +import { js, cclegacy } from '../../core'; /** * Alias of [[SkinnedMeshRenderer]] * @deprecated Since v1.2 */ export { SkinnedMeshRenderer as SkinningModelComponent }; -legacyCC.SkinningModelComponent = SkinnedMeshRenderer; +cclegacy.SkinningModelComponent = SkinnedMeshRenderer; js.setClassAlias(SkinnedMeshRenderer, 'cc.SkinningModelComponent'); /** * Alias of [[SkinnedMeshUnit]] * @deprecated Since v1.2 */ export { SkinnedMeshUnit as SkinningModelUnit }; -legacyCC.SkinningModelUnit = SkinnedMeshUnit; +cclegacy.SkinningModelUnit = SkinnedMeshUnit; js.setClassAlias(SkinnedMeshUnit, 'cc.SkinningModelUnit'); /** * Alias of [[SkinnedMeshBatchRenderer]] * @deprecated Since v1.2 */ export { SkinnedMeshBatchRenderer as BatchedSkinningModelComponent }; -legacyCC.BatchedSkinningModelComponent = SkinnedMeshBatchRenderer; +cclegacy.BatchedSkinningModelComponent = SkinnedMeshBatchRenderer; js.setClassAlias(SkinnedMeshBatchRenderer, 'cc.BatchedSkinningModelComponent'); diff --git a/cocos/3d/skinned-mesh-renderer/index.ts b/cocos/3d/skinned-mesh-renderer/index.ts index 24413a5ef35..8ea33501abd 100644 --- a/cocos/3d/skinned-mesh-renderer/index.ts +++ b/cocos/3d/skinned-mesh-renderer/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/3d/skinned-mesh-renderer/skinned-mesh-batch-renderer.ts b/cocos/3d/skinned-mesh-renderer/skinned-mesh-batch-renderer.ts index 58e785c7c7f..bf8d22f9b54 100644 --- a/cocos/3d/skinned-mesh-renderer/skinned-mesh-batch-renderer.ts +++ b/cocos/3d/skinned-mesh-renderer/skinned-mesh-batch-renderer.ts @@ -1,14 +1,14 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -32,12 +32,10 @@ import { Material } from '../../asset/assets/material'; import { Mesh } from '../assets/mesh'; import { Skeleton } from '../assets/skeleton'; import { Texture2D } from '../../asset/assets/texture-2d'; -import { CCString } from '../../core/data/utils/attribute'; +import { CCString, Mat4, Vec2, Vec3, cclegacy } from '../../core'; import { AttributeName, FormatInfos, Format, Type, Attribute, BufferTextureCopy } from '../../gfx'; -import { Mat4, Vec2, Vec3 } from '../../core/math'; import { mapBuffer, readBuffer, writeBuffer } from '../misc/buffer'; import { SkinnedMeshRenderer } from './skinned-mesh-renderer'; -import { legacyCC } from '../../core/global-exports'; const repeat = (n: number) => n - Math.floor(n); const batch_id: Attribute = new Attribute(AttributeName.ATTR_BATCH_ID, Format.R32F); @@ -477,7 +475,7 @@ export class SkinnedMeshBatchRenderer extends SkinnedMeshRenderer { } } const gfxTex = target.getGFXTexture()!; - const { device } = legacyCC.director.root!; + const { device } = cclegacy.director.root!; if (texBuffers.length > 0) { device.copyBuffersToTexture(texBuffers, gfxTex, texBufferRegions); } if (texImages.length > 0) { device.copyTexImagesToTexture(texImages, gfxTex, texImageRegions); } } @@ -555,7 +553,7 @@ export class SkinnedMeshBatchRenderer extends SkinnedMeshRenderer { const oldMeshData = mesh.data; const newDataView = new DataView(newMeshData.buffer); const oldDataView = new DataView(oldMeshData.buffer); - const { isLittleEndian } = legacyCC.sys; + const { isLittleEndian } = cclegacy.sys; for (const b in modifiedBundles) { const newBundle = newMeshStruct.vertexBundles[b]; const oldBundle = mesh.struct.vertexBundles[b]; diff --git a/cocos/3d/skinned-mesh-renderer/skinned-mesh-renderer.ts b/cocos/3d/skinned-mesh-renderer/skinned-mesh-renderer.ts index 2a62d25cd6e..408dc2ccac5 100644 --- a/cocos/3d/skinned-mesh-renderer/skinned-mesh-renderer.ts +++ b/cocos/3d/skinned-mesh-renderer/skinned-mesh-renderer.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -32,10 +32,9 @@ import { Skeleton } from '../assets/skeleton'; import { Node } from '../../scene-graph/node'; import { MeshRenderer } from '../framework/mesh-renderer'; import type { SkeletalAnimation } from '../skeletal-animation'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy, assertIsTrue } from '../../core'; import { SkinningModel } from '../models/skinning-model'; import { BakedSkinningModel } from '../models/baked-skinning-model'; -import { assertIsTrue } from '../../core/data/utils/asserts'; /** * @en The skinned mesh renderer component. @@ -132,12 +131,13 @@ export class SkinnedMeshRenderer extends MeshRenderer { if (!force && this._modelType === modelType) { return; } this._modelType = modelType; if (this._model) { - legacyCC.director.root.destroyModel(this._model); + cclegacy.director.root.destroyModel(this._model); this._model = null; this._models.length = 0; this._updateModels(); this._updateCastShadow(); this._updateReceiveShadow(); + this._updateUseLightProbe(); if (this.enabledInHierarchy) { this._attachToScene(); } diff --git a/cocos/animation/animation-clip.ts b/cocos/animation/animation-clip.ts index 56f231088ce..5e0179aca6c 100644 --- a/cocos/animation/animation-clip.ts +++ b/cocos/animation/animation-clip.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; import { DEBUG } from 'internal:constants'; import { Asset } from '../asset/assets/asset'; import { SpriteFrame } from '../2d/assets/sprite-frame'; -import { errorID, warnID } from '../core/platform/debug'; -import { binarySearchEpsilon } from '../core/algorithm/binary-search'; -import { murmurhash2_32_gc } from '../core/algorithm/murmurhash2_gc'; +import { errorID, warnID, cclegacy, js, geometry, approx, clamp, Mat4, Quat, Vec3, murmurhash2_32_gc, binarySearchEpsilon, assertIsTrue } from '../core'; import { SkelAnimDataHub } from '../3d/skeletal-animation/skeletal-animation-data-hub'; import { WrapMode as AnimationWrapMode, WrapMode } from './types'; -import { legacyCC } from '../core/global-exports'; -import { approx, clamp, Mat4, Quat, Vec3 } from '../core/math'; import { Node } from '../scene-graph/node'; -import { assertIsTrue } from '../core/data/utils/asserts'; import type { PoseOutput } from './pose-output'; import * as legacy from './legacy-clip-data'; import { BAKE_SKELETON_CURVE_SYMBOL } from './internal-symbols'; @@ -46,11 +40,9 @@ import { Range } from './tracks/utils'; import { ObjectTrack } from './tracks/object-track'; import type { ExoticAnimation } from './exotic-animation/exotic-animation'; import './exotic-animation/exotic-animation'; -import { array } from '../core/utils/js'; import type { AnimationMask } from './marionette/animation-mask'; import { getGlobalAnimationManager } from './global-animation-manager'; import { EmbeddedPlayableState, EmbeddedPlayer } from './embedded-player/embedded-player'; -import { WrapModeMask } from '../core/geometry/curve'; export declare namespace AnimationClip { export interface IEvent { @@ -90,6 +82,11 @@ export const addEmbeddedPlayerTag = Symbol('[[AddEmbeddedPlayer]]'); export const removeEmbeddedPlayerTag = Symbol('[[RemoveEmbeddedPlayer]]'); export const clearEmbeddedPlayersTag = Symbol('[[ClearEmbeddedPlayers]]'); +/** + * Tag to access the additive settings associated on animation clip. + */ +export const additiveSettingsTag = Symbol('[[Additive Settings]]'); + /** * @zh 动画剪辑表示一段使用动画编辑器编辑的关键帧动画或是外部美术工具生产的骨骼动画。 * 它的数据主要被分为几层:轨道、关键帧和曲线。 @@ -239,6 +236,13 @@ export class AnimationClip extends Asset { this._exoticAnimation = value; } + /** + * Accesses the additive animation settings. + */ + get [additiveSettingsTag] () { + return this._additiveSettings; + } + public onLoaded () { this.frameRate = this.sample; this.events = this._events; @@ -392,8 +396,8 @@ export class AnimationClip extends Asset { } public destroy () { - if (legacyCC.director.root?.dataPoolManager) { - (legacyCC.director.root.dataPoolManager).releaseAnimationClip(this); + if (cclegacy.director.root?.dataPoolManager) { + (cclegacy.director.root.dataPoolManager).releaseAnimationClip(this); } SkelAnimDataHub.destroy(this); return super.destroy(); @@ -497,7 +501,7 @@ export class AnimationClip extends Asset { } const nRemovalTracks = removals.length; for (let iRemovalTrack = 0; iRemovalTrack < nRemovalTracks; ++iRemovalTrack) { - array.remove(tracks, removals[iRemovalTrack]); + js.array.remove(tracks, removals[iRemovalTrack]); } tracks.push(...newTracks); } @@ -653,6 +657,16 @@ export class AnimationClip extends Asset { this._embeddedPlayers.length = 0; } + /** + * @internal + */ + public _trySyncLegacyData () { + if (this._legacyDataDirty) { + this._legacyDataDirty = false; + this.syncLegacyData(); + } + } + @serializable private _duration = 0; @@ -677,6 +691,9 @@ export class AnimationClip extends Asset { @serializable private _embeddedPlayers: EmbeddedPlayer[] = []; + @serializable + private _additiveSettings = new AdditiveSettings(); + private _runtimeEvents: { ratios: number[]; eventGroups: IAnimationEventGroup[]; @@ -701,7 +718,7 @@ export class AnimationClip extends Asset { ); } - const trackEvalStatues: TrackEvalStatus[] = []; + const trackEvalStatues: TrackEvalStatus[] = []; let exoticAnimationEvaluator: ExoticAnimationEvaluator | undefined; const { _tracks: tracks } = this; @@ -714,15 +731,29 @@ export class AnimationClip extends Asset { if (Array.from(track.channels()).every(({ curve }) => curve.keyFramesCount === 0)) { continue; } - const trackTarget = binder(track[trackBindingTag]); - if (!trackTarget) { + const runtimeBinding = binder(track[trackBindingTag]); + if (!runtimeBinding) { continue; } - const trackEval = track[createEvalSymbol](trackTarget); - trackEvalStatues.push({ - binding: trackTarget, - trackEval, - }); + + let trackEval: TrackEval; + if (!(track instanceof UntypedTrack)) { + trackEval = track[createEvalSymbol](); + } else { + // Handle untyped track specially. + if (!runtimeBinding.getValue) { + // If we can not get a value from binding, + // we're not able to instantiate the untyped track. + // This matches the behavior prior to V3.3. + errorID(3930); + continue; + } + + const hintValue = runtimeBinding.getValue(); + trackEval = track.createLegacyEval(hintValue); + } + + trackEvalStatues.push(new TrackEvalStatus(runtimeBinding, trackEval)); } if (this._exoticAnimation) { @@ -763,7 +794,7 @@ export class AnimationClip extends Asset { // const { } = rootMotionOptions; const boneTransform = new BoneTransform(); - const rootMotionsTrackEvaluations: TrackEvalStatus[] = []; + const rootMotionsTrackEvaluations: TrackEvalStatus[] = []; const { _tracks: tracks } = this; const nTracks = tracks.length; for (let iTrack = 0; iTrack < nTracks; ++iTrack) { @@ -779,15 +810,12 @@ export class AnimationClip extends Asset { } rootMotionTrackExcludes.push(track); const property = trsPath.property; - const trackTarget = createBoneTransformBinding(boneTransform, property); - if (!trackTarget) { + const runtimeBinding = createBoneTransformBinding(boneTransform, property); + if (!runtimeBinding) { continue; } - const trackEval = track[createEvalSymbol](trackTarget); - rootMotionsTrackEvaluations.push({ - binding: trackTarget, - trackEval, - }); + const trackEval = track[createEvalSymbol](); + rootMotionsTrackEvaluations.push(new TrackEvalStatus(runtimeBinding, trackEval)); } const rootMotionEvaluation = new RootMotionEvaluation( rootBone, @@ -892,17 +920,39 @@ export class AnimationClip extends Asset { } } +@ccclass('cc.AnimationClipAdditiveSettings') +class AdditiveSettings { + @serializable + base: AnimationClip | null = null; +} + +export { AdditiveSettings as AnimationClipAdditiveSettings }; + type WrapMode_ = WrapMode; export declare namespace AnimationClip { export type WrapMode = WrapMode_; } -legacyCC.AnimationClip = AnimationClip; +cclegacy.AnimationClip = AnimationClip; + +class TrackEvalStatus { + constructor (binding: RuntimeBinding, trackEval: TrackEval) { + this._binding = binding; + this._trackEval = trackEval; + } + + public evaluate (time: number) { + const { _binding: binding, _trackEval: trackEval } = this; + const defaultValue = binding.getValue && trackEval.requiresDefault + ? binding.getValue() as TValue extends unknown ? unknown : Readonly + : undefined; + const value = trackEval.evaluate(time, defaultValue); + binding.setValue(value); + } -interface TrackEvalStatus { - binding: RuntimeBinding; - trackEval: TrackEval; + private _binding: RuntimeBinding; + private _trackEval: TrackEval; } interface AnimationClipEvalContext { @@ -1124,7 +1174,7 @@ class EmbeddedPlayerEvaluation { class AnimationClipEvaluation { constructor ( - trackEvalStatuses: TrackEvalStatus[], + trackEvalStatuses: TrackEvalStatus[], exoticAnimationEvaluator: ExoticAnimationEvaluator | undefined, rootMotionEvaluation: RootMotionEvaluation | undefined, ) { @@ -1145,9 +1195,7 @@ class AnimationClipEvaluation { const nTrackEvalStatuses = trackEvalStatuses.length; for (let iTrackEvalStatus = 0; iTrackEvalStatus < nTrackEvalStatuses; ++iTrackEvalStatus) { - const { trackEval, binding } = trackEvalStatuses[iTrackEvalStatus]; - const value = trackEval.evaluate(time, binding); - binding.setValue(value); + trackEvalStatuses[iTrackEvalStatus].evaluate(time); } if (exoticAnimationEvaluator) { @@ -1168,7 +1216,7 @@ class AnimationClipEvaluation { } private _exoticAnimationEvaluator: ExoticAnimationEvaluator | undefined; - private _trackEvalStatues:TrackEvalStatus[] = []; + private _trackEvalStatues: TrackEvalStatus[] = []; private _rootMotionEvaluation: RootMotionEvaluation | undefined = undefined; } @@ -1213,7 +1261,7 @@ class RootMotionEvaluation { private _rootBone: Node, private _duration: number, private _boneTransform: BoneTransform, - private _trackEvalStatuses: TrackEvalStatus[], + private _trackEvalStatuses: TrackEvalStatus[], ) { } @@ -1285,9 +1333,7 @@ class RootMotionEvaluation { const nTrackEvalStatuses = trackEvalStatuses.length; for (let iTrackEvalStatus = 0; iTrackEvalStatus < nTrackEvalStatuses; ++iTrackEvalStatus) { - const { trackEval, binding } = trackEvalStatuses[iTrackEvalStatus]; - const value = trackEval.evaluate(time, binding); - binding.setValue(value); + trackEvalStatuses[iTrackEvalStatus].evaluate(time); } this._boneTransform.getTransform(outTransform); @@ -1425,14 +1471,14 @@ class EventEvaluator { do { if (lastIndex !== eventIndex) { if (direction === -1 && lastIndex === 0 && eventIndex > 0) { - if ((wrapMode & WrapModeMask.PingPong) === WrapModeMask.PingPong) { + if ((wrapMode & geometry.WrapModeMask.PingPong) === geometry.WrapModeMask.PingPong) { direction *= -1; } else { lastIndex = length; } lastIterations++; } else if (direction === 1 && lastIndex === length - 1 && eventIndex < length - 1) { - if ((wrapMode & WrapModeMask.PingPong) === WrapModeMask.PingPong) { + if ((wrapMode & geometry.WrapModeMask.PingPong) === geometry.WrapModeMask.PingPong) { direction *= -1; } else { lastIndex = -1; diff --git a/cocos/animation/animation-component.ts b/cocos/animation/animation-component.ts index b45f9038ce5..b9365029034 100644 --- a/cocos/animation/animation-component.ts +++ b/cocos/animation/animation-component.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,15 +25,10 @@ import { ccclass, executeInEditMode, executionOrder, help, menu, tooltip, type, serializable } from 'cc.decorator'; import { EDITOR, TEST } from 'internal:constants'; import { Component } from '../scene-graph/component'; -import { Eventify } from '../core/event'; -import { warnID } from '../core/platform/debug'; -import * as ArrayUtils from '../core/utils/array'; -import { createMap } from '../core/utils/js-typed'; +import { Eventify, warnID, js, cclegacy } from '../core'; import { AnimationClip } from './animation-clip'; import { AnimationState, EventType } from './animation-state'; import { CrossFade } from './cross-fade'; -import { legacyCC } from '../core/global-exports'; -import { js } from '../core/utils/js'; /** * @en @@ -148,7 +142,7 @@ export class Animation extends Eventify(Component) { /** * @internal */ - protected _nameToState: Record = createMap(true); + protected _nameToState: Record = js.createMap(true); /** * @internal @@ -176,7 +170,7 @@ export class Animation extends Eventify(Component) { } public start () { - if ((!EDITOR || legacyCC.GAME_VIEW) && (this.playOnLoad && !this._hasBeenPlayed) && this._defaultClip) { + if ((!EDITOR || cclegacy.GAME_VIEW) && (this.playOnLoad && !this._hasBeenPlayed) && this._defaultClip) { this.crossFade(this._defaultClip.name, 0); } } @@ -195,7 +189,7 @@ export class Animation extends Eventify(Component) { const state = this._nameToState[name]; state.destroy(); } - this._nameToState = createMap(true); + this._nameToState = js.createMap(true); } /** @@ -322,7 +316,7 @@ export class Animation extends Eventify(Component) { * @returns The created animation state */ public addClip (clip: AnimationClip, name?: string): AnimationState { - if (!ArrayUtils.contains(this._clips, clip)) { + if (js.array.contains(this._clips, clip)) { this._clips.push(clip); } return this.createState(clip, name); @@ -502,12 +496,12 @@ function equalClips (clip1: AnimationClip | null, clip2: AnimationClip | null) { return !!clip1 && !!clip2 && (clip1._uuid === clip2._uuid) && clip1._uuid; } -legacyCC.Animation = Animation; +cclegacy.Animation = Animation; /** * Alias of [[Animation]] * @deprecated Since v1.2 */ export { Animation as AnimationComponent }; -legacyCC.AnimationComponent = Animation; +cclegacy.AnimationComponent = Animation; js.setClassAlias(Animation, 'cc.AnimationComponent'); diff --git a/cocos/animation/animation-curve.ts b/cocos/animation/animation-curve.ts index b634dcb4910..d8152d0ec90 100644 --- a/cocos/animation/animation-curve.ts +++ b/cocos/animation/animation-curve.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { binarySearchEpsilon as binarySearch } from '../core/algorithm/binary-search'; -import { lerp, Quat } from '../core/math'; -import { errorID } from '../core/platform/debug'; -import { ValueType } from '../core/value-types'; -import { bezierByTime, BezierControlPoints } from '../core/curves/bezier'; -import * as easing from '../core/algorithm/easing'; +import { lerp, Quat, errorID, cclegacy, binarySearchEpsilon, ValueType, bezierByTime, BezierControlPoints, easing } from '../core'; import { ILerpable, isLerpable } from './types'; -import { legacyCC } from '../core/global-exports'; import type * as legacy from './legacy-clip-data'; /** @@ -57,14 +50,14 @@ export class RatioSampler { break; } } - this._findRatio = canOptimize ? quickFindIndex : binarySearch; + this._findRatio = canOptimize ? quickFindIndex : binarySearchEpsilon; } public sample (ratio: number) { return this._findRatio(this.ratios, ratio); } } -legacyCC.RatioSampler = RatioSampler; +cclegacy.RatioSampler = RatioSampler; /** * @en @@ -216,7 +209,7 @@ export class AnimCurve { return this._values.length === 1; } } -legacyCC.AnimCurve = AnimCurve; +cclegacy.AnimCurve = AnimCurve; export class EventInfo { public events: any[] = []; @@ -261,7 +254,7 @@ export function sampleAnimationCurve (curve: AnimCurve, sampler: RatioSampler, r // eslint-disable-next-line @typescript-eslint/no-unsafe-return return curve.valueAt(index); } -legacyCC.sampleAnimationCurve = sampleAnimationCurve; +cclegacy.sampleAnimationCurve = sampleAnimationCurve; /** * @en diff --git a/cocos/animation/animation-manager.ts b/cocos/animation/animation-manager.ts index 0ea24ed8c9e..3e929dd6978 100644 --- a/cocos/animation/animation-manager.ts +++ b/cocos/animation/animation-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; -import System from '../core/system'; +import { System, errorID, cclegacy, js } from '../core'; import { director, Director } from '../game/director'; -import { errorID } from '../core/platform/debug'; import { Node } from '../scene-graph'; -import { MutableForwardIterator } from '../core/utils/array'; import { LegacyBlendStateBuffer } from '../3d/skeletal-animation/skeletal-animation-blending'; import { AnimationState } from './animation-state'; import type { CrossFade } from './cross-fade'; -import { legacyCC } from '../core/global-exports'; import { IJointTransform, deleteTransform, getTransform, getWorldMatrix } from './skeletal-animation-utils'; import { Socket } from '../3d/skeletal-animation/skeletal-animation'; @@ -48,8 +44,8 @@ export class AnimationManager extends System { } public static ID = 'animation'; - private _anims = new MutableForwardIterator([]); - private _crossFades = new MutableForwardIterator([]); + private _anims = new js.array.MutableForwardIterator([]); + private _crossFades = new js.array.MutableForwardIterator([]); private _delayEvents: { fn: (...args: any[]) => void; thisArg: any; @@ -95,7 +91,7 @@ export class AnimationManager extends System { } this._blendStateBuffer.apply(); - const stamp = legacyCC.director.getTotalFrames(); + const stamp = director.getTotalFrames(); for (let i = 0, l = _sockets.length; i < l; i++) { const { target, transform } = _sockets[i]; target.matrix = getWorldMatrix(transform, stamp); @@ -169,4 +165,4 @@ director.on(Director.EVENT_INIT, () => { director.registerSystem(AnimationManager.ID, animationManager, System.Priority.HIGH); }); -legacyCC.AnimationManager = AnimationManager; +cclegacy.AnimationManager = AnimationManager; diff --git a/cocos/animation/animation-state.ts b/cocos/animation/animation-state.ts index 3ab6a37ab6c..3383aa26233 100644 --- a/cocos/animation/animation-state.ts +++ b/cocos/animation/animation-state.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,15 +27,11 @@ import { Node } from '../scene-graph/node'; import { AnimationClip } from './animation-clip'; import { Playable } from './playable'; import { WrapMode, WrappedInfo } from './types'; -import { legacyCC } from '../core/global-exports'; -import { ccenum } from '../core/value-types/enum'; -import { assertIsTrue } from '../core/data/utils/asserts'; -import { debug } from '../core/platform/debug'; +import { cclegacy, debug, geometry, ccenum, assertIsTrue } from '../core'; import { AnimationMask } from './marionette/animation-mask'; import { PoseOutput } from './pose-output'; import { BlendStateBuffer } from '../3d/skeletal-animation/skeletal-animation-blending'; import { getGlobalAnimationManager } from './global-animation-manager'; -import { WrapModeMask } from '../core/geometry/curve'; /** * @en The event type supported by Animation @@ -127,7 +122,7 @@ export class AnimationState extends Playable { // dynamic change wrapMode will need reset time to 0 this.time = 0; - if (value & WrapModeMask.Loop) { + if (value & geometry.WrapModeMask.Loop) { this.repeatCount = Infinity; } else { this.repeatCount = 1; @@ -156,8 +151,8 @@ export class AnimationState extends Playable { set repeatCount (value: number) { this._repeatCount = value; - const shouldWrap = this._wrapMode & WrapModeMask.ShouldWrap; - const reverse = (this.wrapMode & WrapModeMask.Reverse) === WrapModeMask.Reverse; + const shouldWrap = this._wrapMode & geometry.WrapModeMask.ShouldWrap; + const reverse = (this.wrapMode & geometry.WrapModeMask.Reverse) === geometry.WrapModeMask.Reverse; if (value === Infinity && !shouldWrap && !reverse) { this._useSimpleProcess = true; } else { @@ -194,18 +189,21 @@ export class AnimationState extends Playable { * The `min` and `max` field of the range are measured in seconds. * While setting, the range object should be a valid range. * The actual playback range would be the inclusion of this field and [0, duration]. + * Set this field would reset the accumulated play time. + * If `min === max`, the animation always play at `min`. * @zh * 获取或设置播放范围。 * 范围的 `min`、`max` 字段都是以秒为单位的。 * 设置时,应当指定一个有效的范围;实际的播放范围是该字段和 [0, 周期] 之间的交集。 * 设置播放范围时将重置累计播放时间。 + * 如果 `min === max`,该动画将一直在 `min` 处播放。 */ get playbackRange (): Readonly<{ min: number; max: number; }> { return this._playbackRange; } set playbackRange (value) { - assertIsTrue(value.max > value.min); + assertIsTrue(value.max >= value.min); this._playbackRange.min = Math.max(value.min, 0); this._playbackRange.max = Math.min(value.max, this.duration); this._playbackDuration = this._playbackRange.max - this._playbackRange.min; @@ -363,7 +361,7 @@ export class AnimationState extends Playable { this._playbackRange.max = clip.duration; this._playbackDuration = clip.duration; - if ((this.wrapMode & WrapModeMask.Loop) === WrapModeMask.Loop) { + if ((this.wrapMode & geometry.WrapModeMask.Loop) === geometry.WrapModeMask.Loop) { this.repeatCount = Infinity; } else { this.repeatCount = 1; @@ -381,7 +379,7 @@ export class AnimationState extends Playable { }); } - if (!(EDITOR && !legacyCC.GAME_VIEW)) { + if (!(EDITOR && !cclegacy.GAME_VIEW)) { if (clip.containsAnyEvent()) { this._clipEventEval = clip.createEventEvaluator(this._targetNode); } @@ -475,7 +473,7 @@ export class AnimationState extends Playable { this._currentFramePlayed = false; this.time = time || 0.0; - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { const info = this.getWrappedInfo(time, this._wrappedInfo); this._clipEventEval?.ignore(info.ratio, info.direction); } @@ -507,7 +505,7 @@ export class AnimationState extends Playable { public sample () { const info = this.getWrappedInfo(this.time, this._wrappedInfo); this._sampleCurves(info.time); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this._sampleEvents(info); } this._sampleEmbeddedPlayers(info); @@ -606,7 +604,7 @@ export class AnimationState extends Playable { if (this._clipEventEval || this._clipEmbeddedPlayerEval) { const wrapInfo = this.getWrappedInfo(this.time, this._wrappedInfo); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this._sampleEvents(wrapInfo); } @@ -630,7 +628,7 @@ export class AnimationState extends Playable { const wrapMode = this.wrapMode; let needReverse = false; - if ((wrapMode & WrapModeMask.PingPong) === WrapModeMask.PingPong) { + if ((wrapMode & geometry.WrapModeMask.PingPong) === geometry.WrapModeMask.PingPong) { const isEnd = currentIterations - (currentIterations | 0) === 0; if (isEnd && (currentIterations > 0)) { currentIterations -= 1; @@ -641,7 +639,7 @@ export class AnimationState extends Playable { needReverse = !needReverse; } } - if ((wrapMode & WrapModeMask.Reverse) === WrapModeMask.Reverse) { + if ((wrapMode & geometry.WrapModeMask.Reverse) === geometry.WrapModeMask.Reverse) { needReverse = !needReverse; } return needReverse; @@ -693,7 +691,7 @@ export class AnimationState extends Playable { } let needReverse = false; - const shouldWrap = this._wrapMode & WrapModeMask.ShouldWrap; + const shouldWrap = this._wrapMode & geometry.WrapModeMask.ShouldWrap; if (shouldWrap) { needReverse = this._needReverse(currentIterations); } @@ -751,4 +749,4 @@ export class AnimationState extends Playable { } } -legacyCC.AnimationState = AnimationState; +cclegacy.AnimationState = AnimationState; diff --git a/cocos/animation/animation.ts b/cocos/animation/animation.ts index 53f5f5c109a..1547d248b30 100644 --- a/cocos/animation/animation.ts +++ b/cocos/animation/animation.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './embedded-player/embedded-player'; import './embedded-player/embedded-animation-clip-player'; diff --git a/cocos/animation/compression.ts b/cocos/animation/compression.ts index 27755b928ba..1b82a4ac093 100644 --- a/cocos/animation/compression.ts +++ b/cocos/animation/compression.ts @@ -1,4 +1,28 @@ -import { approx } from '../core/math/utils'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { approx } from '../core'; /** * Removes keys which are linear interpolations of surrounding keys. diff --git a/cocos/animation/compression/compressed-data.ts b/cocos/animation/compression/compressed-data.ts index ac040e9e50a..0cd4aa7a66b 100644 --- a/cocos/animation/compression/compressed-data.ts +++ b/cocos/animation/compression/compressed-data.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { QuatCurve, RealCurve } from '../../curves'; import { KeySharedQuatCurves, KeySharedRealCurves } from '../../curves/keys-shared-curves'; import { ccclass, serializable } from '../../data/decorators'; diff --git a/cocos/animation/core/animation-handle.ts b/cocos/animation/core/animation-handle.ts new file mode 100644 index 00000000000..0754708a524 --- /dev/null +++ b/cocos/animation/core/animation-handle.ts @@ -0,0 +1,26 @@ +/** + * The reason why we wrap the index into an object is in that + * the number of bones may vary due to animation replacement/added/moved(remember we have "overrideClips"). + */ + +export interface TransformHandle { + __brand: 'TransformHandle'; + + /** + * Index of the transform in pose's transform array. + */ + readonly index: number; + + destroy(): void; +} + +export interface MetaValueHandle { + __brand: 'MetaValueHandle'; + + /** + * Index of the meta value in pose's meta value array. + */ + readonly index: number; + + destroy(): void; +} diff --git a/cocos/animation/core/pose-allocator.ts b/cocos/animation/core/pose-allocator.ts new file mode 100644 index 00000000000..71fc7192e38 --- /dev/null +++ b/cocos/animation/core/pose-allocator.ts @@ -0,0 +1,102 @@ +import { assertIsTrue } from '../../core/data/utils/asserts'; +import { Pose } from './pose'; +import { TransformArray } from './transform-array'; +import { SharedStackBasedAllocator, SharedStackBasedAllocatorManager } from './shared-stack-based-allocator'; + +export class PoseAllocator { + constructor (transformCount: number, metaValueCount: number) { + this._transformCount = transformCount; + this._metaValueCount = metaValueCount; + + const poseBytes = calculateRequiredBytes( + transformCount, + metaValueCount, + 1, + ); + + this._memoryAllocator = globalPosePageMemoryAllocatorManager.createAllocator(poseBytes); + } + + public destroy () { + assertIsTrue(this._allocatedCount === 0, `Can not destroy the allocator since it's not empty.`); + + for (let iPose = 0; iPose < this._poses.length; ++iPose) { + this._memoryAllocator.pop(); + } + + this._poses.length = 0; + + return this._memoryAllocator.destroy(); + } + + public get allocatedCount () { + return this._allocatedCount; + } + + public push (): Pose { + // Lock the allocator when pushing first pose. + if (this._allocatedCount === 0) { + this._memoryAllocator.debugLock(); + } + + if (this._allocatedCount === this._poses.length) { + this._allocateNewPose(); + assertIsTrue(this._allocatedCount < this._poses.length); + } + + const pose = this._poses[this._allocatedCount]; + + ++this._allocatedCount; + + return pose; + } + + public pop () { + assertIsTrue(this.allocatedCount > 0, `PoseAllocator: push/pop does not match.`); + + --this._allocatedCount; + + // Unlock the allocator while popping last pose. + if (this._allocatedCount === 0) { + this._memoryAllocator.debugUnlock(); + } + + // Note: we don't actually free the pose -- only destroy() will free the pose. + // This does not cause big problem since all pose allocators share the same stack memory. + } + + private _poses: Pose[] = []; + + private declare readonly _transformCount: number; + + private declare readonly _metaValueCount: number; + + private _allocatedCount = 0; + + private _memoryAllocator: SharedStackBasedAllocator; + + private _allocateNewPose () { + const slice = this._memoryAllocator.push(); + const transformsByteLength = TransformArray.BYTES_PER_ELEMENT * this._transformCount; + const baseOffset = slice.byteOffset; + const transforms = new TransformArray(slice.buffer, baseOffset, this._transformCount); + const metaValues = new Float64Array(slice.buffer, baseOffset + transformsByteLength, this._metaValueCount); + const pose = Pose._create(transforms, metaValues); + this._poses.push(pose); + } +} + +function calculateRequiredBytes ( + transformCount: number, + metaValueCount: number, + capacity: number, +) { + return (TransformArray.BYTES_PER_ELEMENT * transformCount + + Float64Array.BYTES_PER_ELEMENT * metaValueCount) * capacity; +} + +const PAGE_SIZE = calculateRequiredBytes(128, 10, 4); + +const globalPosePageMemoryAllocatorManager = new SharedStackBasedAllocatorManager([ + PAGE_SIZE, +]); diff --git a/cocos/animation/core/pose.ts b/cocos/animation/core/pose.ts new file mode 100644 index 00000000000..11b9f4450cb --- /dev/null +++ b/cocos/animation/core/pose.ts @@ -0,0 +1,210 @@ +import { DEBUG } from 'internal:constants'; +import { lerp } from '../../core'; +import { assertIsTrue } from '../../core/data/utils/asserts'; +import { Transform, __applyDeltaTransform, __calculateDeltaTransform } from './transform'; +import { TransformArray } from './transform-array'; + +export class Pose { + readonly transforms: TransformArray; + + readonly metaValues: Float64Array; + + private constructor (transforms: TransformArray, metaValues: Float64Array) { + this.transforms = transforms; + this.metaValues = metaValues; + } + + /** + * @internal + */ + public static _create (transforms: TransformArray, metaValues: Float64Array) { + return new Pose(transforms, metaValues); + } +} + +export class TransformFilter { + constructor (involvedTransforms: readonly number[]) { + if (DEBUG) { + assertIsTrue( + involvedTransforms.every((transformIndex) => transformIndex < (2 ** 16)), + 'The number of transforms exceeds the max allowed(2 ** 16)', + ); + } + this._involvedTransforms = new Uint16Array(involvedTransforms); + } + + get involvedTransforms () { + return this._involvedTransforms as Readonly; + } + + /** + * ANOTHER IDEA: if we partition the indices into intervals, + * can we achieve a better performance when do transform copy? + * + * For example: let every two elements of this array represents + * an involved transform range: first index and end index. + * For example, [1, 3, 4, 5, 5, 10] denotes the transform indices: + * - [1, 3) i.e indices 1, 2 + * - [4, 5) i.e indices 4 + * - [5, 10) i.e indices 5, 6, 7, 8, 9 + * Its length always be multiple of 2. + * + * Obviously, the actual optimization effect is decided by the sparsity of the indices. + * + * ```ts + * // Partition the ordered array in intervals. + * let nIntervals = 0; + * const intervals = new Uint32Array(involvedTransforms.length * 2); // Capacity, not size + * for (let iBegin = 0; iBegin < involvedTransforms.length;) { + * const begin = involvedTransforms[iBegin]; + * let iEnd = iBegin + 1; + * let end = begin + 1; + * for (; iEnd < involvedTransforms.length; ++iEnd, ++end) { + * if (intervals[iEnd] !== (end + 1)) { + * break; + * } + * } + * intervals[2 * nIntervals + 0] = begin; + * intervals[2 * nIntervals + 1] = end; + * ++nIntervals; + * } + * + * this._involvedTransformIntervals = intervals.slice(0, nIntervals * 2); + * ``` + */ + private declare _involvedTransforms: Uint16Array; +} + +export function blendPoseInto (target: Pose, source: Readonly, alpha: number, transformFilter: TransformFilter | undefined = undefined) { + blendTransformsInto(target.transforms, source.transforms, alpha, transformFilter); + blendMetaValuesInto(target.metaValues, source.metaValues, alpha); +} + +export function blendTransformsInto ( + target: TransformArray, + source: Readonly, + alpha: number, + transformFilter: TransformFilter | undefined = undefined, +) { + const nTransforms = target.length; + assertIsTrue(nTransforms === target.length); + if (alpha === 0) { + return; + } else if (alpha === 1) { + if (!transformFilter) { + target.set(source); + } else { + copyTransformsWithFilter(target, source, transformFilter); + } + return; + } + if (!transformFilter) { + // Fast path. + for (let iTransform = 0; iTransform < nTransforms; ++iTransform) { + blendIntoTransformArrayAt(target, source, alpha, iTransform); + } + } else { + for (const involvedTransformIndex of transformFilter.involvedTransforms) { + blendIntoTransformArrayAt(target, source, alpha, involvedTransformIndex); + } + } +} + +function copyTransformsWithFilter (target: TransformArray, source: Readonly, filter: TransformFilter) { + const nTransforms = target.length; + assertIsTrue(nTransforms === target.length); + for (const involvedTransformIndex of filter.involvedTransforms) { + target.copyRange(involvedTransformIndex, source, involvedTransformIndex, 1); + } +} + +const blendIntoTransformArrayAt = (() => { + const cacheTransformSource = new Transform(); + const cacheTransformTarget = new Transform(); + return (target: TransformArray, source: Readonly, alpha: number, transformIndex: number) => { + const transformTarget = target.getTransform(transformIndex, cacheTransformTarget); + const transformSource = source.getTransform(transformIndex, cacheTransformSource); + Transform.lerp(transformTarget, transformTarget, transformSource, alpha); + target.setTransform(transformIndex, transformTarget); + }; +})(); + +export function blendMetaValuesInto (target: Float64Array, source: Readonly, alpha: number) { + const nValues = source.length; + assertIsTrue(nValues === target.length); + for (let iValue = 0; iValue < nValues; ++iValue) { + target[iValue] = lerp(target[iValue], source[iValue], alpha); + } +} + +export function calculateDeltaPose (target: Pose, base: Pose) { + calculateDeltaTransforms(target.transforms, base.transforms); + calculateDeltaMetaValues(target.metaValues, base.metaValues); +} + +const calculateDeltaTransformArrayAt = (() => { + const cacheTransformBase = new Transform(); + const cacheTransformTarget = new Transform(); + return (target: TransformArray, base: Readonly, transformIndex: number) => { + const baseTransform = base.getTransform(transformIndex, cacheTransformBase); + const targetTransform = target.getTransform(transformIndex, cacheTransformTarget); + __calculateDeltaTransform(targetTransform, targetTransform, baseTransform); + target.setTransform(transformIndex, targetTransform); + }; +})(); + +export function calculateDeltaTransforms (target: TransformArray, base: TransformArray) { + const nTransforms = target.length; + assertIsTrue(nTransforms === base.length); + for (let iTransform = 0; iTransform < nTransforms; ++iTransform) { + calculateDeltaTransformArrayAt(target, base, iTransform); + } +} + +export function calculateDeltaMetaValues (target: Float64Array, base: Float64Array) { + const nMetaValues = target.length; + assertIsTrue(nMetaValues === base.length); + for (let i = 0; i < target.length; ++i) { + target[i] -= base[i]; + } +} + +export function applyDeltaPose (target: Pose, base: Pose, alpha: number, transformFilter: TransformFilter | undefined = undefined) { + applyDeltaTransforms(target.transforms, base.transforms, alpha, transformFilter); + applyDeltaMetaValues(target.metaValues, base.metaValues, alpha); +} + +const applyDeltaTransformArrayAt = (() => { + const cacheTransformDelta = new Transform(); + const cacheTransformTarget = new Transform(); + return (target: TransformArray, delta: Readonly, alpha: number, transformIndex: number) => { + const deltaTransform = delta.getTransform(transformIndex, cacheTransformDelta); + const targetTransform = target.getTransform(transformIndex, cacheTransformTarget); + __applyDeltaTransform(targetTransform, targetTransform, deltaTransform, alpha); + target.setTransform(transformIndex, targetTransform); + }; +})(); + +export function applyDeltaTransforms ( + target: TransformArray, delta: TransformArray, alpha: number, transformFilter: TransformFilter | undefined = undefined, +) { + const nTransforms = target.length; + assertIsTrue(nTransforms === delta.length); + if (!transformFilter) { + for (let iTransform = 0; iTransform < nTransforms; ++iTransform) { + applyDeltaTransformArrayAt(target, delta, alpha, iTransform); + } + } else { + for (const transformIndex of transformFilter.involvedTransforms) { + applyDeltaTransformArrayAt(target, delta, alpha, transformIndex); + } + } +} + +export function applyDeltaMetaValues (target: Float64Array, delta: Float64Array, alpha: number) { + const nMetaValues = target.length; + assertIsTrue(nMetaValues === delta.length); + for (let i = 0; i < target.length; ++i) { + target[i] += delta[i] * alpha; + } +} diff --git a/cocos/animation/core/shared-stack-based-allocator.ts b/cocos/animation/core/shared-stack-based-allocator.ts new file mode 100644 index 00000000000..857e935bc17 --- /dev/null +++ b/cocos/animation/core/shared-stack-based-allocator.ts @@ -0,0 +1,299 @@ +import { DEBUG, TEST } from 'internal:constants'; +import { assertIsTrue, binarySearchEpsilon } from '../../core'; + +const allocatorPageCountTag = Symbol(DEBUG ? '[[The count of pages used by this allocator.]]' : ''); + +const onStackPurgedTag = Symbol(DEBUG ? `[[Notify that theres is no allocator on the stack anymore.]]` : ''); + +class SharedMemoryPage { + constructor (byteLength: number) { + this.buffer = new ArrayBuffer(byteLength); + } + + public readonly buffer: ArrayBuffer; + + public useCount = 0; +} + +class PagedStack { + constructor (private _manager: SharedStackBasedAllocatorManager, private _pageSize: number) { + } + + get pageSize () { + return this._pageSize; + } + + get debugLocking () { + return this._locking; + } + + public get allocatorCount () { + return this._allocatorCount; + } + + public debugLock () { + assertIsTrue(!this._locking, `The memory is locking.`); + this._locking = true; + } + + public debugUnlock () { + assertIsTrue(this._locking, `Wrong execution logic: the memory is not locking.`); + this._locking = false; + } + + public getPageMemory (index: number) { + assertIsTrue(index >= 0 && index < this._pages.length, `Page index out of range`); + return this._pages[index].buffer; + } + + public pushPage (allocator: SharedStackBasedAllocator): SharedMemoryPage { + const oldAllocatorPageCount = allocator[allocatorPageCountTag]; + + assertIsTrue(oldAllocatorPageCount <= this._pages.length); + if (oldAllocatorPageCount === this._pages.length) { + this._pushNewPage(); + } + assertIsTrue(oldAllocatorPageCount < this._pages.length); + + const page = this._pages[oldAllocatorPageCount]; + ++page.useCount; + ++allocator[allocatorPageCountTag]; + + return page; + } + + public popPage (allocator: SharedStackBasedAllocator) { + const allocatorPageCount = allocator[allocatorPageCountTag]; + assertIsTrue(allocatorPageCount > 0); + const allocatorLastPageIndex = allocatorPageCount - 1; + const lastPage = this._pages[allocatorLastPageIndex]; + assertIsTrue(lastPage.useCount > 0); + + --lastPage.useCount; + --allocator[allocatorPageCountTag]; + + // If the page has no users, remove it. + if (lastPage.useCount === 0) { + // "The page has no users" also means that it's the last page in our list. + assertIsTrue(allocatorLastPageIndex === this._pages.length - 1); + this._pages.pop(); + } + } + + public createAllocator (sliceSize: number) { + const allocator = new SharedStackBasedAllocator(this, sliceSize); + ++this._allocatorCount; + return allocator; + } + + public destroyAllocator (allocator: SharedStackBasedAllocator) { + // Decrease use count of all pages used by the allocator. + const allocatorPageCount = allocator[allocatorPageCountTag]; + for (let iPage = 0; iPage < allocatorPageCount; ++iPage) { + const page = this._pages[iPage]; + assertIsTrue(page.useCount > 0); + --page.useCount; + } + + assertIsTrue(this._allocatorCount > 0); + --this._allocatorCount; + + // If we no longer have allocator, notify manager for possible further cleanup. + if (this._allocatorCount === 0) { + this._manager[onStackPurgedTag](this); + } + } + + private _locking = false; + + private _pages: SharedMemoryPage[] = []; + private _allocatorCount = 0; + + private _pushNewPage () { + const newPage = new SharedMemoryPage(this._pageSize); + this._pages.push(newPage); + } +} + +class SharedMemorySlice { + constructor ( + public readonly buffer: ArrayBuffer, + public readonly byteOffset: number, + ) { + } +} + +/** + * Dev note: + * - `push()` do create new object(SharedMemorySlice) and do array push-back, no caching. + * - `pop()` do array pop-back. + */ +class SharedStackBasedAllocator { + [allocatorPageCountTag] = 0; + + constructor ( + private _resource: PagedStack, + private _sliceSize: number, + ) { + const slicesPerPage = Math.floor(this._resource.pageSize / _sliceSize); + assertIsTrue(slicesPerPage > 0); + this._slicesPerPage = slicesPerPage; + } + + public get isEmpty () { + return this._slices.length === 0; + } + + public destroy () { + assertIsTrue(this._slices.length === 0, `Can not destroy the allocator since it's not empty.`); + assertIsTrue(!this._resource.debugLocking, `Can not destroy the allocator since it's locking.`); + + this._resource.destroyAllocator(this); + } + + public debugLock () { + this._resource.debugLock(); + } + + public debugUnlock () { + this._resource.debugUnlock(); + } + + public push (): SharedMemorySlice { + const { + _sliceSize: sliceLength, + _slices: slices, + _slicesPerPage: slicesPerPage, + } = this; + + const desiredSliceIndex = slices.length; + + let newSliceIndexInPage = 0; + let newSlicePageIndex = 0; + + // Specially handle 0 slice length. + if (sliceLength === 0) { + // If the slice length is 0, we ensure this allocator has and has only one page. + // All slices use this page then. + if (this[allocatorPageCountTag] === 0) { + this._resource.pushPage(this); + } + assertIsTrue(this[allocatorPageCountTag] === 1); + } else { + const capacity = slicesPerPage * this[allocatorPageCountTag]; + assertIsTrue(desiredSliceIndex <= capacity); + if (desiredSliceIndex === capacity) { + // We need more pages. + this._resource.pushPage(this); + assertIsTrue(desiredSliceIndex < slicesPerPage * this[allocatorPageCountTag]); + } + + newSliceIndexInPage = desiredSliceIndex % slicesPerPage; + newSlicePageIndex = (desiredSliceIndex - newSliceIndexInPage) / slicesPerPage; + assertIsTrue(this[allocatorPageCountTag] * slicesPerPage >= desiredSliceIndex); + } + + const pageMemory = this._resource.getPageMemory(newSlicePageIndex); + const newSlice = new SharedMemorySlice( + pageMemory, + sliceLength * newSliceIndexInPage, + ); + this._slices.push(newSlice); + return newSlice; + } + + public pop () { + const { + _slices: slices, + _slicesPerPage: slicesPerPage, + } = this; + + const allocatedCount = slices.length; + assertIsTrue(allocatedCount > 0); + + const removingSliceIndex = allocatedCount - 1; + if (this._sliceSize === 0) { + // If the slice length is 0, we should pop page if we're popping the last slice, + // it's the only page in this allocator. + assertIsTrue(this[allocatorPageCountTag] === 1); + if (removingSliceIndex === 0) { + this._resource.popPage(this); + } + } else { + const removingSliceIndexInPage = removingSliceIndex % slicesPerPage; + if (removingSliceIndexInPage === 0) { + // Now that the last(beginning) slice of last page is pop-ed, + // we pop the last page. + this._resource.popPage(this); + } + } + + this._slices.pop(); + } + + private _slicesPerPage = 0; + + private _slices: SharedMemorySlice[] = []; +} + +export class SharedStackBasedAllocatorManager { + constructor (private _thresholds: number[]) { + assertIsTrue(_thresholds.every((v, i, arr) => i === 0 || v > arr[i - 1])); + } + + public get isEmpty () { + return this._stacks.size === 0; + } + + public createAllocator (pageSize: number): SharedStackBasedAllocator { + const allocationPageSize = pageSize; + + // Select stack page size according to allocation page size and threshold. + const stackPageSize = this._selectStackPageSize(allocationPageSize); + + // Get or create stack. + let stack = this._stacks.get(stackPageSize); + if (!stack) { + stack = new PagedStack(this, stackPageSize); + this._stacks.set(stackPageSize, stack); + } + + // Create the allocator. + return stack.createAllocator(allocationPageSize); + } + + public [onStackPurgedTag] (stack: PagedStack) { + let stackFound = false; + for (const [k, v] of this._stacks) { + if (v === stack) { + this._stacks.delete(k); + stackFound = true; + break; + } + } + if (!stackFound) { + assertIsTrue(false, `Given allocator is not of mime.`); + } + } + + private _stacks = new Map(); + + private _selectStackPageSize (allocationPageSize: number) { + let thresholdIndex = binarySearchEpsilon(this._thresholds, allocationPageSize); + let stackPageSize = allocationPageSize; + if (thresholdIndex >= 0) { + stackPageSize = this._thresholds[thresholdIndex]; + } else { + thresholdIndex = ~thresholdIndex; + if (thresholdIndex === this._thresholds.length) { + // If stack beyonds the max threshold, no shared. + } else { + assertIsTrue(thresholdIndex >= 0 && thresholdIndex < this._thresholds.length); + stackPageSize = this._thresholds[thresholdIndex]; + } + } + return stackPageSize; + } +} + +export type { SharedStackBasedAllocator }; diff --git a/cocos/animation/core/transform-array.ts b/cocos/animation/core/transform-array.ts new file mode 100644 index 00000000000..8b3e815d7a9 --- /dev/null +++ b/cocos/animation/core/transform-array.ts @@ -0,0 +1,227 @@ +import { Vec3 } from '../../core/math/vec3'; +import { Quat } from '../../core/math/quat'; +import { Transform } from './transform'; + +const TRANSFORM_STRIDE_IN_FLOATS = 10; + +const TRANSFORM_STRIDE_IN_BYTES = Float64Array.BYTES_PER_ELEMENT * TRANSFORM_STRIDE_IN_FLOATS; + +const ROTATION_OFFSET = 3; + +const SCALE_OFFSET = ROTATION_OFFSET + 4; + +/** + * Array-buffer-based transform array. + */ +export class TransformArray { + public static get BYTES_PER_ELEMENT () { + return TRANSFORM_STRIDE_IN_BYTES; + } + + constructor (length?: number); + + constructor (buffer: ArrayBuffer, byteOffset?: number, length?: number); + + constructor (bufferOrLength?: number | ArrayBuffer, byteOffset?: number, length_?: number) { + if (typeof bufferOrLength === 'undefined') { + this._data = new Float64Array(); + } else if (typeof bufferOrLength === 'number') { + this._data = new Float64Array(TRANSFORM_STRIDE_IN_FLOATS * bufferOrLength); + } else { + this._data = new Float64Array( + bufferOrLength, + byteOffset, + typeof length_ === 'number' ? TRANSFORM_STRIDE_IN_FLOATS * length_ : undefined, + ); + } + } + + get buffer () { + return this._data.buffer; + } + + get byteLength () { + return this._data.byteLength; + } + + get byteOffset () { + return this._data.byteOffset; + } + + get length () { + return this._data.length / TRANSFORM_STRIDE_IN_FLOATS; + } + + public getTransform (index: number, out: Transform) { + const { + _data: data, + } = this; + const { + position, + rotation, + scale, + } = out; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Vec3.fromArray(position, data, baseOffset); + Quat.fromArray(rotation, data, baseOffset + ROTATION_OFFSET); + Vec3.fromArray(scale, data, baseOffset + SCALE_OFFSET); + return out; + } + + public getPosition (index: number, out: Vec3) { + const { + _data: data, + } = this; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Vec3.fromArray(out, data, baseOffset); + return out; + } + + public getRotation (index: number, out: Quat) { + const { + _data: data, + } = this; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Quat.fromArray(out, data, baseOffset + ROTATION_OFFSET); + return out; + } + + public getScale (index: number, out: Vec3) { + const { + _data: data, + } = this; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Vec3.fromArray(out, data, baseOffset + SCALE_OFFSET); + return out; + } + + public setTransform (index: number, value: Readonly) { + const { + _data: data, + } = this; + const { + position, + rotation, + scale, + } = value; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Vec3.toArray(data, position, baseOffset); + Quat.toArray(data, rotation, baseOffset + ROTATION_OFFSET); + Vec3.toArray(data, scale, baseOffset + SCALE_OFFSET); + } + + public setPosition (index: number, value: Readonly) { + const { + _data: data, + } = this; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Vec3.toArray(data, value, baseOffset); + } + + public setRotation (index: number, value: Readonly) { + const { + _data: data, + } = this; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Quat.toArray(data, value, baseOffset + ROTATION_OFFSET); + } + + public setScale (index: number, value: Readonly) { + const { + _data: data, + } = this; + const baseOffset = TRANSFORM_STRIDE_IN_FLOATS * index; + Vec3.toArray(data, value, baseOffset + SCALE_OFFSET); + } + + /** + * Same algorithm as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin + * except for the the operating objects are transforms. + */ + public copyWithin (target: number, start: number, end?: number) { + this._data.copyWithin( + target * TRANSFORM_STRIDE_IN_FLOATS, + start * TRANSFORM_STRIDE_IN_FLOATS, + typeof end === 'number' ? end * TRANSFORM_STRIDE_IN_FLOATS : undefined, + ); + } + + /** + * Same algorithm as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/fill + * except for the the operating objects are transforms. + */ + public fill (value: Readonly, start?: number, end?: number) { + const { length } = this; + start ??= 0; + end ??= length; + if (start >= length) { + return; + } + this.setTransform(start, value); + for (let i = start + 1; i < end; ++i) { + this.copyWithin(i, start, start + 1); + } + } + + /** + * Same as `this.fill(Transform.ZERO, start, end)`. + */ + public fillZero (start?: number, end?: number) { + this._data.fill( + 0.0, + typeof start === 'number' ? start * TRANSFORM_STRIDE_IN_FLOATS : undefined, + typeof end === 'number' ? end * TRANSFORM_STRIDE_IN_FLOATS : undefined, + ); + } + + /** + * Same algorithm as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set + * except for: + * - the the operating objects are transforms, + * - plain array is not allowed. + */ + public set (transformArray: Readonly, targetOffset?: number) { + this._data.set( + (transformArray as TransformArray)._data, + typeof targetOffset === 'number' ? targetOffset * TRANSFORM_STRIDE_IN_FLOATS : undefined, + ); + } + + /** + * Same algorithm as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice + * except for the the operating objects are transforms. + */ + public slice (start?: number, end?: number) { + const dataSliced = this._data.slice( + typeof start === 'number' ? start * TRANSFORM_STRIDE_IN_FLOATS : undefined, + typeof end === 'number' ? end * TRANSFORM_STRIDE_IN_FLOATS : undefined, + ); + return new TransformArray(dataSliced.buffer, dataSliced.byteOffset, dataSliced.length / TRANSFORM_STRIDE_IN_FLOATS); + } + + /** + * Copy a span of `source` into `this`. + * Equivalent to `this.set(source.slice(sourceOffset, sourceOffset + size), targetOffset)` + * except without perform the slicing. + * */ + public copyRange ( + targetOffset: number, + source: Readonly, + sourceOffset: number, + size: number, + ) { + const sizeInFloats = TRANSFORM_STRIDE_IN_FLOATS * size; + + const targetFloats = this._data; + const targetStartInFloats = TRANSFORM_STRIDE_IN_FLOATS * targetOffset; + + const sourceFloats = (source as TransformArray)._data; + const sourceStartInFloats = TRANSFORM_STRIDE_IN_FLOATS * sourceOffset; + + for (let i = 0; i < sizeInFloats; ++i) { + targetFloats[targetStartInFloats + i] = sourceFloats[sourceStartInFloats + i]; + } + } + + private _data: Float64Array; +} diff --git a/cocos/animation/core/transform.ts b/cocos/animation/core/transform.ts new file mode 100644 index 00000000000..fdfd048dc43 --- /dev/null +++ b/cocos/animation/core/transform.ts @@ -0,0 +1,236 @@ +import { Vec3 } from '../../core/math/vec3'; +import { Quat } from '../../core/math/quat'; +import { EPSILON, Mat4 } from '../../core'; + +const CACHE_VECTOR_A = new Vec3(); +const CACHE_VECTOR_B = new Vec3(); +const CACHE_QUAT_A = new Quat(); +const CACHE_QUAT_B = new Quat(); + +// Can not use `Readonly`. +// See: https://github.com/microsoft/TypeScript/issues/50668 +type ReadonlyTransform = Transform; + +export class Transform { + public static IDENTITY = Object.freeze(new Transform()); + + public static ZERO = Object.freeze((() => { + const transform = new Transform(); + Vec3.copy(transform._position, Vec3.ZERO); + Quat.set(transform._rotation, 0.0, 0.0, 0.0, 0.0); + Vec3.copy(transform._scale, Vec3.ZERO); + return transform; + })()); + + get position (): Readonly { + return this._position; + } + + set position (value) { + Vec3.copy(this._position, value); + } + + get rotation (): Readonly { + return this._rotation; + } + + set rotation (value) { + Quat.copy(this._rotation, value); + } + + get scale (): Readonly { + return this._scale; + } + + set scale (value) { + Vec3.copy(this._scale, value); + } + + public static clone (src: ReadonlyTransform) { + const transform = new Transform(); + Transform.copy(transform, src); + return transform; + } + + public static setIdentity (out: Transform) { + Vec3.copy(out._position, Vec3.ZERO); + Quat.copy(out._rotation, Quat.IDENTITY); + Vec3.copy(out._scale, Vec3.ONE); + return out; + } + + public static copy (out: Transform, src: ReadonlyTransform) { + Vec3.copy(out._position, src._position); + Quat.copy(out._rotation, src._rotation); + Vec3.copy(out._scale, src._scale); + return out; + } + + public static equals (a: ReadonlyTransform, b: ReadonlyTransform, epsilon?: number) { + return Vec3.equals(a._position, b._position, epsilon) + && Quat.equals(a._rotation, b._rotation, epsilon) + && Vec3.equals(a._scale, b._scale, epsilon); + } + + public static strictEquals (a: ReadonlyTransform, b: ReadonlyTransform) { + return Vec3.strictEquals(a._position, b._position) + && Quat.strictEquals(a._rotation, b._rotation) + && Vec3.strictEquals(a._scale, b._scale); + } + + public static lerp (out: Transform, from: ReadonlyTransform, to: ReadonlyTransform, t: number) { + if (t === 0.0) { + return Transform.copy(out, from); + } + if (t === 1.0) { + return Transform.copy(out, to); + } + Vec3.lerp(out._position, from._position, to._position, t); + Quat.slerp(out._rotation, from._rotation, to._rotation, t); + Vec3.lerp(out._scale, from._scale, to._scale, t); + return out; + } + + /** + * Associate two transforms. + * The result is as if the `first` transform is applied and then the `second` transform. + * @param out The result transform. + * @param first The first transform to apply. + * @param second The second transform to apply. + * @returns `out`. + * @note + * Much important things to note is that + * currently the following prerequisites are imposed on scales of both transforms: + * - The scale should be uniformed, ie. all components should be the same. + * - Each component of the scale shall be non-negative. + */ + public static multiply (out: Transform, first: ReadonlyTransform, second: ReadonlyTransform) { + // May reference to https://zhuanlan.zhihu.com/p/119066087 + // for the reason about restrictions on uniform scales. + + const cacheRotation = Quat.multiply(CACHE_QUAT_A, second._rotation, first._rotation); + + const cacheScale = Vec3.multiply(CACHE_VECTOR_A, first._scale, second._scale); + + // T_p + (R_p * (S_p * T_c)) + const cachePosition = Vec3.multiply(CACHE_VECTOR_B, first._position, second._scale); + Vec3.transformQuat(cachePosition, cachePosition, second._rotation); + Vec3.add(cachePosition, cachePosition, second._position); + + Vec3.copy(out._position, cachePosition); + Quat.copy(out._rotation, cacheRotation); + Vec3.copy(out._scale, cacheScale); + + return out; + } + + /** + * Calculates the relative transitions. + * The result is as if `first` transform is associated by applying the result first then the `second`. + * @param out The result transform. + * @param first See description. + * @param second See description. + * @returns `out`. + * @note + * + * Note: if scale of second transform contains 0, + * the result scale's corresponding component would be error. + * + * Same restriction is applied to this method like `Transform.multiply`. + */ + public static calculateRelative = (() => { + const cacheInvRotation = new Quat(); + const cacheInvScale = new Vec3(); + return (out: Transform, first: ReadonlyTransform, second: ReadonlyTransform) => { + const invSecondRotation = Quat.invert(cacheInvRotation, second._rotation); + const invScale = invScaleOrZero(cacheInvScale, second._scale, EPSILON); + + // The inverse process of `T_p + (R_p * (S_p * T_c))` + const cachePosition = Vec3.subtract(CACHE_VECTOR_B, first._position, second._position); + Vec3.transformQuat(cachePosition, cachePosition, invSecondRotation); + Vec3.multiply(cachePosition, cachePosition, invScale); + + Vec3.copy(out._position, cachePosition); + Quat.multiply(out._rotation, invSecondRotation, first._rotation); + Vec3.multiply(out._scale, first._scale, invScale); + + return out; + }; + })(); + + public static fromMatrix (out: Transform, matrix: Readonly) { + Mat4.toRTS( + matrix, + out._rotation, + out._position, + out._scale, + ); + return out; + } + + public static toMatrix (out: Mat4, transform: ReadonlyTransform) { + return Mat4.fromRTS( + out, + transform._rotation, + transform._position, + transform._scale, + ); + } + + private readonly _position = new Vec3(); + + private readonly _rotation = new Quat(); + + private readonly _scale = Vec3.clone(Vec3.ONE); +} + +/** + * Invert each component of scale if it isn't close to zero, or set it to zero otherwise. + */ +function invScaleOrZero (out: Vec3, scale: Readonly, epsilon: number) { + const { x, y, z } = scale; + return Vec3.set( + out, + Math.abs(x) <= epsilon ? 0.0 : 1.0 / x, + Math.abs(y) <= epsilon ? 0.0 : 1.0 / y, + Math.abs(z) <= epsilon ? 0.0 : 1.0 / z, + ); +} + +export function __calculateDeltaTransform (out: Transform, target: Readonly, base: Readonly) { + Vec3.subtract(out.position, target.position, base.position); + deltaQuat(out.rotation, base.rotation, target.rotation); + Vec3.subtract(out.scale, target.scale, base.scale); +} + +export const __applyDeltaTransform = (() => { + const cacheQuat = new Quat(); + return (out: Transform, base: Readonly, delta: Readonly, alpha: number) => { + Vec3.scaleAndAdd(out.position, base.position, delta.position, alpha); + const weightedDeltaRotation = Quat.slerp(cacheQuat, Quat.IDENTITY, delta.rotation, alpha); + Quat.multiply(out.rotation, weightedDeltaRotation, base.rotation); + Vec3.scaleAndAdd(out.scale, base.scale, delta.scale, alpha); + }; +})(); + +/** + * Calculates the delta(relative) rotations between two rotations represented by quaternions. + * @param out + * @param from + * @param to + */ +const deltaQuat = (() => { + const quatMultiInvInverseCache = new Quat(); + return (out: Quat, from: Quat, to: Quat) => { + const fromInv = Quat.invert(quatMultiInvInverseCache, from); + return Quat.multiply(out, to, fromInv); + }; +})(); + +export const ZERO_DELTA_TRANSFORM = Object.freeze((() => { + const transform = new Transform(); + transform.position = Vec3.ZERO; + transform.rotation = Quat.IDENTITY; + transform.scale = Vec3.ZERO; + return transform; +})()); diff --git a/cocos/animation/cross-fade.ts b/cocos/animation/cross-fade.ts index c7dd55ac482..0276134c3ef 100644 --- a/cocos/animation/cross-fade.ts +++ b/cocos/animation/cross-fade.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { clamp01 } from '../core/math/utils'; -import { remove } from '../core/utils/array'; +import { clamp01, js } from '../core'; import { AnimationState } from './animation-state'; import { Playable } from './playable'; import { getGlobalAnimationManager } from './global-animation-manager'; @@ -212,7 +210,7 @@ export class CrossFade extends Playable { if (deadFading.target.state) { deadFading.target.state.stop(); } - remove(this._managedStates, deadFading.target); + js.array.remove(this._managedStates, deadFading.target); } } fadings.splice(deadFadingBegin); diff --git a/cocos/animation/cubic-spline-value.ts b/cocos/animation/cubic-spline-value.ts index fef026ab3a1..e79e61bd835 100644 --- a/cocos/animation/cubic-spline-value.ts +++ b/cocos/animation/cubic-spline-value.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; -import { Quat, Vec2, Vec3, Vec4 } from '../core/math'; +import { Quat, Vec2, Vec3, Vec4 } from '../core'; import { ILerpable } from './types'; interface ICubicSplineValue extends ILerpable { diff --git a/cocos/animation/define.ts b/cocos/animation/define.ts index 4d3e9946e3d..08fd22069ae 100644 --- a/cocos/animation/define.ts +++ b/cocos/animation/define.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export const CLASS_NAME_PREFIX_ANIM = 'cc.animation.'; export const createEvalSymbol = Symbol('CreateEval'); diff --git a/cocos/animation/embedded-player/embedded-animation-clip-player.ts b/cocos/animation/embedded-player/embedded-animation-clip-player.ts index 00a8bc3fd8d..8129163ea66 100644 --- a/cocos/animation/embedded-player/embedded-animation-clip-player.ts +++ b/cocos/animation/embedded-player/embedded-animation-clip-player.ts @@ -1,5 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; -import { errorID } from '../../core/platform/debug'; +import { errorID } from '../../core'; import type { Node } from '../../scene-graph/node'; import { AnimationClip } from '../animation-clip'; import { AnimationState } from '../animation-state'; diff --git a/cocos/animation/embedded-player/embedded-particle-system-player.ts b/cocos/animation/embedded-player/embedded-particle-system-player.ts index eab1fa0f8a8..95c064d3c30 100644 --- a/cocos/animation/embedded-player/embedded-particle-system-player.ts +++ b/cocos/animation/embedded-player/embedded-particle-system-player.ts @@ -1,8 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; import type { ParticleSystem } from '../../particle'; -import { warn } from '../../core/platform/debug'; +import { warn, js } from '../../core'; import type { Node } from '../../scene-graph/node'; -import { getClassByName } from '../../core/utils/js-typed'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { EmbeddedPlayableState, EmbeddedPlayable } from './embedded-player'; @@ -30,7 +53,7 @@ export class EmbeddedParticleSystemPlayable extends EmbeddedPlayable { return null; } // TODO: we shouldn't wanna know the name of `ParticleSystem` indeed. - const ParticleSystemConstructor = getClassByName(`cc.ParticleSystem`) as Constructor | undefined; + const ParticleSystemConstructor = js.getClassByName(`cc.ParticleSystem`) as Constructor | undefined; if (!ParticleSystemConstructor) { warn(`Particle system is required for embedded particle system player.`); return null; diff --git a/cocos/animation/embedded-player/embedded-player.ts b/cocos/animation/embedded-player/embedded-player.ts index 6779451c6b8..b82766acd2c 100644 --- a/cocos/animation/embedded-player/embedded-player.ts +++ b/cocos/animation/embedded-player/embedded-player.ts @@ -1,5 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; -import { EditorExtendable } from '../../core/data/editor-extendable'; +import { EditorExtendable } from '../../core'; import type { Node } from '../../scene-graph'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; diff --git a/cocos/animation/exotic-animation/exotic-animation.ts b/cocos/animation/exotic-animation/exotic-animation.ts index 3fb6678d683..21314ad5320 100644 --- a/cocos/animation/exotic-animation/exotic-animation.ts +++ b/cocos/animation/exotic-animation/exotic-animation.ts @@ -1,13 +1,40 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR, TEST } from 'internal:constants'; -import { binarySearchEpsilon } from '../../core/algorithm/binary-search'; -import { ccclass, serializable } from '../../core/data/decorators'; +import { binarySearchEpsilon, clamp, lerp, Quat, Vec3, _decorator } from '../../core'; import { assertIsTrue } from '../../core/data/utils/asserts'; -import { clamp, lerp, Quat, Vec3 } from '../../core/math'; +import { AnimationClipGraphBindingContext } from '../marionette/animation-graph-animation-clip-binding'; +import { TransformHandle } from '../core/animation-handle'; +import { Pose } from '../core/pose'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { Binder, RuntimeBinding, TrackBinding, TrackPath } from '../tracks/track'; const SPLIT_METHOD_ENABLED = TEST || EDITOR; +const { ccclass, serializable } = _decorator; + function throwIfSplitMethodIsNotValid (): never { // TODO: better handling throw new Error(`split() only valid in Editor.`); @@ -26,6 +53,10 @@ export class ExoticAnimation { return new ExoticTrsAnimationEvaluator(this._nodeAnimations, binder); } + public createEvaluatorForAnimationGraph (context: AnimationClipGraphBindingContext) { + return new ExoticTrsAGEvaluation(this._nodeAnimations, context); + } + public addNodeAnimation (path: string) { const nodeAnimation = new ExoticNodeAnimation(path); this._nodeAnimations.push(nodeAnimation); @@ -87,6 +118,19 @@ class ExoticNodeAnimation { ); } + public createEvaluatorForAnimationGraph (context: AnimationClipGraphBindingContext) { + const transformHandle = context.bindTransform(this._path); + if (!transformHandle) { + return null; + } + return new ExoticNodeAnimationAGEvaluation( + transformHandle, + this._position, + this._rotation, + this._scale, + ); + } + public split (from: number, to: number, splitInfoCache: SplitInfo) { if (!SPLIT_METHOD_ENABLED) { return throwIfSplitMethodIsNotValid(); @@ -681,6 +725,90 @@ interface ExoticTrackEvaluationRecord { evaluator: ExoticTrackEvaluator; } +/** + * Exotic TRS animation graph evaluator. + */ +export class ExoticTrsAGEvaluation { + constructor (nodeAnimations: ExoticNodeAnimation[], context: AnimationClipGraphBindingContext) { + this._nodeEvaluations = nodeAnimations.map( + (nodeAnimation) => nodeAnimation.createEvaluatorForAnimationGraph(context), + ).filter((x) => !!x) as ExoticNodeAnimationAGEvaluation[]; + } + + public destroy () { + const { _nodeEvaluations: nodeEvaluations } = this; + const nNodeEvaluations = nodeEvaluations.length; + for (let iNodeEvaluation = 0; iNodeEvaluation < nNodeEvaluations; ++iNodeEvaluation) { + nodeEvaluations[iNodeEvaluation].destroy(); + } + } + + public evaluate (time: number, pose: Pose) { + const { _nodeEvaluations: nodeEvaluations } = this; + const nNodeEvaluations = nodeEvaluations.length; + for (let iNodeEvaluation = 0; iNodeEvaluation < nNodeEvaluations; ++iNodeEvaluation) { + nodeEvaluations[iNodeEvaluation].evaluate(time, pose); + } + } + + private _nodeEvaluations: ExoticNodeAnimationAGEvaluation[]; +} + +class ExoticNodeAnimationAGEvaluation { + constructor ( + transformHandle: TransformHandle, + position: ExoticVec3Track | null, + rotation: ExoticQuatTrack | null, + scale: ExoticVec3Track | null, + ) { + this._transformHandle = transformHandle; + if (position) { + this._position = new ExoticTrackEvaluator(position.times, position.values, Vec3); + } + if (rotation) { + this._rotation = new ExoticTrackEvaluator(rotation.times, rotation.values, Quat); + } + if (scale) { + this._scale = new ExoticTrackEvaluator(scale.times, scale.values, Vec3); + } + } + + public destroy () { + this._transformHandle.destroy(); + } + + public evaluate (time: number, pose: Pose) { + const { + _transformHandle: { + index: transformIndex, + }, + _position: position, + _rotation: rotation, + _scale: scale, + } = this; + const { + transforms: poseTransforms, + } = pose; + if (position) { + const value = position.evaluate(time); + poseTransforms.setPosition(transformIndex, value); + } + if (rotation) { + const rotationAbs = rotation.evaluate(time); + poseTransforms.setRotation(transformIndex, rotationAbs); + } + if (scale) { + const value = scale.evaluate(time); + poseTransforms.setScale(transformIndex, value); + } + } + + private _position: ExoticTrackEvaluator | null = null; + private _rotation: ExoticTrackEvaluator | null = null; + private _scale: ExoticTrackEvaluator | null = null; + private _transformHandle: TransformHandle; +} + interface InputSampleResult { just: boolean; index: number; diff --git a/cocos/animation/global-animation-manager.ts b/cocos/animation/global-animation-manager.ts index 525f100b6aa..839d834bc43 100644 --- a/cocos/animation/global-animation-manager.ts +++ b/cocos/animation/global-animation-manager.ts @@ -1,7 +1,31 @@ -import { legacyCC } from '../core/global-exports'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { cclegacy } from '../core'; import type { AnimationManager } from './animation-manager'; export function getGlobalAnimationManager () { - const animationManager = legacyCC.director.getAnimationManager() as AnimationManager; + const animationManager = cclegacy.director.getAnimationManager() as AnimationManager; return animationManager; } diff --git a/cocos/animation/index.ts b/cocos/animation/index.ts index 2d43a256796..3459dba706a 100644 --- a/cocos/animation/index.ts +++ b/cocos/animation/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import * as animation from './animation'; diff --git a/cocos/animation/internal-symbols.ts b/cocos/animation/internal-symbols.ts index 37aa2847753..32122fcacba 100644 --- a/cocos/animation/internal-symbols.ts +++ b/cocos/animation/internal-symbols.ts @@ -1,2 +1,26 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export const BAKE_SKELETON_CURVE_SYMBOL = Symbol('BakeNodeCurves'); diff --git a/cocos/animation/kinematics/ccd.ts b/cocos/animation/kinematics/ccd.ts index 335ead5177d..4bd4b66c246 100644 --- a/cocos/animation/kinematics/ccd.ts +++ b/cocos/animation/kinematics/ccd.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { assertIsTrue } from '../../data/utils/asserts'; import { Quat } from '../../math/quat'; diff --git a/cocos/animation/legacy-clip-data.ts b/cocos/animation/legacy-clip-data.ts index 710d4975506..48d2efd7df4 100644 --- a/cocos/animation/legacy-clip-data.ts +++ b/cocos/animation/legacy-clip-data.ts @@ -1,23 +1,41 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ComponentPath, HierarchyPath, TargetPath } from './target-path'; import { IValueProxyFactory } from './value-proxy'; -import * as easing from '../core/algorithm/easing'; -import { BezierControlPoints } from '../core/curves/bezier'; -import { CompactValueTypeArray } from '../core/data/utils/compact-value-type-array'; +import { easing, QuatCurve, QuatInterpolationMode, RealCurve, RealInterpolationMode, RealKeyframeValue, TangentWeightMode, + warnID, Color, Quat, Size, Vec2, Vec3, Vec4, assertIsTrue, EasingMethod, BezierControlPoints, CompactValueTypeArray } from '../core'; import { AnimCurve, RatioSampler } from './animation-curve'; -import { QuatCurve, QuatInterpolationMode, RealCurve, RealInterpolationMode, RealKeyframeValue, TangentWeightMode } from '../core/curves'; -import { assertIsTrue } from '../core/data/utils/asserts'; import { Track, TrackPath } from './tracks/track'; import { UntypedTrack } from './tracks/untyped-track'; -import { warnID } from '../core/platform'; import { RealTrack } from './tracks/real-track'; -import { Color, Quat, Size, Vec2, Vec3, Vec4 } from '../core/math'; import { CubicSplineNumberValue, CubicSplineQuatValue, CubicSplineVec2Value, CubicSplineVec3Value, CubicSplineVec4Value } from './cubic-spline-value'; import { ColorTrack } from './tracks/color-track'; import { VectorTrack } from './tracks/vector-track'; import { QuatTrack } from './tracks/quat-track'; import { ObjectTrack } from './tracks/object-track'; import { SizeTrack } from './tracks/size-track'; -import { EasingMethod } from '../core/curves/curve'; /** * 表示曲线值,曲线值可以是任意类型,但必须符合插值方式的要求。 diff --git a/cocos/animation/marionette/__tmp__/graph-description.ts b/cocos/animation/marionette/__tmp__/graph-description.ts index 74a4240d0dc..e368fc7813b 100644 --- a/cocos/animation/marionette/__tmp__/graph-description.ts +++ b/cocos/animation/marionette/__tmp__/graph-description.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export interface GraphDescription { vars?: Array<{ name: string; diff --git a/cocos/animation/marionette/__tmp__/graph-from-description.ts b/cocos/animation/marionette/__tmp__/graph-from-description.ts index eda785fcfbf..9c68c8a9cb4 100644 --- a/cocos/animation/marionette/__tmp__/graph-from-description.ts +++ b/cocos/animation/marionette/__tmp__/graph-from-description.ts @@ -1,4 +1,28 @@ -import { Vec2 } from '../../../core/math/vec2'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Vec2 } from '../../../core'; import { AnimationGraph, State, StateMachine, AnimationTransition } from '../animation-graph'; import { Condition, BinaryCondition, TriggerCondition, UnaryCondition } from '../condition'; import { ClipMotion } from '../clip-motion'; diff --git a/cocos/animation/marionette/animation-blend-1d.ts b/cocos/animation/marionette/animation-blend-1d.ts index ddf972252c0..a54a9a3c103 100644 --- a/cocos/animation/marionette/animation-blend-1d.ts +++ b/cocos/animation/marionette/animation-blend-1d.ts @@ -1,11 +1,38 @@ -import { serializable } from 'cc.decorator'; -import { ccclass } from '../../core/data/class-decorator'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { _decorator } from '../../core'; import { createEval } from './create-eval'; import { BindableNumber, bindOr, VariableType } from './parametric'; import { MotionEvalContext } from './motion'; import { AnimationBlend, AnimationBlendEval, AnimationBlendItem } from './animation-blend'; import { blend1D } from './blend-1d'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; +import { AnimationGraphLayerWideBindingContext } from './animation-graph-context'; +import { ReadonlyClipOverrideMap } from './graph-eval'; + +const { ccclass, serializable } = _decorator; @ccclass(`${CLASS_NAME_PREFIX_ANIM}AnimationBlend1DItem`) class AnimationBlend1DItem extends AnimationBlendItem { @@ -14,12 +41,12 @@ class AnimationBlend1DItem extends AnimationBlendItem { public clone () { const that = new AnimationBlend1DItem(); - this._assign(that); + this._copyTo(that); return that; } - protected _assign (that: AnimationBlend1DItem) { - super._assign(that); + protected _copyTo (that: AnimationBlend1DItem) { + super._copyTo(that); that.threshold = this.threshold; return that; } @@ -46,15 +73,18 @@ export class AnimationBlend1D extends AnimationBlend { public clone () { const that = new AnimationBlend1D(); + this.copyTo(that); that._items = this._items.map((item) => item.clone()); that.param = this.param.clone(); return that; } - public [createEval] (context: MotionEvalContext) { - const evaluation = new AnimationBlend1DEval(context, this, this._items, this._items.map(({ threshold }) => threshold), 0.0); + public [createEval] (context: AnimationGraphLayerWideBindingContext, clipOverrides: ReadonlyClipOverrideMap | null) { + const evaluation = new AnimationBlend1DEval( + context, clipOverrides, this, this._items, this._items.map(({ threshold }) => threshold), 0.0, + ); const initialValue = bindOr( - context, + context.outerContext, this.param, VariableType.FLOAT, evaluation.setInput, @@ -73,8 +103,12 @@ export declare namespace AnimationBlend1D { class AnimationBlend1DEval extends AnimationBlendEval { private declare _thresholds: readonly number[]; - constructor (context: MotionEvalContext, base: AnimationBlend, items: AnimationBlendItem[], thresholds: readonly number[], input: number) { - super(context, base, items, [input]); + constructor ( + context: AnimationGraphLayerWideBindingContext, + overrides: ReadonlyClipOverrideMap | null, + base: AnimationBlend, items: AnimationBlendItem[], thresholds: readonly number[], input: number, + ) { + super(context, overrides, base, items, [input]); this._thresholds = thresholds; this.doEval(); } diff --git a/cocos/animation/marionette/animation-blend-2d.ts b/cocos/animation/marionette/animation-blend-2d.ts index e0b4c477348..99386116019 100644 --- a/cocos/animation/marionette/animation-blend-2d.ts +++ b/cocos/animation/marionette/animation-blend-2d.ts @@ -1,13 +1,38 @@ -import { Vec2 } from '../../core/math'; -import { ccclass } from '../../core/data/class-decorator'; -import { ccenum } from '../../core/value-types/enum'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Vec2, _decorator, ccenum } from '../../core'; import { createEval } from './create-eval'; import { AnimationBlend, AnimationBlendEval, AnimationBlendItem } from './animation-blend'; import { MotionEvalContext } from './motion'; -import { serializable } from '../../core/data/decorators'; import { BindableNumber, bindOr, VariableType } from './parametric'; import { sampleFreeformCartesian, sampleFreeformDirectional, blendSimpleDirectional } from './blend-2d'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; +import { AnimationGraphLayerWideBindingContext } from './animation-graph-context'; +import { ReadonlyClipOverrideMap } from './graph-eval'; + +const { ccclass, serializable } = _decorator; enum Algorithm { SIMPLE_DIRECTIONAL, @@ -24,12 +49,12 @@ class AnimationBlend2DItem extends AnimationBlendItem { public clone () { const that = new AnimationBlend2DItem(); - this._assign(that); + this._copyTo(that); return that; } - protected _assign (that: AnimationBlend2DItem) { - super._assign(that); + protected _copyTo (that: AnimationBlend2DItem) { + super._copyTo(that); Vec2.copy(that.threshold, this.threshold); return that; } @@ -63,15 +88,17 @@ export class AnimationBlend2D extends AnimationBlend { public clone () { const that = new AnimationBlend2D(); + this.copyTo(that); that._items = this._items.map((item) => item?.clone() ?? null); that.paramX = this.paramX.clone(); that.paramY = this.paramY.clone(); return that; } - public [createEval] (context: MotionEvalContext) { + public [createEval] (context: AnimationGraphLayerWideBindingContext, clipOverrides: ReadonlyClipOverrideMap | null) { const evaluation = new AnimationBlend2DEval( context, + clipOverrides, this, this._items, this._items.map(({ threshold }) => threshold), @@ -79,7 +106,7 @@ export class AnimationBlend2D extends AnimationBlend { [0.0, 0.0], ); const initialValueX = bindOr( - context, + context.outerContext, this.paramX, VariableType.FLOAT, evaluation.setInput, @@ -87,7 +114,7 @@ export class AnimationBlend2D extends AnimationBlend { 0, ); const initialValueY = bindOr( - context, + context.outerContext, this.paramY, VariableType.FLOAT, evaluation.setInput, @@ -112,14 +139,15 @@ class AnimationBlend2DEval extends AnimationBlendEval { private _value = new Vec2(); constructor ( - context: MotionEvalContext, + context: AnimationGraphLayerWideBindingContext, + clipOverrides: ReadonlyClipOverrideMap | null, base: AnimationBlend, items: AnimationBlendItem[], thresholds: readonly Vec2[], algorithm: Algorithm, inputs: [number, number], ) { - super(context, base, items, inputs); + super(context, clipOverrides, base, items, inputs); this._thresholds = thresholds; this._algorithm = algorithm; this.doEval(); diff --git a/cocos/animation/marionette/animation-blend-direct.ts b/cocos/animation/marionette/animation-blend-direct.ts index d27e4547dbd..00b412af163 100644 --- a/cocos/animation/marionette/animation-blend-direct.ts +++ b/cocos/animation/marionette/animation-blend-direct.ts @@ -1,23 +1,51 @@ -import { serializable } from 'cc.decorator'; -import { ccclass } from '../../core/data/class-decorator'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { _decorator } from '../../core'; import { createEval } from './create-eval'; import { MotionEvalContext } from './motion'; import { AnimationBlend, AnimationBlendEval, AnimationBlendItem } from './animation-blend'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; +import { AnimationGraphLayerWideBindingContext } from './animation-graph-context'; +import { ReadonlyClipOverrideMap } from './graph-eval'; +import { BindableNumber, bindOr, VariableType } from './parametric'; + +const { ccclass, serializable } = _decorator; @ccclass(`${CLASS_NAME_PREFIX_ANIM}AnimationBlendDirectItem`) class AnimationBlendDirectItem extends AnimationBlendItem { @serializable - public weight = 0.0; + public weight = new BindableNumber(0.0); public clone () { const that = new AnimationBlendDirectItem(); - this._assign(that); + this._copyTo(that); return that; } - protected _assign (that: AnimationBlendDirectItem) { - super._assign(that); + protected _copyTo (that: AnimationBlendDirectItem) { + super._copyTo(that); that.weight = this.weight; return that; } @@ -40,17 +68,31 @@ export class AnimationBlendDirect extends AnimationBlend { public clone () { const that = new AnimationBlendDirect(); + this.copyTo(that); that._items = this._items.map((item) => item?.clone() ?? null); return that; } - public [createEval] (context: MotionEvalContext) { - const myEval = new AnimationBlendDirectEval( + public [createEval] (context: AnimationGraphLayerWideBindingContext, clipOverrides: ReadonlyClipOverrideMap | null) { + const myEval: AnimationBlendDirectEval = new AnimationBlendDirectEval( context, + clipOverrides, this, this._items, - this._items.map(({ weight }) => weight), + new Array(this._items.length).fill(0.0), ); + for (let iItem = 0; iItem < this._items.length; ++iItem) { + const item = this._items[iItem]; + const initialValue = bindOr( + context.outerContext, + item.weight, + VariableType.FLOAT, + myEval.setInput, + myEval, + iItem, + ); + myEval.setInput(initialValue, iItem); + } return myEval; } } diff --git a/cocos/animation/marionette/animation-blend.ts b/cocos/animation/marionette/animation-blend.ts index bf2bdccbeeb..5265fd0b926 100644 --- a/cocos/animation/marionette/animation-blend.ts +++ b/cocos/animation/marionette/animation-blend.ts @@ -1,15 +1,43 @@ -import { ccclass } from '../../core/data/class-decorator'; -import { MotionEvalContext, Motion, MotionEval } from './motion'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { _decorator, EditorExtendable, editorExtrasTag } from '../../core'; +import { MotionEvalContext, Motion, MotionEval, MotionPort } from './motion'; import { createEval } from './create-eval'; import { VariableTypeMismatchedError } from './errors'; -import { serializable } from '../../core/data/decorators'; -import { ClipStatus } from './graph-eval'; -import { EditorExtendable } from '../../core/data/editor-extendable'; +import { ReadonlyClipOverrideMap, ClipStatus } from './graph-eval'; + import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { getMotionRuntimeID, RUNTIME_ID_ENABLED } from './graph-debug'; +import { cloneAnimationGraphEditorExtrasFrom } from './animation-graph-editor-extras-clone-helper'; +import { AnimationGraphEvaluationContext, AnimationGraphLayerWideBindingContext } from './animation-graph-context'; +import { blendPoseInto, Pose } from '../core/pose'; + +const { ccclass, serializable } = _decorator; export interface AnimationBlend extends Motion, EditorExtendable { - [createEval] (_context: MotionEvalContext): MotionEval | null; + [createEval] (_context: AnimationGraphLayerWideBindingContext, overrides: ReadonlyClipOverrideMap | null): MotionEval | null; } @ccclass(`${CLASS_NAME_PREFIX_ANIM}AnimationBlendItem`) @@ -19,11 +47,11 @@ export class AnimationBlendItem { public clone () { const that = new AnimationBlendItem(); - this._assign(that); + this._copyTo(that); return that; } - protected _assign (that: AnimationBlendItem) { + protected _copyTo (that: AnimationBlendItem) { that.motion = this.motion?.clone() ?? null; return that; } @@ -33,6 +61,11 @@ export class AnimationBlendItem { export class AnimationBlend extends EditorExtendable implements Motion { @serializable name = ''; + + public copyTo (that: AnimationBlend) { + that.name = this.name; + that[editorExtrasTag] = cloneAnimationGraphEditorExtrasFrom(this); + } } export class AnimationBlendEval implements MotionEval { @@ -43,12 +76,13 @@ export class AnimationBlendEval implements MotionEval { private declare _inputs: number[]; constructor ( - context: MotionEvalContext, + context: AnimationGraphLayerWideBindingContext, + overrides: ReadonlyClipOverrideMap | null, base: AnimationBlend, children: AnimationBlendItem[], inputs: number[], ) { - this._childEvaluators = children.map((child) => child.motion?.[createEval](context) ?? null); + this._childEvaluators = children.map((child) => child.motion?.[createEval](context, overrides) ?? null); this._weights = new Array(this._childEvaluators.length).fill(0); this._inputs = [...inputs]; if (RUNTIME_ID_ENABLED) { @@ -56,6 +90,13 @@ export class AnimationBlendEval implements MotionEval { } } + public createPort (): MotionPort { + return new AnimationBlendPort( + this, + this._childEvaluators.map((childEval) => childEval?.createPort() ?? null), + ); + } + get childCount () { return this._weights.length; } @@ -103,9 +144,39 @@ export class AnimationBlendEval implements MotionEval { }; } - public sample (progress: number, weight: number) { + public __evaluatePort (port: AnimationBlendPort, progress: number, context: AnimationGraphEvaluationContext): Pose { + const nChild = this._childEvaluators.length; + let sumWeight = 0.0; + let finalPose: Pose | null = null; + for (let iChild = 0; iChild < nChild; ++iChild) { + const childWeight = this._weights[iChild]; + if (!childWeight) { + continue; + } + const childOutput = port.childPorts[iChild]?.evaluate(progress, context); + if (!childOutput) { + continue; + } + sumWeight += childWeight; + if (!finalPose) { + finalPose = childOutput; + } else { + if (sumWeight) { + const t = childWeight / sumWeight; + blendPoseInto(finalPose, childOutput, t); + } + context.popPose(); + } + } + if (finalPose) { + return finalPose; + } + return context.pushDefaultedPose(); + } + + public overrideClips (overrides: ReadonlyClipOverrideMap, context: AnimationGraphLayerWideBindingContext): void { for (let iChild = 0; iChild < this._childEvaluators.length; ++iChild) { - this._childEvaluators[iChild]?.sample(progress, weight * this._weights[iChild]); + this._childEvaluators[iChild]?.overrideClips(overrides, context); } } @@ -123,6 +194,21 @@ export class AnimationBlendEval implements MotionEval { } } +class AnimationBlendPort implements MotionPort { + constructor (host: AnimationBlendEval, childPorts: readonly (MotionPort | null)[]) { + this._host = host; + this.childPorts = childPorts; + } + + public childPorts: readonly (MotionPort | null)[] = []; + + public evaluate (progress: number, context: AnimationGraphEvaluationContext): Pose { + return this._host.__evaluatePort(this, progress, context); + } + + private _host: AnimationBlendEval; +} + export function validateBlendParam (val: unknown, name: string): asserts val is number { if (typeof val !== 'number') { // TODO var name? diff --git a/cocos/animation/marionette/animation-controller.ts b/cocos/animation/marionette/animation-controller.ts index 571d9eaecba..cfc770980d4 100644 --- a/cocos/animation/marionette/animation-controller.ts +++ b/cocos/animation/marionette/animation-controller.ts @@ -1,16 +1,44 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { Component } from '../../scene-graph/component'; import { AnimationGraph } from './animation-graph'; import type { AnimationGraphRunTime } from './animation-graph'; -import { property, ccclass, menu } from '../../core/data/class-decorator'; +import { _decorator, assertIsNonNullable, assertIsTrue } from '../../core'; import { AnimationGraphEval } from './graph-eval'; -import type { MotionStateStatus, TransitionStatus, ClipStatus } from './graph-eval'; +import type { MotionStateStatus, TransitionStatus, ClipStatus, ReadonlyClipOverrideMap } from './graph-eval'; import { Value } from './variable'; -import { assertIsNonNullable } from '../../core/data/utils/asserts'; +import { AnimationGraphVariant, AnimationGraphVariantRunTime } from './animation-graph-variant'; +import { AnimationGraphLike } from './animation-graph-like'; + +const { ccclass, menu, property } = _decorator; export type { MotionStateStatus, ClipStatus, TransitionStatus, + ReadonlyClipOverrideMap, }; /** @@ -32,17 +60,44 @@ export class AnimationController extends Component { * @en * The animation graph associated with the animation controller. */ - @property(AnimationGraph) - public graph: AnimationGraphRunTime | null = null; + @property(AnimationGraphLike) + public graph: AnimationGraphRunTime | AnimationGraphVariantRunTime | null = null; private _graphEval: AnimationGraphEval | null = null; + /** + * @zh 获取动画图的层级数量。如果控制器没有指定动画图,则返回 0。 + * @en Gets the count of layers in the animation graph. + * If no animation graph is specified, 0 is returned. + */ + public get layerCount () { + return this._graphEval?.layerCount ?? 0; + } + public __preload () { - if (this.graph) { - this._graphEval = new AnimationGraphEval(this.graph as AnimationGraph, this.node, this); + const { graph } = this; + if (graph) { + let originalGraph: AnimationGraph; + let clipOverrides: ReadonlyClipOverrideMap | null = null; + if (graph instanceof AnimationGraphVariant) { + if (!graph.original) { + return; + } + originalGraph = graph.original; + clipOverrides = graph.clipOverrides; + } else { + assertIsTrue(graph instanceof AnimationGraph); + originalGraph = graph; + } + const graphEval = new AnimationGraphEval(originalGraph, this.node, this, clipOverrides); + this._graphEval = graphEval; } } + public onDestroy () { + this._graphEval?.destroy(); + } + public update (deltaTime: number) { this._graphEval?.update(deltaTime); } @@ -98,8 +153,8 @@ export class AnimationController extends Component { * @zh 获取动画图实例中当前状态的运行状况。 * @en Gets the running status of the current state in the animation graph instance. * @param layer @en Index of the layer. @zh 层级索引。 - * @returns @en The running status of the current state. - * @zh 当前的状态运作状态对象。 + * @returns @en The running status of the current state. `null` is returned if current state is not a motion state. + * @zh 当前的状态运作状态对象。如果当前的状态不是动作状态,则返回 `null`。 */ public getCurrentStateStatus (layer: number) { const { _graphEval: graphEval } = this; @@ -112,7 +167,8 @@ export class AnimationController extends Component { * @en Gets the running status of all the animation clips added on the current state in the animation graph instance. * @param layer @en Index of the layer. @zh 层级索引。 * @returns @en Iterable to the animation clip statuses on current state. - * @zh 到动画剪辑运作状态的迭代器。 + * An empty iterable is returned if current state is not a motion state. + * @zh 到动画剪辑运作状态的迭代器。若当前状态不是动画状态,则返回一个空的迭代器。 */ public getCurrentClipStatuses (layer: number) { const { _graphEval: graphEval } = this; @@ -137,8 +193,8 @@ export class AnimationController extends Component { * @zh 获取动画图实例中下一个状态的运行状况。 * @en Gets the running status of the next state in the animation graph instance. * @param layer @en Index of the layer. @zh 层级索引。 - * @returns @en The running status of the next state. `null` is returned in case of no transition. - * @zh 下一状态运作状态对象,若未在进行过渡,则返回 `null`。 + * @returns @en The running status of the next state. `null` is returned in case of no transition or if next state is not a motion state. + * @zh 下一状态运作状态对象,若未在进行过渡或下一状态不是动画状态,则返回 `null`。 */ public getNextStateStatus (layer: number) { const { _graphEval: graphEval } = this; @@ -150,8 +206,9 @@ export class AnimationController extends Component { * @zh 获取动画图实例中下一个状态上添加的所有动画剪辑的运行状况。 * @en Gets the running status of all the animation clips added on the next state in the animation graph instance. * @param layer @en Index of the layer. @zh 层级索引。 - * @returns @en Iterable to the animation clip statuses on next state. An empty iterable is returned in case of no transition. - * @zh 到下一状态上包含的动画剪辑运作状态的迭代器,若未在进行过渡,则返回一个空的迭代器。 + * @returns @en Iterable to the animation clip statuses on next state. + * An empty iterable is returned in case of no transition or next state is not a motion state. + * @zh 到下一状态上包含的动画剪辑运作状态的迭代器,若未在进行过渡或下一状态不是动画状态,则返回一个空的迭代器。 */ public getNextClipStatuses (layer: number) { const { _graphEval: graphEval } = this; @@ -180,4 +237,32 @@ export class AnimationController extends Component { assertIsNonNullable(graphEval); return graphEval.setLayerWeight(layer, weight); } + + /** + * @zh 覆盖动画图实例中的动画剪辑。 + * 对于每一对源剪辑、目标剪辑, + * 动画图(实例)中的出现的所有源剪辑都会被替换为目标剪辑,就好像动画图中一开始就使用的是目标剪辑。 + * 不过,动画图当前的运转状态会依然保持不变,例如: + * + * - 若动作状态涉及的动画剪辑被替换,动作状态的播放进度百分比依然保持不变。 + * + * - 若过渡的周期是相对的,即使在某一刻动画过渡的源头被替换,那么过渡的进度百分比也依然保持不变。 + * + * 不管进行多少次覆盖,源剪辑应该一直指定为原始动画图中的动画剪辑。例如: + * + * ```ts + * // `originalClip` 是原始动画图中的剪辑对象,第一次希望将原剪辑覆盖为 `newClip1`,第二次希望将原剪辑覆盖为 `newClip2` + * animationController.overrideClips_experimental(new Map([ [originalClip, newClip1] ])); // 第一次覆盖 + * animationController.overrideClips_experimental(new Map([ [newClip1, newClip2] ])); // 错误:第二次覆盖 + * animationController.overrideClips_experimental(new Map([ [originalClip, newClip2] ])); // 正确:第二次覆盖 + * ``` + * @en Overrides the animation clips in animation graph instance. + * TODO + * @experimental + */ + public overrideClips_experimental (overrides: ReadonlyClipOverrideMap) { + const { _graphEval: graphEval } = this; + assertIsNonNullable(graphEval); + graphEval.overrideClips(overrides); + } } diff --git a/cocos/animation/marionette/animation-graph-animation-clip-binding.ts b/cocos/animation/marionette/animation-graph-animation-clip-binding.ts new file mode 100644 index 00000000000..45cee04d7f5 --- /dev/null +++ b/cocos/animation/marionette/animation-graph-animation-clip-binding.ts @@ -0,0 +1,354 @@ +import { DEBUG } from 'internal:constants'; +import { error, Quat, Vec3, warnID } from '../../core'; +import { assertIsTrue } from '../../core/data/utils/asserts'; +import { Node } from '../../scene-graph/node'; +import { AnimationClip, exoticAnimationTag } from '../animation-clip'; +import { TransformHandle } from '../core/animation-handle'; +import { Pose } from '../core/pose'; +import { createEvalSymbol } from '../define'; +import { ExoticTrsAGEvaluation } from '../exotic-animation/exotic-animation'; +import { isTrsPropertyName, normalizedFollowTag, Track, TrackBinding, trackBindingTag, TrackEval } from '../tracks/track'; +import { UntypedTrack } from '../tracks/untyped-track'; + +/** + * This module contains utilities to marry animation clip with animation graph. + * + * A typical workflow is: + * + * At initial, an animation clip is bound to animation graph in `AnimationClipGraphBindingContext`, + * an `AnimationClipAGEvaluation` is created after this phase to track the evaluation. + * + * Then at each frame, `AnimationClipAGEvaluation.evaluate()` is called, + * passed with the current `AnimationClipGraphEvaluationContext`. + * The evaluation context gives the pose that need to be filled, + * then animation clip emplaces sampled animation data into the pose. + */ + +/** + * The context in which animation clips can be bound in an animation graph. + */ +export interface AnimationClipGraphBindingContext { + /** + * The root node. This should be the animation controller's host node. + */ + origin: Node; + + /** + * Binds a scene node transform into animation graph. + * @param path Path to the scene node from `origin`. + * @returns The transform handle if successfully bound, `null` otherwise. + */ + bindTransform(path: string): TransformHandle | null; +} + +/** + * The context in which animation clips can evaluate during animation graph evaluation. + * Currently, the context is just the output pose. + */ +export type AnimationClipGraphEvaluationContext = Pose; + +/** + * A pose binding describes how to get/set part of a bound transform in animation graph. + * The `T` can be `Vec3`, `Quat` for now. + */ +export interface PoseBinding { + /** + * Destroys this binding. + */ + destroy(): void; + + /** + * Sets the part's value. + * @param value The value. + * @param pose The pose. + */ + setValue(value: T, pose: Pose): void; + + /** + * Reads the part's value. + * @param pose The pose. + */ + getValue(pose: Pose): Readonly; +} + +const CACHE_VEC3_GET_VALUE = new Vec3(); + +const CACHE_QUAT_GET_VALUE = new Quat(); + +/** + * The pose binding base is base class of all pose binding classes. + * It holds a transform handle. + */ +class PoseBindingBase { + constructor (transformHandle: TransformHandle) { + this._transformHandle = transformHandle; + } + + /** + * Releases the held transform handle. + */ + public destroy () { + this._transformHandle.destroy(); + } + + /** + * The held transform handle. + */ + protected declare readonly _transformHandle: TransformHandle; +} + +/** + * The pose position binding describes how to get/set the position of a bound transform in animation graph. + */ +class PosePositionBinding extends PoseBindingBase implements PoseBinding { + public setValue (value: Vec3, pose: Pose): void { + pose.transforms.setPosition(this._transformHandle.index, value); + } + + public getValue (pose: Pose) { + return pose.transforms.getPosition(this._transformHandle.index, CACHE_VEC3_GET_VALUE) as Readonly; + } +} + +/** + * The pose rotation binding describes how to get/set the rotation(in quaternion) of a bound transform in animation graph. + */ +class PoseRotationBinding extends PoseBindingBase implements PoseBinding { + public setValue (value: Quat, pose: Pose): void { + pose.transforms.setRotation(this._transformHandle.index, value); + } + + public getValue (pose: Pose) { + return pose.transforms.getRotation(this._transformHandle.index, CACHE_QUAT_GET_VALUE) as Readonly; + } +} + +/** + * The pose euler angles binding describes how to get/set the rotation(in euler angles) of a bound transform in animation graph. + */ +class PoseEulerAnglesBinding extends PoseBindingBase implements PoseBinding { + public setValue (value: Vec3, pose: Pose): void { + const quat = Quat.fromEuler(PoseEulerAnglesBinding._EULER_TO_QUAT_CACHE, value.x, value.y, value.z); + pose.transforms.setRotation(this._transformHandle.index, quat); + } + + public getValue (pose: Pose) { + const q = pose.transforms.getRotation(this._transformHandle.index, CACHE_QUAT_GET_VALUE) as Readonly; + return Quat.toEuler(CACHE_VEC3_GET_VALUE, q) as Readonly; + } + + private static _EULER_TO_QUAT_CACHE = new Quat(); +} + +/** + * The pose euler scale binding describes how to get/set the scale of a bound transform in animation graph. + */ +class PoseScaleBinding extends PoseBindingBase implements PoseBinding { + public setValue (value: Vec3, pose: Pose): void { + pose.transforms.setScale(this._transformHandle.index, value); + } + + public getValue (pose: Pose) { + return pose.transforms.getScale(this._transformHandle.index, CACHE_VEC3_GET_VALUE) as Readonly; + } +} + +/** + * Creates a corresponding pose binding. + * @param transformHandle Handle to the transform. + * @param propertyKey Indicates the binding type. + * @returns The pose binding. + */ +// eslint-disable-next-line consistent-return +function bindPoseTransform ( + transformHandle: TransformHandle, + propertyKey: 'position' | 'rotation' | 'scale' | 'eulerAngles', +): PoseBinding { + switch (propertyKey) { + case 'position': + return new PosePositionBinding(transformHandle); + case 'rotation': + return new PoseRotationBinding(transformHandle); + case 'eulerAngles': + return new PoseEulerAnglesBinding(transformHandle); + case 'scale': + return new PoseScaleBinding(transformHandle); + default: + assertIsTrue(false); + } +} + +/** + * Describes the evaluation of a animation clip track in sense of animation graph. + */ +class AGTrackEvaluation { + constructor (binding: PoseBinding, trackEvaluation: TrackEval) { + this._binding = binding; + this._trackSampler = trackEvaluation; + } + + public destroy () { + this._binding.destroy(); + } + + public evaluate (time: number, pose: Pose) { + const { _trackSampler: trackSampler, _binding: binding } = this; + const defaultValue = /* binding.getValue && */trackSampler.requiresDefault + ? binding.getValue(pose) as TValue extends unknown ? unknown : TValue + : undefined; + const value = trackSampler.evaluate(time, defaultValue); + binding.setValue(value, pose); + } + + private _binding: PoseBinding; + private _trackSampler: TrackEval; +} + +function bindTrackAG (animationClip: AnimationClip, track: Track, bindContext: AnimationClipGraphBindingContext) { + const trackBinding = track[trackBindingTag]; + const trackTarget = createRuntimeBindingAG(trackBinding, bindContext); + if (DEBUG && !trackTarget) { + // If we got a null track target here, we should already have warn logged, + // To elaborate on error details, we warn here as well. + // Note: if in the future this log appears alone, + // it must be a BUG which break promise by above statement. + warnID( + 3937, + animationClip.name, + bindContext.origin.name, + ); + } + return trackTarget ?? undefined; +} + +function createRuntimeBindingAG (track: TrackBinding, bindContext: AnimationClipGraphBindingContext) { + const { + origin, + } = bindContext; + const { path, proxy } = track; + const nPaths = path.length; + const iLastPath = nPaths - 1; + + if (nPaths !== 0 && (path.isPropertyAt(iLastPath) || path.isElementAt(iLastPath)) && !proxy) { + const lastPropertyKey = path.isPropertyAt(iLastPath) + ? path.parsePropertyAt(iLastPath) + : path.parseElementAt(iLastPath); + const resultTarget = path[normalizedFollowTag](origin, 0, nPaths - 1); + if (resultTarget === null) { + return null; + } + + if (resultTarget instanceof Node && isTrsPropertyName(lastPropertyKey)) { + const transformPath = (() => { + const segments = [] as string[]; + let node: Node | null = resultTarget; + for (; node && node !== origin; node = node.parent) { + segments.unshift(node.name); + } + if (node === origin) { + return segments.join('/'); + } else { + return undefined; + } + })(); + if (typeof transformPath === 'string') { + const transformHandle = bindContext.bindTransform(transformPath); + if (!transformHandle) { + return undefined; + } + return bindPoseTransform(transformHandle, lastPropertyKey); + } + } + } + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // TODO: here should be resolved before this can be landed. + error(`Animation graph currently only supports (bone) transform animations.`); + return undefined; +} + +/** + * Describes the evaluation of a animation clip in sense of animation graph. + */ +export class AnimationClipAGEvaluation { + constructor ( + clip: AnimationClip, + context: AnimationClipGraphBindingContext, + ) { + clip._trySyncLegacyData(); + + const trackEvaluations: AGTrackEvaluation[] = []; + let exoticAnimationEvaluation: ExoticTrsAGEvaluation | undefined; + + const { + tracks, + [exoticAnimationTag]: exoticAnimation, + } = clip; + + for (const track of tracks) { + if (track instanceof UntypedTrack) { + // Untyped track is not supported in AG. + continue; + } + if (Array.from(track.channels()).every(({ curve }) => curve.keyFramesCount === 0)) { + continue; + } + const trackRuntimeBinding = bindTrackAG(clip, track, context); + if (!trackRuntimeBinding) { + continue; + } + const trackSampler = track[createEvalSymbol](); + const trackEvaluation = new AGTrackEvaluation(trackRuntimeBinding, trackSampler); + trackEvaluations.push(trackEvaluation); + } + + if (exoticAnimation) { + exoticAnimationEvaluation = exoticAnimation.createEvaluatorForAnimationGraph(context); + } + + this._trackEvaluations = trackEvaluations; + this._exoticAnimationEvaluation = exoticAnimationEvaluation; + } + + /** + * Destroys all the track evaluations and exotic animation evaluation. + */ + public destroy () { + this._exoticAnimationEvaluation?.destroy(); + + const { + _trackEvaluations: trackEvaluations, + } = this; + const nTrackEvaluations = trackEvaluations.length; + for (let iNodeEvaluation = 0; iNodeEvaluation < nTrackEvaluations; ++iNodeEvaluation) { + trackEvaluations[iNodeEvaluation].destroy(); + } + } + + /** + * Evaluates. + * @param time The time. + * @param context The evaluation context. + */ + public evaluate (time: number, context: AnimationClipGraphEvaluationContext) { + const { + _trackEvaluations: trackEvaluations, + _exoticAnimationEvaluation: exoticAnimationEvaluation, + } = this; + + const pose = context; + + const nTrackEvaluations = trackEvaluations.length; + for (let iNodeEvaluation = 0; iNodeEvaluation < nTrackEvaluations; ++iNodeEvaluation) { + trackEvaluations[iNodeEvaluation].evaluate(time, pose); + } + + if (exoticAnimationEvaluation) { + exoticAnimationEvaluation.evaluate(time, pose); + } + } + + private _trackEvaluations: AGTrackEvaluation[] = []; + + private _exoticAnimationEvaluation: ExoticTrsAGEvaluation | undefined; +} diff --git a/cocos/animation/marionette/animation-graph-context.ts b/cocos/animation/marionette/animation-graph-context.ts new file mode 100644 index 00000000000..5af67759936 --- /dev/null +++ b/cocos/animation/marionette/animation-graph-context.ts @@ -0,0 +1,560 @@ +import { DEBUG } from 'internal:constants'; +import { Node } from '../../scene-graph'; +import { assertIsTrue } from '../../core/data/utils/asserts'; +import { Pose, TransformFilter } from '../core/pose'; +import { PoseAllocator } from '../core/pose-allocator'; +import { TransformArray } from '../core/transform-array'; +import { TransformHandle, MetaValueHandle } from '../core/animation-handle'; +import { Transform, ZERO_DELTA_TRANSFORM } from '../core/transform'; +import { VarInstance } from './variable'; +import { AnimationMask } from './animation-mask'; +import { error } from '../../core'; +import { partition } from '../../core/algorithm/partition'; + +/** + * This module contains stuffs related to animation graph's evaluation. + * + * The typical workflow to setup a animation graph evaluation is: + * + * At binding phase: + * - Creates a `PoseLayoutMaintainer`. + * - Creates a `AnimationGraphBindingContext`, which collects animation bindings and report them to the `PoseLayoutMaintainer`. + * - Binding all portion of the animation graph under such a context. + * + * At each evaluation phase: + * - Creates a (or reuse a) `AnimationGraphEvaluationContext`. + * - Do the evaluation, generate a pose. + * - Call `PoseLayoutMaintainer.apply()` to apply the pose into scene graph. + * + * When an override-clip request is fired, the binding phase is performed again. + */ + +function findBoneByNameRecursively (from: Node, name: string): Node | null { + if (from.name === name) { + return from; + } + const nChildren = from.children.length; + for (let iChild = 0; iChild < nChildren; ++iChild) { + const found = findBoneByNameRecursively(from.children[iChild], name); + if (found) { + return found; + } + } + return null; +} + +/** + * The binding context of an animation graph in layer-wide. + */ +export interface AnimationGraphLayerWideBindingContext { + /** + * Indicates if the current layer is an additive layer. + */ + additive: boolean; + + /** + * The outer binding context. + */ + outerContext: AnimationGraphBindingContext; +} + +export type VarRegistry = Record; + +/** + * The binding context of an animation graph. + */ +export class AnimationGraphBindingContext { + constructor (origin: Node, poseLayoutMaintainer: AnimationGraphPoseLayoutMaintainer, varRegistry: VarRegistry) { + this._origin = origin; + this._layoutMaintainer = poseLayoutMaintainer; + this._varRegistry = varRegistry; + } + + get origin () { + return this._origin; + } + + public bindTransform (bone: string): TransformHandle | null { + const boneNode = this._origin.getChildByPath(bone); + if (!boneNode) { + return null; + } + return this._layoutMaintainer.getOrCreateTransformBinding(boneNode); + } + + public bindTransformByName (bone: string): TransformHandle | null { + const boneNode = findBoneByNameRecursively(this._origin, bone); + if (!boneNode) { + return null; + } + return this._layoutMaintainer.getOrCreateTransformBinding(boneNode); + } + + public getBoneChildren (bone: string): string[] { + const boneNode = findBoneByNameRecursively(this._origin, bone); + if (!boneNode) { + return []; + } + return boneNode.children.map((childNode) => childNode.name); + } + + public bineMetaValue (name: string): MetaValueHandle { + return this._layoutMaintainer.getOrCreateMetaValueBinding(name); + } + + public getVar (id: string): VarInstance | undefined { + return this._varRegistry[id]; + } + + private _origin: Node; + + private _layoutMaintainer: AnimationGraphPoseLayoutMaintainer; + + private _varRegistry: VarRegistry +} + +const cacheTransform = new Transform(); + +export class MetaValueRegistry { + public names () { + return this._namedCurves.keys(); + } + + public has (name: string) { + return this._namedCurves.has(name); + } + + public get (name: string) { + return this._namedCurves.get(name) ?? 0.0; + } + + public set (name: string, value: number) { + this._namedCurves.set(name, value); + } + + private _namedCurves: Map = new Map(); +} + +export enum LayoutChangeFlag { + /** + * If this flag is set, means the transform count and order has been changed. + */ + TRANSFORM_COUNT = 1, + + /** + * If this flag is set, means the transform count is not change but the order has been changed. + */ + TRANSFORM_ORDER = 2, + + /** + * If this flag is set, means the meta value count has been changed. + */ + META_VALUE_COUNT = 4, +} + +const checkBindStatus = (bindStarted = false): MethodDecorator => (_, _propertyKey, descriptor: TypedPropertyDescriptor) => { + if (!DEBUG) { + return; + } + + const vendor = descriptor.value; + if (vendor) { + // eslint-disable-next-line func-names + descriptor.value = function (this: { readonly _bindStarted: boolean }, ...args: unknown[]) { + assertIsTrue(this._bindStarted === bindStarted, + bindStarted + ? `The operation is invalid since bind has not been started.` + : `The operation is invalid since bind has already been started.`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return vendor.call(this, ...args); + }; + } +}; + +export class AnimationGraphPoseLayoutMaintainer { + constructor (metaValueRegistry: MetaValueRegistry) { + this._metaValueRegistry = metaValueRegistry; + } + + get transformCount () { + return this._transformRecords.length; + } + + get metaValueCount () { + return this._metaValueRecords.length; + } + + @checkBindStatus(true) + public getOrCreateTransformBinding (node: Node) { + const { _transformRecords: transformRecords } = this; + + const transformIndex = transformRecords.findIndex((transformRecord) => transformRecord.node === node); + if (transformIndex >= 0) { + const transformRecord = transformRecords[transformIndex]; + ++transformRecord.refCount; + return transformRecord.handle; + } + + // Ensure parent is preceding to children. + let newNodeIndex = 0; + for (let parent = node.parent; parent; parent = parent.parent) { + const parentIndex = transformRecords.findIndex((transformRecord) => transformRecord.node === parent); + if (parentIndex >= 0) { + newNodeIndex = parentIndex + 1; + break; + } + } + + // Update necessary bone handle. + for (let transformIndex = newNodeIndex; transformIndex < transformRecords.length; ++transformIndex) { + ++transformRecords[transformIndex].handle.index; + } + + // Insert new transform record. + const transformRecord = new TransformRecord( + new TransformHandleInternal(this, newNodeIndex), + node, + ); + transformRecords.splice(newNodeIndex, 0, transformRecord); + + return transformRecord.handle; + } + + @checkBindStatus(true) + public getOrCreateMetaValueBinding (name: string) { + const { _metaValueRecords: metaValueRecords } = this; + + const metaValueIndex = metaValueRecords.findIndex((record) => record.name === name); + if (metaValueIndex >= 0) { + const metaValueRecord = metaValueRecords[metaValueIndex]; + ++metaValueRecord.refCount; + return metaValueRecord.handle; + } else { + const newMetaValueIndex = metaValueRecords.length; + const metaValueRecord = new MetaValueRecord( + new MetaValueHandleInternal(this, newMetaValueIndex), + name, + ); + metaValueRecords.push(metaValueRecord); + return metaValueRecord.handle; + } + } + + public createTransformFilter (mask: Readonly, origin: Node) { + const involvedTransformIndices: number[] = []; + for (const { node, handle } of this._transformRecords) { + const path = countPath(origin, node); + if (typeof path === 'undefined') { + error(`${node.getPathInHierarchy()} is not a child of ${origin.getPathInHierarchy()}`); + // fallthrough + } else if (mask.isExcluded(path)) { + continue; + } + involvedTransformIndices.push(handle.index); + } + involvedTransformIndices.sort(); + const poseFilter = new TransformFilter(involvedTransformIndices); + return poseFilter; + + function countPath (from: Node, to: Node) { + const path: string[] = []; + for (let node: Node | null = to; node; node = node.parent) { + if (node === from) { + return path.join('/'); + } else { + path.unshift(node.name); + } + } + return undefined; // Non-closed. + } + } + + public fetchDefaultTransforms (transforms: TransformArray) { + const nTransforms = this._transformRecords.length; + assertIsTrue(transforms.length === nTransforms); + for (let iTransform = 0; iTransform < nTransforms; ++iTransform) { + const { defaultTransform } = this._transformRecords[iTransform]; + transforms.setTransform(iTransform, defaultTransform); + } + } + + public apply (pose: Pose) { + const { + transforms, + metaValues, + } = pose; + + const nTransforms = this._transformRecords.length; + assertIsTrue(transforms.length === nTransforms); + for (let iTransform = 0; iTransform < nTransforms; ++iTransform) { + const transform = transforms.getTransform(iTransform, cacheTransform); + const { node } = this._transformRecords[iTransform]; + node.setRTS( + transform.rotation, + transform.position, + transform.scale, + ); + } + + const nMetaValues = this._metaValueRecords.length; + for (let iMetaValue = 0; iMetaValue < nMetaValues; ++iMetaValue) { + const { name: curveName } = this._metaValueRecords[iMetaValue]; + const curveValue = metaValues[iMetaValue]; + this._metaValueRegistry.set(curveName, curveValue); + } + } + + /** + * @engineInternal + */ + @checkBindStatus(true) + public _destroyTransformHandle (index: number) { + assertIsTrue(index >= 0 && index < this._transformRecords.length, `Invalid transform handle.`); + const record = this._transformRecords[index]; + assertIsTrue(record.refCount > 0, `Something work wrong: refCount mismatch.`); + --record.refCount; + } + + /** + * @engineInternal + */ + @checkBindStatus(true) + public _destroyMetaValueHandle (index: number) { + assertIsTrue(index >= 0 && index < this._metaValueRecords.length, `Invalid meta value handle.`); + const record = this._metaValueRecords[index]; + assertIsTrue(record.refCount > 0, `Something work wrong: refCount mismatch.`); + --record.refCount; + } + + @checkBindStatus(false) + public startBind () { + this._bindStarted = true; + this._transformCountBeforeBind = this._transformRecords.length; + this._metaValueCountBeforeBind = this._metaValueRecords.length; + } + + @checkBindStatus(true) + public endBind () { + const { + _transformRecords: transformRecords, + _metaValueRecords: metaValueRecords, + } = this; + + let changeFlags = 0; + + // Detect changes in transforms. + trimRecords(transformRecords); + if (transformRecords.length !== this._transformCountBeforeBind) { + changeFlags |= LayoutChangeFlag.TRANSFORM_COUNT; + // If the transform's count is changed, we only sync orders. + const nRecords = transformRecords.length; + for (let iRecord = 0; iRecord < nRecords; ++iRecord) { + const record = transformRecords[iRecord]; + record.order = iRecord; + } + } else { + // Sync order and detect change. + const nRecords = transformRecords.length; + let orderChanged = false; + for (let iRecord = 0; iRecord < nRecords; ++iRecord) { + const record = transformRecords[iRecord]; + if (record.order !== iRecord) { + orderChanged = true; + record.order = iRecord; + } + } + if (orderChanged) { + changeFlags |= LayoutChangeFlag.TRANSFORM_ORDER; + } + } + + // Detect changes in meta values. + trimRecords(metaValueRecords); + if (metaValueRecords.length !== this._metaValueCountBeforeBind) { + changeFlags |= LayoutChangeFlag.META_VALUE_COUNT; + } + + this._bindStarted = false; + + // Do some checks in debug mode. + if (DEBUG) { + transformRecords.forEach((transformRecord, index, transformRecords) => { + assertIsTrue(transformRecord.handle.index === index, `Bad transform handle.`); + + assertIsTrue(transformRecord.order === index, `Bad transform order field.`); + + // Ensure that transforms are sorted so that parent is in front of child. + for (let parent = transformRecord.node.parent; parent; parent = parent.parent) { + const parentIndex = transformRecords.findIndex((r) => r.node === parent); + if (parentIndex >= 0) { + assertIsTrue(parentIndex < index, `Bad transform order.`); + } + } + }); + + this._transformCountBeforeBind = -1; + this._metaValueCountBeforeBind = -1; + } + + return changeFlags; + } + + private _metaValueRegistry: MetaValueRegistry; + private _metaValueRecords: MetaValueRecord[] = []; + private _transformRecords: TransformRecord[] = []; + + private _bindStarted = false; + private _transformCountBeforeBind = -1; + private _metaValueCountBeforeBind = -1; +} + +interface AnimationRecord { + handle: THandle; + + refCount: number; +} + +class TransformRecord implements AnimationRecord { + constructor (handle: TransformHandleInternal, node: Node) { + this.handle = handle; + this.node = node; + const defaultTransform = new Transform(); + defaultTransform.position = node.position; + defaultTransform.rotation = node.rotation; + defaultTransform.scale = node.scale; + this.defaultTransform = defaultTransform; + } + + /** The order of the transform. */ + public order = -1; + + public refCount = 1; + + public readonly handle: TransformHandleInternal; + + public readonly node: Node; + + public readonly defaultTransform: Readonly; +} + +class MetaValueRecord implements AnimationRecord { + constructor (handle: MetaValueHandleInternal, name: string) { + this.handle = handle; + this.name = name; + } + + public refCount = 1; + + public readonly handle: MetaValueHandleInternal; + + public readonly name: string; +} + +function trimRecords> (records: TRecord[]) { + const nUsedRecords = partition(records, (record) => { + assertIsTrue(record.refCount >= 0); + return record.refCount > 0; + }); + assertIsTrue(nUsedRecords <= records.length); + if (nUsedRecords === records.length) { + return; + } + // Reassign indices. + for (let iRecord = 0; iRecord < nUsedRecords; ++iRecord) { + records[iRecord].handle.index = iRecord; + } + // Trim the array. + if (DEBUG) { + records.slice(nUsedRecords).forEach((record) => record.refCount = -1); + } + records.splice(nUsedRecords, records.length - nUsedRecords); +} + +export const defaultTransformsTag = Symbol('[[DefaultTransforms]]'); + +export class AnimationGraphEvaluationContext { + constructor (layout: PoseLayout) { + this._poseAllocator = new PoseAllocator(layout.transformCount, layout.metaValueCount); + this[defaultTransformsTag] = new TransformArray(layout.transformCount); + } + + public destroy () { + this._poseAllocator.destroy(); + } + + /** + * @engineInternal + */ + public readonly [defaultTransformsTag]: TransformArray; + + public get allocatedPoseCount () { + return this._poseAllocator.allocatedCount; + } + + public pushDefaultedPose () { + const pose = this._poseAllocator.push(); + pose.transforms.set(this[defaultTransformsTag]); + pose.metaValues.fill(0.0); + return pose; + } + + public pushZeroDeltaPose () { + const pose = this._poseAllocator.push(); + pose.transforms.fill(ZERO_DELTA_TRANSFORM); + pose.metaValues.fill(0.0); + return pose; + } + + public pushDuplicatedPose (src: Pose) { + const pose = this._poseAllocator.push(); + pose.transforms.set(src.transforms); + pose.metaValues.set(src.metaValues); + return pose; + } + + public popPose () { + this._poseAllocator.pop(); + } + + private _poseAllocator: PoseAllocator; +} + +export interface PoseLayout { + transformCount: number; + + metaValueCount: number; +} + +class TransformHandleInternal implements TransformHandle { + declare __brand: TransformHandle['__brand']; + + constructor (host: AnimationGraphPoseLayoutMaintainer, index: number) { + this._host = host; + this.index = index; + } + + public index = -1; + + public destroy () { + this._host._destroyTransformHandle(this.index); + } + + private _host: AnimationGraphPoseLayoutMaintainer; +} + +class MetaValueHandleInternal implements MetaValueHandle { + constructor (host: AnimationGraphPoseLayoutMaintainer, index: number) { + this._host = host; + this.index = index; + } + + declare __brand: MetaValueHandle['__brand']; + + public index = -1; + + public destroy () { + this._host._destroyMetaValueHandle(this.index); + } + + private _host: AnimationGraphPoseLayoutMaintainer; +} diff --git a/cocos/animation/marionette/animation-graph-editor-extras-clone-helper.ts b/cocos/animation/marionette/animation-graph-editor-extras-clone-helper.ts new file mode 100644 index 00000000000..c78f30e94d3 --- /dev/null +++ b/cocos/animation/marionette/animation-graph-editor-extras-clone-helper.ts @@ -0,0 +1,45 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { EditorExtendableObject, editorExtrasTag } from '../../core/data/editor-extras-tag'; + +/** + * Clones the editor extras from an animation-graph-specific object. + * @internal This is a HACKY way. + * + * If the editor extras from an animation-graph-specific object has a method called `clone`, + * that method would be called to perform a clone operation. + * The return value would be used as the clone result. + * The method `clone` has the signature: `(host: EditorExtendableObject) => unknown`. + */ +export function cloneAnimationGraphEditorExtrasFrom (object: EditorExtendableObject): unknown { + const editorExtras = object[editorExtrasTag]; + if (typeof editorExtras === 'object' && editorExtras) { + const maybeCloneableEditorExtras = editorExtras as { + clone?(host: EditorExtendableObject): unknown; + }; + return maybeCloneableEditorExtras.clone?.(object); + } + return undefined; +} diff --git a/cocos/animation/marionette/animation-graph-like.ts b/cocos/animation/marionette/animation-graph-like.ts new file mode 100644 index 00000000000..d6e3b82928d --- /dev/null +++ b/cocos/animation/marionette/animation-graph-like.ts @@ -0,0 +1,40 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ccclass } from 'cc.decorator'; +import { Asset } from '../../asset/assets/asset'; +import { CLASS_NAME_PREFIX_ANIM } from '../define'; + +/** + * @zh `AnimationGraph` 和 `AnimationGraphVariant` 的内部共同基类, + * 仅用于特殊目的,不应另作它用,也不应导出为公开接口。 + * @en The common base class of `AnimationGraph` and `AnimationGraphVariant` + * which exists for special purpose and should not be used otherwise and should not be exported. + * + * @internal This class serves as the editor switch of + * animation graph asset and animation graph variant asset, + * especially as the `graph` property on animation controller component. + */ +@ccclass(`${CLASS_NAME_PREFIX_ANIM}AnimationGraphLike`) +export abstract class AnimationGraphLike extends Asset { } diff --git a/cocos/animation/marionette/animation-graph-variant.ts b/cocos/animation/marionette/animation-graph-variant.ts new file mode 100644 index 00000000000..b57dcd8a256 --- /dev/null +++ b/cocos/animation/marionette/animation-graph-variant.ts @@ -0,0 +1,121 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ccclass, editable, serializable, type } from 'cc.decorator'; +import { removeIf } from '../../core/utils/array'; +import { AnimationClip } from '../animation-clip'; +import { CLASS_NAME_PREFIX_ANIM } from '../define'; +import { AnimationGraph } from './animation-graph'; +import { AnimationGraphLike } from './animation-graph-like'; +import { ReadonlyClipOverrideMap } from './graph-eval'; + +/** + * @en + * An opacity type which denotes what the animation graph variant seems like outside the engine. + * @zh + * 一个非透明的类型,它是动画图变体在引擎外部的表示。 + */ +export interface AnimationGraphVariantRunTime { + /** + * @internal + */ + readonly __brand: 'AnimationGraphVariant'; +} + +@ccclass(`${CLASS_NAME_PREFIX_ANIM}ClipOverrideEntry`) +class ClipOverrideEntry { + @serializable + public original: AnimationClip = null!; + + @serializable + public substitution: AnimationClip = null!; +} + +@ccclass(`${CLASS_NAME_PREFIX_ANIM}AnimationGraphVariant`) +export class AnimationGraphVariant extends AnimationGraphLike implements AnimationGraphVariantRunTime { + declare __brand: 'AnimationGraphVariant'; + + @type(AnimationGraph) + @editable + get original () { + return this._graph; + } + + set original (value) { + this._graph = value; + } + + get clipOverrides (): ClipOverrideMap { + return this._clipOverrides; + } + + @serializable + private _graph: AnimationGraph | null = null; + + @serializable + private _clipOverrides: ClipOverrideMap = new ClipOverrideMap(); +} + +@ccclass(`${CLASS_NAME_PREFIX_ANIM}ClipOverrideMap`) +class ClipOverrideMap implements ReadonlyClipOverrideMap { + get size () { + return this._entries.length; + } + + public [Symbol.iterator] () { + return this._entries[Symbol.iterator](); + } + + public has (original: AnimationClip) { + return !!this._entries.find(({ original: o }) => o === original); + } + + public get (original: AnimationClip) { + const entry = this._entries.find(({ original: o }) => o === original); + return entry?.substitution; + } + + public set (original: AnimationClip, substitution: AnimationClip) { + const entry = this._entries.find(({ original: o }) => o === original); + if (entry) { + entry.substitution = substitution; + } else { + const newEntry = new ClipOverrideEntry(); + newEntry.original = original; + newEntry.substitution = substitution; + this._entries.push(newEntry); + } + } + + public delete (original: AnimationClip) { + removeIf(this._entries, ({ original: o }) => o === original); + } + + public clear () { + this._entries.length = 0; + } + + @serializable + private _entries: ClipOverrideEntry[] = []; +} diff --git a/cocos/animation/marionette/animation-graph.ts b/cocos/animation/marionette/animation-graph.ts index 0ddd0443e49..4df477dc79a 100644 --- a/cocos/animation/marionette/animation-graph.ts +++ b/cocos/animation/marionette/animation-graph.ts @@ -1,10 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; import { DEBUG } from 'internal:constants'; -import { remove, removeIf } from '../../core/utils/array'; -import { assertIsNonNullable, assertIsTrue } from '../../core/data/utils/asserts'; +import { js, clamp, assertIsNonNullable, assertIsTrue, EditorExtendable, shift } from '../../core'; import { MotionEval, MotionEvalContext } from './motion'; import type { Condition } from './condition'; -import { Asset } from '../../asset/assets'; import { OwnedBy, assertsOwnedBy, own, markAsDangling, ownerSymbol } from './ownership'; import { TriggerResetMode, Value, VariableType } from './variable'; import { InvalidTransitionError } from './errors'; @@ -12,12 +34,10 @@ import { createEval } from './create-eval'; import { MotionState } from './motion-state'; import { State, outgoingsSymbol, incomingsSymbol, InteractiveState } from './state'; import { AnimationMask } from './animation-mask'; -import { EditorExtendable } from '../../core/data/editor-extendable'; -import { array } from '../../core/utils/js'; -import { move } from '../../core/algorithm/move'; -import { onAfterDeserializedTag } from '../../core/data/deserialize-symbols'; +import { onAfterDeserializedTag } from '../../serialization/deserialize-symbols'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; -import { clamp } from '../../core/math'; +import { AnimationGraphLike } from './animation-graph-like'; +import { renameObjectProperty } from '../../core/utils/internal'; export { State }; @@ -52,6 +72,10 @@ class Transition extends EditorExtendable implements OwnedBy, Tran } } + public copyTo (that: Transition) { + that.conditions = this.conditions.map((condition) => condition.clone()); + } + [ownerSymbol]: StateMachine | undefined; } @@ -130,6 +154,17 @@ class AnimationTransition extends Transition { : TransitionInterruptionSource.NONE; } + public copyTo (that: AnimationTransition) { + super.copyTo(that); + that.duration = this.duration; + that.relativeDuration = this.relativeDuration; + that.exitConditionEnabled = this.exitConditionEnabled; + that.exitCondition = this.exitCondition; + that.destinationStart = this.destinationStart; + that.relativeDestinationStart = this.relativeDestinationStart; + that.interruptible = this.interruptible; + } + /** * @internal This field is exposed for **internal** usage. */ @@ -154,6 +189,13 @@ export function isAnimationTransition (transition: TransitionView): transition i @ccclass(`${CLASS_NAME_PREFIX_ANIM}EmptyState`) export class EmptyState extends State { public declare __brand: 'EmptyState'; + + public _clone () { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + const that = new EmptyState(); + this.copyTo(that); + return that; + } } @ccclass(`${CLASS_NAME_PREFIX_ANIM}EmptyStateTransition`) @@ -180,6 +222,13 @@ export class EmptyStateTransition extends Transition { */ @serializable public relativeDestinationStart = false; + + public copyTo (that: EmptyStateTransition) { + super.copyTo(that); + that.duration = this.duration; + that.destinationStart = this.destinationStart; + that.relativeDestinationStart = this.relativeDestinationStart; + } } @ccclass('cc.animation.StateMachine') @@ -346,7 +395,7 @@ export class StateMachine extends EditorExtendable { } this.eraseTransitionsIncludes(state); - remove(this._states, state); + js.array.remove(this._states, state); markAsDangling(state); } @@ -422,12 +471,12 @@ export class StateMachine extends EditorExtendable { ++iOTransitionToRemove ) { const oTransition = oTransitionsToRemove[iOTransitionToRemove]; - remove(oTransitions, oTransition); + js.array.remove(oTransitions, oTransition); assertIsTrue( - remove(transitions, oTransition), + js.array.remove(transitions, oTransition), ); assertIsNonNullable( - removeIf(iTransitions, (transition) => transition === oTransition), + js.array.removeIf(iTransitions, (transition) => transition === oTransition), ); markAsDangling(oTransition); } @@ -435,13 +484,13 @@ export class StateMachine extends EditorExtendable { public removeTransition (removal: Transition) { assertIsTrue( - remove(this._transitions, removal), + js.array.remove(this._transitions, removal), ); assertIsNonNullable( - removeIf(removal.from[outgoingsSymbol], (transition) => transition === removal), + js.array.removeIf(removal.from[outgoingsSymbol], (transition) => transition === removal), ); assertIsNonNullable( - removeIf(removal.to[incomingsSymbol], (transition) => transition === removal), + js.array.removeIf(removal.to[incomingsSymbol], (transition) => transition === removal), ); markAsDangling(removal); } @@ -454,10 +503,10 @@ export class StateMachine extends EditorExtendable { const oTransition = oTransitions[iOTransition]; const to = oTransition.to; assertIsTrue( - remove(this._transitions, oTransition), + js.array.remove(this._transitions, oTransition), ); assertIsNonNullable( - removeIf(to[incomingsSymbol], (transition) => transition === oTransition), + js.array.removeIf(to[incomingsSymbol], (transition) => transition === oTransition), ); markAsDangling(oTransition); } @@ -472,10 +521,10 @@ export class StateMachine extends EditorExtendable { const iTransition = iTransitions[iITransition]; const from = iTransition.from; assertIsTrue( - remove(this._transitions, iTransition), + js.array.remove(this._transitions, iTransition), ); assertIsNonNullable( - removeIf(from[outgoingsSymbol], (transition) => transition === iTransition), + js.array.removeIf(from[outgoingsSymbol], (transition) => transition === iTransition), ); markAsDangling(iTransition); } @@ -553,12 +602,26 @@ export class StateMachine extends EditorExtendable { } // eslint-disable-next-line no-lone-blocks { // 2. Adjust the order in outgoing array. - move(outgoings, iAdjusting, iNew); + shift(outgoings, iAdjusting, iNew); } } - public clone () { - const that = new StateMachine(); + public copyTo (that: StateMachine) { + // Clear that first + const thatStatesOld = that._states.filter((state) => { + switch (state) { + case that._entryState: + case that._exitState: + case that._anyState: + return true; + default: + return false; + } + }); + for (const thatStateOld of thatStatesOld) { + that.remove(thatStateOld); + } + const stateMap = new Map(); for (const state of this._states) { switch (state) { @@ -572,8 +635,8 @@ export class StateMachine extends EditorExtendable { stateMap.set(state, that._anyState); break; default: - if (state instanceof MotionState || state instanceof SubStateMachine) { - const thatState = state.clone(); + if (state instanceof MotionState || state instanceof SubStateMachine || state instanceof EmptyState) { + const thatState = state._clone(); that._addState(thatState); stateMap.set(state, thatState); } else { @@ -590,11 +653,19 @@ export class StateMachine extends EditorExtendable { thatTransition.conditions = transition.conditions.map((condition) => condition.clone()); if (thatTransition instanceof AnimationTransition) { assertIsTrue(transition instanceof AnimationTransition); - thatTransition.duration = transition.duration; - thatTransition.exitConditionEnabled = transition.exitConditionEnabled; - thatTransition.exitCondition = transition.exitCondition; + transition.copyTo(thatTransition); + } else if (thatTransition instanceof EmptyStateTransition) { + assertIsTrue(transition instanceof EmptyStateTransition); + transition.copyTo(thatTransition); + } else { + transition.copyTo(thatTransition); } } + } + + public clone () { + const that = new StateMachine(); + this.copyTo(that); return that; } @@ -611,9 +682,14 @@ export class SubStateMachine extends InteractiveState { return this._stateMachine; } - public clone () { + public copyTo (that: SubStateMachine) { + super.copyTo(that); + this._stateMachine.copyTo(that._stateMachine); + } + + public _clone () { const that = new SubStateMachine(); - that._stateMachine = this._stateMachine.clone(); + this.copyTo(that); return that; } @@ -637,6 +713,9 @@ export class Layer implements OwnedBy { @serializable public mask: AnimationMask | null = null; + @serializable + public additive = false; + /** * @marked_as_engine_private */ @@ -795,7 +874,7 @@ export type VariableDescription = | TriggerVariable; @ccclass('cc.animation.AnimationGraph') -export class AnimationGraph extends Asset implements AnimationGraphRunTime { +export class AnimationGraph extends AnimationGraphLike implements AnimationGraphRunTime { public declare readonly __brand: 'AnimationGraph'; @serializable @@ -840,7 +919,7 @@ export class AnimationGraph extends Asset implements AnimationGraphRunTime { * @param index Index to the layer to remove. */ public removeLayer (index: number) { - array.removeAt(this._layers, index); + js.array.removeAt(this._layers, index); } /** @@ -849,7 +928,7 @@ export class AnimationGraph extends Asset implements AnimationGraphRunTime { * @param newIndex */ public moveLayer (index: number, newIndex: number) { - move(this._layers, index, newIndex); + shift(this._layers, index, newIndex); } /** @@ -918,17 +997,6 @@ export class AnimationGraph extends Asset implements AnimationGraphRunTime { * @param newName @zh 新的名字。 @en New name. */ public renameVariable (name: string, newName: string) { - const { _variables: variables } = this; - if (!(name in variables)) { - return; - } - if (newName in variables) { - return; - } - // Rename but also retain order. - this._variables = Object.entries(variables).reduce((result, [k, v]) => { - result[k === name ? newName : k] = v; - return result; - }, {} as AnimationGraph['_variables']); + this._variables = renameObjectProperty(this._variables, name, newName); } } diff --git a/cocos/animation/marionette/animation-mask.ts b/cocos/animation/marionette/animation-mask.ts index 7b3327e79a5..8f4157ecfe4 100644 --- a/cocos/animation/marionette/animation-mask.ts +++ b/cocos/animation/marionette/animation-mask.ts @@ -1,16 +1,59 @@ -import { ccclass, serializable, editable } from 'cc.decorator'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ccclass, serializable, editable, type } from 'cc.decorator'; import type { Node } from '../../scene-graph/node'; import { Asset } from '../../asset/assets/asset'; -import { removeIf } from '../../core/utils/array'; +import { js } from '../../core'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; +interface JointMaskInfo { + readonly path: string; + + enabled: boolean; +} + +@ccclass('cc.JointMask') +class JointMask { + @serializable + public path = ''; + + @serializable + public enabled = true; +} + @ccclass(`${CLASS_NAME_PREFIX_ANIM}AnimationMask`) export class AnimationMask extends Asset { @serializable private _jointMasks: JointMask[] = []; @editable + @type(JointMask) get joints (): Iterable { + // TODO: editor currently treats this property as (and expects it to be) an array. + // If later refactoring is needed, changes should also be made to editor. + return this._jointMasks; } @@ -38,7 +81,7 @@ export class AnimationMask extends Asset { } public removeJoint (removal: string) { - removeIf(this._jointMasks, ({ path }) => path === removal); + js.array.removeIf(this._jointMasks, ({ path }) => path === removal); } public clear () { @@ -61,6 +104,10 @@ export class AnimationMask extends Asset { } return disabledNodes; } + + public isExcluded (path: string) { + return !(this._jointMasks.find(({ path: p }) => p === path)?.enabled ?? true); + } } type JointMaskInfo_ = JointMaskInfo; @@ -68,18 +115,3 @@ type JointMaskInfo_ = JointMaskInfo; export declare namespace AnimationMask { export type JointMaskInfo = JointMaskInfo_; } - -interface JointMaskInfo { - readonly path: string; - - enabled: boolean; -} - -@ccclass('cc.JointMask') -class JointMask { - @serializable - public path = ''; - - @serializable - public enabled = true; -} diff --git a/cocos/animation/marionette/asset-creation.ts b/cocos/animation/marionette/asset-creation.ts index 7d1ca131927..bbc8d26c55e 100644 --- a/cocos/animation/marionette/asset-creation.ts +++ b/cocos/animation/marionette/asset-creation.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export { InvalidTransitionError, VariableNotDefinedError } from './errors'; export { AnimationGraph, isAnimationTransition, StateMachine, SubStateMachine, EmptyStateTransition, EmptyState } from './animation-graph'; export type { Transition, AnimationTransition, Layer, State, VariableDescription } from './animation-graph'; @@ -14,3 +38,4 @@ export { AnimationBlend2D } from './animation-blend-2d'; export { VariableType } from './parametric'; export { BindableNumber, BindableBoolean } from './parametric'; export { AnimationMask } from './animation-mask'; +export { AnimationGraphVariant } from './animation-graph-variant'; \ No newline at end of file diff --git a/cocos/animation/marionette/blend-1d.ts b/cocos/animation/marionette/blend-1d.ts index 89f051b867f..9a1fca0ffe4 100644 --- a/cocos/animation/marionette/blend-1d.ts +++ b/cocos/animation/marionette/blend-1d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export function blend1D (weights: number[], thresholds: readonly number[], value: number) { weights.fill(0.0); if (thresholds.length === 0) { diff --git a/cocos/animation/marionette/blend-2d.ts b/cocos/animation/marionette/blend-2d.ts index b54fd198b8d..7b0b634ea95 100644 --- a/cocos/animation/marionette/blend-2d.ts +++ b/cocos/animation/marionette/blend-2d.ts @@ -1,5 +1,28 @@ -import { assertIsTrue } from '../../core/data/utils/asserts'; -import { Vec2, Vec3 } from '../../core/math'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { assertIsTrue, Vec2, Vec3 } from '../../core'; /** * Blends given samples using simple directional algorithm. diff --git a/cocos/animation/marionette/clip-motion.ts b/cocos/animation/marionette/clip-motion.ts index a23558ab85a..e624b327e13 100644 --- a/cocos/animation/marionette/clip-motion.ts +++ b/cocos/animation/marionette/clip-motion.ts @@ -1,22 +1,53 @@ -import { ccclass, type } from '../../core/data/class-decorator'; -import { EditorExtendable } from '../../core/data/editor-extendable'; -import { AnimationClip } from '../animation-clip'; -import { AnimationState } from '../animation-state'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { editorExtrasTag, _decorator, EditorExtendable } from '../../core'; +import { additiveSettingsTag, AnimationClip } from '../animation-clip'; +import { cloneAnimationGraphEditorExtrasFrom } from './animation-graph-editor-extras-clone-helper'; import { createEval } from './create-eval'; -import { getMotionRuntimeID, GRAPH_DEBUG_ENABLED, pushWeight, RUNTIME_ID_ENABLED } from './graph-debug'; -import { ClipStatus } from './graph-eval'; -import { MotionEvalContext, Motion, MotionEval } from './motion'; +import { getMotionRuntimeID, RUNTIME_ID_ENABLED } from './graph-debug'; +import { ClipStatus, ReadonlyClipOverrideMap } from './graph-eval'; +import { Motion, MotionEval, MotionPort } from './motion'; +import { wrap } from '../wrap'; +import { calculateDeltaPose, Pose } from '../core/pose'; +import { AnimationGraphEvaluationContext, AnimationGraphLayerWideBindingContext } from './animation-graph-context'; +import { WrappedInfo } from '../types'; +import { WrapModeMask } from '../../core/geometry'; +import { AnimationClipAGEvaluation } from './animation-graph-animation-clip-binding'; + +const { ccclass, type } = _decorator; @ccclass('cc.animation.ClipMotion') export class ClipMotion extends EditorExtendable implements Motion { @type(AnimationClip) public clip: AnimationClip | null = null; - public [createEval] (context: MotionEvalContext) { + public [createEval] (context: AnimationGraphLayerWideBindingContext, overrides: ReadonlyClipOverrideMap | null) { if (!this.clip) { return null; } - const clipMotionEval = new ClipMotionEval(context, this.clip); + const clipMotionEval = new ClipMotionEval(context, this.clip, overrides); if (RUNTIME_ID_ENABLED) { clipMotionEval.runtimeId = getMotionRuntimeID(this); } @@ -26,10 +57,13 @@ export class ClipMotion extends EditorExtendable implements Motion { public clone () { const that = new ClipMotion(); that.clip = this.clip; + that[editorExtrasTag] = cloneAnimationGraphEditorExtrasFrom(this); return that; } } +const evaluatePortTag = Symbol('EvaluatePort'); + class ClipMotionEval implements MotionEval { /** * @internal @@ -38,14 +72,18 @@ class ClipMotionEval implements MotionEval { public declare runtimeId?: number; - private declare _state: AnimationState; + constructor (context: AnimationGraphLayerWideBindingContext, clip: AnimationClip, clipOverrides: ReadonlyClipOverrideMap | null) { + this._originalClip = clip; + const overriding = clipOverrides?.get(clip) ?? clip; + this._setClip(overriding, context); + } - public declare readonly duration: number; + get duration () { + return this._duration; + } - constructor (context: MotionEvalContext, clip: AnimationClip) { - this.duration = clip.duration / clip.speed; - this._state = new AnimationState(clip); - this._state.initialize(context.node, context.blendBuffer, context.mask); + public createPort (): MotionPort { + return new ClipMotionPort(this); } public getClipStatuses (baseWeight: number): Iterator { @@ -63,7 +101,7 @@ class ClipMotionEval implements MotionEval { done: false, value: { __DEBUG_ID__: this.__DEBUG__ID__, - clip: this._state.clip, + clip: this._clip, weight: baseWeight, }, }; @@ -72,21 +110,105 @@ class ClipMotionEval implements MotionEval { }; } - get progress () { - return this._state.time / this.duration; + public [evaluatePortTag] (progress: number, context: AnimationGraphEvaluationContext) { + const { + _duration: duration, + _clip: { duration: clipDuration }, + _clipEval: clipEval, + _baseClipEval: baseClipEval, + } = this; + + const elapsedTime = duration * progress; + + const { wrapMode } = this._clip; + const repeatCount = (wrapMode & WrapModeMask.Loop) === WrapModeMask.Loop + ? Infinity : 1; + const wrapInfo = wrap( + elapsedTime, + duration, + wrapMode, + repeatCount, + false, + this._wrapInfo, + ); + + // Transform the motion space time(scaled by clip speed) into clip space time. + const clipTime = wrapInfo.ratio * clipDuration; + + // Evaluate this clip. + const pose = context.pushDefaultedPose(); + clipEval.evaluate(clipTime, pose); + + if (baseClipEval) { + const basePose = context.pushDefaultedPose(); + const baseEvalTime = 0.0; // TODO: base clip may specify a time? + baseClipEval.evaluate(baseEvalTime, basePose); + calculateDeltaPose(pose, basePose); + context.popPose(); + } + + // TODO: Evaluate root motions. + + // TODO: Evaluate embedded players. + // this._clipEmbeddedPlayerEval?.evaluate(); + + return pose; + } + + public overrideClips (clipOverrides: ReadonlyClipOverrideMap, context: AnimationGraphLayerWideBindingContext): void { + const { _originalClip: originalClip } = this; + const overriding = clipOverrides.get(originalClip); + if (overriding) { + this._setClip(overriding, context); + } } - public sample (progress: number, weight: number) { - if (weight === 0.0) { - return; + /** + * Preserved here for clip overriding. + */ + private declare _originalClip: AnimationClip; + /** + * Actual clip used. Will be equal to `this._originalClip` if not being override. + */ + private declare _clip: AnimationClip; + private declare _clipEval: AnimationClipAGEvaluation; + private _clipEmbeddedPlayerEval: ReturnType | null = null; + private _wrapInfo = new WrappedInfo(); + private _baseClipEval: AnimationClipAGEvaluation | null = null; + private _duration = 0.0; + + private _setClip (clip: AnimationClip, context: AnimationGraphLayerWideBindingContext) { + this._clipEval?.destroy(); + if (this._clipEmbeddedPlayerEval) { + this._clipEmbeddedPlayerEval.destroy(); + this._clipEmbeddedPlayerEval = null; } - if (GRAPH_DEBUG_ENABLED) { - pushWeight(this._state.name, weight); + + this._clip = clip; + this._duration = clip.speed === 0.0 + ? 0.0 + : clip.duration / clip.speed; // TODO, a test for `clip.speed === 0` is required! + const clipEval = new AnimationClipAGEvaluation(clip, context.outerContext); + this._clipEval = clipEval; + if (clip.containsAnyEmbeddedPlayer()) { + this._clipEmbeddedPlayerEval = clip.createEmbeddedPlayerEvaluator(context.outerContext.origin); + } + if (context.additive) { + const additiveSettings = clip[additiveSettingsTag]; + const baseClip = additiveSettings.base ?? clip; + this._baseClipEval = new AnimationClipAGEvaluation(baseClip, context.outerContext); } - const time = this._state.duration * progress; - this._state.time = time; - this._state.weight = weight; - this._state.sample(); - this._state.weight = 0.0; } } + +class ClipMotionPort implements MotionPort { + constructor (host: ClipMotionEval) { + this._eval = host; + } + + public evaluate (progress: number, context: AnimationGraphEvaluationContext): Pose { + return this._eval[evaluatePortTag](progress, context); + } + + private _eval: ClipMotionEval; +} diff --git a/cocos/animation/marionette/condition.ts b/cocos/animation/marionette/condition.ts index 7fafb175342..c24f9d99034 100644 --- a/cocos/animation/marionette/condition.ts +++ b/cocos/animation/marionette/condition.ts @@ -1,19 +1,44 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { VariableType, BindableBoolean, BindableNumber, BindContext, bindOr, validateVariableExistence, bindNumericOr, validateVariableTypeTriggerLike, } from './parametric'; -import { ccclass, serializable } from '../../core/data/decorators'; +import { _decorator } from '../../core'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { createEval } from './create-eval'; import { VariableTypeMismatchedError } from './errors'; +import { AnimationGraphBindingContext } from './animation-graph-context'; export type ConditionEvalContext = BindContext; export interface Condition { clone (): Condition; - [createEval] (context: BindContext): ConditionEval; + [createEval] (context: AnimationGraphBindingContext): ConditionEval; } export interface ConditionEval { @@ -23,6 +48,8 @@ export interface ConditionEval { eval(): boolean; } +const { ccclass, serializable } = _decorator; + enum BinaryOperator { EQUAL_TO, NOT_EQUAL_TO, diff --git a/cocos/animation/marionette/create-eval.ts b/cocos/animation/marionette/create-eval.ts index e2355aaeafa..e4a29d38e35 100644 --- a/cocos/animation/marionette/create-eval.ts +++ b/cocos/animation/marionette/create-eval.ts @@ -1 +1,25 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export const createEval = Symbol('[[createEval]]'); diff --git a/cocos/animation/marionette/errors.ts b/cocos/animation/marionette/errors.ts index 3ff36a1605c..b05acd090a3 100644 --- a/cocos/animation/marionette/errors.ts +++ b/cocos/animation/marionette/errors.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export class InvalidTransitionError extends Error { constructor (type: 'to-entry' | 'to-any' | 'from-exit') { super(`${type} transition is invalid`); diff --git a/cocos/animation/marionette/graph-debug.ts b/cocos/animation/marionette/graph-debug.ts index 2377a7029db..e867439bf86 100644 --- a/cocos/animation/marionette/graph-debug.ts +++ b/cocos/animation/marionette/graph-debug.ts @@ -1,7 +1,30 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; -import { editorExtrasTag } from '../../core/data'; +import { editorExtrasTag } from '../../core'; -import { debug } from '../../core/platform/debug'; import { AnimationBlend } from './animation-blend'; import { ClipMotion } from './clip-motion'; @@ -14,31 +37,3 @@ export function getMotionRuntimeID (motion: ClipMotion | AnimationBlend) { } export const GRAPH_DEBUG_ENABLED = false; - -export const graphDebug = GRAPH_DEBUG_ENABLED - ? debug - : EMPTY as typeof debug; - -export const graphDebugGroup = GRAPH_DEBUG_ENABLED - ? console.group - : EMPTY as typeof debug; - -export const graphDebugGroupEnd = GRAPH_DEBUG_ENABLED - ? console.groupEnd - : EMPTY as typeof debug; - -function EMPTY (...args: unknown[]) { } - -const weightsStats: [string, number][] = []; - -export function pushWeight (name: string, weight: number) { - weightsStats.push([name, weight]); -} - -export function getWeightsStats () { - return `[${weightsStats.map(([name, weight]) => `[${name}: ${weight}]`).join(' ')}]`; -} - -export function clearWeightsStats () { - weightsStats.length = 0; -} diff --git a/cocos/animation/marionette/graph-eval.ts b/cocos/animation/marionette/graph-eval.ts index eca5145ee50..c25b423b4a0 100644 --- a/cocos/animation/marionette/graph-eval.ts +++ b/cocos/animation/marionette/graph-eval.ts @@ -1,10 +1,33 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { DEBUG } from 'internal:constants'; import { AnimationGraph, Layer, StateMachine, State, isAnimationTransition, SubStateMachine, EmptyState, EmptyStateTransition, TransitionInterruptionSource, } from './animation-graph'; -import { assertIsTrue, assertIsNonNullable } from '../../core/data/utils/asserts'; -import { MotionEval, MotionEvalContext } from './motion'; +import { MotionEval, MotionEvalContext, MotionPort } from './motion'; import type { Node } from '../../scene-graph/node'; import { createEval } from './create-eval'; import { Value, VarInstance, TriggerResetMode } from './variable'; @@ -12,24 +35,27 @@ import { BindContext, validateVariableExistence, validateVariableType, VariableT import { ConditionEval, TriggerCondition } from './condition'; import { MotionState } from './motion-state'; import { AnimationMask } from './animation-mask'; -import { warnID } from '../../core/platform/debug'; -import { BlendStateBuffer, LayeredBlendStateBuffer } from '../../3d/skeletal-animation/skeletal-animation-blending'; +import { warnID, assertIsTrue, assertIsNonNullable } from '../../core'; import { MAX_ANIMATION_LAYER } from '../../3d/skeletal-animation/limits'; -import { clearWeightsStats, getWeightsStats, graphDebug, graphDebugGroup, graphDebugGroupEnd, GRAPH_DEBUG_ENABLED } from './graph-debug'; import { AnimationClip } from '../animation-clip'; import type { AnimationController } from './animation-controller'; import { StateMachineComponent } from './state-machine-component'; import { InteractiveState } from './state'; +import { + AnimationGraphBindingContext, AnimationGraphEvaluationContext, + AnimationGraphLayerWideBindingContext, AnimationGraphPoseLayoutMaintainer, defaultTransformsTag, LayoutChangeFlag, MetaValueRegistry, +} from './animation-graph-context'; +import { TransformArray } from '../core/transform-array'; +import { applyDeltaPose, blendPoseInto, Pose, TransformFilter } from '../core/pose'; export class AnimationGraphEval { private declare _layerEvaluations: LayerEval[]; - private _blendBuffer = new LayeredBlendStateBuffer(); private _currentTransitionCache: TransitionStatus = { duration: 0.0, time: 0.0, }; - constructor (graph: AnimationGraph, root: Node, controller: AnimationController) { + constructor (graph: AnimationGraph, root: Node, controller: AnimationController, clipOverrides: ReadonlyClipOverrideMap | null) { if (DEBUG) { if (graph.layers.length >= MAX_ANIMATION_LAYER) { throw new Error( @@ -50,50 +76,62 @@ export class AnimationGraphEval { } } - const context: LayerContext = { - controller, - blendBuffer: this._blendBuffer, - node: root, - getVar: (id: string): VarInstance | undefined => this._varInstances[id], - triggerResetFn: (name: string) => { - this.setValue(name, false); - }, + const triggerResetFn = (name: string) => { + this.setValue(name, false); }; - const layerEvaluations = this._layerEvaluations = graph.layers.map((layer) => { - const layerEval = new LayerEval(layer, { - ...context, - mask: layer.mask ?? undefined, - }); + const poseLayoutMaintainer = new AnimationGraphPoseLayoutMaintainer(this._metaValueRegistry); + this._poseLayoutMaintainer = poseLayoutMaintainer; + + const bindingContext = new AnimationGraphBindingContext(root, poseLayoutMaintainer, this._varInstances); + this._bindingContext = bindingContext; + + poseLayoutMaintainer.startBind(); + + this._layerEvaluations = graph.layers.map((layer) => { + const layerEval = new LayerEval( + layer, + bindingContext, + clipOverrides, + controller, + triggerResetFn, + ); return layerEval; }); - // Set layer masks. - const nLayers = layerEvaluations.length; - for (let iLayer = 0; iLayer < nLayers; ++iLayer) { - const mask = graph.layers[iLayer].mask; - if (mask) { - const excludeNodes = mask.filterDisabledNodes(context.node); - this._blendBuffer.setMask(iLayer, excludeNodes); - } - } + this._root = root; + this._initializeContexts(); + } + + public destroy () { + this._evaluationContext.destroy(); + } + + public get layerCount () { + return this._layerEvaluations.length; } public update (deltaTime: number) { const { - _blendBuffer: blendBuffer, _layerEvaluations: layerEvaluations, + _evaluationContext: evaluationContext, + _poseLayoutMaintainer: poseLayoutMaintainer, } = this; - graphDebugGroup(`New frame started.`); - if (GRAPH_DEBUG_ENABLED) { - clearWeightsStats(); - } + + const finalPose = evaluationContext.pushDefaultedPose(); const nLayers = layerEvaluations.length; for (let iLayer = 0; iLayer < nLayers; ++iLayer) { const layerEval = layerEvaluations[iLayer]; - layerEval.update(deltaTime); - blendBuffer.commitLayerChanges(iLayer, layerEval.weight * layerEval.passthroughWeight); + const layerPose = layerEval.update(deltaTime, evaluationContext); + const layerActualWeight = layerEval.weight * layerEval.passthroughWeight; + if (layerEval.additive) { + applyDeltaPose(finalPose, layerPose, layerActualWeight, layerEval.transformFilter); + } else { + blendPoseInto(finalPose, layerPose, layerActualWeight, layerEval.transformFilter); + } + evaluationContext.popPose(); } + if (this._hasAutoTrigger) { const { _varInstances: varInstances } = this; for (const varName in varInstances) { @@ -104,11 +142,13 @@ export class AnimationGraphEval { } } } - if (GRAPH_DEBUG_ENABLED) { - graphDebug(`Weights: ${getWeightsStats()}`); + + poseLayoutMaintainer.apply(finalPose); + evaluationContext.popPose(); + + if (DEBUG) { + assertIsTrue(evaluationContext.allocatedPoseCount === 0, `Pose leaked.`); } - this._blendBuffer.apply(); - graphDebugGroupEnd(); } public getVariables (): Iterable]>> { @@ -137,7 +177,6 @@ export class AnimationGraphEval { } public getNextClipStatuses (layer: number): Iterable> { - assertIsNonNullable(this.getCurrentTransition(layer), '!!this.getCurrentTransition(layer)'); return this._layerEvaluations[layer].getNextClipStatuses(); } @@ -159,17 +198,143 @@ export class AnimationGraphEval { } public getLayerWeight (layerIndex: number) { + assertIsTrue(layerIndex >= 0 && layerIndex < this._layerEvaluations.length, `Invalid layer index`); return this._layerEvaluations[layerIndex].weight; } public setLayerWeight (layerIndex: number, weight: number) { + assertIsTrue(layerIndex >= 0 && layerIndex < this._layerEvaluations.length, `Invalid layer index`); this._layerEvaluations[layerIndex].weight = weight; } + public overrideClips (overrides: ReadonlyClipOverrideMap) { + const { + _poseLayoutMaintainer: poseLayoutMaintainer, + _layerEvaluations: layerEvaluations, + } = this; + + poseLayoutMaintainer.startBind(); + + const nLayers = layerEvaluations.length; + for (let iLayer = 0; iLayer < nLayers; ++iLayer) { + const layerEval = layerEvaluations[iLayer]; + layerEval.overrideClips(overrides, this._bindingContext); + } + + this._updateAfterPossiblePoseLayoutChange(); + } + private _varInstances: Record = {}; private _hasAutoTrigger = false; + private _metaValueRegistry = new MetaValueRegistry(); + private _poseLayoutMaintainer: AnimationGraphPoseLayoutMaintainer; + private _bindingContext: AnimationGraphBindingContext; + /** + * Preserved here for clip overriding. + */ + private declare _root: Node; + private declare _evaluationContext: AnimationGraphEvaluationContext; + + private _initializeContexts () { + const { + _poseLayoutMaintainer: poseLayoutMaintainer, + } = this; + + // Ignore in initialization. + // eslint-disable-next-line no-void + void poseLayoutMaintainer.endBind(); + + this._createOrUpdateTransformFilters(); + + const evaluationContext = new AnimationGraphEvaluationContext({ + transformCount: poseLayoutMaintainer.transformCount, + metaValueCount: poseLayoutMaintainer.metaValueCount, + }); + this._evaluationContext = evaluationContext; + + // Capture the default transforms. + poseLayoutMaintainer.fetchDefaultTransforms(evaluationContext[defaultTransformsTag]); + } + + private _updateAfterPossiblePoseLayoutChange () { + const { + _poseLayoutMaintainer: poseLayoutMaintainer, + } = this; + + const layoutChangeFlags = poseLayoutMaintainer.endBind(); + + // Nothing changed, this should be the commonest case in real world. + if (layoutChangeFlags === 0) { + return; + } + + // No matter count or order changed, we should update the transform filters. + if ((layoutChangeFlags & LayoutChangeFlag.TRANSFORM_COUNT) + || (layoutChangeFlags & LayoutChangeFlag.TRANSFORM_ORDER)) { + this._createOrUpdateTransformFilters(); + } + + // Either transform count or meta value count changed, we should recreate the eval context. + let evaluationContextRecreated = false; + if ((layoutChangeFlags & LayoutChangeFlag.TRANSFORM_COUNT) + || (layoutChangeFlags & LayoutChangeFlag.META_VALUE_COUNT)) { + const evaluationContext = new AnimationGraphEvaluationContext({ + transformCount: poseLayoutMaintainer.transformCount, + metaValueCount: poseLayoutMaintainer.metaValueCount, + }); + this._evaluationContext.destroy(); + this._evaluationContext = evaluationContext; + evaluationContextRecreated = true; + } + + // If the eval context was recreated or the layout has changed, we should update the default transforms. + if (evaluationContextRecreated + || (layoutChangeFlags & LayoutChangeFlag.TRANSFORM_COUNT) + || (layoutChangeFlags & LayoutChangeFlag.TRANSFORM_ORDER)) { + poseLayoutMaintainer.fetchDefaultTransforms(this._evaluationContext[defaultTransformsTag]); + } + } + + private _createOrUpdateTransformFilters () { + const { + _layerEvaluations: layerEvaluations, + _poseLayoutMaintainer: poseLayoutMaintainer, + _root: root, + } = this; + + const nLayers = layerEvaluations.length; + for (let iLayer = 0; iLayer < nLayers; ++iLayer) { + const mask = layerEvaluations[iLayer].mask; + if (mask) { + const transformFilter = poseLayoutMaintainer.createTransformFilter(mask, root); + layerEvaluations[iLayer].transformFilter = transformFilter; + } + } + } } +/** + * @zh + * 描述了如何对动画图中引用的动画剪辑进行替换。 + * @en + * Describes how to override animation clips in an animation graph. + */ +export type ReadonlyClipOverrideMap = { + /** + * @zh + * 获取指定原始动画剪辑应替换成的动画剪辑。 + * @en + * Gets the overriding animation clip of specified original animation clip. + * + * @param animationClip @zh 原始动画剪辑。@en Original animation clip. + * + * @returns @zh 替换的动画剪辑;如果原始动画剪辑不应被替换,则应该返回 `undefined`。 @en + * The overriding animation clip. + * If the original animation clip should not be overrode, `undefined` should be returned. + */ + get(animationClip: AnimationClip): AnimationClip | undefined; +}; + /** * @en * Runtime status of a transition. @@ -248,31 +413,6 @@ export interface MotionStateStatus { type TriggerResetFn = (name: string) => void; -interface LayerContext extends BindContext { - controller: AnimationController; - - /** - * The root node bind to the graph. - */ - node: Node; - - /** - * The blend buffer. - */ - blendBuffer: BlendStateBuffer; - - /** - * The mask applied to this layer. - */ - mask?: AnimationMask; - - /** - * TODO: A little hacky. - * A function which resets specified trigger. This function can be stored. - */ - triggerResetFn: TriggerResetFn; -} - class LayerEval { public declare name: string; @@ -280,17 +420,47 @@ class LayerEval { public passthroughWeight = 1.0; - constructor (layer: Layer, context: LayerContext) { + /** Used by top level eval. */ + public transformFilter: TransformFilter | undefined = undefined; + + /** Used by top level eval. */ + public declare readonly additive: boolean; + + /** Used by top level eval. */ + public get mask () { + return this._mask; + } + + constructor ( + layer: Layer, + context: AnimationGraphBindingContext, + clipOverrides: ReadonlyClipOverrideMap | null, + controller: AnimationController, + triggerResetFn: TriggerResetFn, + ) { + const isAdditiveLayer = layer.additive; + this.name = layer.name; - this._controller = context.controller; + this._controller = controller; this.weight = layer.weight; - const { entry, exit } = this._addStateMachine(layer.stateMachine, null, { - ...context, - }, layer.name); + this.additive = isAdditiveLayer; + const myContext: AnimationGraphLayerWideBindingContext = { + outerContext: context, + additive: isAdditiveLayer, + }; + const { entry, exit } = this._addStateMachine( + layer.stateMachine, + null, + myContext, + clipOverrides, + layer.name, + ); this._topLevelEntry = entry; this._topLevelExit = exit; this._currentNode = entry; - this._resetTrigger = context.triggerResetFn; + this._resetTrigger = triggerResetFn; + + this._mask = layer.mask; } /** @@ -300,13 +470,17 @@ class LayerEval { return this._currentNode === this._topLevelExit; } - public update (deltaTime: number) { + public update (deltaTime: number, context: AnimationGraphEvaluationContext): Pose { if (!this.exited) { - this._fromWeight = 1.0; - this._toWeight = 0.0; + this._transitionAlpha = 0.0; this._eval(deltaTime); - this._sample(); + const sampled = this._sample(context); + if (sampled) { + return sampled; + } + // fallthrough } + return this._pushNullishPose(context); } public getCurrentStateStatus (): Readonly | null { @@ -323,9 +497,9 @@ class LayerEval { public getCurrentClipStatuses (): Iterable { const { _currentNode: currentNode } = this; if (currentNode.kind === NodeKind.animation) { - return currentNode.getClipStatuses(this._fromWeight); + return currentNode.getClipStatuses(1.0 - this._transitionAlpha); } else if (currentNode.kind === NodeKind.transitionSnapshot) { - return currentNode.first.getClipStatuses(this._fromWeight); + return currentNode.first.getClipStatuses(1.0 - this._transitionAlpha); } else { return emptyClipStatusesIterable; } @@ -335,7 +509,7 @@ class LayerEval { const { _currentTransitionPath: currentTransitionPath } = this; if (currentTransitionPath.length !== 0) { const lastNode = currentTransitionPath[currentTransitionPath.length - 1]; - if (lastNode.to.kind !== NodeKind.animation) { + if (lastNode.to.kind !== NodeKind.animation && lastNode.to.kind !== NodeKind.empty) { return false; } const { @@ -358,24 +532,46 @@ class LayerEval { } public getNextStateStatus (): Readonly | null { - assertIsTrue( - this._currentTransitionToNode && this._currentTransitionToNode.kind !== NodeKind.empty, - 'There is no transition currently in layer.', - ); + if (!this._currentTransitionToNode + || this._currentTransitionToNode.kind === NodeKind.empty) { + return null; + } return this._currentTransitionToNode.getToPortStatus(); } public getNextClipStatuses (): Iterable { const { _currentTransitionPath: currentTransitionPath } = this; const nCurrentTransitionPath = currentTransitionPath.length; - assertIsTrue(nCurrentTransitionPath > 0, 'There is no transition currently in layer.'); + if (nCurrentTransitionPath === 0) { + return emptyClipStatusesIterable; + } const to = currentTransitionPath[nCurrentTransitionPath - 1].to; - assertIsTrue(to.kind === NodeKind.animation); - return to.getClipStatuses(this._toWeight) ?? emptyClipStatusesIterable; + if (to.kind !== NodeKind.animation) { + return emptyClipStatusesIterable; + } + return to.getClipStatuses(this._transitionAlpha) ?? emptyClipStatusesIterable; + } + + public overrideClips (overrides: ReadonlyClipOverrideMap, context: AnimationGraphBindingContext) { + const { _motionStates: motionStates } = this; + const nMotionStates = motionStates.length; + const myContext: AnimationGraphLayerWideBindingContext = { + outerContext: context, + additive: this.additive, + }; + for (let iMotionState = 0; iMotionState < nMotionStates; ++iMotionState) { + const node = motionStates[iMotionState]; + if (node.kind === NodeKind.animation) { + node.overrideClips(overrides, myContext); + } + } } private declare _controller: AnimationController; - private _nodes: NodeEval[] = []; + /** + * Preserved here for clip overriding. + */ + private _motionStates: MotionStateEval[] = []; private _topLevelEntry: NodeEval; private _topLevelExit: NodeEval; private _currentNode: NodeEval; @@ -383,17 +579,24 @@ class LayerEval { private _currentTransitionPath: TransitionEval[] = []; private _transitionProgress = 0; private declare _triggerReset: TriggerResetFn; - private _fromWeight = 0.0; - private _toWeight = 0.0; + private _transitionAlpha = 0.0; private _fromUpdated = false; private _toUpdated = false; /** * A virtual state which represents the transition snapshot captured when a transition is interrupted. */ private _transitionSnapshot = new TransitionSnapshotEval(); + /** + * Preserved here for clip overriding. + */ + private _mask: AnimationMask | null = null; private _addStateMachine ( - graph: StateMachine, parentStateMachineInfo: StateMachineInfo | null, context: LayerContext, __DEBUG_ID__: string, + graph: StateMachine, + parentStateMachineInfo: StateMachineInfo | null, + context: AnimationGraphLayerWideBindingContext, + clipOverrides: ReadonlyClipOverrideMap | null, + __DEBUG_ID__: string, ): StateMachineInfo { const nodes = Array.from(graph.states()); @@ -403,7 +606,9 @@ class LayerEval { const nodeEvaluations = nodes.map((node): NodeEval | null => { if (node instanceof MotionState) { - return new MotionStateEval(node, context); + const motionStateEval = new MotionStateEval(node, context, clipOverrides); + this._motionStates.push(motionStateEval); + return motionStateEval; } else if (node === graph.entryState) { return entryEval = new SpecialStateEval(node, NodeKind.entry, node.name); } else if (node === graph.exitState) { @@ -439,7 +644,13 @@ class LayerEval { const subStateMachineInfos = nodes.map((node) => { if (node instanceof SubStateMachine) { - const subStateMachineInfo = this._addStateMachine(node.stateMachine, stateMachineInfo, context, `${__DEBUG_ID__}/${node.name}`); + const subStateMachineInfo = this._addStateMachine( + node.stateMachine, + stateMachineInfo, + context, + clipOverrides, + `${__DEBUG_ID__}/${node.name}`, + ); subStateMachineInfo.components = new InstantiatedComponents(node); return subStateMachineInfo; } else { @@ -489,7 +700,7 @@ class LayerEval { toNode = nodeEval; } - const conditions = outgoing.conditions.map((condition) => condition[createEval](context)); + const conditions = outgoing.conditions.map((condition) => condition[createEval](context.outerContext)); const transitionEval: TransitionEval = { conditions, @@ -502,6 +713,7 @@ class LayerEval { exitCondition: 0.0, exitConditionEnabled: false, interruption: TransitionInterruptionSource.NONE, + activated: false, }; if (isAnimationTransition(outgoing)) { @@ -541,7 +753,6 @@ class LayerEval { */ private _eval (deltaTime: Readonly) { assertIsTrue(!this.exited); - graphDebugGroup(`[Layer ${this.name}]: UpdateStart ${deltaTime}s`); const haltOnNonMotionState = this._continueDanglingTransition(); if (haltOnNonMotionState) { @@ -549,7 +760,6 @@ class LayerEval { } const MAX_ITERATIONS = 100; - let passConsumed = 0.0; let remainTimePiece = deltaTime; for (let continueNextIterationForce = true, // Force next iteration even remain time piece is zero @@ -558,21 +768,11 @@ class LayerEval { ) { continueNextIterationForce = false; - if (iterations !== 0) { - graphDebug(`Pass end. Consumed ${passConsumed}s, remain: ${remainTimePiece}s`); - } - if (iterations === MAX_ITERATIONS) { warnID(14000, MAX_ITERATIONS); break; } - graphDebug(`Pass ${iterations} started.`); - - if (GRAPH_DEBUG_ENABLED) { - passConsumed = 0.0; - } - ++iterations; // Update current transition if we're in transition. @@ -590,9 +790,6 @@ class LayerEval { } const currentUpdatingConsume = this._updateCurrentTransition(remainTimePiece); - if (GRAPH_DEBUG_ENABLED) { - passConsumed = currentUpdatingConsume; - } remainTimePiece -= currentUpdatingConsume; if (this._currentNode.kind === NodeKind.exit) { break; @@ -615,10 +812,6 @@ class LayerEval { requires: updateRequires, } = transitionMatch; - graphDebug(`[SubStateMachine ${this.name}]: CurrentNodeUpdate: ${currentNode.name}`); - if (GRAPH_DEBUG_ENABLED) { - passConsumed = updateRequires; - } remainTimePiece -= updateRequires; if (currentNode.kind === NodeKind.animation) { @@ -633,7 +826,6 @@ class LayerEval { continueNextIterationForce = true; } else { // If no transition matched, we update current node. - graphDebug(`[SubStateMachine ${this.name}]: CurrentNodeUpdate: ${currentNode.name}`); if (currentNode.kind === NodeKind.animation) { currentNode.updateFromPort(remainTimePiece); this._fromUpdated = true; @@ -645,16 +837,10 @@ class LayerEval { // I'm sure conscious of it's redundant with above statement, just emphasize. remainTimePiece = 0.0; } - if (GRAPH_DEBUG_ENABLED) { - passConsumed = remainTimePiece; - } continue; } } - graphDebug(`[SubStateMachine ${this.name}]: UpdateEnd`); - graphDebugGroupEnd(); - if (this._fromUpdated && this._currentNode.kind === NodeKind.animation) { this._fromUpdated = false; this._currentNode.triggerFromPortUpdate(this._controller); @@ -668,39 +854,59 @@ class LayerEval { return remainTimePiece; } - private _sample () { + private _sample (context: AnimationGraphEvaluationContext): Pose | null { const { _currentNode: currentNode, _currentTransitionToNode: currentTransitionToNode, - _fromWeight: fromWeight, - _toWeight: toWeight, + _transitionAlpha: transitionAlpha, } = this; if (currentNode.kind === NodeKind.empty) { - this.passthroughWeight = toWeight; + // If current state is empty: + // - if there is no transition, the passthrough weight is 0.0, means this layer has no effect. + // - otherwise, + // - if the destination is also empty state, it's as if no transition. + // - otherwise, asserts the destination to be motion state; + // the passthrough weight is set to the transition rate, + // the motion state is sampled with full weight. + this.passthroughWeight = 0.0; if (currentTransitionToNode && currentTransitionToNode.kind === NodeKind.animation) { - currentTransitionToNode.sampleToPort(1.0); + this.passthroughWeight = transitionAlpha; + return currentTransitionToNode.sampleToPort(context); } } else if (currentTransitionToNode && currentTransitionToNode.kind === NodeKind.empty) { - this.passthroughWeight = fromWeight; - this._sampleSource(1.0); + this.passthroughWeight = (1.0 - transitionAlpha); + return this._sampleSource(context); } else { this.passthroughWeight = 1.0; - this._sampleSource(fromWeight); + const sourcePose = this._sampleSource(context) ?? this._pushNullishPose(context); if (currentTransitionToNode && currentTransitionToNode.kind === NodeKind.animation) { - currentTransitionToNode.sampleToPort(toWeight); + const destPose = currentTransitionToNode.sampleToPort(context) ?? this._pushNullishPose(context); + blendPoseInto(sourcePose, destPose, transitionAlpha); + context.popPose(); + return sourcePose; + } else { + return sourcePose; } } + return null; } - private _sampleSource (weight: number) { + private _sampleSource (context: AnimationGraphEvaluationContext): Pose | null { const { _currentNode: currentNode, } = this; if (currentNode.kind === NodeKind.animation) { - currentNode.sampleFromPort(weight); + return currentNode.sampleFromPort(context); } else if (currentNode.kind === NodeKind.transitionSnapshot) { - currentNode.sample(weight); + return currentNode.sample(context); } + return null; + } + + private _pushNullishPose (context: AnimationGraphEvaluationContext) { + return this.additive + ? context.pushZeroDeltaPose() + : context.pushDefaultedPose(); } /** @@ -718,7 +924,6 @@ class LayerEval { currentNode, currentNode, deltaTime, - null, transitionMatch, ); if (transitionMatch.hasZeroCost()) { @@ -757,7 +962,6 @@ class LayerEval { ancestor.any, realNode, deltaTime, - null, result, ); if (updated) { @@ -777,7 +981,7 @@ class LayerEval { * @returns True if a transition match is updated into the `result`. */ private _matchTransition ( - node: NodeEval, realNode: NodeEval, deltaTime: Readonly, except: TransitionEval | null, result: TransitionMatchCache, + node: NodeEval, realNode: NodeEval, deltaTime: Readonly, result: TransitionMatchCache, ) { assertIsTrue(node === realNode || node.kind === NodeKind.any); const { outgoingTransitions } = node; @@ -785,7 +989,7 @@ class LayerEval { let resultUpdated = false; for (let iTransition = 0; iTransition < nTransitions; ++iTransition) { const transition = outgoingTransitions[iTransition]; - if (transition === except) { + if (transition.activated) { continue; } @@ -849,10 +1053,7 @@ class LayerEval { * @returns If the transition finally ran into entry/exit state. */ private _switchTo (transition: TransitionEval) { - const { _currentTransitionPath: currentTransitionPath } = this; - this._consumeTransition(transition); - currentTransitionPath.push(transition); const motionNode = this._matchTransitionPathUntilMotion(); if (motionNode) { @@ -912,7 +1113,6 @@ class LayerEval { tailNode, tailNode, 0.0, - null, transitionMatch, ); if (!transitionMatch.transition) { @@ -920,7 +1120,6 @@ class LayerEval { } const transition = transitionMatch.transition; this._consumeTransition(transition); - currentTransitionPath.push(transition); tailNode = transition.to; } @@ -934,6 +1133,9 @@ class LayerEval { // We're entering a state machine this._callEnterMethods(to); } + + transition.activated = true; + this._currentTransitionPath.push(transition); } private _resetTriggersAlongThePath () { @@ -1023,31 +1225,23 @@ class LayerEval { const toNodeName = toNode?.name ?? ''; - this._fromWeight = (1.0 - ratio); - this._toWeight = ratio; + this._transitionAlpha = ratio; const shouldUpdatePorts = contrib !== 0; const hasFinished = ratio === 1.0; if (fromNode.kind === NodeKind.animation && shouldUpdatePorts) { - graphDebugGroup(`Update ${fromNode.name}`); fromNode.updateFromPort(contrib); this._fromUpdated = true; - graphDebugGroupEnd(); } if (toNode.kind === NodeKind.animation && shouldUpdatePorts) { - graphDebugGroup(`Update ${toNode.name}`); toNode.updateToPort(contrib); this._toUpdated = true; - graphDebugGroupEnd(); } - graphDebugGroupEnd(); - if (hasFinished) { // Transition done. - graphDebug(`[SubStateMachine ${this.name}]: Transition finished: ${fromNode.name} -> ${toNodeName}.`); this._finishCurrentTransition(); } @@ -1080,26 +1274,32 @@ class LayerEval { } this._fromUpdated = this._toUpdated; this._toUpdated = false; - this._dropCurrentTransition(); + this._dropCurrentTransition(true); this._currentNode = toNode; if (fromNode.kind === NodeKind.transitionSnapshot) { fromNode.clear(); } } - private _dropCurrentTransition () { + private _dropCurrentTransition (inactivate: boolean) { const { + _currentTransitionPath: currentTransitionPath, _currentTransitionToNode: currentTransitionToNode, } = this; assertIsNonNullable(currentTransitionToNode); if (currentTransitionToNode.kind === NodeKind.animation) { currentTransitionToNode.finishTransition(); } + if (inactivate) { + const nTransitions = currentTransitionPath.length; + for (let iTransition = 0; iTransition < nTransitions; ++iTransition) { + currentTransitionPath[iTransition].activated = false; + } + } this._currentTransitionToNode = null; - this._currentTransitionPath.length = 0; + currentTransitionPath.length = 0; // Make sure we won't suffer from precision problem - this._fromWeight = 1.0; - this._toWeight = 0.0; + this._transitionAlpha = 0.0; } private _detectInterruption (remainTimePiece: number, result: InterruptingTransitionMatchCache): InterruptingTransitionMatch | null { @@ -1154,7 +1354,6 @@ class LayerEval { motion0, motion0, remainTimePiece, - currentTransition, transitionMatch, ); if (transitionMatchUpdated) { @@ -1172,7 +1371,6 @@ class LayerEval { motion1, motion1, remainTimePiece, - currentTransition, transitionMatch, ); if (transitionMatchUpdated) { @@ -1218,7 +1416,10 @@ class LayerEval { transitionSnapshot.enqueue(currentNode, 1.0); } this._takeCurrentTransitionSnapshot(transitionSource); - this._dropCurrentTransition(); + // Drop transitions. + // Do not inactivate the transitions since in snapshot mode, transitions are treated as inactivated. + // They will be inactivated when the snapshot is cleared. + this._dropCurrentTransition(false); // Install the snapshot as "current" this._currentNode = this._transitionSnapshot; const ranIntoNonMotionState = this._switchTo(transition); @@ -1260,6 +1461,7 @@ class LayerEval { } transitionSnapshot.enqueue(currentTransitionToNode, ratio); + transitionSnapshot.transferTransitions(currentTransitionPath); } private _resetTriggersOnTransition (transition: TransitionEval) { @@ -1521,7 +1723,7 @@ interface StateMachineInfo { } export class MotionStateEval extends StateEval { - constructor (node: MotionState, context: LayerContext) { + constructor (node: MotionState, context: AnimationGraphLayerWideBindingContext, overrides: ReadonlyClipOverrideMap | null) { super(node); this._baseSpeed = node.speed; @@ -1529,7 +1731,7 @@ export class MotionStateEval extends StateEval { if (node.speedMultiplierEnabled && node.speedMultiplier) { const speedMultiplierVarName = node.speedMultiplier; - const varInstance = context.getVar(speedMultiplierVarName); + const varInstance = context.outerContext.getVar(speedMultiplierVarName); if (validateVariableExistence(varInstance, speedMultiplierVarName)) { validateVariableType(varInstance.type, VariableType.FLOAT, speedMultiplierVarName); varInstance.bind(this._setSpeedMultiplier, this); @@ -1538,14 +1740,16 @@ export class MotionStateEval extends StateEval { } } - const sourceEvalContext: MotionEvalContext = { - ...context, - }; - const sourceEval = node.motion?.[createEval](sourceEvalContext) ?? null; + const sourceEval = node.motion?.[createEval](context, overrides) ?? null; if (sourceEval) { Object.defineProperty(sourceEval, '__DEBUG_ID__', { value: this.name }); } + this._source = sourceEval; + + this._fromPort = new MotionStateEvalPort(sourceEval?.createPort() ?? null); + this._toPort = new MotionStateEvalPort(sourceEval?.createPort() ?? null); + this.components = new InstantiatedComponents(node); } @@ -1590,12 +1794,7 @@ export class MotionStateEval extends StateEval { } public getFromPortStatus (): Readonly { - const { statusCache: stateStatus } = this._fromPort; - if (DEBUG) { - stateStatus.__DEBUG_ID__ = this.name; - } - stateStatus.progress = normalizeProgress(this._fromPort.progress); - return stateStatus; + return this._fromPort.getStatus(this.name); } public getToPortStatus (): Readonly { @@ -1603,12 +1802,7 @@ export class MotionStateEval extends StateEval { // See `this.finishTransition()` assertIsTrue(!Number.isNaN(this._toPort.progress)); } - const { statusCache: stateStatus } = this._toPort; - if (DEBUG) { - stateStatus.__DEBUG_ID__ = this.name; - } - stateStatus.progress = normalizeProgress(this._toPort.progress); - return stateStatus; + return this._toPort.getStatus(this.name); } public resetToPort (at: number) { @@ -1629,16 +1823,16 @@ export class MotionStateEval extends StateEval { } } - public sampleFromPort (weight: number) { - this._source?.sample(this._fromPort.progress, weight); + public sampleFromPort (context: AnimationGraphEvaluationContext): Pose | null { + return this._fromPort.evaluate(context) ?? null; } - public sampleToPort (weight: number) { + public sampleToPort (context: AnimationGraphEvaluationContext): Pose | null { if (DEBUG) { // See `this.finishTransition()` assertIsTrue(!Number.isNaN(this._toPort.progress)); } - this._source?.sample(this._toPort.progress, weight); + return this._toPort.evaluate(context) ?? null; } public getClipStatuses (baseWeight: number): Iterable { @@ -1652,23 +1846,46 @@ export class MotionStateEval extends StateEval { } } + public overrideClips (overrides: ReadonlyClipOverrideMap, context: AnimationGraphLayerWideBindingContext) { + this._source?.overrideClips(overrides, context); + } + private _source: MotionEval | null = null; + private _fromPort: MotionStateEvalPort; + private _toPort: MotionStateEvalPort; private _baseSpeed = 1.0; private _speed = 1.0; - private _fromPort: MotionEvalPort = { - progress: 0.0, - statusCache: createStateStatusCache(), - }; - private _toPort: MotionEvalPort = { - progress: 0.0, - statusCache: createStateStatusCache(), - }; private _setSpeedMultiplier (value: number) { this._speed = this._baseSpeed * value; } } +class MotionStateEvalPort { + constructor (motionPort: MotionPort | null) { + this.motionPort = motionPort; + } + + public readonly motionPort: MotionPort | null = null; + + public progress = 0.0; + + public readonly statusCache: MotionStateStatus = createStateStatusCache(); + + public evaluate (context: AnimationGraphEvaluationContext) { + return this.motionPort?.evaluate(this.progress, context); + } + + public getStatus (name: string): Readonly { + const { statusCache: stateStatus } = this; + if (DEBUG) { + stateStatus.__DEBUG_ID__ = name; + } + stateStatus.progress = normalizeProgress(this.progress); + return stateStatus; + } +} + function calcProgressUpdate (currentProgress: number, duration: number, deltaTime: number) { if (duration === 0.0) { // TODO? @@ -1683,11 +1900,6 @@ function normalizeProgress (progress: number) { return signedFrac >= 0.0 ? signedFrac : (1.0 + signedFrac); } -interface MotionEvalPort { - progress: number; - statusCache: MotionStateStatus; -} - export class SpecialStateEval extends StateEval { constructor (node: State, kind: SpecialStateEval['kind'], name: string) { super(node); @@ -1727,21 +1939,41 @@ class TransitionSnapshotEval extends StateEval { return queue[0].motion; } - public sample (weight: number) { + public sample (context: AnimationGraphEvaluationContext): Pose { const { _queue: queue } = this; const nQueue = queue.length; + assertIsTrue(nQueue !== 0); + let finalPose: Pose | null = null; + let sumWeight = 0.0; for (let iQueuedMotions = 0; iQueuedMotions < nQueue; ++iQueuedMotions) { const { motion, weight: snapshotWeight, } = queue[iQueuedMotions]; // Here implies: motions added to snapshot should have been switched from "target" to "source". - motion.sampleFromPort(snapshotWeight * weight); + const queuedMotionPose = motion.sampleFromPort(context) ?? context.pushDefaultedPose(); + sumWeight += snapshotWeight; + if (!finalPose) { + finalPose = queuedMotionPose; + } else { + if (sumWeight) { + const t = snapshotWeight / sumWeight; + blendPoseInto(finalPose, queuedMotionPose, t); + } + context.popPose(); + } } + return finalPose ?? context.pushDefaultedPose(); } public clear () { this._queue.length = 0; + + const { _heldTransitions: heldTransitions } = this; + const nTransitions = heldTransitions.length; + for (let iTransition = 0; iTransition < nTransitions; ++iTransition) { + heldTransitions[iTransition].activated = false; + } } public enqueue (state: MotionStateEval, weight: number) { @@ -1754,7 +1986,15 @@ class TransitionSnapshotEval extends StateEval { queue.push(new QueuedMotion(state, weight)); } + public transferTransitions (transitions: readonly TransitionEval[]) { + if (DEBUG) { + assertIsTrue(transitions.every((transition) => transition.activated)); + } + this._heldTransitions.push(...transitions); + } + private _queue: QueuedMotion[] = []; + private _heldTransitions: TransitionEval[] = []; } export type NodeEval = MotionStateEval | SpecialStateEval | EmptyStateEval | TransitionSnapshotEval; @@ -1773,6 +2013,11 @@ interface TransitionEval { */ triggers: string[] | undefined; interruption: TransitionInterruptionSource; + + /** + * Whether the transition is activated, if it has already been activated, it can not be activated(matched) again. + */ + activated: boolean; } export type { VarInstance } from './variable'; diff --git a/cocos/animation/marionette/index-empty.ts b/cocos/animation/marionette/index-empty.ts index 336ce12bb91..4d527fe9699 100644 --- a/cocos/animation/marionette/index-empty.ts +++ b/cocos/animation/marionette/index-empty.ts @@ -1 +1,25 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export {} diff --git a/cocos/animation/marionette/motion-state.ts b/cocos/animation/marionette/motion-state.ts index 56b3e5f46c6..35e6b62630a 100644 --- a/cocos/animation/marionette/motion-state.ts +++ b/cocos/animation/marionette/motion-state.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; import { Motion } from './motion'; import { State, InteractiveState } from './state'; @@ -21,12 +45,18 @@ export class MotionState extends InteractiveState { @serializable public speedMultiplierEnabled = false; - public clone () { - const that = new MotionState(); + public copyTo (that: MotionState) { + super.copyTo(that); that.motion = this.motion?.clone() ?? null; that.speed = this.speed; that.speedMultiplier = this.speedMultiplier; that.speedMultiplierEnabled = this.speedMultiplierEnabled; + return this; + } + + public _clone () { + const that = new MotionState(); + this.copyTo(that); return that; } } diff --git a/cocos/animation/marionette/motion.ts b/cocos/animation/marionette/motion.ts index 9e4976f2943..8872f6dcdd5 100644 --- a/cocos/animation/marionette/motion.ts +++ b/cocos/animation/marionette/motion.ts @@ -1,12 +1,38 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { Node } from '../../scene-graph'; import { AnimationMask } from './animation-mask'; import { createEval } from './create-eval'; import type { BindContext } from './parametric'; import type { BlendStateBuffer } from '../../3d/skeletal-animation/skeletal-animation-blending'; -import type { ClipStatus } from './graph-eval'; +import type { ReadonlyClipOverrideMap, ClipStatus } from './graph-eval'; import type { RuntimeID } from './graph-debug'; +import { AnimationGraphEvaluationContext, AnimationGraphLayerWideBindingContext } from './animation-graph-context'; +import { Pose } from '../core/pose'; -export interface MotionEvalContext extends BindContext { +export interface CreateClipEvalContext { node: Node; blendBuffer: BlendStateBuffer; @@ -14,19 +40,35 @@ export interface MotionEvalContext extends BindContext { mask?: AnimationMask; } +export interface MotionEvalContext extends BindContext, CreateClipEvalContext { + clipOverrides: ReadonlyClipOverrideMap | null; +} + export interface MotionEval { /** * The runtime ID. Maybe invalid. */ readonly runtimeId?: RuntimeID; + /** + * The duration of this motion. If it's a clip motion. + * It should be $duration_{clip} / speed_{clip}$. + */ readonly duration: number; - sample(progress: number, baseWeight: number): void; + getClipStatuses(baseWeight: number): Iterator; + + overrideClips(clipOverrides: ReadonlyClipOverrideMap, context: AnimationGraphLayerWideBindingContext): void; + + createPort(): MotionPort; } export interface Motion { - [createEval] (context: MotionEvalContext): MotionEval | null; + [createEval] (context: AnimationGraphLayerWideBindingContext, clipOverrides: ReadonlyClipOverrideMap | null): MotionEval | null; clone(): Motion; } + +export interface MotionPort { + evaluate(progress: number, context: AnimationGraphEvaluationContext): Pose; +} diff --git a/cocos/animation/marionette/ownership.ts b/cocos/animation/marionette/ownership.ts index c4b1c681fd4..390b0a34c3b 100644 --- a/cocos/animation/marionette/ownership.ts +++ b/cocos/animation/marionette/ownership.ts @@ -1,5 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { DEBUG } from 'internal:constants'; -import { assertIsTrue } from '../../core/data/utils/asserts'; +import { assertIsTrue } from '../../core'; export const ownerSymbol = Symbol('[[Owner]]'); diff --git a/cocos/animation/marionette/parametric.ts b/cocos/animation/marionette/parametric.ts index 5cf635e1a8d..f43d31c0eeb 100644 --- a/cocos/animation/marionette/parametric.ts +++ b/cocos/animation/marionette/parametric.ts @@ -1,4 +1,28 @@ -import { ccclass, serializable } from '../../core/data/decorators'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { _decorator } from '../../core'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { VariableNotDefinedError, VariableTypeMismatchedError } from './errors'; import type { VarInstance } from './graph-eval'; @@ -14,6 +38,8 @@ export interface Bindable { clone(): Bindable; } +const { ccclass, serializable } = _decorator; + @ccclass(`${CLASS_NAME_PREFIX_ANIM}BindableNumber`) export class BindableNumber implements Bindable { @serializable diff --git a/cocos/animation/marionette/runtime-exports.ts b/cocos/animation/marionette/runtime-exports.ts index b31621e42ae..af1296a12c4 100644 --- a/cocos/animation/marionette/runtime-exports.ts +++ b/cocos/animation/marionette/runtime-exports.ts @@ -1,13 +1,39 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import './animation-graph'; import './clip-motion'; import './animation-blend-1d'; import './animation-blend-2d'; import './animation-blend-direct'; import './animation-mask'; +import './animation-graph-variant'; import type { MotionStateStatus } from './animation-controller'; export type { AnimationGraphRunTime } from './animation-graph'; +export type { AnimationGraphVariantRunTime } from './animation-graph-variant'; export { AnimationController } from './animation-controller'; export type { ClipStatus, TransitionStatus, MotionStateStatus } from './animation-controller'; export { VariableType } from './parametric'; diff --git a/cocos/animation/marionette/state-machine-component.ts b/cocos/animation/marionette/state-machine-component.ts index 875fe851202..fad89c52534 100644 --- a/cocos/animation/marionette/state-machine-component.ts +++ b/cocos/animation/marionette/state-machine-component.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass } from 'cc.decorator'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import type { AnimationController, MotionStateStatus } from './animation-controller'; diff --git a/cocos/animation/marionette/state.ts b/cocos/animation/marionette/state.ts index 000ff71a9a3..20732ee303e 100644 --- a/cocos/animation/marionette/state.ts +++ b/cocos/animation/marionette/state.ts @@ -1,16 +1,41 @@ -import { ccclass, serializable } from 'cc.decorator'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { OwnedBy, ownerSymbol } from './ownership'; import type { Layer, StateMachine, TransitionInternal } from './animation-graph'; -import { EditorExtendable } from '../../core/data/editor-extendable'; +import { EditorExtendable, js, editorExtrasTag, _decorator } from '../../core'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { StateMachineComponent } from './state-machine-component'; -import { remove } from '../../core/utils/array'; -import { instantiate } from '../../core/data/instantiate'; +import { instantiate } from '../../serialization/instantiate'; +import { cloneAnimationGraphEditorExtrasFrom } from './animation-graph-editor-extras-clone-helper'; export const outgoingsSymbol = Symbol('[[Outgoing transitions]]'); export const incomingsSymbol = Symbol('[[Incoming transitions]]'); +const { ccclass, serializable } = _decorator; + @ccclass('cc.animation.State') export class State extends EditorExtendable implements OwnedBy { declare [ownerSymbol]: StateMachine | undefined; @@ -25,6 +50,11 @@ export class State extends EditorExtendable implements OwnedBy = Constructor; @@ -42,7 +72,7 @@ export class InteractiveState extends State { } public removeComponent (component: StateMachineComponent) { - remove(this._components, component); + js.array.remove(this._components, component); } public instantiateComponents (): StateMachineComponent[] { @@ -54,6 +84,11 @@ export class InteractiveState extends State { return instantiatedComponents; } + public copyTo (that: InteractiveState) { + super.copyTo(that); + that._components = this.instantiateComponents(); + } + @serializable private _components: StateMachineComponent[] = []; } diff --git a/cocos/animation/marionette/variable.ts b/cocos/animation/marionette/variable.ts index 3906056fdc5..280a92f574d 100644 --- a/cocos/animation/marionette/variable.ts +++ b/cocos/animation/marionette/variable.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /** * @en * Represents variable's value. diff --git a/cocos/animation/motion-path-helper.ts b/cocos/animation/motion-path-helper.ts deleted file mode 100644 index 961d7f9dca5..00000000000 --- a/cocos/animation/motion-path-helper.ts +++ /dev/null @@ -1,433 +0,0 @@ -/* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. - - https://www.cocos.com/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import { binarySearchEpsilon as binarySearch } from '../algorithm/binary-search'; -import { errorID } from '../platform/debug'; -import { Vec2, Vec3 } from '../math'; -import { AnimCurve, computeRatioByType, CurveValue, EasingMethod } from './animation-curve'; -import { bezier } from './bezier'; - -export class Curve { - public beziers: Bezier[] = []; - - public ratios: number[] = []; - - public progresses: number[] = []; - - public length = 0; - - constructor (public points: IControlPoint[] = []) { - this.computeBeziers(); - } - - public computeBeziers () { - this.beziers.length = 0; - this.ratios.length = 0; - this.progresses.length = 0; - this.length = 0; - - for (let i = 1; i < this.points.length; i++) { - const startPoint = this.points[i - 1]; - const endPoint = this.points[i]; - const bezier = new Bezier(); - bezier.start = startPoint.pos; - bezier.startCtrlPoint = startPoint.out; - bezier.end = endPoint.pos; - bezier.endCtrlPoint = endPoint.in; - this.beziers.push(bezier); - - this.length += bezier.getLength(); - } - - let current = 0; - for (let i = 0; i < this.beziers.length; i++) { - const bezier = this.beziers[i]; - this.ratios[i] = bezier.getLength() / this.length; - this.progresses[i] = current = current + this.ratios[i]; - } - - return this.beziers; - } -} - -export class Bezier { - public start = new Vec2(); - - public end = new Vec2(); - - /** - * cp0, cp1 - */ - public startCtrlPoint = new Vec2(); - - /** - * cp2, cp3 - */ - public endCtrlPoint = new Vec2(); - - /** - * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. - */ - public __arcLengthDivisions?: number; - - private cacheArcLengths?: number[]; - - /** - * Get point at relative position in curve according to arc length - * @param u [0 .. 1] - */ - public getPointAt (u: number) { - const t = this.getUtoTmapping(u); - return this.getPoint(t); - } - - /** - * Get point at time t. - * @param t [0 .. 1] - */ - public getPoint (t: number) { - const x = bezier(this.start.x, this.startCtrlPoint.x, this.endCtrlPoint.x, this.end.x, t); - const y = bezier(this.start.y, this.startCtrlPoint.y, this.endCtrlPoint.y, this.end.y, t); - return new Vec2(x, y); - } - - /** - * Get total curve arc length. - */ - public getLength () { - const lengths = this.getLengths(); - return lengths[lengths.length - 1]; - } - - /** - * Get list of cumulative segment lengths. - */ - public getLengths (divisions?: number) { - if (!divisions) { - divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions) : 200; - } - - if (this.cacheArcLengths - && (this.cacheArcLengths.length === divisions + 1)) { - - // console.log( "cached", this.cacheArcLengths ); - return this.cacheArcLengths; - - } - - const cache: number[] = []; - let current; - let last = this.getPoint(0); - const vector = new Vec2(); - let p; - let sum = 0; - - cache.push(0); - - for (p = 1; p <= divisions; p++) { - - current = this.getPoint(p / divisions); - vector.x = last.x - current.x; - vector.y = last.y - current.y; - sum += vector.length(); - cache.push(sum); - last = current; - - } - - this.cacheArcLengths = cache; - - return cache; // { sums: cache, sum:sum }; Sum is in the last element. - } - - public getUtoTmapping (u: number, distance?: number) { - const arcLengths = this.getLengths(); - - let i = 0; - const il = arcLengths.length; - - let targetArcLength; // The targeted u distance value to get - - if (distance) { - targetArcLength = distance; - } else { - targetArcLength = u * arcLengths[il - 1]; - } - - // var time = Date.now(); - - // binary search for the index with largest value smaller than target u distance - - let low = 0; - let high = il - 1; - let comparison; - - while (low <= high) { - // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats - i = Math.floor(low + (high - low) / 2); - comparison = arcLengths[i] - targetArcLength; - if (comparison < 0) { - low = i + 1; - continue; - } else if (comparison > 0) { - high = i - 1; - continue; - } else { - high = i; - break; // DONE - } - } - - i = high; - - // console.log('b' , i, low, high, Date.now()- time); - - if (arcLengths[i] === targetArcLength) { - return i / (il - 1); - } - - // we could get finer grain at lengths, or use simple interpolatation between two points - - const lengthBefore = arcLengths[i]; - const lengthAfter = arcLengths[i + 1]; - - const segmentLength = lengthAfter - lengthBefore; - - // determine where we are between the 'before' and 'after' points - - const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; - - // add that fractional amount to t - - const t = (i + segmentFraction) / (il - 1); - - return t; - } -} - -function checkMotionPath (motionPath) { - if (!Array.isArray(motionPath)) { return false; } - - for (let i = 0, l = motionPath.length; i < l; i++) { - const controls = motionPath[i]; - - if (!Array.isArray(controls) || controls.length !== 6) { return false; } - } - - return true; -} - -interface IControlPoint { - in: Vec2; - pos: Vec2; - out: Vec2; -} - -export type MotionPath = Vec2[]; - -export function sampleMotionPaths (motionPaths: Array<(MotionPath | undefined)>, data: AnimCurve, duration: number, fps: number) { - const createControlPoints = (array: number[] | Vec2): IControlPoint => { - if (array instanceof Vec2) { - return { - in: array, - pos: array, - out: array, - }; - } else if (Array.isArray(array) && array.length === 6) { - return { - in: new Vec2(array[2], array[3]), - pos: new Vec2(array[0], array[1]), - out: new Vec2(array[4], array[5]), - }; - } - return { - in: Vec2.ZERO, - pos: Vec2.ZERO, - out: Vec2.ZERO, - }; - }; - - // @ts-expect-error - const values = data.values = data.values.map((value) => { - if (Array.isArray(value)) { - value = value.length === 2 ? new Vec2(value[0], value[1]) : new Vec3(value[0], value[1], value[2]); - } - return value; - }); - - if (motionPaths.length === 0 || values.length === 0) { - return; - } - - let motionPathValid = false; - for (let i = 0; i < motionPaths.length; i++) { - let motionPath = motionPaths[i]; - if (motionPath && !checkMotionPath(motionPath)) { - errorID(3904, '', 'position', i); - motionPath = undefined; - } - if (motionPath && motionPath.length > 0) { - motionPathValid = true; - break; - } - } - - if (!motionPathValid) { - return; - } - - if (values.length === 1) { - return; - } - - const types = data.types; - // @ts-expect-error - const ratios = (data.ratioSampler ? data.ratioSampler.ratios : []); - - // @ts-expect-error - const newValues: CurveValue[] = data.values = []; - const newTypes: any[] = data.types = []; - // @ts-expect-error - const newRatios: number[] = data.ratios = []; - - function addNewDatas (value: CurveValue, type: any, ratio: number) { - newValues.push(value); - newTypes.push(type); - newRatios.push(ratio); - } - - // ensure every ratio section's length is the same - let startRatioOffset = 0; - - const EPSILON = 1e-6; - let newType: any = AnimCurve.Linear; - - // do not need to compute last path - for (let i = 0, l = motionPaths.length; i < l - 1; i++) { - const motionPath = motionPaths[i]; - - const ratio = ratios[i]; - const nextRatio = ratios[i + 1]; - const betweenRatio = nextRatio - ratio; - - const value = values[i]; - const nextValue = values[i + 1]; - - const type = types && types[i]; - - const results: Vec2[] = []; - let progress = startRatioOffset / betweenRatio; - const speed = 1 / (betweenRatio * duration * fps); - let finalProgress; - - if (motionPath && motionPath.length > 0) { - const points: IControlPoint[] = []; - points.push(createControlPoints(value)); - - for (let j = 0, l2 = motionPath.length; j < l2; j++) { - const controlPoints = createControlPoints(motionPath[j]); - points.push(controlPoints); - } - - points.push(createControlPoints(nextValue)); - - // create Curve to compute beziers - const curve = new Curve(points); - curve.computeBeziers(); - - // sample beziers - const progresses = curve.progresses; - - while (1 - progress > EPSILON) { - finalProgress = progress; - - finalProgress = computeRatioByType(finalProgress, type as EasingMethod); - - let pos = new Vec2(); - - if (finalProgress < 0) { - const bezier = curve.beziers[0]; - const length = (0 - finalProgress) * bezier.getLength(); - const normal = new Vec2(bezier.start); - normal.subtract(bezier.endCtrlPoint); - normal.normalize(); - normal.multiplyScalar(length); - pos.set(bezier.start); - pos.add(normal); - } else if (finalProgress > 1) { - const bezier = curve.beziers[curve.beziers.length - 1]; - const length = (finalProgress - 1) * bezier.getLength(); - const normal = new Vec2(bezier.end); - normal.subtract(bezier.startCtrlPoint); - normal.normalize(); - normal.multiplyScalar(length); - pos.set(bezier.end); - pos.add(normal); - } else { - let bezierIndex = binarySearch(progresses, finalProgress); - if (bezierIndex < 0) { bezierIndex = ~bezierIndex; } - - finalProgress -= bezierIndex > 0 ? progresses[bezierIndex - 1] : 0; - finalProgress = finalProgress / curve.ratios[bezierIndex]; - - pos = curve.beziers[bezierIndex].getPointAt(finalProgress); - } - - results.push(pos); - progress += speed; - } - - } - else { - while (1 - progress > EPSILON) { - finalProgress = progress; - - finalProgress = computeRatioByType(finalProgress, type as EasingMethod); - - results.push(value.lerp(nextValue, finalProgress)); - - progress += speed; - } - } - - newType = type === 'constant' ? type : AnimCurve.Linear; - - for (let j = 0, l2 = results.length; j < l2; j++) { - const newRatio = ratio + startRatioOffset + speed * j * betweenRatio; - addNewDatas(results[j], newType, newRatio); - } - - if (Math.abs(progress - 1) > EPSILON) { // progress > 1 - startRatioOffset = (progress - 1) * betweenRatio; - } - else { - startRatioOffset = 0; - } - } - - if (ratios[ratios.length - 1] !== newRatios[newRatios.length - 1]) { - addNewDatas(values[values.length - 1], newType, ratios[ratios.length - 1]); - } -} diff --git a/cocos/animation/playable.ts b/cocos/animation/playable.ts index d53b5017331..635cd30ca60 100644 --- a/cocos/animation/playable.ts +++ b/cocos/animation/playable.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { getError } from '../core/platform/debug'; +import { getError } from '../core'; export class Playable { /** diff --git a/cocos/animation/pose-output.ts b/cocos/animation/pose-output.ts index d1616d5f8ab..ee6bb9a4201 100644 --- a/cocos/animation/pose-output.ts +++ b/cocos/animation/pose-output.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { BlendStateBuffer, BlendingPropertyName, BlendStateWriter } from '../3d/skeletal-animation/skeletal-animation-blending'; import type { Node } from '../scene-graph'; diff --git a/cocos/animation/skeletal-animation-utils.ts b/cocos/animation/skeletal-animation-utils.ts index 09c9df1f245..3f137e84dde 100644 --- a/cocos/animation/skeletal-animation-utils.ts +++ b/cocos/animation/skeletal-animation-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Mat4 } from '../core/math'; +import { Mat4 } from '../core'; import { Node } from '../scene-graph/node'; const stack: IJointTransform[] = []; diff --git a/cocos/animation/target-path.ts b/cocos/animation/target-path.ts index 575d490a500..daa64ec7623 100644 --- a/cocos/animation/target-path.ts +++ b/cocos/animation/target-path.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; import { Node } from '../scene-graph/node'; -import { warnID } from '../core/platform/debug'; +import { warnID } from '../core'; /** * @deprecated Since V3.3, use [[TrackPath]] instead. diff --git a/cocos/animation/tracks/array-track.ts b/cocos/animation/tracks/array-track.ts index c43d12b79ab..db5f401bbe9 100644 --- a/cocos/animation/tracks/array-track.ts +++ b/cocos/animation/tracks/array-track.ts @@ -1,7 +1,32 @@ -import { ccclass, serializable } from 'cc.decorator'; -import { RealCurve } from '../../core/curves'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { _decorator, RealCurve } from '../../core'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; -import { Channel, RealChannel, RuntimeBinding, Track } from './track'; +import { Channel, RealChannel, RuntimeBinding, Track, TrackEval } from './track'; + +const { ccclass, serializable } = _decorator; /** * @en @@ -56,14 +81,18 @@ export class RealArrayTrack extends Track { private _channels: RealChannel[] = []; } -export class RealArrayTrackEval { +export class RealArrayTrackEval implements TrackEval { constructor ( private _curves: RealCurve[], ) { this._result = new Array(_curves.length).fill(0.0); } - public evaluate (time: number, _runtimeBinding: RuntimeBinding) { + public get requiresDefault () { + return false; + } + + public evaluate (time: number) { const { _result: result, } = this; diff --git a/cocos/animation/tracks/color-track.ts b/cocos/animation/tracks/color-track.ts index 0eaf9bd7a41..b0ce404a6b3 100644 --- a/cocos/animation/tracks/color-track.ts +++ b/cocos/animation/tracks/color-track.ts @@ -1,8 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; -import { RealCurve } from '../../core/curves'; -import { Color } from '../../core/math'; +import { RealCurve, Color } from '../../core'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; -import { Channel, RealChannel, RuntimeBinding, Track } from './track'; +import { Channel, RealChannel, RuntimeBinding, Track, TrackEval } from './track'; import { maskIfEmpty } from './utils'; const CHANNEL_NAMES: ReadonlyArray = ['Red', 'Green', 'Blue', 'Alpha']; @@ -51,7 +74,7 @@ export class ColorTrack extends Track { private _channels: [RealChannel, RealChannel, RealChannel, RealChannel]; } -export class ColorTrackEval { +export class ColorTrackEval implements TrackEval { constructor ( private _x: RealCurve | undefined, private _y: RealCurve | undefined, @@ -61,9 +84,13 @@ export class ColorTrackEval { } - public evaluate (time: number, runtimeBinding: RuntimeBinding) { - if ((!this._x || !this._y || !this._z || !this._w) && runtimeBinding.getValue) { - Color.copy(this._result, runtimeBinding.getValue() as Color); + public get requiresDefault () { + return !this._x || !this._y || !this._z || !this._w; + } + + public evaluate (time: number, defaultValue?: Color) { + if (defaultValue) { + Color.copy(this._result, defaultValue); } if (this._x) { diff --git a/cocos/animation/tracks/object-track.ts b/cocos/animation/tracks/object-track.ts index a57818b5c96..5d895d2a23e 100644 --- a/cocos/animation/tracks/object-track.ts +++ b/cocos/animation/tracks/object-track.ts @@ -1,5 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass } from 'cc.decorator'; -import { ObjectCurve } from '../../core/curves'; +import { ObjectCurve } from '../../core'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { SingleChannelTrack } from './track'; diff --git a/cocos/animation/tracks/quat-track.ts b/cocos/animation/tracks/quat-track.ts index 80a2b522a7e..b354b7fe8ee 100644 --- a/cocos/animation/tracks/quat-track.ts +++ b/cocos/animation/tracks/quat-track.ts @@ -1,8 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass } from 'cc.decorator'; -import { QuatCurve } from '../../core/curves'; +import { QuatCurve, Quat } from '../../core'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; -import { SingleChannelTrack } from './track'; -import { Quat } from '../../core/math'; +import { SingleChannelTrack, TrackEval } from './track'; /** * @en @@ -27,11 +50,15 @@ export class QuatTrack extends SingleChannelTrack { } } -export class QuatTrackEval { +export class QuatTrackEval implements TrackEval { constructor (private _curve: QuatCurve) { } + public get requiresDefault () { + return false; + } + public evaluate (time: number) { this._curve.evaluate(time, this._result); return this._result; diff --git a/cocos/animation/tracks/real-track.ts b/cocos/animation/tracks/real-track.ts index 6ff2b445881..82ad7db530a 100644 --- a/cocos/animation/tracks/real-track.ts +++ b/cocos/animation/tracks/real-track.ts @@ -1,5 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass } from 'cc.decorator'; -import { RealCurve } from '../../core/curves'; +import { RealCurve } from '../../core'; import { CLASS_NAME_PREFIX_ANIM } from '../define'; import { SingleChannelTrack } from './track'; diff --git a/cocos/animation/tracks/size-track.ts b/cocos/animation/tracks/size-track.ts index 2ef14f330d0..bf102665ee3 100644 --- a/cocos/animation/tracks/size-track.ts +++ b/cocos/animation/tracks/size-track.ts @@ -1,8 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; -import { RealCurve } from '../../core/curves'; -import { Size } from '../../core/math'; +import { RealCurve, Size } from '../../core'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; -import { Channel, RealChannel, RuntimeBinding, Track } from './track'; +import { Channel, RealChannel, RuntimeBinding, Track, TrackEval } from './track'; import { maskIfEmpty } from './utils'; const CHANNEL_NAMES: ReadonlyArray = ['Width', 'Height']; @@ -49,7 +72,7 @@ export class SizeTrack extends Track { private _channels: [RealChannel, RealChannel]; } -export class SizeTrackEval { +export class SizeTrackEval implements TrackEval { constructor ( private _width: RealCurve | undefined, private _height: RealCurve | undefined, @@ -57,11 +80,14 @@ export class SizeTrackEval { } - public evaluate (time: number, runtimeBinding: RuntimeBinding) { - if ((!this._width || !this._height) && runtimeBinding.getValue) { - const size = runtimeBinding.getValue() as Size; - this._result.x = size.x; - this._result.y = size.y; + public get requiresDefault () { + return !this._width || !this._height; + } + + public evaluate (time: number, defaultValue?: Readonly) { + if (defaultValue) { + this._result.x = defaultValue.x; + this._result.y = defaultValue.y; } if (this._width) { diff --git a/cocos/animation/tracks/track.ts b/cocos/animation/tracks/track.ts index 86fe5a2dffb..81025beceb9 100644 --- a/cocos/animation/tracks/track.ts +++ b/cocos/animation/tracks/track.ts @@ -1,11 +1,34 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable, uniquelyReferenced } from 'cc.decorator'; import { SUPPORT_JIT } from 'internal:constants'; import type { Component } from '../../scene-graph/component'; -import type { ObjectCurve, QuatCurve, RealCurve } from '../../core/curves'; +import { error, ObjectCurve, QuatCurve, RealCurve, errorID, warnID, js } from '../../core'; import { assertIsTrue } from '../../core/data/utils/asserts'; -import { errorID, warnID } from '../../core/platform'; + import { Node } from '../../scene-graph'; -import { js } from '../../core/utils/js'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; import type { AnimationMask } from '../marionette/animation-mask'; import { PoseOutput } from '../pose-output'; @@ -13,16 +36,16 @@ import { ComponentPath, HierarchyPath, isPropertyPath, TargetPath } from '../tar import { IValueProxyFactory } from '../value-proxy'; import { Range } from './utils'; -const normalizedFollowTag = Symbol('NormalizedFollow'); +export const normalizedFollowTag = Symbol('NormalizedFollow'); const parseTrsPathTag = Symbol('ConvertAsTrsPath'); export const trackBindingTag = Symbol('TrackBinding'); -export type RuntimeBinding = { - setValue(value: unknown): void; +export type RuntimeBinding = { + setValue(value: T): void; - getValue?(): unknown; + getValue?(): T; }; export type Binder = (binding: TrackBinding) => undefined | RuntimeBinding; @@ -301,7 +324,7 @@ export class TrackBinding { @serializable public proxy: IValueProxyFactory | undefined; - private static _animationFunctions = new WeakMap any, setValue:(val: any) => void}>>(); + private static _animationFunctions = new WeakMap any, setValue: (val: any) => void}>>(); public parseTrsPath () { if (this.proxy) { @@ -400,7 +423,7 @@ export class TrackBinding { } } -function isTrsPropertyName (name: string | number): name is 'position' | 'rotation' | 'scale' | 'eulerAngles' { +export function isTrsPropertyName (name: string | number): name is 'position' | 'rotation' | 'scale' | 'eulerAngles' { return name === 'position' || name === 'rotation' || name === 'scale' || name === 'eulerAngles'; } @@ -476,18 +499,26 @@ export abstract class Track { /** * @internal */ - public abstract [createEvalSymbol] (runtimeBinding: RuntimeBinding): TrackEval; + public abstract [createEvalSymbol] (): TrackEval; @serializable private _binding = new TrackBinding(); } -export interface TrackEval { +export interface TrackEval { + /** + * A flag indicating if the track requires a default value to be passed to `this.evaluate`. + */ + readonly requiresDefault: boolean; + /** - * Evaluates the track. - * @param time The time. - */ - evaluate(time: number, runtimeBinding: RuntimeBinding): unknown; + * Evaluates the track. + * @param time The time. + * @param defaultValue A default value. + * This param will be passed if `this.requiresDefault === true` and + * the caller is able to provide such a default value. + */ + evaluate(time: number, defaultValue?: TValue extends unknown ? unknown : Readonly): TValue; } export type Curve = RealCurve | QuatCurve | ObjectCurve; @@ -558,7 +589,7 @@ export abstract class SingleChannelTrack extends Track { /** * @internal */ - public [createEvalSymbol] (_runtimeBinding: RuntimeBinding): TrackEval { + public [createEvalSymbol] (): TrackEval { const { curve } = this._channel; return new SingleChannelTrackEval(curve); } @@ -567,10 +598,14 @@ export abstract class SingleChannelTrack extends Track { private _channel: Channel; } -class SingleChannelTrackEval implements TrackEval { +class SingleChannelTrackEval implements TrackEval { constructor (private _curve: TCurve) { } + public get requiresDefault () { + return false; + } + public evaluate (time: number) { return this._curve.evaluate(time); } diff --git a/cocos/animation/tracks/untyped-track.ts b/cocos/animation/tracks/untyped-track.ts index 5eca046b04a..16a0f666dea 100644 --- a/cocos/animation/tracks/untyped-track.ts +++ b/cocos/animation/tracks/untyped-track.ts @@ -1,12 +1,34 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; -import { RealCurve } from '../../core/curves'; -import { Color, Size, Vec2, Vec3, Vec4 } from '../../core/math'; -import { getError } from '../../core/platform'; +import { RealCurve, Color, Size, Vec2, Vec3, Vec4, getError } from '../../core'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; import { IValueProxyFactory } from '../value-proxy'; import { ColorTrack, ColorTrackEval } from './color-track'; import { SizeTrackEval } from './size-track'; -import { Channel, RealChannel, RuntimeBinding, Track, TrackPath } from './track'; +import { Channel, RealChannel, Track, TrackEval, TrackPath } from './track'; import { Vec2TrackEval, Vec3TrackEval, Vec4TrackEval, VectorTrack } from './vector-track'; @ccclass(`${CLASS_NAME_PREFIX_ANIM}UntypedTrackChannel`) @@ -28,37 +50,37 @@ export class UntypedTrack extends Track { return this._channels; } + public [createEvalSymbol] (): TrackEval { + throw new Error(`UntypedTrack should be handled specially. Please file an issue.`); + } + /** * @internal */ - public [createEvalSymbol] (runtimeBinding: RuntimeBinding) { - if (!runtimeBinding.getValue) { - throw new Error(getError(3930)); - } + public createLegacyEval (hintValue?: unknown) { const trySearchCurve = (property: string) => this._channels.find((channel) => channel.property === property)?.curve; - const value = runtimeBinding.getValue(); switch (true) { default: throw new Error(getError(3931)); - case value instanceof Vec2: + case hintValue instanceof Vec2: return new Vec2TrackEval( trySearchCurve('x'), trySearchCurve('y'), ); - case value instanceof Vec3: + case hintValue instanceof Vec3: return new Vec3TrackEval( trySearchCurve('x'), trySearchCurve('y'), trySearchCurve('z'), ); - case value instanceof Vec4: + case hintValue instanceof Vec4: return new Vec4TrackEval( trySearchCurve('x'), trySearchCurve('y'), trySearchCurve('z'), trySearchCurve('w'), ); - case value instanceof Color: + case hintValue instanceof Color: // TODO: what if x, y, z, w? return new ColorTrackEval( trySearchCurve('r'), @@ -66,7 +88,7 @@ export class UntypedTrack extends Track { trySearchCurve('b'), trySearchCurve('a'), ); - case value instanceof Size: + case hintValue instanceof Size: return new SizeTrackEval( trySearchCurve('width'), trySearchCurve('height'), diff --git a/cocos/animation/tracks/utils.ts b/cocos/animation/tracks/utils.ts index b2ca4e78b8a..7e9a43f0644 100644 --- a/cocos/animation/tracks/utils.ts +++ b/cocos/animation/tracks/utils.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import type { Curve } from './track'; export function maskIfEmpty (curve: T) { diff --git a/cocos/animation/tracks/vector-track.ts b/cocos/animation/tracks/vector-track.ts index 028780634ce..f8dfe9997aa 100644 --- a/cocos/animation/tracks/vector-track.ts +++ b/cocos/animation/tracks/vector-track.ts @@ -1,8 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable } from 'cc.decorator'; -import { RealCurve } from '../../core/curves'; -import { Vec2, Vec3, Vec4 } from '../../core/math'; +import { RealCurve, Vec2, Vec3, Vec4 } from '../../core'; import { CLASS_NAME_PREFIX_ANIM, createEvalSymbol } from '../define'; -import { Channel, RealChannel, RuntimeBinding, Track } from './track'; +import { Channel, RealChannel, RuntimeBinding, Track, TrackEval } from './track'; import { maskIfEmpty } from './utils'; const CHANNEL_NAMES: ReadonlyArray = ['X', 'Y', 'Z', 'W']; @@ -81,14 +104,18 @@ export class VectorTrack extends Track { private _nComponents: 2 | 3 | 4 = 4; } -export class Vec2TrackEval { +export class Vec2TrackEval implements TrackEval { constructor (private _x: RealCurve | undefined, private _y: RealCurve | undefined) { } - public evaluate (time: number, runtimeBinding: RuntimeBinding) { - if ((!this._x || !this._y) && runtimeBinding.getValue) { - Vec2.copy(this._result, runtimeBinding.getValue() as Vec2); + public get requiresDefault () { + return !this._x || !this._y; + } + + public evaluate (time: number, defaultValue?: Readonly) { + if (defaultValue) { + Vec2.copy(this._result, defaultValue); } if (this._x) { @@ -104,14 +131,18 @@ export class Vec2TrackEval { private _result: Vec2 = new Vec2(); } -export class Vec3TrackEval { +export class Vec3TrackEval implements TrackEval { constructor (private _x: RealCurve | undefined, private _y: RealCurve | undefined, private _z: RealCurve | undefined) { } - public evaluate (time: number, runtimeBinding: RuntimeBinding) { - if ((!this._x || !this._y || !this._z) && runtimeBinding.getValue) { - Vec3.copy(this._result, runtimeBinding.getValue() as Vec3); + public get requiresDefault () { + return !this._x || !this._y || !this._z; + } + + public evaluate (time: number, defaultValue?: Readonly) { + if (defaultValue) { + Vec3.copy(this._result, defaultValue); } if (this._x) { @@ -130,7 +161,7 @@ export class Vec3TrackEval { private _result: Vec3 = new Vec3(); } -export class Vec4TrackEval { +export class Vec4TrackEval implements TrackEval { constructor ( private _x: RealCurve | undefined, private _y: RealCurve | undefined, @@ -140,9 +171,13 @@ export class Vec4TrackEval { } - public evaluate (time: number, runtimeBinding: RuntimeBinding) { - if ((!this._x || !this._y || !this._z || !this._w) && runtimeBinding.getValue) { - Vec4.copy(this._result, runtimeBinding.getValue() as Vec4); + public get requiresDefault () { + return !this._x || !this._y || !this._z || !this._w; + } + + public evaluate (time: number, defaultValue?: Readonly) { + if (defaultValue) { + Vec4.copy(this._result, defaultValue); } if (this._x) { diff --git a/cocos/animation/transform-utils.ts b/cocos/animation/transform-utils.ts index 94292f7dccf..7b9b7bf065b 100644 --- a/cocos/animation/transform-utils.ts +++ b/cocos/animation/transform-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ -import { Mat4 } from '../core/math'; +import { Mat4 } from '../core'; import { Node } from '../scene-graph'; const m4_1 = new Mat4(); diff --git a/cocos/animation/types.ts b/cocos/animation/types.ts index 830f7149a57..2310e766098 100644 --- a/cocos/animation/types.ts +++ b/cocos/animation/types.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { WrapModeMask } from '../core/geometry/curve'; -import { ccenum } from '../core/value-types/enum'; +import { ccenum, geometry } from '../core'; /** * 动画使用的循环模式。 @@ -33,37 +31,37 @@ export enum WrapMode { /** * 向 Animation Component 或者 AnimationClip 查找 wrapMode */ - Default = WrapModeMask.Default, + Default = geometry.WrapModeMask.Default, /** * 动画只播放一遍 */ - Normal = WrapModeMask.Normal, + Normal = geometry.WrapModeMask.Normal, /** * 从最后一帧或结束位置开始反向播放,到第一帧或开始位置停止 */ - Reverse = WrapModeMask.Reverse, + Reverse = geometry.WrapModeMask.Reverse, /** * 循环播放 */ - Loop = WrapModeMask.Loop, + Loop = geometry.WrapModeMask.Loop, /** * 反向循环播放 */ - LoopReverse = WrapModeMask.Loop | WrapModeMask.Reverse, + LoopReverse = geometry.WrapModeMask.Loop | geometry.WrapModeMask.Reverse, /** * 从第一帧播放到最后一帧,然后反向播放回第一帧,到第一帧后再正向播放,如此循环 */ - PingPong = WrapModeMask.PingPong, + PingPong = geometry.WrapModeMask.PingPong, /** * 从最后一帧开始反向播放,其他同 PingPong */ - PingPongReverse = WrapModeMask.PingPong | WrapModeMask.Reverse, + PingPongReverse = geometry.WrapModeMask.PingPong | geometry.WrapModeMask.Reverse, } ccenum(WrapMode); diff --git a/cocos/animation/value-proxy-factories/index.ts b/cocos/animation/value-proxy-factories/index.ts index f289d423b45..001b4f9817a 100644 --- a/cocos/animation/value-proxy-factories/index.ts +++ b/cocos/animation/value-proxy-factories/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './uniform'; diff --git a/cocos/animation/value-proxy-factories/morph-weights.ts b/cocos/animation/value-proxy-factories/morph-weights.ts index c9253c2a752..783b8933e78 100644 --- a/cocos/animation/value-proxy-factories/morph-weights.ts +++ b/cocos/animation/value-proxy-factories/morph-weights.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; import { MeshRenderer } from '../../3d/framework/mesh-renderer'; diff --git a/cocos/animation/value-proxy-factories/uniform.ts b/cocos/animation/value-proxy-factories/uniform.ts index 7e51ef8dd6d..4a3b8c039fb 100644 --- a/cocos/animation/value-proxy-factories/uniform.ts +++ b/cocos/animation/value-proxy-factories/uniform.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, float, serializable } from 'cc.decorator'; import { builtinResMgr } from '../../asset/asset-manager'; @@ -32,7 +31,7 @@ import { deviceManager, Type } from '../../gfx'; import { Pass } from '../../render-scene/core/pass'; import { getDefaultFromType, getStringFromType } from '../../render-scene/core/pass-utils'; import { IValueProxy, IValueProxyFactory } from '../value-proxy'; -import { warn } from '../../core/platform/debug'; +import { warn } from '../../core'; /** * @en diff --git a/cocos/animation/value-proxy.ts b/cocos/animation/value-proxy.ts index cfb6d0dd89f..3bab33889a6 100644 --- a/cocos/animation/value-proxy.ts +++ b/cocos/animation/value-proxy.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @en diff --git a/cocos/animation/wrap.ts b/cocos/animation/wrap.ts new file mode 100644 index 00000000000..f079b878355 --- /dev/null +++ b/cocos/animation/wrap.ts @@ -0,0 +1,84 @@ +import { WrapModeMask } from '../core/geometry'; +import { WrapMode, WrappedInfo } from './types'; + +export function wrap ( + elapsedTime: number, + duration: number, + wrapMode: WrapMode, + repeatCount: number, + negativeSpeed: boolean, + info: WrappedInfo, +): WrappedInfo { + if (duration === 0.0) { + info.time = 0.0; + info.ratio = 0.0; + info.direction = 1.0; + info.stopped = !!Number.isFinite(repeatCount); + info.iterations = 0.0; + return info; + } + + let stopped = false; + + let currentIterations = elapsedTime > 0 ? (elapsedTime / duration) : -(elapsedTime / duration); + if (currentIterations >= repeatCount) { + currentIterations = repeatCount; + + stopped = true; + let tempRatio = repeatCount - (repeatCount | 0); + if (tempRatio === 0) { + tempRatio = 1; // 如果播放过,动画不复位 + } + elapsedTime = tempRatio * duration * (elapsedTime > 0 ? 1 : -1); + } + + if (elapsedTime > duration) { + const tempTime = elapsedTime % duration; + elapsedTime = tempTime === 0 ? duration : tempTime; + } else if (elapsedTime < 0) { + elapsedTime %= duration; + if (elapsedTime !== 0) { elapsedTime += duration; } + } + + let needReverse = false; + const shouldWrap = wrapMode & WrapModeMask.ShouldWrap; + if (shouldWrap) { + needReverse = isReverseIteration(wrapMode, currentIterations); + } + + let direction = needReverse ? -1 : 1; + if (negativeSpeed) { + direction *= -1; + } + + // calculate wrapped time + if (shouldWrap && needReverse) { + elapsedTime = duration - elapsedTime; + } + + info.time = elapsedTime; + info.ratio = info.time / duration; + info.direction = direction; + info.stopped = stopped; + info.iterations = currentIterations; + + return info; +} + +function isReverseIteration (wrapMode: WrapMode, currentIterations: number) { + let needReverse = false; + if ((wrapMode & WrapModeMask.PingPong) === WrapModeMask.PingPong) { + const isEnd = currentIterations - (currentIterations | 0) === 0; + if (isEnd && (currentIterations > 0)) { + currentIterations -= 1; + } + const isOddIteration = currentIterations & 1; + if (isOddIteration) { + needReverse = !needReverse; + } + } + if ((wrapMode & WrapModeMask.Reverse) === WrapModeMask.Reverse) { + needReverse = !needReverse; + } + return needReverse; +} diff --git a/cocos/asset/asset-manager/asset-manager.ts b/cocos/asset/asset-manager/asset-manager.ts index adafea2c6a7..614ab9786d7 100644 --- a/cocos/asset/asset-manager/asset-manager.ts +++ b/cocos/asset/asset-manager/asset-manager.ts @@ -1,18 +1,18 @@ +/* eslint-disable max-len */ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,45 +21,35 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BUILD, EDITOR, PREVIEW } from 'internal:constants'; import { Asset } from '../assets/asset'; -import { legacyCC } from '../../core/global-exports'; -import { error } from '../../core/platform/debug'; -import { sys } from '../../core/platform/sys'; -import { Settings, settings } from '../../core/settings'; -import { basename, extname } from '../../core/utils/path'; +import { error, sys, Settings, settings, path, cclegacy } from '../../core'; import Bundle from './bundle'; import Cache, { ICache } from './cache'; import CacheManager from './cache-manager'; -import dependUtil from './depend-util'; -import downloader from './downloader'; +import dependUtil, { DependUtil } from './depend-util'; +import downloader, { Downloader } from './downloader'; import factory from './factory'; import fetch from './fetch'; import * as helper from './helper'; import load from './load'; import packManager from './pack-manager'; -import parser from './parser'; -import { IPipe, Pipeline } from './pipeline'; +import parser, { Parser } from './parser'; +import { Pipeline } from './pipeline'; import preprocess from './preprocess'; import releaseManager from './release-manager'; import RequestItem from './request-item'; import { - CompleteCallbackWithData, - ProgressCallback, - IBundleOptions, - IOptions, - IRemoteOptions, presets, - Request, references, - IJsonAssetOptions, - assets, BuiltinBundleName, bundles, fetchPipeline, files, parsed, pipeline, transformPipeline, assetsOverrideMap } from './shared'; + assets, BuiltinBundleName, bundles, fetchPipeline, files, parsed, pipeline, transformPipeline, assetsOverrideMap, IRequest } from './shared'; import Task from './task'; import { combine, parse, replaceOverrideAsset } from './url-transformer'; import { asyncify, parseParameters } from './utilities'; +import { IAddressableInfo, IAssetInfo, IPackInfo, ISceneInfo } from './config'; /** * @zh @@ -79,33 +69,33 @@ export interface IAssetManagerOptions { /** * @zh - * 所有 bundle 的版本信息 + * 所有 bundle 的版本信息。 * @en - * Version for all bundles + * Version for all bundles. */ bundleVers?: Record; /** * @zh - * 远程服务器地址 + * 远程服务器地址。 * @en - * Remote server address + * Remote server address. */ server?: string; /** * @zh - * 配置为子包的 bundle + * 配置为子包的 bundle。 * @en - * All subpackages + * All subpackages. */ subpackages?: string[]; /** * @zh - * 配置为远程包的 bundle + * 配置为远程包的 bundle。 * @en - * All remote bundles + * All remote bundles. */ remoteBundles?: string[]; @@ -114,85 +104,90 @@ export interface IAssetManagerOptions { /** * @en * This module controls asset's behaviors and information, include loading, releasing etc. it is a singleton - * All member can be accessed with `assetManager`. + * You can access it via [[assetManager]]. * * @zh - * 此模块管理资源的行为和信息,包括加载,释放等,这是一个单例,所有成员能够通过 `assetManager` 调用 - * + * 此模块管理资源的行为和信息,包括加载,释放等,这是一个单例,你能够通过 `assetManager` 访问它。 */ export class AssetManager { /** * @en - * Normal loading pipeline + * Normal loading pipeline. Asset manager uses this pipeline to load all assets, it has an additional asset parsing process compared to the fetchPipeline. * * @zh - * 正常加载管线 - * + * 正常加载管线。Asset manager 使用此管线来加载所有资源,他与 fetchPipeline 相比额外多了资源的解析过程。 */ public pipeline: Pipeline = pipeline.append(preprocess).append(load); /** * @en - * Fetching pipeline + * Fetching pipeline. Asset manager uses this pipeline to preload all assets, which lacks the asset parsing process compared to the pipeline. * * @zh - * 下载管线 + * 下载管线。Asset manager 使用此管线来预加载所有资源,他与 pipeline 相比缺少了资源的解析过程。 * */ public fetchPipeline: Pipeline = fetchPipeline.append(preprocess).append(fetch); /** * @en - * Url transformer + * Url transformer. Asset manager uses this pipeline to convert the uuid, path, etc. to the path of the final file path to be loaded. + * You can customize this pipeline to redirect the path to the path you want. * * @zh - * Url 转换器 + * Url 转换器。Asset manager 使用此管线将 uuid, 路径等信息转换为最终要加载的文件路径。你可以自定义此管线将路径重定向到你想要的路径。 * */ public transformPipeline: Pipeline = transformPipeline.append(parse).append(replaceOverrideAsset).append(combine); /** * @en - * The collection of bundle which is already loaded, you can remove cache with [[removeBundle]] + * The collection of bundle which is already loaded, you can remove cache with [[removeBundle]]. * * @zh - * 已加载 bundle 的集合, 你能通过 [[removeBundle]] 来移除缓存 + * 已加载 bundle 的集合, 你能通过 [[removeBundle]] 来移除缓存。 * */ public bundles: ICache = bundles; /** * @en - * The collection of asset which is already loaded, you can remove cache with [[releaseAsset]] + * The collection of asset which is already loaded, you can remove cache with [[releaseAsset]]. * * @zh - * 已加载资源的集合, 你能通过 [[releaseAsset]] 来移除缓存 + * 已加载资源的集合, 你能通过 [[releaseAsset]] 来移除缓存。 */ public assets: ICache = assets; /** - * @internal only using in L10N for now + * @internal only using in L10N for now. */ public readonly assetsOverrideMap = assetsOverrideMap; + /** + * @internal + */ public generalImportBase = ''; + /** + * @internal + */ public generalNativeBase = ''; /** * @en - * Manage relationship between asset and its dependencies + * Manage relationship between asset and its dependencies. * * @zh - * 管理资源依赖关系 + * 管理资源间依赖关系。 */ public dependUtil = dependUtil; /** * @en - * Whether or not load asset forcibly, if it is true, asset will be loaded regardless of error + * A flag indicates whether to force loading assets and ignore errors. * * @zh - * 是否强制加载资源, 如果为 true ,加载资源将会忽略报错 + * 是否强制加载资源标志, 如果为 true,加载资源时将会忽略错误。 * */ public force = EDITOR || PREVIEW; @@ -202,57 +197,58 @@ export class AssetManager { * Whether to use image bitmap to load image first. If enabled, images loading will become faster but memory usage will increase. * * @zh - * 是否优先使用 image bitmap 来加载图片,启用之后,图片加载速度会更快, 但内存占用会变高, + * 是否优先使用 image bitmap 来加载图片,启用之后,图片加载速度会更快, 但内存占用会变高。 * */ - public allowImageBitmap = !sys.isMobile; + public allowImageBitmap = !EDITOR && !sys.isMobile; /** * @en - * Some useful function + * Some useful functions, such as the convert function between url and uuid. * * @zh - * 一些有用的方法 + * 一些有用的方法, 例如 url 与 uuid 之间的转换方法。 * */ public utils = helper; /** * @en - * Manage all downloading task + * The downloader used by `assetManager`.It manages all downloading tasks. * * @zh - * 管理所有下载任务 + * `assetManager` 所使用的下载器,管理所有下载任务。 * */ public downloader = downloader; /** * @en - * Manage all parsing task + * The parser used by `assetManager`.It manages all parsing tasks. * * @zh - * 管理所有解析任务 + * `assetManager` 所使用的解析器,管理所有解析任务。 * */ public parser = parser; /** * @en - * Manage all packed asset + * Manage all packed assets. * * @zh - * 管理所有合并后的资源 + * 管理所有合并后的资源。 * + * @deprecated Since v3.7, this is an engine internal interface. You usually don't need to care about how resources are merged and split. */ public packManager = packManager; /** * @en - * Whether or not cache the loaded asset + * Whether to cache loaded assets. * * @zh - * 是否缓存已加载的资源 + * 是否缓存已加载的资源。 * */ public cacheAsset = true; @@ -262,45 +258,75 @@ export class AssetManager { * Cache manager is a module which controls all caches downloaded from server in non-web platform. * * @zh - * 缓存管理器是一个模块,在非 WEB 平台上,用于管理所有从服务器上下载下来的缓存 + * 缓存管理器是一个模块,在非 WEB 平台上,用于管理所有从服务器上下载下来的缓存。 * */ public cacheManager: CacheManager | null = null; /** * @en - * The preset of options + * The preset of options. * * @zh - * 可选参数的预设集 + * 可选参数的预设集。 * */ public presets = presets; + /** + * @internal + */ public factory = factory; - public preprocessPipe: IPipe = preprocess; + /** + * @internal + */ + public preprocessPipe = preprocess; - public fetchPipe: IPipe = fetch; + /** + * @internal + */ + public fetchPipe = fetch; - public loadPipe: IPipe = load; + /** + * @internal + */ + public loadPipe = load; + /** + * @internal + */ public references = references; private _releaseManager = releaseManager; - private _files = files; - private _parsed = parsed; private _parsePipeline = BUILD ? null : new Pipeline('parse existing json', [this.loadPipe]); private _projectBundles: string[] = []; + private static _instance: AssetManager; /** * @en - * The builtin 'main' bundle + * A global singleton instance of [[AssetManager]], which you can access directly through [[assetManager]]. * * @zh - * 内置 main 包 + * [[AssetManager]] 的全局单例,你可以直接通过 [[assetManager]] 访问。 + */ + static get instance () { + if (!this._instance) { + this._instance = new AssetManager(); + } + return this._instance; + } + + private constructor () {} + + /** + * @en + * The builtin 'main' bundle. + * + * @zh + * 内置 main 包。 */ public get main (): Bundle | null { return bundles.get(BuiltinBundleName.MAIN) || null; @@ -308,10 +334,10 @@ export class AssetManager { /** * @en - * The builtin 'resources' bundle + * The builtin 'resources' bundle. * * @zh - * 内置 resources 包 + * 内置 resources 包。 * */ public get resources (): Bundle | null { @@ -320,13 +346,14 @@ export class AssetManager { /** * @en - * Initialize assetManager with options + * Initializes assetManager with options. + * This method will be called automatically when the engine starts, you should not call this method manually at any time. * * @zh - * 初始化资源管理器 - * - * @param options - the configuration + * 初始化资源管理器,引擎在启动时,将会自动调用此方法,你不应该在任何时候手动调用此方法。 * + * @param options @en The configuration of asset manager. @zh 资源管理器的配置选项。 + * @internal */ public init (options: IAssetManagerOptions = {}) { const server = options.server || settings.querySettings(Settings.Category.ASSETS, 'server') || ''; @@ -360,13 +387,13 @@ export class AssetManager { /** * @en - * Get the bundle which has been loaded + * Gets the bundle which has been loaded with the name of bundle. * * @zh - * 获取已加载的分包 + * 通过包名称获取已加载的分包。 * - * @param name - The name of bundle - * @return - The loaded bundle + * @param name @en The name of bundle. @zh 资源包的名称。 + * @returns @en The loaded bundle. @zh 已加载的资源包。 * * @example * // ${project}/assets/test1 @@ -381,16 +408,14 @@ export class AssetManager { /** * @en - * Remove this bundle. NOTE: The asset within this bundle will not be released automatically, - * you can call [[AssetManager.Bundle.releaseAll]] manually before remove it if you need + * Removes this bundle. NOTE: The asset within this bundle will not be released automatically, + * you can call [[AssetManager.Bundle.releaseAll]] manually before removing it if you need. * * @zh - * 移除此包, 注意:这个包内的资源不会自动释放, 如果需要的话你可以在摧毁之前手动调用 [[AssetManager.Bundle.releaseAll]] 进行释放 + * 移除此包, 注意:这个包内的资源不会自动释放, 如果需要的话你可以在摧毁之前手动调用 [[AssetManager.Bundle.releaseAll]] 进行释放。 * - * @param bundle - The bundle to be removed + * @param bundle @en The bundle to be removed. @zh 准备移除的 Bundle。 * - * @typescript - * removeBundle(bundle: AssetManager.Bundle): void */ public removeBundle (bundle: Bundle) { bundle._destroy(); @@ -399,37 +424,36 @@ export class AssetManager { /** * @en - * General interface used to load assets with a progression callback and a complete callback. You can achieve almost all - * effect you want with combination of `requests` and `options`.It is highly recommended that you use more simple API, - * such as `load`, `loadDir` etc. Every custom parameter in `options` will be distribute to each of `requests`. if request - * already has same one, the parameter in request will be given priority. Besides, if request has dependencies, `options` - * will distribute to dependencies too. Every custom parameter in `requests` will be transferred to handler of `downloader` - * and `parser` as `options`. You can register you own handler downloader or parser to collect these custom parameters for some effect. + * General interface used to load assets with a progression callback and a complete callback. + * It is highly recommended that you use more simple API, such as `load`, `loadDir` etc. You can pass + * some additional data via the `options` parameter, and the parameters in `options` will affect this loading. + * The optional parameter will be transferred to handler of `downloader` and `parser` as `options`. You can + * register you own handler downloader or parser to collect these custom parameters for some effect. * - * Reserved Keyword: `uuid`, `url`, `path`, `dir`, `scene`, `type`, `priority`, `preset`, `audioLoadMode`, `ext`, + * Reserved Keywords for additional parameters: `uuid`, `url`, `path`, `dir`, `scene`, `type`, `priority`, `preset`, `audioLoadMode`, `ext`, * `bundle`, `onFileProgress`, `maxConcurrency`, `maxRequestsPerFrame`, `maxRetryCount`, `version`, `xhrResponseType`, * `xhrWithCredentials`, `xhrMimeType`, `xhrTimeout`, `xhrHeader`, `reloadAsset`, `cacheAsset`, `cacheEnabled`, - * Please DO NOT use these words as custom options! + * Please DO NOT use these words as your own options! * * @zh - * 通用加载资源接口,可传入进度回调以及完成回调,通过组合 `request` 和 `options` 参数,几乎可以实现和扩展所有想要的加载效果。非常建议 - * 你使用更简单的API,例如 `load`、`loadDir` 等。`options` 中的自定义参数将会分发到 `requests` 的每一项中,如果request中已存在同名的 - * 参数则以 `requests` 中为准,同时如果有其他依赖资源,则 `options` 中的参数会继续向依赖项中分发。request中的自定义参数都会以 `options` - * 形式传入加载流程中的 `downloader`, `parser` 的方法中, 你可以扩展 `downloader`, `parser` 收集参数完成想实现的效果。 + * 通用加载资源接口,可传入进度回调以及完成回调,建议你使用更简单的API,例如 `load`、`loadDir` 等。你可以通过 `options` 参数额外传递一些数据,`options` 中的参数将会影响本次加载。 + * 额外参数会传入加载流程中的 `downloader`, `parser` 的处理方法中, 你可以扩展 `downloader`, `parser` 收集参数完成想实现的效果。 * - * 保留关键字: `uuid`, `url`, `path`, `dir`, `scene`, `type`, `priority`, `preset`, `audioLoadMode`, `ext`, `bundle`, `onFileProgress`, + * 额外参数保留关键字: `uuid`, `url`, `path`, `dir`, `scene`, `type`, `priority`, `preset`, `audioLoadMode`, `ext`, `bundle`, `onFileProgress`, * `maxConcurrency`, `maxRequestsPerFrame`, `maxRetryCount`, `version`, `xhrResponseType`, `xhrWithCredentials`, `xhrMimeType`, `xhrTimeout`, `xhrHeader`, - * `reloadAsset`, `cacheAsset`, `cacheEnabled`, 请不要使用这些字段为自定义参数! - * - * @param requests - The request you want to load - * @param options - Optional parameters - * @param onProgress - Callback invoked when progression change - * @param onProgress.finished - The number of the items that are already completed - * @param onProgress.total - The total number of the items - * @param onProgress.item - The current request item - * @param onComplete - Callback invoked when finish loading - * @param onComplete.err - The error occurred in loading process. - * @param onComplete.data - The loaded content + * `reloadAsset`, `cacheAsset`, `cacheEnabled`, 请不要使用这些字段为你自己的参数! + * + * @param requests @en The loading requests. @zh 加载请求。 + * @param options @en Optional parameters. @zh 可选参数。 + * @param onProgress @en Callback invoked when the loading progress change. @zh 加载进度发生变化时执行的回调。 + * @param onProgress.finished + * @en The number of request items that have finished loading. + * @zh 已经完成加载的资源数量。 + * @param onProgress.total @en The number of all request items to be loaded. @zh 所有待加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的加载项。 + * @param onComplete @en Callback invoked when all assets loaded. @zh 所有资源加载完成后的回调。 + * @param onComplete.err @en Error message during loading, or null if loaded successfully. @zh 加载过程中的错误信息,如果加载成功则为 null。 + * @param onComplete.data @en The loaded data, or null if an error occurred during loading. @zh 已加载的数据,如果加载过程中有错误发生,则为 null。 * * @example * assetManager.loadAny({url: 'http://example.com/a.png'}, (err, img) => log(img)); @@ -437,7 +461,7 @@ export class AssetManager { * assetManager.loadAny([{ uuid: '0cbZa5Y71CTZAccaIFluuZ'}, {url: 'http://example.com/a.png'}], (err, assets) => log(assets)); * assetManager.downloader.register('.asset', (url, options, onComplete) => { * url += '?userName=' + options.userName + "&password=" + options.password; - * assetManager.downloader.downloadFile(url, null, onComplete); + * // other logic. * }); * assetManager.parser.register('.asset', (file, options, onComplete) => { * var json = JSON.parse(file); @@ -445,20 +469,20 @@ export class AssetManager { * var model = json[options.model]; * onComplete(null, {skin, model}); * }); - * assetManager.loadAny({ url: 'http://example.com/my.asset', skin: 'xxx', model: 'xxx', userName: 'xxx', password: 'xxx' }); + * assetManager.loadAny({ url: 'http://example.com/my.asset' }, { skin: 'xxx', model: 'xxx', userName: 'xxx', password: 'xxx' }); * */ - public loadAny (requests: Request, options: IOptions | null, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadAny (requests: Request, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadAny (requests: Request, options: IOptions | null, onComplete?: CompleteCallbackWithData | null): void; - public loadAny (requests: string, onComplete?: CompleteCallbackWithData | null): void; - public loadAny (requests: string[], onComplete?: CompleteCallbackWithData | null): void; - public loadAny (requests: Request, onComplete?: CompleteCallbackWithData | null): void; + public loadAny (requests: string | string[] | IRequest | Array, options: { [key: string]: any, preset?: string } | null, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: any) => void) | null): void; + public loadAny (requests: string | string[] | IRequest | Array, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: any) => void) | null): void; + public loadAny (requests: string | string[] | IRequest | Array, options: { [key: string]: any, preset?: string } | null, onComplete?: ((err: Error | null, data: any) => void) | null): void; + public loadAny (requests: string, onComplete?: ((err: Error | null, data: T) => void) | null): void; + public loadAny (requests: string[], onComplete?: ((err: Error | null, data: T[]) => void) | null): void; + public loadAny (requests: string | string[] | IRequest | Array, onComplete?: ((err: Error | null, data: any) => void) | null): void; public loadAny ( - requests: Request, - options?: IOptions | ProgressCallback | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + requests: string | string[] | IRequest | Array, + options?: { [key: string]: any, preset?: string } | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: any) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: any) => void) | null, + onComplete?: ((err: Error | null, data: any) => void) | null, ) { const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters(options, onProgress, onComplete); opts.preset = opts.preset || 'default'; @@ -471,40 +495,44 @@ export class AssetManager { * @en * General interface used to preload assets with a progression callback and a complete callback.It is highly recommended that you use * more simple API, such as `preloadRes`, `preloadResDir` etc. Everything about preload is just likes `assetManager.loadAny`, the - * difference is `assetManager.preloadAny` will only download asset but not parse asset. You need to invoke `assetManager.loadAny(preloadTask)` + * difference is `assetManager.preloadAny` will only download asset but not parse asset. You need to invoke `assetManager.loadAny()` * to finish loading asset * * @zh * 通用预加载资源接口,可传入进度回调以及完成回调,非常建议你使用更简单的 API ,例如 `preloadRes`, `preloadResDir` 等。`preloadAny` 和 `loadAny` - * 几乎一样,区别在于 `preloadAny` 只会下载资源,不会去解析资源,你需要调用 `assetManager.loadAny(preloadTask)` 来完成资源加载。 - * - * @param requests - The request you want to preload - * @param options - Optional parameters - * @param onProgress - Callback invoked when progression change - * @param onProgress.finished - The number of the items that are already completed - * @param onProgress.total - The total number of the items - * @param onProgress.item - The current request item - * @param onComplete - Callback invoked when finish preloading - * @param onComplete.err - The error occurred in preloading process. - * @param onComplete.items - The preloaded content + * 几乎一样,区别在于 `preloadAny` 只会下载资源,不会去解析资源,你需要调用 `assetManager.loadAny()` 来完成资源加载。 + * + * @param requests @en The preloading requests. @zh 预加载请求。 + * @param options @en Optional parameters. @zh 可选参数。 + * @param onProgress @en Callback invoked when the preloading progress change. @zh 预加载进度发生变化时执行的回调。 + * @param onProgress.finished + * @en The number of request items that have finished preloading. + * @zh 已经完成加载的资源数量。 + * @param onProgress.total @en The number of all request items to be preloaded. @zh 所有待预加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的预加载项。 + * @param onComplete @en Callback invoked when all assets preloaded. @zh 所有资源预加载完成后的回调。 + * @param onComplete.err + * @en The error occurred in preloading process. Or null if preloaded successfully. + * @zh 预加载过程中的发生的错误,如果预加载成功则为 null。 + * @param onComplete.items @en The preloaded content. @zh 完成预加载的内容。 * * @example * assetManager.preloadAny('0cbZa5Y71CTZAccaIFluuZ', (err) => assetManager.loadAny('0cbZa5Y71CTZAccaIFluuZ')); * */ public preloadAny ( - requests: Request, - options: IOptions | null, - onProgress: ProgressCallback | null, - onComplete: CompleteCallbackWithData|null): void; - public preloadAny (requests: Request, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public preloadAny (requests: Request, options: IOptions | null, onComplete?: CompleteCallbackWithData | null): void; - public preloadAny (requests: Request, onComplete?: CompleteCallbackWithData | null): void; + requests: string | string[] | IRequest | Array, + options: { [key: string]: any, preset?: string } | null, + onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, + onComplete: ((err: Error | null, data: RequestItem[]) => void)|null): void; + public preloadAny (requests: string | string[] | IRequest | Array, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preloadAny (requests: string | string[] | IRequest | Array, options: { [key: string]: any, preset?: string } | null, onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preloadAny (requests: string | string[] | IRequest | Array, onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null): void; public preloadAny ( - requests: Request, - options?: IOptions | ProgressCallback | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + requests: string | string[] | IRequest | Array, + options?: { [key: string]: any, preset?: string } | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: RequestItem[]) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: RequestItem[]) => void) | null, + onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null, ) { const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters(options, onProgress, onComplete); opts.preset = opts.preset || 'preload'; @@ -515,18 +543,25 @@ export class AssetManager { /** * @en - * Load remote asset with url, such as audio, image, text and so on. + * Loads remote asset with url, such as audio, image, text and so on. + * Note that `loadRemote` uses the extension name in the url to determine how to load the asset. + * If you pass in a url without the extension name, you need to specify the `ext` parameter + * in the `options` to indicate how you want the asset loaded. See the third example below. * * @zh - * 使用 url 加载远程资源,例如音频,图片,文本等等。 - * - * @param url - The url of asset - * @param options - Some optional parameters - * @param options.audioLoadMode - Indicate which mode audio you want to load - * @param options.ext - If the url does not have a extension name, you can specify one manually. - * @param onComplete - Callback invoked when finish loading - * @param onComplete.err - The error occurred in loading process. - * @param onComplete.asset - The loaded texture + * 使用 url 加载远程资源,例如音频,图片,文本等等。需要注意的是 `loadRemote` 是通过 url 中的扩展名判断以何种方式加载该资源, + * 如果你传入的 url 中没有携带后缀名,你需要额外指定 `options` 中的 `ext` 参数来表明你需要何种方式加载该资源。请参考下面的第三个示例。 + * + * @param url @en The url of asset. @zh 资源的 URL 链接。 + * @param options @en Some optional parameters. @zh 一些可选参数。 + * @param options.ext + * @en If the url does not have an extension name, you can specify one manually. This will affect the way the assets are loaded. + * @zh 如果 URL 链接中没有包含扩展名,你可以手动指定一个扩展名。这将会影响资源的加载方式。 + * @param onComplete @en Callback invoked when finish loading. @zh 当完成加载时触发的回调函数。 + * @param onComplete.err @en The error occurred in loading process. Or null if loaded successfully. @zh 加载过程中出现的错误,如果加载成功则为 null。 + * @param onComplete.asset + * @en The loaded asset. If there is an error in the loading process, this asset will be null. + * @zh 加载好的资源,如果加载过程出现了错误,资源将会 null。 * * @example * assetManager.loadRemote('http://www.cloud.com/test1.jpg', (err, texture) => console.log(err)); @@ -534,10 +569,10 @@ export class AssetManager { * assetManager.loadRemote('http://www.cloud.com/test3', { ext: '.png' }, (err, texture) => console.log(err)); * */ - public loadRemote (url: string, options: IRemoteOptions | null, onComplete?: CompleteCallbackWithData | null): void; - public loadRemote (url: string, onComplete?: CompleteCallbackWithData | null): void; - public loadRemote (url: string, options?: IRemoteOptions | CompleteCallbackWithData | null, onComplete?: CompleteCallbackWithData | null) { - const { options: opts, onComplete: onComp } = parseParameters>(options, undefined, onComplete); + public loadRemote (url: string, options: { [k: string]: any, ext?: string } | null, onComplete?: ((err: Error | null, data: T) => void) | null): void; + public loadRemote (url: string, onComplete?: ((err: Error | null, data: T) => void) | null): void; + public loadRemote (url: string, options?: { [k: string]: any, ext?: string } | ((err: Error | null, data: T) => void) | null, onComplete?: ((err: Error | null, data: T) => void) | null) { + const { options: opts, onComplete: onComp } = parseParameters<((err: Error | null, data: T) => void)>(options, undefined, onComplete); if (!opts.reloadAsset && this.assets.has(url)) { asyncify(onComp)(null, this.assets.get(url)); @@ -551,7 +586,7 @@ export class AssetManager { error(err.message, err.stack); if (onComp) { onComp(err, data); } } else { - factory.create(url, data, opts.ext || extname(url), opts, (p1, p2) => { + factory.create(url, data, opts.ext || path.extname(url), opts, (p1, p2) => { if (onComp) { onComp(p1, p2 as T); } }); } @@ -560,28 +595,44 @@ export class AssetManager { /** * @en - * load bundle + * loads bundle with bundle name or URL. When you have configured a bundle in your project, you can load the bundle by the name configured in your project. + * Or when you put the bundle on the server, you can also load it by the full url address. * - * @zh - * 加载资源包 + * Note: When you load a remote bundle by name, the bundle will be cached locally after download and will continue to use that cache in future, even if + * the version of the bundle file on your server has changed. When you need to load the latest bundle, you can pass an additional `version` parameter in the + * optional parameters and the asset system will compare this version number with the local cache, if the comparison fails, the asset system will pull + * the latest version of the bundle data from the server again. * - * @param nameOrUrl - The name or root path of bundle - * @param options - Some optional paramter, same like downloader.downloadFile - * @param options.version - The version of this bundle, you can check config.json in this bundle - * @param onComplete - Callback when bundle loaded or failed - * @param onComplete.err - The occurred error, null indicates success - * @param onComplete.bundle - The loaded bundle + * @zh + * 通过包名称或 url 加载资源包。当你在项目中配置了 Bundle 后,你可以通过项目中配置的名称来加载该 Bundle。 + * 或者当你将 bundle 放在服务器上时,你也可以通过完整的 url 地址进行加载。 + * + * 注意:当你用名称加载远程 bundle 时,该 bundle 在下载后将会缓存在本地并在后续持续使用该缓存,即使你服务器上的 bundle 文件版本已经发生变化。当你需要加载 + * 最新的 bundle 时,你可以在可选参数中额外传入一个 `version` 参数,资源系统将比对此版本号与本地缓存是否一致,如果比对失败,则资源系统将重新从服务器上拉取 + * 最新版本的 bundle 数据。 + * + * @param nameOrUrl @en The name or root path of bundle. @zh 待加载的 bundle 在项目中的名称或在服务器上的 url 路径。 + * @param options @en Some optional parameters. @zh 一些可选参数。 + * @param options.version + * @en The version of the bundle, which you can get in the editor's build system, or directly by looking at the md5 hash value in the `config.json` path in the bundle directory after the build. + * @zh bundle 的版本号,你可以在编辑器的构建系统中获取,或者直接查看构建后的 bundle 目录中 config.json 路径中的 md5 hash 值。 + * @param onComplete @en Callback invoked when bundle loaded or failed. @zh bundle 加载完成的回调。 + * @param onComplete.err @en The occurred error during the loading, Or null if loaded successfully. @zh 加载过程中发生的错误,如果加载成功则为 null。 + * @param onComplete.bundle + * @en The loaded bundle. If there is an error in the loading process, this bundle will be null. + * @zh 加载完成的 bundle。如果加载过程中出现了错误,则为 null。 * * @example + * loadBundle('myBundle', (err, bundle) => console.log(bundle)); * loadBundle('http://localhost:8080/test', null, (err, bundle) => console.log(err)); * */ - public loadBundle (nameOrUrl: string, options: IBundleOptions | null, onComplete?: CompleteCallbackWithData | null): void; - public loadBundle (nameOrUrl: string, onComplete?: CompleteCallbackWithData | null): void; - public loadBundle (nameOrUrl: string, options?: IBundleOptions | CompleteCallbackWithData | null, onComplete?: CompleteCallbackWithData | null) { - const { options: opts, onComplete: onComp } = parseParameters>(options, undefined, onComplete); + public loadBundle (nameOrUrl: string, options: { [k: string]: any, version?: string } | null, onComplete?: ((err: Error | null, data: Bundle) => void) | null): void; + public loadBundle (nameOrUrl: string, onComplete?: ((err: Error | null, data: Bundle) => void) | null): void; + public loadBundle (nameOrUrl: string, options?: { [k: string]: any, version?: string } | ((err: Error | null, data: Bundle) => void) | null, onComplete?: ((err: Error | null, data: Bundle) => void) | null) { + const { options: opts, onComplete: onComp } = parseParameters<((err: Error | null, data: Bundle) => void)>(options, undefined, onComplete); - const bundleName = basename(nameOrUrl); + const bundleName = path.basename(nameOrUrl); if (this.bundles.has(bundleName)) { asyncify(onComp)(null, this.getBundle(bundleName)); @@ -616,7 +667,7 @@ export class AssetManager { * 比如说,当你释放一个 texture 资源,这个 texture 和它的 gl 贴图数据都会被释放。 * 注意,这个函数可能会导致资源贴图或资源所依赖的贴图不可用,如果场景中存在节点仍然依赖同样的贴图,它们可能会变黑并报 GL 错误。 * - * @param asset - The asset to be released + * @param asset @en The asset to be released. @zh 被释放的资源。 * * @example * // release a texture which is no longer need @@ -632,7 +683,7 @@ export class AssetManager { * Release all unused assets. Refer to [[releaseAsset]] for detailed information. * * @zh - * 释放所有没有用到的资源。详细信息请参考 [[releaseAsset]] + * 释放所有没有用到的资源。详细信息请参考 [[releaseAsset]]。 * * @engineInternal * @@ -648,7 +699,7 @@ export class AssetManager { * Release all assets. Refer to [[releaseAsset]] for detailed information. * * @zh - * 释放所有资源。详细信息请参考 [[releaseAsset]] + * 释放所有资源。详细信息请参考 [[releaseAsset]]。 * */ public releaseAll () { @@ -662,25 +713,25 @@ export class AssetManager { * @param json * @param options * @param onComplete - * @private + * @internal */ public loadWithJson ( json: Record, - options: IJsonAssetOptions | null, - onProgress: ProgressCallback | null, - onComplete: CompleteCallbackWithData | null): void; - public loadWithJson (json: Record, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadWithJson (json: Record, options: IJsonAssetOptions | null, onComplete?: CompleteCallbackWithData | null): void; - public loadWithJson (json: Record, onComplete?: CompleteCallbackWithData | null): void; + options: { [key: string]: any, assetId?: string } | null, + onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, + onComplete: ((err: Error | null, data: T) => void) | null): void; + public loadWithJson (json: Record, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: T) => void) | null): void; + public loadWithJson (json: Record, options: { [key: string]: any, assetId?: string }, onComplete?: ((err: Error | null, data: T) => void) | null): void; + public loadWithJson (json: Record, onComplete?: ((err: Error | null, data: T) => void) | null): void; public loadWithJson ( json: Record, - options?: IJsonAssetOptions | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + options?: { [key: string]: any, assetId?: string } | ((err: Error | null, data: T) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: T) => void) | null, + onComplete?: ((err: Error | null, data: T) => void) | null, ) { if (BUILD) { throw new Error('Only valid in Editor'); } - const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters>(options, onProgress, onComplete); + const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters<((err: Error | null, data: T) => void)>(options, onProgress, onComplete); const item = RequestItem.create(); item.isNative = false; @@ -711,6 +762,10 @@ AssetManager.Cache = Cache; AssetManager.RequestItem = RequestItem; AssetManager.Bundle = Bundle; AssetManager.BuiltinBundleName = BuiltinBundleName; +AssetManager.CacheManager = CacheManager; +AssetManager.Downloader = Downloader; +AssetManager.Parser = Parser; +AssetManager.DependUtil = DependUtil; export declare namespace AssetManager { export { Pipeline }; @@ -719,7 +774,20 @@ export declare namespace AssetManager { export { RequestItem }; export { Bundle }; export { BuiltinBundleName }; + export { CacheManager }; + // Can not export interface in namespace for now. + // export { ICache }; + // export { IAssetInfo, IPackInfo, IAddressableInfo, ISceneInfo, IRequest }; + export { DependUtil }; + export { Downloader }; + export { Parser }; } -export default legacyCC.assetManager = new AssetManager(); -legacyCC.AssetManager = AssetManager; +/** + * @en `assetManager` is a global singleton instance of [[AssetManager]]. + * The engine uses `assetManager` to manage all asset and asset bundle, including loading, releasing, etc. + * @zh `assetManager` 为 [[AssetManager]] 的全局单例,引擎使用 `assetManager` 来完成所有资源和资源包的管理工作,包括加载,释放等。 + */ +const assetManager = cclegacy.assetManager = AssetManager.instance; +export default assetManager; +cclegacy.AssetManager = AssetManager; diff --git a/cocos/asset/asset-manager/builtin-res-mgr.jsb.ts b/cocos/asset/asset-manager/builtin-res-mgr.jsb.ts index deebba92004..55680b02946 100644 --- a/cocos/asset/asset-manager/builtin-res-mgr.jsb.ts +++ b/cocos/asset/asset-manager/builtin-res-mgr.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,13 +22,13 @@ THE SOFTWARE. */ -import { legacyCC } from '../../core/global-exports'; import { SpriteFrame } from '../../2d/assets/sprite-frame'; import type { ImageSource } from '../assets/image-asset'; import assetManager from '../asset-manager/asset-manager'; import { BuiltinBundleName } from '../asset-manager/shared'; import { TEST, EDITOR } from 'internal:constants'; -import { Settings, settings } from '../../core/settings'; +import Bundle from '../asset-manager/bundle'; +import { Settings, settings, cclegacy } from '../../core'; import releaseManager from '../asset-manager/release-manager'; declare const jsb: any; @@ -71,8 +70,8 @@ builtinResMgrProto.init = function (): Promise { blackTexture.image = imgAsset; resources[blackTexture._uuid] = blackTexture; - if (legacyCC.SpriteFrame) { - const spriteFrame = new legacyCC.SpriteFrame() as SpriteFrame; + if (cclegacy.SpriteFrame) { + const spriteFrame = new cclegacy.SpriteFrame() as SpriteFrame; const image = imgAsset; const texture = new Texture2D(); texture.image = image; @@ -80,6 +79,27 @@ builtinResMgrProto.init = function (): Promise { spriteFrame._uuid = 'default-spriteframe'; resources[spriteFrame._uuid] = spriteFrame; } + if (EDITOR) { + const builtinAssets = settings.querySettings(Settings.Category.ENGINE, 'builtinAssets'); + const builtinBundle = new Bundle(); + builtinBundle.init({ + name: BuiltinBundleName.INTERNAL, + uuids: builtinAssets || [], + deps: [], + importBase: '', + nativeBase: '', + base: '', + paths: {}, + scenes: {}, + packs: {}, + versions: { import: [], native: [] }, + redirect: [], + debug: false, + types: [], + extensionMap: {}, + }); + } + this.initBuiltinRes(); }; @@ -119,9 +139,9 @@ builtinResMgrProto.loadBuiltinAssets = function () { resources[asset.name] = asset; const url = asset.nativeUrl; // In Editor, no need to ignore asset destroy, we use auto gc to handle destroy - if (!EDITOR || legacyCC.GAME_VIEW) releaseManager.addIgnoredAsset(asset); + if (!EDITOR || cclegacy.GAME_VIEW) releaseManager.addIgnoredAsset(asset); this.addAsset(asset.name, asset); - if (asset instanceof legacyCC.Material) { + if (asset instanceof cclegacy.Material) { this._materialsToBeCompiled.push(asset); } }); @@ -132,5 +152,5 @@ builtinResMgrProto.loadBuiltinAssets = function () { }); } -const builtinResMgr = legacyCC.builtinResMgr = BuiltinResMgr.getInstance(); +const builtinResMgr = cclegacy.builtinResMgr = BuiltinResMgr.getInstance(); export { builtinResMgr }; diff --git a/cocos/asset/asset-manager/builtin-res-mgr.ts b/cocos/asset/asset-manager/builtin-res-mgr.ts index 836d8ab1a24..d07222ab14e 100644 --- a/cocos/asset/asset-manager/builtin-res-mgr.ts +++ b/cocos/asset/asset-manager/builtin-res-mgr.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, TEST } from 'internal:constants'; import { Asset } from '../assets/asset'; @@ -29,11 +28,10 @@ import { ImageAsset, ImageSource } from '../assets/image-asset'; import { SpriteFrame } from '../../2d/assets/sprite-frame'; import { Texture2D } from '../assets/texture-2d'; import { TextureCube } from '../assets/texture-cube'; -import { legacyCC } from '../../core/global-exports'; import assetManager from './asset-manager'; import { BuiltinBundleName } from './shared'; import Bundle from './bundle'; -import { Settings, settings } from '../../core/settings'; +import { Settings, settings, cclegacy } from '../../core'; import releaseManager from './release-manager'; import { Material } from '../assets'; @@ -272,8 +270,8 @@ class BuiltinResMgr { }; resources[defaultCubeTexture._uuid] = defaultCubeTexture; - if (legacyCC.SpriteFrame) { - const spriteFrame = new legacyCC.SpriteFrame() as SpriteFrame; + if (cclegacy.SpriteFrame) { + const spriteFrame = new cclegacy.SpriteFrame() as SpriteFrame; const image = imgAsset; const texture = new Texture2D(); texture.image = image; @@ -332,8 +330,8 @@ class BuiltinResMgr { assets.forEach((asset) => { resources[asset.name] = asset; // In Editor, no need to ignore asset destroy, we use auto gc to handle destroy - if (!EDITOR || legacyCC.GAME_VIEW) { releaseManager.addIgnoredAsset(asset); } - if (asset instanceof legacyCC.Material) { + if (!EDITOR || cclegacy.GAME_VIEW) { releaseManager.addIgnoredAsset(asset); } + if (asset instanceof cclegacy.Material) { this._materialsToBeCompiled.push(asset as Material); } }); @@ -356,5 +354,5 @@ class BuiltinResMgr { } } -const builtinResMgr = legacyCC.builtinResMgr = new BuiltinResMgr(); +const builtinResMgr = cclegacy.builtinResMgr = new BuiltinResMgr(); export { builtinResMgr }; diff --git a/cocos/asset/asset-manager/bundle.ts b/cocos/asset/asset-manager/bundle.ts index 391a170691e..3aa70c1bcd2 100644 --- a/cocos/asset/asset-manager/bundle.ts +++ b/cocos/asset/asset-manager/bundle.ts @@ -1,18 +1,18 @@ +/* eslint-disable max-len */ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,32 +21,31 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Asset } from '../assets/asset'; import { SceneAsset } from '../assets/scene-asset'; -import { legacyCC } from '../../core/global-exports'; -import { error, errorID } from '../../core/platform/debug'; +import { error, errorID, cclegacy } from '../../core'; import Config, { IAddressableInfo, IAssetInfo, IConfigOption, ISceneInfo } from './config'; import releaseManager from './release-manager'; import RequestItem from './request-item'; -import { assets, AssetType, bundles, CompleteCallbackWithData, CompleteCallbackNoData, IAssetOptions, ProgressCallback, RequestType } from './shared'; +import { assets, bundles, RequestType } from './shared'; import { parseLoadResArgs, parseParameters } from './utilities'; /** * @en - * A bundle contains an amount of assets(includes scene), you can load, preload, release asset which is in this bundle + * A bundle contains an amount of assets(includes scene), you can load, preload, release asset which is in this bundle. * * @zh - * 一个包含一定数量资源(包括场景)的包,你可以加载,预加载,释放此包内的资源 + * 一个包含一定数量资源(包括场景)的包,你可以加载,预加载,释放此包内的资源。 * */ export default class Bundle { private _config: Config = new Config(); /** - * for internal use - * @private + * For internal use. + * @engineInternal */ public get config (): Config { return this._config; @@ -54,10 +53,10 @@ export default class Bundle { /** * @en - * The name of this bundle + * The name of this bundle. * * @zh - * 此 bundle 的名称 + * 此 bundle 的名称。 * */ public get name (): string { @@ -66,10 +65,10 @@ export default class Bundle { /** * @en - * The dependency of this bundle + * The dependent bundles of this bundle. * * @zh - * 此 bundle 的依赖 + * 此 bundle 的依赖包。 * */ public get deps (): string[] { @@ -78,10 +77,10 @@ export default class Bundle { /** * @en - * The root path of this bundle, such like 'http://example.com/bundle1' + * The root path of this bundle, such like 'http://example.com/bundle1'. * * @zh - * 此 bundle 的根路径, 例如 'http://example.com/bundle1' + * 此 bundle 的根路径, 例如 'http://example.com/bundle1'。 * */ public get base (): string { @@ -90,56 +89,57 @@ export default class Bundle { /** * @en - * Get asset's info using path, only valid when asset is in bundle folder. + * Gets asset's info using path, only valid when asset is in bundle folder. * * @zh - * 使用 path 获取资源的配置信息 + * 使用 path 获取资源的配置信息。 * - * @param path - The relative path of asset, such as 'images/a' - * @param type - The constructor of asset, such as `Texture2D` - * @returns The asset info + * @param path @en The relative path of asset, such as 'images/a'. @zh 资源的相对路径,例如 `images/a`。 + * @param type @en The constructor of asset, such as `Texture2D`. @zh 资源的类型,例如 [[Texture2D]]。 + * @returns @en The asset info. @zh 资源的信息。 * * @example - * var info = bundle.getInfoWithPath('image/a', Texture2D); + * const info = bundle.getInfoWithPath('image/a', Texture2D); * */ - public getInfoWithPath (path: string, type?: AssetType | null): IAddressableInfo | null { + public getInfoWithPath (path: string, type?: Constructor | null): IAddressableInfo | null { return this._config.getInfoWithPath(path, type); } /** * @en - * Get all asset's info within specific folder + * Gets all asset's info within specific folder. * * @zh - * 获取在某个指定文件夹下的所有资源信息 + * 获取在某个指定文件夹下的所有资源信息。 * - * @param path - The relative path of folder, such as 'images' - * @param type - The constructor should be used to filter paths - * @param out - The output array - * @returns Infos + * @param path @en The relative path of folder, such as 'images'. @zh 文件夹的相对路径,例如 `images`。 + * @param type + * @en The asset type, can be used to find the information of the specified type of asset in the directory. + * @zh 资源的类型,指定后可以用来查找目录下指定类型的资源信息。 + * @param out @en The output array. @zh 输出数组。 + * @returns @en Queried asset information. @zh 查询到的资源信息。 * * @example - * var infos = []; + * const infos = []; * bundle.getDirWithPath('images', Texture2D, infos); */ - public getDirWithPath (path: string, type?: AssetType | null, out?: IAddressableInfo[]): IAddressableInfo[] { + public getDirWithPath (path: string, type?: Constructor | null, out?: IAddressableInfo[]): IAddressableInfo[] { return this._config.getDirWithPath(path, type, out); } /** * @en - * Get asset's info with uuid + * Get asset's information with uuid. * * @zh - * 通过 uuid 获取资源信息 + * 通过 uuid 获取资源信息。 * - * @method getAssetInfo - * @param uuid - The asset's uuid - * @returns info + * @param uuid @en The asset's uuid. @zh 资源的 uuid。 + * @returns @en The information of asset. @zh 资源的信息。 * * @example - * var info = bundle.getAssetInfo('fcmR3XADNLgJ1ByKhqcC5Z'); + * const info = bundle.getAssetInfo('fcmR3XADNLgJ1ByKhqcC5Z'); * */ public getAssetInfo (uuid: string): IAssetInfo | null { @@ -148,17 +148,16 @@ export default class Bundle { /** * @en - * Get scene'info with name + * Gets scene's information with name. * * @zh - * 通过场景名获取场景信息 + * 通过场景名获取场景信息。 * - * @method getSceneInfo - * @param name - The name of scene - * @return info + * @param name @en The name of scene. @zh 场景名称。 + * @returns @en The information of scene. @zh 场景信息。 * * @example - * var info = bundle.getSceneInfo('first.fire'); + * const info = bundle.getSceneInfo('first.fire'); * */ public getSceneInfo (name: string): ISceneInfo | null { @@ -167,12 +166,13 @@ export default class Bundle { /** * @en - * Initialize this bundle with options + * Initializes this bundle with options. * * @zh - * 初始化此 bundle + * 初始化此 bundle。 * * @param options + * @deprecate Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. * */ public init (options: IConfigOption) { @@ -182,20 +182,30 @@ export default class Bundle { /** * @en - * Load the asset within this bundle by the path which is relative to bundle's path + * Loads the asset within this bundle by the path which is relative to bundle's path. * * @zh - * 通过相对路径加载分包中的资源。路径是相对分包文件夹路径的相对路径 - * - * @param paths - Paths of the target assets.The path is relative to the bundle's folder, extensions must be omitted. - * @param type - Only asset of type will be loaded if this argument is supplied. - * @param onProgress - Callback invoked when progression change. - * @param onProgress.finish - The number of the items that are already completed. - * @param onProgress.total - The total number of the items. - * @param onProgress.item - The finished request item. - * @param onComplete - Callback invoked when all assets loaded. - * @param onComplete.error - The error info or null if loaded successfully. - * @param onComplete.assets - The loaded assets. + * 通过相对路径加载分包中的资源。路径是相对分包文件夹路径的相对路径。 + * + * @param paths + * @en Paths of the target assets.These paths are relative to the bundle's folder, extension name must be omitted. + * @zh 需要加载的资源的路径。此路径为工程中相对于 bundle 文件夹的相对路径,路径中请不要带扩展名。 + * @param type + * @en Asset type, if this parameter is passed, the asset of the corresponding type will be found in the assets of the corresponding path to finish loading. + * @zh 资源类型,如果传入此参数,则会在对应路径的资源中找到对应类型的资源完成加载。 + * @param onProgress + * @en Callback invoked when the loading progress change. + * @zh 加载进度发生变化时执行的回调。 + * @param onProgress.finish + * @en The number of request items that have been loaded. + * @zh 已经完成加载的资源数量。 + * @param onProgress.total + * @en The number of all request items to be loaded. + * @zh 所有待加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的加载项。 + * @param onComplete @en Callback invoked when all assets loaded. @zh 所有资源加载完成后的回调。 + * @param onComplete.error @en Error message during loading, or null if loaded successfully. @zh 加载过程中的错误信息,如果加载成功则为 null。 + * @param onComplete.assets @en The loaded asset, or null if an error occurred during loading. @zh 已加载的资源,如果加载过程中有错误发生,则为 null。 * * @example * // load the texture (${project}/assets/resources/textures/background.jpg) from resources @@ -213,50 +223,60 @@ export default class Bundle { */ public load ( paths: string, - type: AssetType | null, - onProgress: ProgressCallback | null, - onComplete: CompleteCallbackWithData | null): void; + type: Constructor | null, + onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, + onComplete: ((err: Error | null, data: T) => void) | null): void; public load ( - paths: string[], type: AssetType | null, - onProgress: ProgressCallback | null, - onComplete: CompleteCallbackWithData | null): void; - public load (paths: string, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public load (paths: string[], onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public load (paths: string, onComplete?: CompleteCallbackWithData | null): void; - public load (paths: string[], onComplete?: CompleteCallbackWithData | null): void; - public load (paths: string, type: AssetType | null, onComplete?: CompleteCallbackWithData | null): void; - public load (paths: string[], type: AssetType | null, onComplete?: CompleteCallbackWithData | null): void; + paths: string[], type: Constructor | null, + onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, + onComplete: ((err: Error | null, data: T[]) => void) | null): void; + public load (paths: string, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: T) => void) | null): void; + public load (paths: string[], onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: T[]) => void) | null): void; + public load (paths: string, onComplete?: ((err: Error | null, data: T) => void) | null): void; + public load (paths: string[], onComplete?: ((err: Error | null, data: T[]) => void) | null): void; + public load (paths: string, type: Constructor | null, onComplete?: ((err: Error | null, data: T) => void) | null): void; + public load (paths: string[], type: Constructor | null, onComplete?: ((err: Error | null, data: T[]) => void) | null): void; public load ( paths: string|string[], - type?: AssetType | ProgressCallback | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + type?: Constructor | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: T|T[]) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: T|T[]) => void) | null, + onComplete?: ((err: Error | null, data: T|T[]) => void) | null, ) { const { type: _type, onProgress: onProg, onComplete: onComp } = parseLoadResArgs(type, onProgress, onComplete); const options = { __requestType__: RequestType.PATH, type: _type, bundle: this.name, __outputAsArray__: Array.isArray(paths) }; - legacyCC.assetManager.loadAny(paths, options, onProg, onComp); + cclegacy.assetManager.loadAny(paths, options, onProg, onComp); } /** * @en - * Preload the asset within this bundle by the path which is relative to bundle's path. - * After calling this method, you still need to finish loading by calling `Bundle.load`. - * It will be totally fine to call `Bundle.load` at any time even if the preloading is not - * yet finished + * Preloads the asset within this bundle by the path which is relative to bundle's path. + * After calling this method, you still need to finish loading by calling [[Bundle.load]]. + * It will be totally fine to call [[Bundle.load]] at any time even if the preloading is not + * yet finished. * * @zh - * 通过相对路径预加载分包中的资源。路径是相对分包文件夹路径的相对路径。调用完后,你仍然需要通过 `Bundle.load` 来完成加载。 - * 就算预加载还没完成,你也可以直接调用 `Bundle.load`。 - * - * @param paths - Paths of the target asset.The path is relative to bundle folder, extensions must be omitted. - * @param type - Only asset of type will be loaded if this argument is supplied. - * @param onProgress - Callback invoked when progression change. - * @param onProgress.finish - The number of the items that are already completed. - * @param onProgress.total - The total number of the items. - * @param onProgress.item - The finished request item. - * @param onComplete - Callback invoked when the resource loaded. - * @param onComplete.error - The error info or null if loaded successfully. - * @param onComplete.items - The preloaded items. + * 通过相对路径预加载分包中的资源。路径是相对分包文件夹路径的相对路径。调用完后,你仍然需要通过 [[Bundle.load]] 来完成加载。 + * 就算预加载还没完成,你也可以直接调用 [[Bundle.load]]。 + * + * @param paths + * @en Paths of the target assets.These paths are relative to the bundle's folder, extension name must be omitted. + * @zh 需要加载的资源的路径。此路径为工程中相对于 bundle 文件夹的相对路径,路径中请不要带扩展名。 + * @param type + * @en Asset type, if this parameter is passed, the asset of the corresponding type will be found in the assets of the corresponding path to finish preloading. + * @zh 资源类型,如果传入此参数,则会在对应路径的资源中找到对应类型的资源完成预加载。 + * @param onProgress + * @en Callback invoked when the preloading progress change. + * @zh 预加载进度发生变化时执行的回调。 + * @param onProgress.finish + * @en The number of request items that have been preloaded. + * @zh 已经完成预加载的资源数量。 + * @param onProgress.total + * @en The number of all request items to be preloaded. + * @zh 所有待预加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的预加载项。 + * @param onComplete @en Callback invoked when all assets preloaded. @zh 所有资源预加载完成后的回调。 + * @param onComplete.error @en Error message during preloading, or null if preloaded successfully. @zh 预加载过程中的错误信息,如果预加载成功则为 null。 + * @param onComplete.items @en The preloaded items. @zh 预加载项。 * * @example * // preload the texture (${project}/assets/resources/textures/background.jpg) from resources @@ -276,39 +296,44 @@ export default class Bundle { * bundle2.load('imgs/cocos', SpriteFrame, (err, spriteFrame) => {}); * */ - public preload (paths: string|string[], type: AssetType|null, onProgress: ProgressCallback|null, onComplete: CompleteCallbackWithData|null): void; - public preload (paths: string|string[], onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public preload (paths: string|string[], onComplete?: CompleteCallbackWithData | null): void; - public preload (paths: string|string[], type: AssetType | null, onComplete?: CompleteCallbackWithData | null): void; + public preload (paths: string|string[], type: Constructor|null, onProgress: ((finished: number, total: number, item: RequestItem) => void)|null, onComplete: ((err: Error | null, data: RequestItem[]) => void)|null): void; + public preload (paths: string|string[], onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preload (paths: string|string[], onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preload (paths: string|string[], type: Constructor | null, onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null): void; public preload ( paths: string|string[], - type?: AssetType | ProgressCallback | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + type?: Constructor | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: RequestItem[]) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: RequestItem[]) => void) | null, + onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null, ) { const { type: _type, onProgress: onProg, onComplete: onComp } = parseLoadResArgs(type, onProgress, onComplete); - legacyCC.assetManager.preloadAny(paths, { __requestType__: RequestType.PATH, type: _type, bundle: this.name }, onProg, onComp); + cclegacy.assetManager.preloadAny(paths, { __requestType__: RequestType.PATH, type: _type, bundle: this.name }, onProg, onComp); } /** * @en - * Load all assets under a folder inside the bundle folder.
+ * Loads all assets under a folder inside the bundle folder.
*
* Note: All asset paths in Creator use forward slashes, paths using backslashes will not work. * * @zh - * 加载目标文件夹中的所有资源, 注意:路径中只能使用斜杠,反斜杠将停止工作 - * - * @param dir - path of the target folder.The path is relative to the bundle folder, extensions must be omitted. - * @param type - Only asset of type will be loaded if this argument is supplied. - * @param onProgress - Callback invoked when progression change. - * @param onProgress.finish - The number of the items that are already completed. - * @param onProgress.total - The total number of the items. - * @param onProgress.item - The latest request item - * @param onComplete - A callback which is called when all assets have been loaded, or an error occurs. - * @param onComplete.error - If one of the asset failed, the complete callback is immediately called with the error. - * If all assets are loaded successfully, error will be null. - * @param onComplete.assets - An array of all loaded assets. + * 加载目标文件夹中的所有资源, 注意:路径中只能使用斜杠,反斜杠将停止工作。 + * + * @param dir @en The path of the target folder. The path is relative to the bundle folder. @zh 目标文件夹路径,此路径为相对于 bundle 文件夹的路径。 + * @param type @en The asset type. Only specify type asset will be loaded if this argument is supplied. @zh 资源类型,如果指定了此参数,则只会加载目标文件夹下此类型的资源。 + * @param onProgress + * @en Callback invoked when the loading progress change. + * @zh 加载进度发生变化时执行的回调。 + * @param onProgress.finish + * @en The number of request items that have been loaded. + * @zh 已经完成加载的资源数量。 + * @param onProgress.total + * @en The number of all request items to be loaded. + * @zh 所有待加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的加载项。 + * @param onComplete @en Callback invoked when all assets loaded. @zh 所有资源加载完成后的回调。 + * @param onComplete.error @en Error message during loading, or null if loaded successfully. @zh 加载过程中的错误信息,如果加载成功则为 null。 + * @param onComplete.assets @en An array of all loaded assets. @zh 完成加载的资源数组。 * * @example * // load all audios (resources/audios/) @@ -327,40 +352,45 @@ export default class Bundle { * bundle2.loadDir('skills', SpriteFrame, null, (err, spriteFrames) => console.log(err)); * */ - public loadDir (dir: string, type: AssetType | null, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadDir (dir: string, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadDir (dir: string, onComplete?: CompleteCallbackWithData | null): void; - public loadDir (dir: string, type: AssetType | null, onComplete?: CompleteCallbackWithData | null): void; + public loadDir (dir: string, type: Constructor | null, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: T[]) => void) | null): void; + public loadDir (dir: string, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: T[]) => void) | null): void; + public loadDir (dir: string, onComplete?: ((err: Error | null, data: T[]) => void) | null): void; + public loadDir (dir: string, type: Constructor | null, onComplete?: ((err: Error | null, data: T[]) => void) | null): void; public loadDir ( dir: string, - type?: AssetType | ProgressCallback | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + type?: Constructor | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: T[]) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: T[]) => void) | null, + onComplete?: ((err: Error | null, data: T[]) => void) | null, ) { const { type: _type, onProgress: onProg, onComplete: onComp } = parseLoadResArgs(type, onProgress, onComplete); - legacyCC.assetManager.loadAny(dir, { __requestType__: RequestType.DIR, type: _type, bundle: this.name, __outputAsArray__: true }, onProg, onComp); + cclegacy.assetManager.loadAny(dir, { __requestType__: RequestType.DIR, type: _type, bundle: this.name, __outputAsArray__: true }, onProg, onComp); } /** * @en - * Preload all assets under a folder inside the bundle folder.
After calling this method, you still need to - * finish loading by calling `Bundle.loadDir`. - * It will be totally fine to call `Bundle.loadDir` at any time even if the preloading is not yet finished + * Preloads all assets under a folder inside the bundle folder.
After calling this method, you still need to + * finish loading by calling [[Bundle.loadDir]]. + * It will be totally fine to call [[Bundle.loadDir]] at any time even if the preloading is not yet finished. * * @zh - * 预加载目标文件夹中的所有资源。调用完后,你仍然需要通过 `Bundle.loadDir` 来完成加载。 - * 就算预加载还没完成,你也可以直接调用 `Bundle.loadDir`。 - * - * @param dir - path of the target folder.The path is relative to the bundle folder, extensions must be omitted. - * @param type - Only asset of type will be preloaded if this argument is supplied. - * @param onProgress - Callback invoked when progression change. - * @param onProgress.finish - The number of the items that are already completed. - * @param onProgress.total - The total number of the items. - * @param onProgress.item - The latest request item - * @param onComplete - A callback which is called when all assets have been loaded, or an error occurs. - * @param onComplete.error - If one of the asset failed, the complete callback is immediately called with the error. - * If all assets are preloaded successfully, error will be null. - * @param onComplete.items - An array of all preloaded items. + * 预加载目标文件夹中的所有资源。调用完后,你仍然需要通过 [[Bundle.loadDir]] 来完成加载。 + * 就算预加载还没完成,你也可以直接调用 [[Bundle.loadDir]]。 + * + * @param dir @en The path of the target folder. The path is relative to the bundle folder. @zh 目标文件夹路径,此路径为相对于 bundle 文件夹的路径。 + * @param type @en The asset type. Only specify type asset will be preloaded if this argument is supplied. @zh 资源类型,如果指定了此参数,则只会预加载目标文件夹下此类型的资源。 + * @param onProgress + * @en Callback invoked when the preloading progress change. + * @zh 预加载进度发生变化时执行的回调。 + * @param onProgress.finish + * @en The number of request items that have been preloaded. + * @zh 已经完成预加载的资源数量。 + * @param onProgress.total + * @en The number of all request items to be preloaded. + * @zh 所有待预加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的预加载项。 + * @param onComplete @en Callback invoked when all assets preloaded. @zh 所有资源预加载完成后的回调。 + * @param onComplete.error @en Error message during preloading, or null if preloaded successfully. @zh 预加载过程中的错误信息,如果预加载成功则为 null。 + * @param onComplete.items @en The preloaded items. @zh 预加载项。 * * @example * // preload all audios (resources/audios/) @@ -379,18 +409,18 @@ export default class Bundle { * // wait for while * bundle2.loadDir('skills', SpriteFrame, (err, spriteFrames) => {}); */ - public preloadDir (dir: string, type: AssetType | null, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public preloadDir (dir: string, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public preloadDir (dir: string, onComplete?: CompleteCallbackWithData | null): void; - public preloadDir (dir: string, type: AssetType | null, onComplete?: CompleteCallbackWithData | null): void; + public preloadDir (dir: string, type: Constructor | null, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preloadDir (dir: string, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preloadDir (dir: string, onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null): void; + public preloadDir (dir: string, type: Constructor | null, onComplete?: ((err: Error | null, data: RequestItem[]) => void) | null): void; public preloadDir ( dir: string, - type?: AssetType | ProgressCallback | CompleteCallbackWithData| null, - onProgress?: ProgressCallback | CompleteCallbackWithData| null, - onComplete?: CompleteCallbackWithData| null, + type?: Constructor | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: RequestItem[]) => void)| null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: RequestItem[]) => void)| null, + onComplete?: ((err: Error | null, data: RequestItem[]) => void)| null, ) { const { type: _type, onProgress: onProg, onComplete: onComp } = parseLoadResArgs(type, onProgress, onComplete); - legacyCC.assetManager.preloadAny(dir, { __requestType__: RequestType.DIR, type: _type, bundle: this.name }, onProg, onComp); + cclegacy.assetManager.preloadAny(dir, { __requestType__: RequestType.DIR, type: _type, bundle: this.name }, onProg, onComp); } /** @@ -400,35 +430,41 @@ export default class Bundle { * @zh * 通过场景名称加载分包中的场景资源。 * - * @param sceneName - The name of the scene to load. - * @param options - Some optional parameters - * @param onProgress - Callback invoked when progression change. - * @param onProgress.finish - The number of the items that are already completed. - * @param onProgress.total - The total number of the items. - * @param onProgress.item - The latest request item - * @param onComplete - callback, will be called after scene launched. - * @param onComplete.err - The occurred error, null indicetes success - * @param onComplete.sceneAsset - The scene asset + * @param sceneName @en The name of the scene to be loaded. @zh 待加载的场景名称。 + * @param options @en Some optional parameters. @zh 可选参数。 + * @param onProgress + * @en Callback invoked when the loading progress change. + * @zh 加载进度发生变化时执行的回调。 + * @param onProgress.finish + * @en The number of request items that have been loaded. + * @zh 已经完成加载的资源数量。 + * @param onProgress.total + * @en The number of all request items to be loaded. + * @zh 所有待加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的加载项。 + * @param onComplete @en Callback invoked when the scene loaded. @zh 场景加载完成后的回调。 + * @param onComplete.error @en Error message during loading, or null if loaded successfully. @zh 加载过程中的错误信息,如果加载成功则为 null。 + * @param onComplete.sceneAsset @en The scene asset. @zh 加载完成的场景资源。 * * @example * bundle1.loadScene('first', (err, sceneAsset) => director.runScene(sceneAsset)); * */ - public loadScene (sceneName: string, options: IAssetOptions | null, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadScene (sceneName: string, onProgress: ProgressCallback | null, onComplete: CompleteCallbackWithData | null): void; - public loadScene (sceneName: string, options: IAssetOptions | null, onComplete?: CompleteCallbackWithData | null): void; - public loadScene (sceneName: string, onComplete?: CompleteCallbackWithData | null): void; + public loadScene (sceneName: string, options: { [key: string]: any, preset?: 'string' } | null, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: SceneAsset) => void) | null): void; + public loadScene (sceneName: string, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err: Error | null, data: SceneAsset) => void) | null): void; + public loadScene (sceneName: string, options: { [key: string]: any, preset?: 'string' } | null, onComplete?: ((err: Error | null, data: SceneAsset) => void) | null): void; + public loadScene (sceneName: string, onComplete?: ((err: Error | null, data: SceneAsset) => void) | null): void; public loadScene ( sceneName: string, - options?: IAssetOptions | ProgressCallback | CompleteCallbackWithData | null, - onProgress?: ProgressCallback | CompleteCallbackWithData | null, - onComplete?: CompleteCallbackWithData | null, + options?: { [key: string]: any, preset?: 'string' } | ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: SceneAsset) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err: Error | null, data: SceneAsset) => void) | null, + onComplete?: ((err: Error | null, data: SceneAsset) => void) | null, ) { - const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters>(options, onProgress, onComplete); + const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters<((err: Error | null, data: SceneAsset) => void)>(options, onProgress, onComplete); opts.preset = opts.preset || 'scene'; opts.bundle = this.name; - legacyCC.assetManager.loadAny({ scene: sceneName }, opts, onProg, (err, sceneAsset) => { + cclegacy.assetManager.loadAny({ scene: sceneName }, opts, onProg, (err, sceneAsset) => { if (err) { error(err.message, err.stack); } else if (sceneAsset.scene) { @@ -445,21 +481,27 @@ export default class Bundle { /** * @en * Preload the scene asset within this bundle by its name. After calling this method, you still need to finish loading - * by calling `Bundle.loadScene` or `director.loadScene`.It will be totally fine to call `Bundle.loadDir` at any - * time even if the preloading is not yet finished + * by calling [[Bundle.loadScene]] or [[Director.loadScene]].It will be totally fine to call [[Bundle.loadScene]] at any + * time even if the preloading is not yet finished. * * @zh - * 通过场景名称预加载分包中的场景资源.调用完后,你仍然需要通过 `Bundle.loadScene` 或 `director.loadScene` 来完成加载。 - * 就算预加载还没完成,你也可以直接调用 `Bundle.loadScene` 或 `director.loadScene`。 - * - * @param sceneName - The name of the scene to preload. - * @param options - Some optional parameters - * @param onProgress - callback, will be called when the load progression change. - * @param onProgress.finish - The number of the items that are already completed - * @param onProgress.total - The total number of the items - * @param onProgress.item The latest request item - * @param onComplete - callback, will be called after scene loaded. - * @param onComplete.error - null or the error object. + * 通过场景名称预加载分包中的场景资源.调用完后,你仍然需要通过 [[Bundle.loadScene]] 或 [[Director.loadScene]] 来完成加载。 + * 就算预加载还没完成,你也可以直接调用 [[Bundle.loadScene]] 或 [[Director.loadScene]]。 + * + * @param sceneName @en The name of the scene to be preloaded. @zh 待预加载的场景名称。 + * @param options @en Some optional parameters. @zh 可选参数。 + * @param onProgress + * @en Callback invoked when the preloading progress change. + * @zh 预加载进度发生变化时执行的回调。 + * @param onProgress.finish + * @en The number of request items that have been preloaded. + * @zh 已经完成预加载的资源数量。 + * @param onProgress.total + * @en The number of all request items to be preloaded. + * @zh 所有待预加载的资源数量。 + * @param onProgress.item @en The finished request item. @zh 当前完成的预加载项。 + * @param onComplete @en Callback invoked when the scene preloaded. @zh 场景预加载完成后的回调。 + * @param onComplete.error @en Error message during preloading, or null if preloaded successfully. @zh 预加载过程中的错误信息,如果预加载成功则为 null。 * * @example * bundle1.preloadScene('first'); @@ -467,20 +509,20 @@ export default class Bundle { * bundle1.loadScene('first', (err, scene) => director.runScene(scene)); * */ - public preloadScene (sceneName: string, options: IAssetOptions | null, onProgress: ProgressCallback, onComplete: CompleteCallbackNoData | null): void; - public preloadScene (sceneName: string, onProgress: ProgressCallback | null, onComplete: CompleteCallbackNoData | null): void; - public preloadScene (sceneName: string, options: IAssetOptions | null, onComplete?: CompleteCallbackNoData | null): void; - public preloadScene (sceneName: string, onComplete?: CompleteCallbackNoData | null): void; + public preloadScene (sceneName: string, options: { [key: string]: any, preset?: 'string' } | null, onProgress: ((finished: number, total: number, item: RequestItem) => void), onComplete: ((err?: Error | null) => void) | null): void; + public preloadScene (sceneName: string, onProgress: ((finished: number, total: number, item: RequestItem) => void) | null, onComplete: ((err?: Error | null) => void) | null): void; + public preloadScene (sceneName: string, options: { [key: string]: any, preset?: 'string' } | null, onComplete?: ((err?: Error | null) => void) | null): void; + public preloadScene (sceneName: string, onComplete?: ((err?: Error | null) => void) | null): void; public preloadScene ( sceneName: string, - options?: IAssetOptions | ProgressCallback | CompleteCallbackNoData | null, - onProgress?: ProgressCallback | CompleteCallbackNoData | null, - onComplete?: CompleteCallbackNoData | null, + options?: { [key: string]: any, preset?: 'string' } | ((finished: number, total: number, item: RequestItem) => void) | ((err?: Error | null) => void) | null, + onProgress?: ((finished: number, total: number, item: RequestItem) => void) | ((err?: Error | null) => void) | null, + onComplete?: ((err?: Error | null) => void) | null, ) { - const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters(options, onProgress, onComplete); + const { options: opts, onProgress: onProg, onComplete: onComp } = parseParameters<((err?: Error | null) => void)>(options, onProgress, onComplete); opts.bundle = this.name; - legacyCC.assetManager.preloadAny({ scene: sceneName }, opts, onProg, (err) => { + cclegacy.assetManager.preloadAny({ scene: sceneName }, opts, onProg, (err) => { if (err) { errorID(1210, sceneName, err.message); } @@ -490,27 +532,28 @@ export default class Bundle { /** * @en - * Get cached asset within this bundle by path and type.
+ * Gets cached asset within this bundle by path and type.
* After you load asset with [[load]] or [[loadDir]], * you can acquire them by passing the path to this API. * - * NOTE:The `path` and `type` parameters passed need to be the same as those passed to `Bundle.load`, - * otherwise it may return some other resources with the same name! + * NOTE:When there are multiple asset with the same name, you can get the specific asset by specifying the type. + * Otherwise the first asset matching that name will be returned. * * @zh * 通过路径与类型获取已缓存资源。在你使用 [[load]] 或者 [[loadDir]] 之后, * 你能通过传路径通过这个 API 获取到这些资源。 * - * 注意:传入的 path 与 type 参数需要与 `Bundle.load` 加载资源时传入的参数一致,否则可能会获取到其他同名资源 + * 注意:当有多个同名的资产时,你可以通过指定类型来获得具体的资产。 + * 否则将返回与该名称相匹配的第一个资产。 * - * @param path - The path of asset - * @param type - Only asset of type will be returned if this argument is supplied. - * @returns - the asset has been cached + * @param path @en The path of asset. @zh 资源的路径。 + * @param type @en The asset type. Only specify type asset will be returned if this argument is supplied. @zh 资源类型,指定后只会返回该类型的资源。 + * @returns @en The asset has been cached. @zh 已缓存的资源。 * * @example * bundle1.get('music/hit', AudioClip); */ - public get (path: string, type?: AssetType | null): T | null { + public get (path: string, type?: Constructor | null): T | null { const info = this.getInfoWithPath(path, type); if (info) { return assets.get(info.uuid) as T || null; @@ -521,27 +564,28 @@ export default class Bundle { /** * @en - * Release the asset loaded by [[load]] or [[loadDir]] - * and it's dependencies. Refer to [[AssetManager.releaseAsset]] for detailed informations. + * Releases the asset loaded by [[load]] or [[loadDir]]. + * and it's dependencies. Refer to [[AssetManager.releaseAsset]] for detailed information. * - * NOTE:The `path` and `type` parameters passed need to be the same as those passed to `Bundle.load`, - * otherwise it may release some other resources with the same name! + * NOTE:When there are multiple asset with the same name, you can specify the asset to be released by specifying the type. + * Otherwise the first resource matching that name will be released. * * @zh * 释放通过 [[load]] 或者 [[loadDir]] 加载的资源。 - * 详细信息请参考 [[AssetManager.releaseAsset]] + * 详细信息请参考 [[AssetManager.releaseAsset]]。 * - * 注意:传入的 path 与 type 参数需要与 `Bundle.load` 加载资源时传入的参数一致,否则可能会释放到其他同名资源 + * 注意:当存在多个资源同名时,可以通过指定类型来指定要释放的资源,否则将释放第一个匹配该名称的资源。 + * - * @param path - The path of asset - * @param type - Only asset of type will be released if this argument is supplied. + * @param path @en The path of asset. @zh 资源的路径。 + * @param type @en The type of asset. @zh 资源的类型。 * * @example * // release a texture which is no longer need * bundle1.release('misc/character/cocos'); * */ - public release (path: string, type?: AssetType | null) { + public release (path: string, type?: Constructor | null) { const asset = this.get(path, type); if (asset) { releaseManager.tryRelease(asset, true); @@ -550,17 +594,16 @@ export default class Bundle { /** * @en - * Release all unused assets within this bundle. Refer to [[AssetManager.releaseAll]] for detailed informations. + * Release all unused assets within this bundle. Refer to [[AssetManager.releaseAll]] for detailed information. * * @zh - * 释放此包中的所有没有用到的资源。详细信息请参考 [[AssetManager.releaseAll]] - * - * @private + * 释放此包中的所有没有用到的资源。详细信息请参考 [[AssetManager.releaseAll]]。 * * @example * // release all unused asset within bundle1 * bundle1.releaseUnusedAssets(); * + * @engineInternal */ public releaseUnusedAssets () { assets.forEach((asset) => { @@ -576,7 +619,7 @@ export default class Bundle { * Release all assets within this bundle. Refer to [[AssetManager.releaseAll]] for detailed information. * * @zh - * 释放此包中的所有资源。详细信息请参考 [[AssetManager.releaseAll]] + * 释放此包中的所有资源。详细信息请参考 [[AssetManager.releaseAll]]。 * * @example * // release all asset within bundle1 @@ -601,10 +644,10 @@ export default class Bundle { /** * @en - * resources is a bundle and controls all asset under assets/resources + * A [[Bundle]] instance to manage all assets in assets/resources. * * @zh - * resources 是一个 bundle,用于管理所有在 assets/resources 下的资源 + * 一个 [[Bundle]] 实例,用于管理所有在 assets/resources 下的资源。 */ export const resources: Bundle = new Bundle(); -legacyCC.resources = resources; +cclegacy.resources = resources; diff --git a/cocos/asset/asset-manager/cache-manager.ts b/cocos/asset/asset-manager/cache-manager.ts index 446eb42e109..21e9ef7d937 100644 --- a/cocos/asset/asset-manager/cache-manager.ts +++ b/cocos/asset/asset-manager/cache-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,130 +20,131 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import Cache from './cache'; /** * @en * Cache manager is a module which controls all caches downloaded from server in non-web platform, it is a singleton - * All member can be accessed with `assetManager.cacheManager`. + * You can access it via [[AssetManager.cacheManager]]. * * @zh - * 缓存管理器是一个模块,在非 WEB 平台上,用于管理所有从服务器上下载下来的缓存,这是一个单例,所有成员能通过 `assetManager.cacheManager` 访问。 + * 缓存管理器是一个模块,在非 WEB 平台上,用于管理所有从服务器上下载下来的缓存,这是一个单例,你能通过 [[AssetManager.cacheManager]] 访问它。 * */ export default abstract class CacheManager { /** * @en - * The name of cacheDir + * The name of cache directory. * * @zh - * 缓存目录的名称 + * 缓存目录的名称。 */ public abstract cacheDir: string; /** * @en - * Whether or not cache asset into user's storage space, this property only works on mini-game platforms + * Whether to cache file into user's storage space, this property only works on mini-game platforms. * * @zh - * 是否缓存资源到用户存储空间,此属性只在小游戏平台有效 + * 是否缓存文件到用户存储空间,此属性只在小游戏平台有效。 * */ public abstract cacheEnabled: boolean; /** * @en - * Whether or not auto clear cache when storage ran out, this property only works on mini-game platforms + * Whether to clear cache automatically when storage ran out, this property only works on mini-game platforms. * * @zh - * 是否在存储空间满了后自动清理缓存,此属性只在小游戏平台有效 + * 是否在存储空间满了后自动清理缓存,此属性只在小游戏平台有效。 * */ public abstract autoClear: boolean; /** * @en - * The interval between caching resources, this property only works on mini-game platforms, unit: ms + * The interval between caching file, this property only works on mini-game platforms, unit: ms. * * @zh - * 缓存资源的间隔时间,此属性只在小游戏平台有效,单位:毫秒 + * 缓存文件的间隔时间,此属性只在小游戏平台有效,单位:毫秒。 * */ public abstract cacheInterval: number; /** * @en - * The interval between deleting resources, when you use `cleanLRU`, the resources will be deleted as this interval, unit: ms + * The interval between deleting file, when you use `cleanLRU`, the file will be deleted as this interval, unit: ms. * * @zh - * 清理资源的间隔时间,当你使用 `cleanLRU` 时,资源将以此间隔被删除,单位:毫秒 + * 清理资源的间隔时间,当你使用 `cleanLRU` 时,资源将以此间隔被删除,单位:毫秒。 * */ public abstract deleteInterval: number; /** * @en - * List of all cached files + * List of all cached files. * * @zh - * 所有缓存文件列表 + * 所有缓存文件列表。 * */ public abstract cachedFiles: Cache<{ bundle: string, url: string, lastTime: number }>; /** * @en - * Get cached path with origin url + * Gets cached path with origin url. * * @zh - * 通过原始 url 获取缓存后的路径 + * 通过原始 url 获取缓存后的路径。 * - * @param originUrl - * @returns The cached path + * @param originUrl @en The origin url of file. @zh 文件的原始 url。 + * @returns @en The path where the file is cached. @zh 该文件所缓存的路径。 */ public abstract getCache (originUrl: string): string; /** * @en - * Get temporary path with origin url, this method only works on mini-game platforms + * Gets temporary path with origin url, this method only works on mini-game platforms. * * @zh - * 通过原始 url 获取临时文件的路径,此方法只在小游戏平台有效 + * 通过原始 url 获取临时文件的路径,此方法只在小游戏平台有效。 * - * @param originUrl - * @returns The temp path + * @param originUrl @en The origin url of file. @zh 文件的原始 url。 + * @returns @en The temporary path where the file is stored. @zh 该文件所存储的临时路径。 */ public abstract getTemp (originUrl: string): string; /** * @en - * Clear all caches, please use with caution, If necessary, we recommend using it before the game is launched + * Clear all caches, please use with caution, If necessary, we recommend using it before the game is launched. * * @zh - * 清空所有缓存,请谨慎使用,如果必要的话,我们建议在游戏启动之前使用 + * 清空所有缓存,请谨慎使用,如果必要的话,我们建议在游戏启动之前使用。 * */ public abstract clearCache (): void; /** * @en - * Clear part of caches with LRU strategy + * Clear part of caches with LRU strategy. * * @zh - * 使用 LRU 策略清空部分缓存 + * 使用 LRU 策略清空部分缓存。 * */ public abstract clearLRU (): void; /** * @en - * Remove cache with origin url + * Removes cache with origin url. * * @zh - * 通过原始 url 移除缓存 + * 通过原始 url 移除缓存。 * + * @param originUrl @en The origin url to remove from cache. @zh 要从缓存中移除的原始 url。 */ public abstract removeCache (originUrl: string): void; } diff --git a/cocos/asset/asset-manager/cache.ts b/cocos/asset/asset-manager/cache.ts index cbde3ec9f28..87b3f8d9901 100644 --- a/cocos/asset/asset-manager/cache.ts +++ b/cocos/asset/asset-manager/cache.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,28 +20,119 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { js } from '../../core/utils/js'; +import { js } from '../../core'; +/** + * @zh 缓存结构的接口定义,可以用于保存数据。 + * @en Interface definition of a cache structure that can be used to save data. + */ export interface ICache { + /** + * @en + * Adds a Key-Value pair to cache. + * + * @zh + * 增加键值对到缓存中。 + * + * @param key @en The key. @zh 要增加的键值对中的键。 + * @param val @en The value. @zh 要增加的键值对中的值。 + * @returns @en The value. @zh 新增的键值对中的值。 + */ add (key: string, val: T): T; + /** + * @en + * Gets the cached content by key. + * + * @zh + * 通过 key 获取对应的 value。 + * + * @param key @en The key. @zh 要查询的键。 + * @returns @en The corresponding content. @zh 对应键值对中的值。 + */ get (key: string): T | undefined | null; + /** + * @en + * Checks whether or not content exists by key. + * + * @zh + * 通过 Key 判断是否存在对应的内容。 + * + * @param key @en The key. @zh 要查询的键。 + * @returns @en True indicates that content of the key exists. @zh 返回 True 则表明该值存在。 + */ has (key: string): boolean; + /** + * @en + * Removes the cached content by key. + * + * @zh + * 通过 Key 移除对应的内容。 + * + * @param key @en The key. @zh 要移除的键值对中的键。 + * @returns @en The removed content. @zh 移出的键值对中的值。 + */ remove (key: string): T | undefined | null; + + /** + * @en + * Clear all contents. + * + * @zh + * 清除所有内容。 + */ clear (): void; + + /** + * + * @en + * Enumerates all contents and invokes function. + * + * @zh + * 枚举所有内容并执行方法。 + * + * @param func @en Function to be invoked. @zh 待执行的方法。 + * @param func.val @en The value. @zh 传入的键值对中的值。 + * @param func.key @en The corresponding key. @zh 传入的键值对中的键。 + */ forEach (func: (val: T, key: string) => void): void; + /** + * @en + * Enumerates all content to find one element which can fulfill condition. + * + * @zh + * 枚举所有内容,找到一个可以满足条件的元素。 + * + * @param predicate @en The condition function. @zh 条件方法。 + * @returns @en The first content that meets this condition. @zh 第一个符合该条件的内容。 + */ find (predicate: (val: T, key: string) => boolean): T | null; + /** + * @en + * The count of cached content. + * + * @zh + * 缓存数量。 + */ readonly count: number; + + /** + * @en + * Destroy this cache。 + * + * @zh + * 销毁这个 cache. + */ destroy (): void; } /** * @en - * use to cache something + * A data structure used to cache certain content. * * @zh - * 用于缓存某些内容 + * 用于缓存某些内容的数据结构。 * */ export default class Cache implements ICache { @@ -51,12 +141,12 @@ export default class Cache implements ICache { /** * @en - * Create a cache + * Creates a Cache. * * @zh - * 创建一个 cache + * 创建一个 Cache。 * - * @param map - An object used to initialize + * @param map @en An object used to initialize. @zh 用于初始化此缓存的对象。 * */ constructor (map?: Record) { @@ -71,14 +161,14 @@ export default class Cache implements ICache { /** * @en - * Add Key-Value to cache + * Adds a Key-Value pair to cache. * * @zh - * 增加键值对到缓存中 + * 增加键值对到缓存中。 * - * @param key - The key - * @param val - The value - * @returns The value + * @param key @en The key. @zh 要增加的键值对中的键。 + * @param val @en The value. @zh 要增加的键值对中的值。 + * @returns @en The value. @zh 新增的键值对中的值。 * * @example * var cache = new Cache(); @@ -94,13 +184,13 @@ export default class Cache implements ICache { /** * @en - * Get the cached content by key + * Gets the cached content by key. * * @zh - * 通过 key 获取对应的 value + * 通过 key 获取对应的 value。 * - * @param key - The key - * @returns The corresponding content + * @param key @en The key. @zh 要查询的键。 + * @returns @en The corresponding content. @zh 对应键值对中的值。 * * @example * let cache = new Cache(); @@ -113,13 +203,13 @@ export default class Cache implements ICache { /** * @en - * Check whether or not content exists by key + * Checks whether or not content exists by key. * * @zh - * 通过 Key 判断是否存在对应的内容 + * 通过 Key 判断是否存在对应的内容。 * - * @param key - The key - * @returns True indicates that content of the key exists + * @param key @en The key. @zh 要查询的键。 + * @returns @en True indicates that content of the key exists. @zh 返回 True 则表明该值存在。 * * @example * var cache = new Cache(); @@ -132,13 +222,13 @@ export default class Cache implements ICache { /** * @en - * Remove the cached content by key + * Removes the cached content by key. * * @zh - * 通过 Key 移除对应的内容 + * 通过 Key 移除对应的内容。 * - * @param key - The key - * @returns The removed content + * @param key @en The key. @zh 要移除的键值对中的键。 + * @returns @en The removed content. @zh 移出的键值对中的值。 * * @example * var cache = new Cache(); @@ -156,10 +246,10 @@ export default class Cache implements ICache { /** * @en - * Clear all content + * Clear all content. * * @zh - * 清除所有内容 + * 清除所有内容。 * * @example * var cache = new Cache(); @@ -175,14 +265,14 @@ export default class Cache implements ICache { /** * @en - * Enumerate all content and invoke function + * Enumerates all content and invokes function. * * @zh - * 枚举所有内容并执行方法 + * 枚举所有内容并执行方法。 * - * @param func - Function to be invoked - * @param func.val - The value - * @param func.key - The corresponding key + * @param func @en Function to be invoked. @zh 待执行的方法。 + * @param func.val @en The value. @zh 传入的键值对中的值。 + * @param func.key @en The corresponding key. @zh 传入的键值对中的键。 * * @example * var cache = new Cache(); @@ -197,13 +287,13 @@ export default class Cache implements ICache { /** * @en - * Enumerate all content to find one element which can fulfill condition + * Enumerate all content to find one element which can fulfill condition. * * @zh - * 枚举所有内容,找到一个可以满足条件的元素 + * 枚举所有内容,找到一个可以满足条件的元素。 * - * @param predicate - The condition - * @returns content + * @param predicate @en The condition function. @zh 条件方法。 + * @returns @en The first content that meets this condition. @zh 第一个符合该条件的内容。 * * @example * var cache = new Cache(); @@ -221,10 +311,10 @@ export default class Cache implements ICache { /** * @en - * The count of cached content + * The count of cached content. * * @zh - * 缓存数量 + * 缓存数量。 * */ get count (): number { @@ -233,10 +323,10 @@ export default class Cache implements ICache { /** * @en - * Destroy this cache + * Destroy this cache. * * @zh - * 销毁这个 cache + * 销毁这个 cache。 * */ public destroy (): void { diff --git a/cocos/asset/asset-manager/config.ts b/cocos/asset/asset-manager/config.ts index f138d31159b..6f76b0c7028 100644 --- a/cocos/asset/asset-manager/config.ts +++ b/cocos/asset/asset-manager/config.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, TEST } from 'internal:constants'; import { Asset } from '../assets'; -import { legacyCC } from '../../core/global-exports'; -import { js } from '../../core/utils/js'; +import { js, cclegacy } from '../../core'; import Cache from './cache'; import { decodeUuid, normalize } from './helper'; -import { AssetType } from './shared'; export interface IConfigOption { importBase: string; @@ -47,26 +44,97 @@ export interface IConfigOption { extensionMap: Record; } +/** + * @en Th asset's meta information. Used to obtain information about the asset. + * @zh 资源的元信息。用于获取资源的相关信息。 + */ export interface IAssetInfo { + /** + * @en The uuid of asset. + * @zh 资源的 uuid. + */ uuid: string; + /** + * @en Information about the file where the asset is located. A asset can be in multiple merged files. + * @zh 资源所在文件的相关信息。一个资源可在多个合并文件中。 + */ packs?: IPackInfo[]; + /** + * @en The redirect bundle of this asset. When multiple bundles with different priorities reference to the same asset, + * the asset will be stored in the bundle with the higher priority first, while the other bundles will store a record + * and the `redirect` property of that record will point to the bundle that actually stores the resource. + * @zh 资源所重定向的 bundle。当多个 bundle 引用同一份资源,且优先级不一样时,资源会优先存储在优先级高的 bundle 中, + * 其他 bundle 则会存储一条记录,并且该记录的 redirect 属性将指向真实存储此资源的 bundle。 + */ redirect?: string; + /** + * @en The version of the asset. + * @zh 资源的版本号。 + */ ver?: string; + /** + * @en The version of the native dependency of the asset. + * @zh 资源的原生依赖的版本号。 + */ nativeVer?: string; + /** + * @en The extension of the asset, or 'json' if it is null. + * This property is used to mark assets with special extensions like 'CCON'. + * @zh 资源的原生依赖的版本号。 + */ extension?: string; } -export interface IPackInfo extends IAssetInfo { +/** + * @en Information about the merged files. + * @zh 合并文件的信息。 + */ +export interface IPackInfo { + /** + * @en The unique id of this merged file. + * @zh 此合并文件的唯一 id. + */ + uuid: string; + + /** + * @en The uuid of all the assets contained in this file. + * @zh 此文件中包含的所有资源的 uuid。 + */ packedUuids: string[]; + + /** + * @en The extension of this merged file on the file system, default is 'json'. + * @zh 此合并文件在文件系统上的扩展名,默认为 'json'. + */ ext: string; } +/** + * @en Addressable asset information, you can look up the path of the asset in the project and the type of the asset. + * @zh 可寻址资源的信息,你可以查询到该资源在项目中的路径与资源的类型。 + */ export interface IAddressableInfo extends IAssetInfo { + /** + * @en The relative path of this asset in the project relative to the bundle folder. + * @zh 此资源在项目中相对于 bundle 文件夹的相对路径。 + */ path: string; - ctor: AssetType; + /** + * @en The type of the asset. + * @zh 此资源的类型。 + */ + ctor: Constructor; } +/** + * @en Information about the scene asset. + * @zh 场景资源的相关信息。 + */ export interface ISceneInfo extends IAssetInfo { + /** + * @en The path of the scene asset in the project relative to the bundle folder. + * @zh 场景资源在项目中相对 bundle 文件夹的路径。 + */ url: string; } @@ -201,7 +269,7 @@ export default class Config { } } - public getInfoWithPath (path: string, type?: AssetType | null): IAddressableInfo | null { + public getInfoWithPath (path: string, type?: Constructor | null): IAddressableInfo | null { if (!path) { return null; } @@ -222,7 +290,7 @@ export default class Config { return null; } - public getDirWithPath (path: string, type?: AssetType | null, out?: IAddressableInfo[]): IAddressableInfo[] { + public getDirWithPath (path: string, type?: Constructor | null, out?: IAddressableInfo[]): IAddressableInfo[] { path = normalize(path); if (path[path.length - 1] === '/') { path = path.slice(0, -1); @@ -372,5 +440,5 @@ export default class Config { } if (TEST) { - legacyCC._Test.Config = Config; + cclegacy._Test.Config = Config; } diff --git a/cocos/asset/asset-manager/depend-maps.ts b/cocos/asset/asset-manager/depend-maps.ts index 04d981e801f..796cee74b71 100644 --- a/cocos/asset/asset-manager/depend-maps.ts +++ b/cocos/asset/asset-manager/depend-maps.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import type { Asset } from '../assets/asset'; import type { IDependProp } from './deserialize'; diff --git a/cocos/asset/asset-manager/depend-util.ts b/cocos/asset/asset-manager/depend-util.ts index cc6824e67b3..63aa625634c 100644 --- a/cocos/asset/asset-manager/depend-util.ts +++ b/cocos/asset/asset-manager/depend-util.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BUILD, EDITOR } from 'internal:constants'; import { Asset } from '../assets'; -import { hasNativeDep, isCompiledJson, parseUuidDependencies } from '../../core/data/deserialize'; +import { hasNativeDep, isCompiledJson, parseUuidDependencies } from '../../serialization/deserialize'; import Cache from './cache'; import deserialize from './deserialize'; import { decodeUuid } from './helper'; import { files, parsed } from './shared'; import { dependMap, nativeDependMap } from './depend-maps'; -import { assertIsNonNullable } from '../../core/data/utils/asserts'; -import { CCON } from '../../core/data/ccon'; +import { assertIsNonNullable } from '../../core'; +import { CCON } from '../../serialization/ccon'; export interface IDependencies { nativeDep?: Record; @@ -43,10 +42,10 @@ export interface IDependencies { /** * @en - * Control asset's dependency list, it is a singleton. All member can be accessed with `assetManager.dependUtil` + * Manages asset's dependency list, it is a singleton. You can access it via [[AssetManager.dependUtil]]. * * @zh - * 控制资源的依赖列表,这是一个单例, 所有成员能通过 `assetManager.dependUtil` 访问 + * 管理资源的依赖列表,这是一个单例, 你能通过 [[AssetManager.dependUtil]] 访问它。 * */ export class DependUtil { @@ -54,23 +53,43 @@ export class DependUtil { * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _depends: Cache = new Cache(); + private static _instance: DependUtil; + /** + * @en Global singleton for [[DependUtil]]. You can access it via [[AssetManager.dependUtil]]. + * @zh [[DependUtil]] 的全局单例. 你可以通过 [[AssetManager.dependUtil]] 访问. + */ + static get instance () { + if (!this._instance) { + this._instance = new DependUtil(); + } + return this._instance; + } + private constructor () {} + + /** + * @engineInternal + */ public init (): void { this._depends.clear(); } /** * @en - * Get asset's native dependency. For example, Texture's native dependency is image. + * Gets asset's native dependency. For example, ImageAsset's native dependency is image. + * Note: You will need to have loaded this resource to query this information. * * @zh - * 获取资源的原生依赖,例如 Texture 的原生依赖是图片 + * 获取资源的原生依赖,例如 ImageAsset 的原生依赖是图片。 + * 注意:你需要加载过该资源,才能查询此信息。 * - * @param uuid - asset's uuid - * @returns native dependency + * @param uuid @en asset's uuid. @zh 资源的 uuid。 + * @returns @en The native dependency information of this asset. @zh 资源的原生依赖的信息。 * * @example * var dep = dependUtil.getNativeDep('fcmR3XADNLgJ1ByKhqcC5Z'); + * @deprecated Since v3.7, this is an engine internal interface. + * If you want to know the native dependency of the asset, use [[Asset.nativeUrl]] instead. */ public getNativeDep (uuid: string): Record | null { const depend = this._depends.get(uuid); @@ -82,13 +101,15 @@ export class DependUtil { /** * @en - * Get asset's direct referencing non-native dependency list. For example, Material's non-native dependencies are Texture. + * Gets asset's direct referencing dependency list. For example, Material's dependencies are Texture, effect asset etc. + * Note: You will need to have loaded this resource to query this information. * * @zh - * 获取资源直接引用的非原生依赖列表,例如,材质的非原生依赖是 Texture + * 获取资源直接引用的依赖列表,例如,材质的直接依赖资源是 Texture, Effect 等。 + * 注意:你需要加载过该资源,才能查询此信息。 * - * @param uuid - asset's uuid - * @returns direct referencing non-native dependency list + * @param uuid @en asset's uuid. @zh 资源的 uuid。 + * @returns @en The direct referencing dependency asset list. @zh 直接引用的依赖资源列表。 * * @example * var deps = dependUtil.getDeps('fcmR3XADNLgJ1ByKhqcC5Z'); @@ -103,15 +124,17 @@ export class DependUtil { /** * @en - * Get non-native dependency list of the loaded asset, include indirect reference. - * The returned array stores the dependencies with their uuid, after retrieve dependencies, + * Gets dependency list of the loaded asset, include indirect reference. + * Note: You will need to have loaded this resource to query this information. * * @zh - * 获取某个已经加载好的资源的所有非原生依赖资源列表,包括间接引用的资源,并保存在数组中返回。 - * 返回的数组将仅保存依赖资源的 uuid。 + * 获取某个已经加载好的资源的所有依赖资源列表,包括间接引用的资源,并保存在数组中返回。 + * 注意:你需要加载过该资源,才能查询此信息。 * - * @param uuid - The asset's uuid - * @returns non-native dependency list + * @param uuid @en asset's uuid. @zh 资源的 uuid。 + * @returns + * @en The all dependency list including direct reference and indirect reference. + * @zh 所有依赖列表,包括直接引用的与间接引用的。 * * @example * var deps = dependUtil.getDepsRecursively('fcmR3XADNLgJ1ByKhqcC5Z'); @@ -124,13 +147,16 @@ export class DependUtil { return depends; } + /** + * @engineInternal + */ public remove (uuid: string) { this._depends.remove(uuid); } /** * @en - * Extract dependency list from serialized data or asset and then store in cache. + * Extracts dependency list from serialized data or asset and then store in cache. * * @zh * 从序列化数据或资源中提取出依赖列表,并且存储在缓存中。 @@ -144,6 +170,7 @@ export class DependUtil { * var dependencies = parse('fcmR3XADNLgJ1ByKhqcC5Z', file); * }); * + * @engineInternal */ public parse (uuid: string, json: any): IDependencies { let out: IDependencies | null = null; @@ -222,4 +249,4 @@ export class DependUtil { } } -export default new DependUtil(); +export default DependUtil.instance; diff --git a/cocos/asset/asset-manager/deprecated.ts b/cocos/asset/asset-manager/deprecated.ts index 145b585a885..e05b3e87802 100644 --- a/cocos/asset/asset-manager/deprecated.ts +++ b/cocos/asset/asset-manager/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BUILD } from 'internal:constants'; import { Asset } from '../assets/asset'; -import { director } from '../../game/director'; -import { game } from '../../game'; -import { legacyCC } from '../../core/global-exports'; -import { getError } from '../../core/platform/debug'; -import { macro } from '../../core/platform/macro'; -import { path, removeProperty, replaceProperty } from '../../core/utils'; +import { getError, macro, path, removeProperty, replaceProperty, cclegacy } from '../../core'; import Cache from './cache'; import assetManager, { AssetManager } from './asset-manager'; import { resources } from './bundle'; @@ -39,10 +33,10 @@ import downloader from './downloader'; import { getUuidFromURL, transform } from './helper'; import parser from './parser'; import releaseManager from './release-manager'; -import { assets, BuiltinBundleName, bundles, ProgressCallback, CompleteCallback } from './shared'; +import { assets, BuiltinBundleName, bundles } from './shared'; import { parseLoadResArgs, setDefaultProgressCallback } from './utilities'; -import { ISceneInfo } from './config'; import factory from './factory'; +import RequestItem from './request-item'; const ImageFmts = ['.png', '.jpg', '.bmp', '.jpeg', '.gif', '.ico', '.tiff', '.webp', '.image', '.pvr', '.pkm', '.astc']; const AudioFmts = ['.mp3', '.ogg', '.wav', '.m4a']; @@ -99,7 +93,7 @@ export class CCLoader { * * @deprecated since v3.0, loader.onProgress is deprecated, please transfer onProgress to API as a parameter */ - public set onProgress (val: ProgressCallback) { + public set onProgress (val: ((finished: number, total: number, item: RequestItem) => void)) { setDefaultProgressCallback(val); } @@ -588,7 +582,7 @@ export class CCLoader { * @param extMap Handlers for corresponding type in a map * @deprecated since v3.0 loader.addDownloadHandlers is deprecated, please use assetManager.downloader.register instead */ - public addDownloadHandlers (extMap: Record void>) { + public addDownloadHandlers (extMap: Record void)) => void>) { const handler = Object.create(null); for (const type in extMap) { const func = extMap[type]; @@ -612,7 +606,7 @@ export class CCLoader { * @param extMap Handlers for corresponding type in a map * @deprecated since v3.0 loader.addLoadHandlers is deprecated, please use assetManager.parser.register instead */ - public addLoadHandlers (extMap: Record void>) { + public addLoadHandlers (extMap: Record void)) => void>) { const handler = Object.create(null); for (const type in extMap) { const func = extMap[type]; @@ -886,7 +880,7 @@ export const AssetLibrary = { * @param {Asset} options.existingAsset - 加载现有资源,此参数仅在编辑器中可用。 * @deprecated since v3.0 AssetLibrary.loadAsset is deprecated, please use assetManager.loadAny instead */ - loadAsset (uuid: string, callback: CompleteCallback, options?) { + loadAsset (uuid: string, callback: ((err: Error | null, data?: any | null) => void), options?) { assetManager.loadAny(uuid, callback); }, }; @@ -951,7 +945,7 @@ removeProperty(loader, 'loader', [ }, ]); -replaceProperty(legacyCC, 'cc', [ +replaceProperty(cclegacy, 'cc', [ { name: 'loader', newName: 'assetManager', @@ -977,7 +971,7 @@ replaceProperty(legacyCC, 'cc', [ }, ]); -removeProperty(legacyCC, 'cc', [{ +removeProperty(cclegacy, 'cc', [{ name: 'LoadingItems', suggest: getError(1400, 'LoadingItems', 'AssetManager.Task'), }]); @@ -991,37 +985,6 @@ replaceProperty(macro, 'macro', [ }, ]); -replaceProperty(director, 'director', [ - { - name: '_getSceneUuid', - targetName: 'assetManager.main', - newName: 'getSceneInfo', - customFunction: (sceneName) => { - if (assetManager.main) { - return assetManager.main.getSceneInfo(sceneName)?.uuid; - } - return ''; - }, - }, -]); - -replaceProperty(game, 'game', [ - { - name: '_sceneInfos', - targetName: 'assetManager.main', - newName: 'getSceneInfo', - customGetter: () => { - const scenes: ISceneInfo[] = []; - if (assetManager.main) { - assetManager.main.config.scenes.forEach((val) => { - scenes.push(val); - }); - } - return scenes; - }, - }, -]); - const _autoRelease = releaseManager._autoRelease; releaseManager._autoRelease = function (oldScene, newScene, persistNodes) { _autoRelease.call(releaseManager, oldScene, newScene, persistNodes); diff --git a/cocos/asset/asset-manager/deserialize.ts b/cocos/asset/asset-manager/deserialize.ts index c67a08cd452..f17a748b8de 100644 --- a/cocos/asset/asset-manager/deserialize.ts +++ b/cocos/asset/asset-manager/deserialize.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { Asset } from '../assets/asset'; import { MissingScript } from '../../misc/missing-script'; -import { deserialize, Details } from '../../core/data/deserialize'; -import { error } from '../../core/platform/debug'; -import { js } from '../../core/utils/js'; +import { deserialize, Details } from '../../serialization/deserialize'; +import { error, js } from '../../core'; import { dependMap, nativeDependMap } from './depend-maps'; import { decodeUuid } from './helper'; diff --git a/cocos/asset/asset-manager/download-dom-image.ts b/cocos/asset/asset-manager/download-dom-image.ts index 33f721cdd60..d8025f159cb 100644 --- a/cocos/asset/asset-manager/download-dom-image.ts +++ b/cocos/asset/asset-manager/download-dom-image.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,19 +21,21 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { getError } from '../../core/platform/debug'; -import { CompleteCallback, IDownloadParseOptions } from './shared'; +import { XIAOMI } from 'internal:constants'; +import { getError } from '../../core'; +import { ccwindow } from '../../core/global-exports'; export default function downloadDomImage ( url: string, - options: IDownloadParseOptions, - onComplete: CompleteCallback, + options: Record, + onComplete: ((err: Error | null, data?: HTMLImageElement | null) => void), ): HTMLImageElement { - const img = new Image(); + const img = new ccwindow.Image(); - if (window.location.protocol !== 'file:') { + // NOTE: on xiaomi platform, we need to force setting img.crossOrigin as 'anonymous' + if (ccwindow.location.protocol !== 'file:' || XIAOMI) { img.crossOrigin = 'anonymous'; } diff --git a/cocos/asset/asset-manager/download-file.ts b/cocos/asset/asset-manager/download-file.ts index 1b3eb54b6cf..a03fbcc9784 100644 --- a/cocos/asset/asset-manager/download-file.ts +++ b/cocos/asset/asset-manager/download-file.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -import { CompleteCallback, IXHROptions } from './shared'; +*/ type FileProgressCallback = (loaded: number, total: number) => void; export default function downloadFile ( url: string, - options: IXHROptions, + options: Record, onProgress: FileProgressCallback | null | undefined, - onComplete: CompleteCallback, + onComplete: ((err: Error | null, data?: any | null) => void), ): XMLHttpRequest { const xhr = new XMLHttpRequest(); const errInfo = `download failed: ${url}, status: `; diff --git a/cocos/asset/asset-manager/download-script.ts b/cocos/asset/asset-manager/download-script.ts index 66adb1821b9..728f723c62c 100644 --- a/cocos/asset/asset-manager/download-script.ts +++ b/cocos/asset/asset-manager/download-script.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { getError } from '../../core/platform/debug'; -import { CompleteCallback, IBundleOptions } from './shared'; +import { getError } from '../../core'; +import { ccwindow } from '../../core/global-exports'; + +const ccdocument = ccwindow.document; const downloaded = {}; export default function downloadScript ( url: string, - options: IBundleOptions, - onComplete: CompleteCallback, + options: Record, + onComplete: ((err: Error | null, data?: any | null) => void), ): HTMLScriptElement | null { // no need to load script again if (downloaded[url]) { @@ -39,9 +40,9 @@ export default function downloadScript ( return null; } - const script = document.createElement('script'); + const script = ccdocument.createElement('script'); - if (window.location.protocol !== 'file:') { + if (ccwindow.location.protocol !== 'file:') { script.crossOrigin = 'anonymous'; } @@ -64,6 +65,6 @@ export default function downloadScript ( script.addEventListener('load', loadHandler, false); script.addEventListener('error', errorHandler, false); - document.body.appendChild(script); + ccdocument.body.appendChild(script); return script; } diff --git a/cocos/asset/asset-manager/downloader.ts b/cocos/asset/asset-manager/downloader.ts index c894f4cee10..a8f69c594f8 100644 --- a/cocos/asset/asset-manager/downloader.ts +++ b/cocos/asset/asset-manager/downloader.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,58 +20,54 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BUILD, EDITOR } from 'internal:constants'; -import { sys } from '../../core/platform/sys'; -import { js } from '../../core/utils/js'; -import { callInNextTick } from '../../core/utils/misc'; -import { basename, mainFileName } from '../../core/utils/path'; +import { sys, js, misc, path, cclegacy } from '../../core'; import Cache from './cache'; import downloadDomImage from './download-dom-image'; import downloadFile from './download-file'; import downloadScript from './download-script'; -import { CompleteCallback, CompleteCallbackNoData, IBundleOptions, IDownloadParseOptions, files } from './shared'; +import { files } from './shared'; import { retry, RetryFunction, urlAppendTimestamp } from './utilities'; -import { legacyCC } from '../../core/global-exports'; import { IConfigOption } from './config'; -import { CCON, parseCCONJson, decodeCCONBinary } from '../../core/data/ccon'; +import { CCON, parseCCONJson, decodeCCONBinary } from '../../serialization/ccon'; -export type DownloadHandler = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => void; +export type DownloadHandler = (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void; interface IDownloadRequest { id: string; priority: number; url: string; - options: IDownloadParseOptions; - done: CompleteCallback; + options: Record; + done: ((err: Error | null, data?: any | null) => void); handler: DownloadHandler; } const REGEX = /^(?:\w+:\/\/|\.+\/).+/; -const downloadImage = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => { +const downloadImage = (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => { // if createImageBitmap is valid, we can transform blob to ImageBitmap. Otherwise, just use HTMLImageElement to load - const func = sys.hasFeature(sys.Feature.IMAGE_BITMAP) && legacyCC.assetManager.allowImageBitmap ? downloadBlob : downloadDomImage; + const func = sys.hasFeature(sys.Feature.IMAGE_BITMAP) && cclegacy.assetManager.allowImageBitmap ? downloadBlob : downloadDomImage; func(url, options, onComplete); }; -const downloadBlob = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => { +const downloadBlob = (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => { options.xhrResponseType = 'blob'; downloadFile(url, options, options.onFileProgress, onComplete); }; -const downloadJson = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback>) => { +const downloadJson = (url: string, options: Record, onComplete: ((err: Error | null, data?: Record | null) => void)) => { options.xhrResponseType = 'json'; downloadFile(url, options, options.onFileProgress, onComplete); }; -const downloadArrayBuffer = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => { +const downloadArrayBuffer = (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => { options.xhrResponseType = 'arraybuffer'; downloadFile(url, options, options.onFileProgress, onComplete); }; -const downloadCCON = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => { +const downloadCCON = (url: string, options: Record, onComplete: ((err: Error | null, data?: CCON | null) => void)) => { downloadJson(url, options, (err, json) => { if (err) { onComplete(err); @@ -80,7 +75,7 @@ const downloadCCON = (url: string, options: IDownloadParseOptions, onComplete: C } const cconPreface = parseCCONJson(json); const chunkPromises = Promise.all(cconPreface.chunks.map((chunk) => new Promise((resolve, reject) => { - downloadArrayBuffer(`${mainFileName(url)}${chunk}`, {}, (errChunk, chunkBuffer) => { + downloadArrayBuffer(`${path.mainFileName(url)}${chunk}`, {}, (errChunk, chunkBuffer) => { if (err) { reject(err); } else { @@ -97,7 +92,7 @@ const downloadCCON = (url: string, options: IDownloadParseOptions, onComplete: C }); }; -const downloadCCONB = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => { +const downloadCCONB = (url: string, options: Record, onComplete: ((err: Error | null, data?: CCON | null) => void)) => { downloadArrayBuffer(url, options, (err, arrayBuffer: ArrayBuffer) => { if (err) { onComplete(err); @@ -112,13 +107,13 @@ const downloadCCONB = (url: string, options: IDownloadParseOptions, onComplete: }); }; -const downloadText = (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) => { +const downloadText = (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => { options.xhrResponseType = 'text'; downloadFile(url, options, options.onFileProgress, onComplete); }; -const downloadBundle = (nameOrUrl: string, options: IBundleOptions, onComplete: CompleteCallback) => { - const bundleName = basename(nameOrUrl); +const downloadBundle = (nameOrUrl: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => { + const bundleName = path.basename(nameOrUrl); let url = nameOrUrl; if (!REGEX.test(url)) { if (downloader.remoteBundles.indexOf(bundleName) !== -1) { @@ -152,49 +147,50 @@ const downloadBundle = (nameOrUrl: string, options: IBundleOptions, onComplete: /** * @en - * Control all download process, it is a singleton. - * All member can be accessed with `assetManager.downloader`, it can download several types of files: - * 1. Text - * 2. Image - * 3. Audio - * 4. Assets - * 5. Scripts + * Manages all download process, it is a singleton. + * You can access it via [[AssetManager.downloader]], It can download various types of files. * * @zh - * 管理所有下载过程,downloader 是个单例,所有成员能通过 `assetManager.downloader` 访问,它能下载以下几种类型的文件: - * 1. 文本 - * 2. 图片 - * 3. 音频 - * 4. 资源 - * 5. 脚本 + * 管理所有下载过程,downloader 是个单例,你能通过 [[AssetManager.downloader]] 访问它,它能下载各种类型的文件。 * */ export class Downloader { + /** + * @en Global singleton for [[Downloader]]. You can access it via [[AssetManager.downloader]]. + * @zh [[Downloader]] 的全局单例. 你可以通过 [[AssetManager.downloader]] 访问. + */ + public static get instance () { + if (!Downloader._instance) { + Downloader._instance = new Downloader(); + } + return Downloader._instance; + } + /** * @en - * The maximum number of concurrent when downloading + * The maximum number of concurrent when downloading. * * @zh - * 下载时的最大并发数 + * 下载时的最大并发数。 */ - public maxConcurrency = 6; + public maxConcurrency = 15; /** * @en - * The maximum number of request can be launched per frame when downloading + * The maximum number of request can be launched per frame when downloading. * * @zh - * 下载时每帧可以启动的最大请求数 + * 下载时每帧可以启动的最大请求数。 * */ - public maxRequestsPerFrame = 6; + public maxRequestsPerFrame = 15; /** * @en - * The address of remote server + * The address of remote server. * * @zh - * 远程服务器地址 + * 远程服务器地址。 * */ public get remoteServerAddress () { @@ -203,40 +199,67 @@ export class Downloader { /** * @en - * The max number of retries when fail + * The max number of retries when fail. * * @zh - * 失败重试次数 + * 失败重试次数。 * - * @property maxRetryCount - * @type {Number} */ public maxRetryCount = BUILD ? 3 : 0; + /** + * Whether to automatically add a timestamp after the url. + * This function is mainly used to prevent the browser from using cache in editor mode. + * You don't need to change it at runtime. + * @internal + */ public appendTimeStamp = !!EDITOR; + /** + * @engineInternal + */ public limited = !EDITOR; /** * @en - * Wait for while before another retry, unit: ms + * Wait for while before another retry, unit: ms. * * @zh - * 重试的间隔时间 + * 重试的间隔时间,单位为毫秒。 * */ public retryInterval = 2000; + /** + * Version information of all bundles. + * @engineInternal + */ public bundleVers: Record | null = null; - public remoteBundles: string[] = []; + /** + * Remote bundle list. + * @engineInternal + */ + public remoteBundles: ReadonlyArray = []; + /** + * @deprecated Since v3.7, this is an engine internal interface. You can easily implement the functionality of this API using HTMLImageElement. + */ public downloadDomImage = downloadDomImage; + /** + * @deprecated Since v3.7, this is an engine internal interface. You can easily implement the functionality of this API using HTMLAudioElement. + */ public downloadDomAudio: DownloadHandler | null = null; + /** + * @deprecated Since v3.7, this is an engine internal interface. You can easily implement the functionality of this API using XMLHttpRequest. + */ public downloadFile = downloadFile; + /** + * @deprecated Since v3.7, this is an engine internal interface. You can easily implement the functionality of this API using XMLHttpRequest. + */ public downloadScript = downloadScript; // default handler map @@ -287,7 +310,7 @@ export class Downloader { default: downloadText, }; - private _downloading = new Cache(); + private _downloading = new Cache<((err: Error | null, data?: any | null) => void)[]>(); private _queue: IDownloadRequest[] = []; private _queueDirty = false; // the number of loading thread @@ -300,7 +323,11 @@ export class Downloader { private _checkNextPeriod = false; private _remoteServerAddress = ''; private _maxInterval = 1 / 30; + private static _instance: Downloader; + /** + * @engineInternal + */ public init (remoteServerAddress = '', bundleVers: Record = {}, remoteBundles: string[] = []) { this._downloading.clear(); this._queue.length = 0; @@ -311,16 +338,21 @@ export class Downloader { /** * @en - * Register custom handler if you want to change default behavior or extend downloader to download other format file + * Register custom handler if you want to change default behavior or extend downloader to download other format file. * * @zh - * 当你想修改默认行为或者拓展 downloader 来下载其他格式文件时可以注册自定义的 handler + * 当你想修改默认行为或者拓展 downloader 来下载其他格式文件时可以注册自定义的 handler。 * - * @param type - Extension likes '.jpg' or map likes {'.jpg': jpgHandler, '.png': pngHandler} - * @param handler - handler - * @param handler.url - url - * @param handler.options - some optional parameters will be transferred to handler. - * @param handler.onComplete - callback when finishing downloading + * @param type + * @en Extension name likes '.jpg' or map likes {'.jpg': jpgHandler, '.png': pngHandler}. + * @zh 扩展名,或者形如 {'.jpg': jpgHandler, '.png': pngHandler} 的映射表。 + * @param handler @en Customized handling for this extension. @zh 针对此扩展名的自定义的处理方法。 + * @param handler.url @en The url to be downloaded. @zh 待下载的 url. + * @param handler.options @en Some optional parameters will be transferred to handler. @zh 传递到处理方法的可选参数。 + * @param handler.onComplete + * @en Callback when finishing downloading. You need to call this method manually and pass in the execution result after the custom handler + * is executed. + * @zh 完成下载后的回调。你需要在自定义处理方法执行完后手动调用此方法,并将执行结果传入。 * * @example * downloader.register('.tga', (url, options, onComplete) => onComplete(null, null)); @@ -328,9 +360,12 @@ export class Downloader { * '.ext': (url, options, onComplete) => onComplete(null, null)}); * */ - public register (type: string, handler: DownloadHandler): void; - public register (map: Record): void; - public register (type: string | Record, handler?: DownloadHandler) { + public register (type: string, handler: (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void): void; + public register (map: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void>): void; + public register ( + type: string | Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void>, + handler?: (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void, + ) { if (typeof type === 'object') { js.mixin(this._downloaders, type); } else { @@ -340,29 +375,29 @@ export class Downloader { /** * @en - * Use corresponding handler to download file under limitation + * Use corresponding handler to download file under limitation. * * @zh - * 在限制下使用对应的 handler 来下载文件 + * 在限制下使用对应的 handler 来下载文件。 * - * @param id - The unique id of this download - * @param url - The url should be downloaded - * @param type - The type indicates that which handler should be used to download, such as '.jpg' - * @param options - some optional parameters will be transferred to the corresponding handler. - * @param options.onFileProgress - progressive callback will be transferred to handler. - * @param options.maxRetryCount - How many times should retry when download failed - * @param options.maxConcurrency - The maximum number of concurrent when downloading - * @param options.maxRequestsPerFrame - The maximum number of request can be launched per frame when downloading - * @param options.priority - The priority of this url, default is 0, the greater number is higher priority. - * @param onComplete - callback when finishing downloading - * @param onComplete.err - The occurred error, null indicates success - * @param onComplete.content - The downloaded file + * @param id @en The unique id of this download. @zh 本次下载的唯一 id. + * @param url @en The url should be downloaded. @zh 待下载的 url。 + * @param type @en The type indicates that which handler should be used to download, such as '.jpg'. @zh 要使用的处理方法的类型,例如 '.jpg'。 + * @param options @en Some optional parameters will be transferred to the corresponding handler. @zh 传递到处理方法的一些可选参数。 + * @param options.onFileProgress @en Progressive callback will be transferred to handler. @zh 传递到处理方法的进度回调。 + * @param options.maxRetryCount @en How many times should retry when download failed. @zh 下载失败后的重试数量。 + * @param options.maxConcurrency @en The maximum number of concurrent when downloading. @zh 下载的最大并行数。 + * @param options.maxRequestsPerFrame @en The maximum number of request can be launched per frame when downloading. @zh 每帧能发起的最大请求数量,在下载时。 + * @param options.priority @en The priority of this url, default is 0, the greater number is higher priority. @zh 下载的优先级,值越大优先级越高。 + * @param onComplete @en Callback when finishing downloading. @zh 完成下载后的回调。 + * @param onComplete.err @en The occurred error, null indicates success. @zh 下载过程中出现的错误,如果为 null 则表明下载成功。 + * @param onComplete.content @en The downloaded file. @zh 下载下来的文件内容。 * * @example * download('http://example.com/test.tga', '.tga', { onFileProgress: (loaded, total) => console.log(loaded/total) }, * onComplete: (err) => console.log(err)); */ - public download (id: string, url: string, type: string, options: IDownloadParseOptions, onComplete: CompleteCallback): void { + public download (id: string, url: string, type: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)): void { // if it is downloaded, don't download again const file = files.get(id); if (file) { @@ -402,7 +437,7 @@ export class Downloader { // refresh this._updateTime(); - const done: CompleteCallback = (err, data) => { + const done: ((err: Error | null, data?: any | null) => void) = (err, data) => { // when finish downloading, update _totalNum this._totalNum--; this._handleQueueInNextFrame(maxConcurrency, maxRequestsPerFrame); @@ -425,7 +460,7 @@ export class Downloader { // when retry finished, invoke callbacks const finale = (err, result) => { if (!err) { files.add(id, result); } - const callbacks = this._downloading.remove(id) as CompleteCallback[]; + const callbacks = this._downloading.remove(id) as ((err: Error | null, data?: any | null) => void)[]; for (let i = 0, l = callbacks.length; i < l; i++) { callbacks[i](err, result); } @@ -436,21 +471,23 @@ export class Downloader { /** * @en Load sub package with name. - * @zh 通过子包名加载子包代码。 - * @param name - Sub package name - * @param completeCallback - Callback invoked when sub package loaded - * @param {Error} completeCallback.error - error information + * @zh 通过子包名加载子包。 + * @param name @en Sub package name. @zh 子包名称。 + * @param completeCallback @en Callback invoked when sub package loaded. @zh 子包加载完成后的回调。 + * @param completeCallback.error @en Error information. Will be null if loaded successfully. @zh 错误信息。如果加载成功则为 null。 * - * @deprecated loader.downloader.loadSubpackage is deprecated, please use AssetManager.loadBundle instead + * @deprecated loader.downloader.loadSubpackage is deprecated, please use AssetManager.loadBundle instead. */ - public loadSubpackage (name: string, completeCallback?: CompleteCallbackNoData) { - legacyCC.assetManager.loadBundle(name, null, completeCallback); + public loadSubpackage (name: string, completeCallback?: ((err?: Error | null) => void)) { + cclegacy.assetManager.loadBundle(name, null, completeCallback); } + private constructor () {} + private _updateTime () { const now = performance.now(); // use deltaTime as interval - const deltaTime = legacyCC.game.deltaTime; + const deltaTime = cclegacy.game.deltaTime; const interval = deltaTime > this._maxInterval ? this._maxInterval : deltaTime; if (now - this._lastDate > interval * 1000) { this._totalNumThisPeriod = 0; @@ -481,12 +518,10 @@ export class Downloader { private _handleQueueInNextFrame (maxConcurrency: number, maxRequestsPerFrame: number) { if (!this._checkNextPeriod && this._queue.length > 0) { - callInNextTick(this._handleQueue.bind(this), maxConcurrency, maxRequestsPerFrame); + misc.callInNextTick(this._handleQueue.bind(this), maxConcurrency, maxRequestsPerFrame); this._checkNextPeriod = true; } } } - -const downloader = new Downloader(); - -export default downloader; +const downloader = Downloader.instance; +export default Downloader.instance; diff --git a/cocos/asset/asset-manager/editor-path-replace.ts b/cocos/asset/asset-manager/editor-path-replace.ts index 055935e2312..f1fe2b3cf98 100644 --- a/cocos/asset/asset-manager/editor-path-replace.ts +++ b/cocos/asset/asset-manager/editor-path-replace.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, NATIVE, PREVIEW, TEST } from 'internal:constants'; -import { assert } from '../../core/platform/debug'; -import { Settings, settings } from '../../core/settings'; +import { assert, Settings, settings } from '../../core'; import { fetchPipeline, pipeline } from './shared'; -import Task, { TaskCompleteCallback } from './task'; +import Task from './task'; declare const Editor: any; if ((EDITOR || PREVIEW) && !TEST) { const cache: {[uuid: string]: string | null} = {}; const resolveMap: { [uuid: string]: Function[] } = {}; - const replaceExtension = (task: Task, done: TaskCompleteCallback) => { + const replaceExtension = (task: Task, done) => { task.output = task.input; (async () => { for (let i = 0; i < task.input.length; i++) { diff --git a/cocos/asset/asset-manager/factory.ts b/cocos/asset/asset-manager/factory.ts index a9967fa6f33..5d77950426c 100644 --- a/cocos/asset/asset-manager/factory.ts +++ b/cocos/asset/asset-manager/factory.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { ImageAsset } from '../assets/image-asset'; @@ -29,20 +28,18 @@ import JsonAsset from '../assets/json-asset'; import TextAsset from '../assets/text-asset'; import { Asset } from '../assets/asset'; import { BufferAsset } from '../assets/buffer-asset'; -import { js } from '../../core/utils/js'; import Bundle, { resources } from './bundle'; import Cache from './cache'; import { IConfigOption } from './config'; import { - assets, BuiltinBundleName, bundles, CompleteCallback, IRemoteOptions, - IDownloadParseOptions, + assets, BuiltinBundleName, bundles, } from './shared'; - import { cache } from './utilities'; +import { js } from '../../core'; -export type CreateHandler = (id: string, data: any, options: IDownloadParseOptions, onComplete: CompleteCallback) => void; +export type CreateHandler = (id: string, data: any, options: Record, onComplete: ((err: Error | null, data?: Asset | Bundle | null) => void)) => void; -function createImageAsset (id: string, data: HTMLImageElement, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createImageAsset (id: string, data: HTMLImageElement, options: Record, onComplete: ((err: Error | null, data?: ImageAsset | null) => void)) { let out: ImageAsset | null = null; let err: Error | null = null; try { @@ -55,33 +52,33 @@ function createImageAsset (id: string, data: HTMLImageElement, options: IDownloa onComplete(err, out); } -function createJsonAsset (id: string, data: Record, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createJsonAsset (id: string, data: Record, options: Record, onComplete: ((err: Error | null, data?: JsonAsset | null) => void)) { const out = new JsonAsset(); out.json = data; onComplete(null, out); } -function createTextAsset (id: string, data: string, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createTextAsset (id: string, data: string, options: Record, onComplete: ((err: Error | null, data?: TextAsset | null) => void)) { const out = new TextAsset(); out.text = data; onComplete(null, out); } -function createBufferAsset (id: string, data: ArrayBufferView, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createBufferAsset (id: string, data: ArrayBufferView, options: Record, onComplete: ((err: Error | null, data?: BufferAsset | null) => void)) { const out = new BufferAsset(); out._nativeUrl = id; out._nativeAsset = data; onComplete(null, out); } -function createAsset (id: string, data: any, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createAsset (id: string, data: any, options: Record, onComplete: ((err: Error | null, data?: Asset | null) => void)) { const out = new Asset(); out._nativeUrl = id; out._nativeAsset = data; onComplete(null, out); } -function createBundle (id: string, data: IConfigOption, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createBundle (id: string, data: IConfigOption, options: Record, onComplete: ((err: Error | null, data?: Bundle | null) => void)) { let bundle = bundles.get(data.name); if (!bundle) { bundle = data.name === BuiltinBundleName.RESOURCES ? resources : new Bundle(); @@ -99,7 +96,7 @@ function createBundle (id: string, data: IConfigOption, options: IDownloadParseO } export class Factory { - private _creating = new Cache(); + private _creating = new Cache<((err: Error | null, data?: any | null) => void)[]>(); private _producers: Record = { // Images @@ -149,7 +146,7 @@ export class Factory { } } - public create (id: string, data: any, type: string, options: IRemoteOptions, onComplete: CompleteCallback): void { + public create (id: string, data: any, type: string, options: Record, onComplete: ((err: Error | null, data?: Asset | Bundle | null) => void)): void { const handler = this._producers[type] || this._producers.default; const asset = assets.get(id); if (!options.reloadAsset && asset) { diff --git a/cocos/asset/asset-manager/fetch.ts b/cocos/asset/asset-manager/fetch.ts index f4b1c60b8ed..e325c1947e9 100644 --- a/cocos/asset/asset-manager/fetch.ts +++ b/cocos/asset/asset-manager/fetch.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Asset } from '../assets'; -import { error } from '../../core/platform/debug'; +import { error, cclegacy } from '../../core'; import packManager from './pack-manager'; import RequestItem from './request-item'; -import { assets, CompleteCallbackNoData, fetchPipeline } from './shared'; +import { assets, fetchPipeline } from './shared'; import Task from './task'; import { clear, forEach, getDepends } from './utilities'; -import { legacyCC } from '../../core/global-exports'; -export default function fetch (task: Task, done: CompleteCallbackNoData) { +export default function fetch (task: Task, done: ((err?: Error | null) => void)) { let firstTask = false; if (!task.progress) { task.progress = { finish: 0, total: task.input.length, canInvoke: true }; @@ -60,8 +58,8 @@ export default function fetch (task: Task, done: CompleteCallbackNoData) { packManager.load(item, task.options, (err, data) => { if (err) { - if (!task.isFinish) { - if (!legacyCC.assetManager.force || firstTask) { + if (!task.isFinished) { + if (!cclegacy.assetManager.force || firstTask) { error(err.message, err.stack); progress.canInvoke = false; done(err); @@ -72,7 +70,7 @@ export default function fetch (task: Task, done: CompleteCallbackNoData) { } } } - } else if (!task.isFinish) { + } else if (!task.isFinished) { item.file = data; task.output.push(item); if (!item.isNative) { @@ -87,7 +85,7 @@ export default function fetch (task: Task, done: CompleteCallbackNoData) { cb(); }); }, () => { - if (task.isFinish) { + if (task.isFinished) { clear(task, true); task.dispatch('error'); return; diff --git a/cocos/asset/asset-manager/helper.ts b/cocos/asset/asset-manager/helper.ts index 364f9f650ec..a12991b2c89 100644 --- a/cocos/asset/asset-manager/helper.ts +++ b/cocos/asset/asset-manager/helper.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -import { legacyCC } from '../../core/global-exports'; -import { error } from '../../core/platform/debug'; +*/ +import { cclegacy, error } from '../../core'; import RequestItem from './request-item'; -import { bundles, Request, IOptions, transformPipeline } from './shared'; +import { bundles, transformPipeline } from './shared'; import Task from './task'; const _uuidRegex = /.*[/\\][0-9a-fA-F]{2}[/\\]([0-9a-fA-F-@]{8,}).*/; @@ -34,13 +32,13 @@ export { default as decodeUuid } from '../../core/utils/decode-uuid'; /** * @en - * Extract uuid from url + * Extracts uuid from url. * * @zh - * 从 url 中提取 uuid + * 从 url 中提取 uuid。 * - * @param url - url - * @returns the uuid parsed from url + * @param url @en The url to be converted. @zh 待转换的 url。 + * @returns @en The uuid extracted from url. @zh url 转换为的 uuid。 * * @example * var url = 'res/import/fc/fc991dd7-0033-4b80-9d41-c8a86a702e59.json'; @@ -56,16 +54,16 @@ export function getUuidFromURL (url: string): string { /** * @en - * Transform uuid to url + * Transforms uuid to url. * * @zh - * 转换 uuid 为 url + * 转换 uuid 为 url。 * - * @param uuid - The uuid of asset - * @param options - Some optional parameters - * @param options.isNative - Indicates whether the path you want is a native resource path - * @param options.nativeExt - Extension of the native resource path, it is required when isNative is true - * @returns url + * @param uuid @en The uuid of asset. @zh 资源的 uuid。 + * @param options @en Some optional parameters. @zh 一些可选参数。 + * @param options.isNative @en Indicates whether the path you want is a native resource path. @zh 需要转换的路径是否是原生资源路径。 + * @param options.nativeExt @en Extension of the native resource path, it is required when isNative is true. @zh 原生资源路径的扩展名,如果 `isNative` 为 true,则需要。 + * @returns @en The url converted from uuid. @zh 从 uuid 转换而来的 url. * * @example * // json path, 'assets/main/import/fc/fc991dd7-0033-4b80-9d41-c8a86a702e59.json'; @@ -92,29 +90,28 @@ export function getUrlWithUuid (uuid: string, options?: { [k: string]: any, isNa /** * @en - * Check if the type of asset is scene + * Checks if the type of asset is scene. * * @zh - * 检查资源类型是否是场景 + * 检查资源类型是否是场景。 * - * @method isScene - * @param {*} asset - asset - * @returns {boolean} - whether or not type is SceneAsset + * @param asset @en The asset to be checked. @zh 待检查的资源。 + * @returns @en Whether or not the asset is a SceneAsset. @zh 此资源是否是场景资源。 * */ export function isScene (asset) { - return !!asset && (asset instanceof legacyCC.SceneAsset || asset instanceof legacyCC.Scene); + return !!asset && (asset instanceof cclegacy.SceneAsset || asset instanceof cclegacy.Scene); } /** * @en - * Normalize url, strip './' and '/' + * Normalizes url, strip './' and '/'. * * @zh - * 标准化 url ,去除 './' 和 '/' + * 标准化 url ,去除 './' 和 '/'。 * - * @param url - url - * @returns - The normalized url + * @param url @en The url to be normalized. @zh 待标准化的 url。 + * @returns @en The normalized url. @zh 标准化后的 url。 */ export function normalize (url: string): string { if (url) { @@ -129,7 +126,7 @@ export function normalize (url: string): string { return url; } -export function transform (input: Request, options?: IOptions | null): string | string[] { +export function transform (input: string | string[] | Record | Array>, options?: Record | null): string | string[] { const subTask = Task.create({ input, options }); const urls: string[] = []; try { diff --git a/cocos/asset/asset-manager/index.ts b/cocos/asset/asset-manager/index.ts index 10a41a6393c..16eea9c92ac 100644 --- a/cocos/asset/asset-manager/index.ts +++ b/cocos/asset/asset-manager/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +import './asset-manager'; import './editor-path-replace'; export { default as assetManager, AssetManager } from './asset-manager'; diff --git a/cocos/asset/asset-manager/load.ts b/cocos/asset/asset-manager/load.ts index 2a807fb7fce..898bcfebe26 100644 --- a/cocos/asset/asset-manager/load.ts +++ b/cocos/asset/asset-manager/load.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BUILD, EDITOR, PREVIEW } from 'internal:constants'; import { Asset } from '../assets/asset'; -import { error } from '../../core/platform/debug'; +import { error, cclegacy } from '../../core'; import packManager from './pack-manager'; import parser from './parser'; import { Pipeline } from './pipeline'; import RequestItem from './request-item'; -import { CompleteCallbackNoData, assets, files, parsed, pipeline } from './shared'; +import { assets, files, parsed, pipeline } from './shared'; import Task from './task'; import { cache, checkCircleReference, clear, forEach, gatherAsset, getDepends, setProperties } from './utilities'; -import { legacyCC } from '../../core/global-exports'; import { nativeDependMap, onLoadedInvokedMap } from './depend-maps'; interface IProgress { @@ -45,10 +43,10 @@ interface ILoadingRequest { content: Asset; finish: boolean; err?: Error | null; - callbacks: Array<{ done: CompleteCallbackNoData; item: RequestItem }>; + callbacks: Array<{ done: ((err?: Error | null) => void); item: RequestItem }>; } -export default function load (task: Task, done: CompleteCallbackNoData) { +export default function load (task: Task, done: ((err?: Error | null) => void)) { let firstTask = false; if (!task.progress) { task.progress = { finish: 0, total: task.input.length, canInvoke: true }; @@ -68,8 +66,8 @@ export default function load (task: Task, done: CompleteCallbackNoData) { options, progress, onComplete: (err, result) => { - if (err && !task.isFinish) { - if (!legacyCC.assetManager.force || firstTask) { + if (err && !task.isFinished) { + if (!cclegacy.assetManager.force || firstTask) { if (BUILD) { error(err.message, err.stack); } @@ -89,7 +87,7 @@ export default function load (task: Task, done: CompleteCallbackNoData) { }, () => { options!.__exclude__ = null; - if (task.isFinish) { + if (task.isFinished) { clear(task, true); task.dispatch('error'); return; @@ -175,7 +173,7 @@ const loadOneAssetPipeline = new Pipeline('loadOneAsset', [ }, ]); -function loadDepends (task: Task, asset: Asset, done: CompleteCallbackNoData) { +function loadDepends (task: Task, asset: Asset, done: ((err?: Error | null) => void)) { const { input: item, progress } = task; const { uuid, id, options, config } = item as RequestItem; const { cacheAsset } = options; @@ -227,7 +225,7 @@ function loadDepends (task: Task, asset: Asset, done: CompleteCallbackNoData) { } else { // TODO: remove it. // scene asset might be a json in editor or preview - legacyCC.SceneAsset.prototype.initDefault.call(asset); + cclegacy.SceneAsset.prototype.initDefault.call(asset); } } } diff --git a/cocos/asset/asset-manager/pack-manager.ts b/cocos/asset/asset-manager/pack-manager.ts index ac0ad41016f..cf3676d8d93 100644 --- a/cocos/asset/asset-manager/pack-manager.ts +++ b/cocos/asset/asset-manager/pack-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,23 +20,22 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ImageAsset } from '../assets/image-asset'; import { Texture2D } from '../assets/texture-2d'; -import { packCustomObjData, unpackJSONs } from '../../core/data/deserialize'; -import { error, errorID } from '../../core/platform/debug'; -import { js } from '../../core/utils/js'; +import { packCustomObjData, unpackJSONs } from '../../serialization/deserialize'; +import { error, errorID, js } from '../../core'; import Cache from './cache'; import downloader from './downloader'; import { transform } from './helper'; import RequestItem from './request-item'; -import { CompleteCallback, files, IDownloadParseOptions } from './shared'; +import { files } from './shared'; -export type Unpacker = (packUuid: string[], data: any, options: IDownloadParseOptions, onComplete: CompleteCallback) => void; +export type Unpacker = (packUuid: string[], data: any, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void; interface IUnpackRequest { - onComplete: CompleteCallback; + onComplete: ((err: Error | null, data?: any | null) => void); id: string; } @@ -75,7 +73,7 @@ export class PackManager { * }); * */ - public unpackJson (pack: string[], json: any, options: IDownloadParseOptions, onComplete: CompleteCallback>): void { + public unpackJson (pack: string[], json: any, options: Record, onComplete: ((err: Error | null, data?: Record | null) => void)): void { let out = js.createMap(true); let err: Error | null = null; @@ -172,7 +170,7 @@ export class PackManager { * }); * */ - public unpack (pack: string[], data: any, type: string, options: IDownloadParseOptions, onComplete: CompleteCallback): void { + public unpack (pack: string[], data: any, type: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)): void { if (!data) { onComplete(new Error('package data is wrong!')); return; @@ -202,7 +200,7 @@ export class PackManager { * packManager.load(requestItem, null, (err, data) => console.log(err)); * */ - public load (item: RequestItem, options: IDownloadParseOptions | null, onComplete: CompleteCallback): void { + public load (item: RequestItem, options: Record | null, onComplete: ((err: Error | null, data?: any | null) => void)): void { // if not in any package, download as uausl if (item.isNative || !item.info || !item.info.packs) { downloader.download(item.id, item.url, item.ext, item.options, onComplete); diff --git a/cocos/asset/asset-manager/parser.ts b/cocos/asset/asset-manager/parser.ts index 6715e5949f8..4982f766cb3 100644 --- a/cocos/asset/asset-manager/parser.ts +++ b/cocos/asset/asset-manager/parser.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,122 +20,30 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { IMemoryImageSource } from '../assets/image-asset'; -import { js } from '../../core/utils/js'; +import { ImageAsset, IMemoryImageSource } from '../assets/image-asset'; +import { js } from '../../core'; import Cache from './cache'; import deserialize from './deserialize'; import { isScene } from './helper'; import plistParser from './plist-parser'; -import { CompleteCallback, IDownloadParseOptions, files, parsed } from './shared'; - -import { PixelFormat } from '../assets/asset-enum'; -import { CCON } from '../../core/data/ccon'; +import { files, parsed } from './shared'; +import { CCON } from '../../serialization/ccon'; import { Asset } from '../assets'; -// PVR constants // -// https://github.com/toji/texture-tester/blob/master/js/webgl-texture-util.js#L424 -const PVR_HEADER_LENGTH = 13; // The header length in 32 bit ints. -const PVR_MAGIC = 0x03525650; // 0x50565203; - -// Offsets into the header array. -const PVR_HEADER_MAGIC = 0; -const PVR_HEADER_FORMAT = 2; -const PVR_HEADER_HEIGHT = 6; -const PVR_HEADER_WIDTH = 7; -const PVR_HEADER_MIPMAPCOUNT = 11; -const PVR_HEADER_METADATA = 12; - -// ETC constants // -const ETC_PKM_HEADER_SIZE = 16; - -const ETC_PKM_FORMAT_OFFSET = 6; -const ETC_PKM_ENCODED_WIDTH_OFFSET = 8; -const ETC_PKM_ENCODED_HEIGHT_OFFSET = 10; -const ETC_PKM_WIDTH_OFFSET = 12; -const ETC_PKM_HEIGHT_OFFSET = 14; - -const ETC1_RGB_NO_MIPMAPS = 0; -const ETC2_RGB_NO_MIPMAPS = 1; -const ETC2_RGBA_NO_MIPMAPS = 3; - -//= ==============// -// ASTC constants // -//= ==============// - -// struct astc_header -// { -// uint8_t magic[4]; -// uint8_t blockdim_x; -// uint8_t blockdim_y; -// uint8_t blockdim_z; -// uint8_t xsize[3]; // x-size = xsize[0] + xsize[1] + xsize[2] -// uint8_t ysize[3]; // x-size, y-size and z-size are given in texels; -// uint8_t zsize[3]; // block count is inferred -// }; -const ASTC_MAGIC = 0x5CA1AB13; - -const ASTC_HEADER_LENGTH = 16; // The header length -const ASTC_HEADER_MAGIC = 4; -const ASTC_HEADER_BLOCKDIM = 3; - -const ASTC_HEADER_SIZE_X_BEGIN = 7; -const ASTC_HEADER_SIZE_Y_BEGIN = 10; -const ASTC_HEADER_SIZE_Z_BEGIN = 13; - -function getASTCFormat (xdim, ydim) { - if (xdim === 4) { - return PixelFormat.RGBA_ASTC_4x4; - } if (xdim === 5) { - if (ydim === 4) { - return PixelFormat.RGBA_ASTC_5x4; - } - return PixelFormat.RGBA_ASTC_5x5; - } if (xdim === 6) { - if (ydim === 5) { - return PixelFormat.RGBA_ASTC_6x5; - } - return PixelFormat.RGBA_ASTC_6x6; - } if (xdim === 8) { - if (ydim === 5) { - return PixelFormat.RGBA_ASTC_8x5; - } if (ydim === 6) { - return PixelFormat.RGBA_ASTC_8x6; - } - return PixelFormat.RGBA_ASTC_8x8; - } if (xdim === 10) { - if (ydim === 5) { - return PixelFormat.RGBA_ASTC_10x5; - } if (ydim === 6) { - return PixelFormat.RGBA_ASTC_10x6; - } if (ydim === 8) { - return PixelFormat.RGBA_ASTC_10x8; - } - return PixelFormat.RGBA_ASTC_10x10; - } - if (ydim === 10) { - return PixelFormat.RGBA_ASTC_12x10; - } - return PixelFormat.RGBA_ASTC_12x12; -} - -function readBEUint16 (header, offset: number) { - return (header[offset] << 8) | header[offset + 1]; -} - -export type ParseHandler = (file: any, options: IDownloadParseOptions, onComplete: CompleteCallback) => void; +export type ParseHandler = (file: any, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void; /** * @en - * Parse the downloaded file, it's a singleton, all member can be accessed with `assetManager.parser` + * Parse the downloaded file, it's a singleton, you can access it via [[AssetManager.parser]]. * * @zh - * 解析已下载的文件,parser 是一个单例, 所有成员能通过 `assetManaager.parser` 访问 + * 解析已下载的文件,parser 是一个单例, 你能通过 [[assetManager.parser]] 访问它。 * */ export class Parser { - private _parsing = new Cache(); + private _parsing = new Cache<((err: Error | null, data?: any | null) => void)[]>(); private _parsers: Record = { '.png': this.parseImage, @@ -160,7 +67,20 @@ export class Parser { '.cconb': this.parseImport, }; - public parseImage (file: HTMLImageElement | Blob, options: IDownloadParseOptions, onComplete: CompleteCallback) { + private static _instance: Parser; + + public static get instance () { + if (!this._instance) { + this._instance = new Parser(); + } + return this._instance; + } + private constructor () {} + + /** + * @engineInternal + */ + public parseImage (file: HTMLImageElement | Blob, options: Record, onComplete: ((err: Error | null, data?: HTMLImageElement | ImageBitmap | null) => void)) { if (file instanceof HTMLImageElement) { onComplete(null, file); return; @@ -172,135 +92,65 @@ export class Parser { }); } - public parsePVRTex (file: ArrayBuffer | ArrayBufferView, options: IDownloadParseOptions, onComplete: CompleteCallback) { + /** + * @engineInternal + */ + public parsePVRTex (file: ArrayBuffer | ArrayBufferView, options: Record, onComplete: ((err: Error | null, data?: IMemoryImageSource | null) => void)) { let err: Error | null = null; let out: IMemoryImageSource | null = null; try { - const buffer = file instanceof ArrayBuffer ? file : file.buffer; - // Get a view of the arrayBuffer that represents the DDS header. - const header = new Int32Array(buffer, 0, PVR_HEADER_LENGTH); - - // Do some sanity checks to make sure this is a valid DDS file. - if (header[PVR_HEADER_MAGIC] === PVR_MAGIC) { - // Gather other basic metrics and a view of the raw the DXT data. - const width = header[PVR_HEADER_WIDTH]; - const height = header[PVR_HEADER_HEIGHT]; - const dataOffset = header[PVR_HEADER_METADATA] + 52; - // todo: use new Uint8Array(buffer, dataOffset) instead - // buffer = buffer.slice(dataOffset, buffer.byteLength); - const pvrtcData = new Uint8Array(buffer, dataOffset); - out = { - _data: pvrtcData, - _compressed: true, - width, - height, - format: 0, - }; - } else if (header[11] === 0x21525650) { - const headerLength = header[0]; - const height = header[1]; - const width = header[2]; - // todo: use new Uint8Array(buffer, headerLength) instead - // buffer = buffer.slice(headerLength, buffer.byteLength); - const pvrtcData = new Uint8Array(buffer, headerLength); - out = { - _data: pvrtcData, - _compressed: true, - width, - height, - format: 0, - }; - } else { - throw new Error('Invalid magic number in PVR header'); - } + out = ImageAsset.parseCompressedTextures(file, 0); } catch (e) { err = e as Error; + console.warn(err); } onComplete(err, out); } - public parsePKMTex (file: ArrayBuffer | ArrayBufferView, options: IDownloadParseOptions, onComplete: CompleteCallback) { + /** + * @engineInternal + */ + public parsePKMTex (file: ArrayBuffer | ArrayBufferView, options: Record, onComplete: ((err: Error | null, data?: IMemoryImageSource | null) => void)) { let err: Error | null = null; let out: IMemoryImageSource | null = null; try { - const buffer = file instanceof ArrayBuffer ? file : file.buffer; - const header = new Uint8Array(buffer); - const format = readBEUint16(header, ETC_PKM_FORMAT_OFFSET); - if (format !== ETC1_RGB_NO_MIPMAPS && format !== ETC2_RGB_NO_MIPMAPS && format !== ETC2_RGBA_NO_MIPMAPS) { - throw new Error('Invalid magic number in ETC header'); - } - const width = readBEUint16(header, ETC_PKM_WIDTH_OFFSET); - const height = readBEUint16(header, ETC_PKM_HEIGHT_OFFSET); - const encodedWidth = readBEUint16(header, ETC_PKM_ENCODED_WIDTH_OFFSET); - const encodedHeight = readBEUint16(header, ETC_PKM_ENCODED_HEIGHT_OFFSET); - const etcData = new Uint8Array(buffer, ETC_PKM_HEADER_SIZE); - out = { - _data: etcData, - _compressed: true, - width, - height, - format: 0, - }; + out = ImageAsset.parseCompressedTextures(file, 1); } catch (e) { err = e as Error; + console.warn(err); } onComplete(err, out); } - public parseASTCTex (file: ArrayBuffer | ArrayBufferView, options: IDownloadParseOptions, onComplete: CompleteCallback) { + /** + * @engineInternal + */ + public parseASTCTex (file: ArrayBuffer | ArrayBufferView, options: Record, onComplete: ((err: Error | null, data?: IMemoryImageSource | null) => void)) { let err: Error | null = null; let out: IMemoryImageSource | null = null; try { - const buffer = file instanceof ArrayBuffer ? file : file.buffer; - const header = new Uint8Array(buffer); - - const magicval = header[0] + (header[1] << 8) + (header[2] << 16) + (header[3] << 24); - if (magicval !== ASTC_MAGIC) { - throw new Error('Invalid magic number in ASTC header'); - } - - const xdim = header[ASTC_HEADER_MAGIC]; - const ydim = header[ASTC_HEADER_MAGIC + 1]; - const zdim = header[ASTC_HEADER_MAGIC + 2]; - if ((xdim < 3 || xdim > 6 || ydim < 3 || ydim > 6 || zdim < 3 || zdim > 6) - && (xdim < 4 || xdim === 7 || xdim === 9 || xdim === 11 || xdim > 12 - || ydim < 4 || ydim === 7 || ydim === 9 || ydim === 11 || ydim > 12 || zdim !== 1)) { - throw new Error('Invalid block number in ASTC header'); - } - - const format = getASTCFormat(xdim, ydim); - - const xsize = header[ASTC_HEADER_SIZE_X_BEGIN] + (header[ASTC_HEADER_SIZE_X_BEGIN + 1] << 8) - + (header[ASTC_HEADER_SIZE_X_BEGIN + 2] << 16); - const ysize = header[ASTC_HEADER_SIZE_Y_BEGIN] + (header[ASTC_HEADER_SIZE_Y_BEGIN + 1] << 8) - + (header[ASTC_HEADER_SIZE_Y_BEGIN + 2] << 16); - const zsize = header[ASTC_HEADER_SIZE_Z_BEGIN] + (header[ASTC_HEADER_SIZE_Z_BEGIN + 1] << 8) - + (header[ASTC_HEADER_SIZE_Z_BEGIN + 2] << 16); - - // buffer = buffer.slice(ASTC_HEADER_LENGTH, buffer.byteLength); - const astcData = new Uint8Array(buffer, ASTC_HEADER_LENGTH); - - out = { - _data: astcData, - _compressed: true, - width: xsize, - height: ysize, - format, - }; + out = ImageAsset.parseCompressedTextures(file, 2); } catch (e) { err = e as Error; + console.warn(err); } onComplete(err, out); } - public parsePlist (file: string, options: IDownloadParseOptions, onComplete: CompleteCallback) { + /** + * @engineInternal + */ + public parsePlist (file: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) { let err: Error | null = null; const result = plistParser.parse(file); if (!result) { err = new Error('parse failed'); } onComplete(err, result); } - public parseImport (file: Record | CCON, options: IDownloadParseOptions, onComplete: CompleteCallback) { + /** + * @engineInternal + */ + public parseImport (file: Record | CCON, options: Record, onComplete: ((err: Error | null, data?: Asset | null) => void)) { if (!file) { onComplete(new Error(`The json file of asset ${options.__uuid__ as string} is empty or missing`)); return; @@ -315,22 +165,27 @@ export class Parser { onComplete(err, result); } + /** + * @engineInternal + */ public init () { this._parsing.clear(); } /** * @en - * Register custom handler if you want to change default behavior or extend parser to parse other format file + * Register custom handler if you want to change default behavior or extend parser to parse other format file. * * @zh - * 当你想修改默认行为或者拓展 parser 来解析其他格式文件时可以注册自定义的handler + * 当你想修改默认行为或者拓展 parser 来解析其他格式文件时可以注册自定义的 handler。 * - * @param type - Extension likes '.jpg' or map likes {'.jpg': jpgHandler, '.png': pngHandler} - * @param handler - The corresponding handler - * @param handler.file - File - * @param handler.options - Some optional paramter - * @param handler.onComplete - callback when finishing parsing + * @param type + * @en Extension name likes '.jpg' or map likes {'.jpg': jpgHandler, '.png': pngHandler}. + * @zh 形如 '.jpg' 的扩展名或形如 {'.jpg': jpgHandler, '.png': pngHandler} 的映射表。 + * @param handler @en The corresponding handler. @zh 对应扩展名的处理方法。 + * @param handler.file @en The file to be parsed. @zh 待解析的文件。 + * @param handler.options @en Some optional parameters. @zh 一些可选的参数。 + * @param handler.onComplete @en The callback invoked when parsing finished. @zh 完成解析的回调。 * * @example * parser.register('.tga', (file, options, onComplete) => onComplete(null, null)); @@ -338,9 +193,12 @@ export class Parser { * '.ext': (file, options, onComplete) => onComplete(null, null)}); * */ - public register (type: string, handler: ParseHandler): void; - public register (map: Record): void; - public register (type: string | Record, handler?: ParseHandler) { + public register (type: string, handler: (file: any, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void): void; + public register (map: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void>): void; + public register ( + type: string | Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void>, + handler?: (file: any, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) => void, + ) { if (typeof type === 'object') { js.mixin(this._parsers, type); } else { @@ -350,18 +208,18 @@ export class Parser { /** * @en - * Use corresponding handler to parse file + * Use corresponding handler to parse file. * * @zh - * 使用对应的handler来解析文件 + * 使用对应的 handler 来解析文件。 * - * @param id - The id of file - * @param file - File - * @param type - The corresponding type of file, likes '.jpg'. - * @param options - Some optional parameters will be transferred to the corresponding handler. - * @param onComplete - callback when finishing downloading - * @param onComplete.err - The occurred error, null indicates success - * @param onComplete.content - The parsed file + * @param id @en The id of file. @zh 文件的唯一 id。 + * @param file @en The data of file. @zh 文件的数据。 + * @param type @en The corresponding type of file, likes '.jpg'. @zh 需要使用的解析方法类型。 + * @param options @en Some optional parameters will be transferred to the corresponding handler. @zh 传递到解析方法的额外参数。 + * @param onComplete @en The callback invoked when finishing parsing. @zh 完成解析的回调。 + * @param onComplete.err @en The occurred error, null indicates success. @zh 解析过程中发生的错误,null 表明解析成功。 + * @param onComplete.content @en The parsed data. @zh 解析后的数据。 * * @example * downloader.download('test.jpg', 'test.jpg', '.jpg', {}, (err, file) => { @@ -369,7 +227,7 @@ export class Parser { * }); * */ - public parse (id: string, file: any, type: string, options: IDownloadParseOptions, onComplete: CompleteCallback): void { + public parse (id: string, file: any, type: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)): void { const parsedAsset = parsed.get(id); if (parsedAsset) { onComplete(null, parsedAsset); @@ -402,4 +260,4 @@ export class Parser { } } -export default new Parser(); +export default Parser.instance; diff --git a/cocos/asset/asset-manager/pipeline.ts b/cocos/asset/asset-manager/pipeline.ts index d96a734eb13..78c19f681d1 100644 --- a/cocos/asset/asset-manager/pipeline.ts +++ b/cocos/asset/asset-manager/pipeline.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,22 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { warnID } from '../../core/platform/debug'; -import { CompleteCallbackNoData } from './shared'; +import { warnID } from '../../core'; import Task from './task'; -export type IAsyncPipe = (task: Task, done: CompleteCallbackNoData) => void; -export type ISyncPipe = (task: Task) => Error | void; -export type IPipe = IAsyncPipe | ISyncPipe; - /** * @en - * Pipeline can execute the task for some effect. + * The loading pipeline can complete the loading task by executing a series of phases. [[AssetManager]] uses it to load all assets. * * @zh - * 管线能执行任务达到某个效果 + * 加载管线能通过执行一系列阶段来完成加载任务。[[AssetManager]] 使用其来加载所有资源。 * */ export class Pipeline { @@ -44,44 +38,46 @@ export class Pipeline { /** * @en - * The id of pipeline + * The unique id of this pipeline. * * @zh - * 管线的 id + * 管线的唯一 id。 * */ public id: number = Pipeline._pipelineId++; /** * @en - * The name of pipeline + * The name of this pipeline. * * @zh - * 管线的名字 + * 此管线的名称。 * */ public name = ''; /** * @en - * All pipes of pipeline + * All pipes of this pipeline. * * @zh - * 所有的管道 + * 此管线的所有管道。 * */ - public pipes: IPipe[] = []; + public pipes: Array<((task: Task, done: ((err?: Error | null) => void)) => void) | ((task: Task) => Error | void)> = []; /** * @en - * Create a new pipeline + * Creates a new pipeline. * * @zh - * 创建一个管线 + * 创建一个管线。 * - * @param name - The name of pipeline - * @param funcs - The array of pipe, every pipe must be function which take two parameters, - * the first is a `Task` flowed in pipeline, the second is complete callback + * @param name - @en The name of pipeline. @zh 管线的名称。 + * @param funcs + * @en The array of pipes to create pipeline, every pipe must be function which take two parameters, + * the first is a `Task` flowed in pipeline, the second is complete callback. + * @zh 用于创建管线的管道数组,每个管道必须是一个接受两个参数的方法,第一个参数为任务 [[Task]], 第二个参数为完成回调。 * * @example * const pipeline = new Pipeline('download', [ @@ -101,7 +97,7 @@ export class Pipeline { * ]); * */ - constructor (name: string, funcs: IPipe[]) { + constructor (name: string, funcs: Array<((task: Task, done: ((err?: Error | null) => void)) => void) | ((task: Task) => Error | void)>) { this.name = name; for (let i = 0, l = funcs.length; i < l; i++) { this.pipes.push(funcs[i]); @@ -110,16 +106,18 @@ export class Pipeline { /** * @en - * At specific point insert a new pipe to pipeline + * Inserts a new pipe to pipeline at specific point . * * @zh - * 在某个特定的点为管线插入一个新的 pipe + * 在某个特定的点为管线插入一个新的 pipe。 * - * @param func - The new pipe - * @param func.task - The task handled with pipeline will be transferred to this function - * @param func.done - Callback you need to invoke manually when this pipe is finished. if the pipeline is synchronous, callback is unnecessary. - * @param index - The specific point you want to insert at. - * @return pipeline + * @param func @en The new pipe to be inserted. @zh 待插入的管道。 + * @param func.task @en The task handled with pipeline will be transferred to this function. @zh 正在被此管线处理的任务。 + * @param func.done + * @en Callback you need to invoke manually when this pipe is finished. if the pipeline is synchronous, callback is unnecessary. + * @zh 当这个管道完成时,你需要手动调用回调。如果管道是同步的,回调就没有必要。 + * @param index @en The specific point you want to insert at. @zh 要插入进的位置。 + * @return @en Returns the Pipeline itself, which can be used to make chain calls. @zh 返回 Pipeline 本身,可以用于做链式调用。 * * @example * var pipeline = new Pipeline('test', []); @@ -129,7 +127,7 @@ export class Pipeline { * }, 0); * */ - public insert (func: IPipe, index: number): Pipeline { + public insert (func: ((task: Task, done: ((err?: Error | null) => void)) => void) | ((task: Task) => Error | void), index: number): Pipeline { if (index > this.pipes.length) { warnID(4921); return this; @@ -141,15 +139,19 @@ export class Pipeline { /** * @en - * Append a new pipe to the pipeline + * Appends a new pipe to the pipeline. * * @zh - * 添加一个管道到管线中 + * 添加一个管道到管线中。 * - * @param func - The new pipe - * @param func.task - The task handled with pipeline will be transferred to this function - * @param func.done - Callback you need to invoke manually when this pipe is finished. if the pipeline is synchronous, callback is unnecessary. - * @return pipeline + * @param func @en The new pipe to be appended. @zh 要追加的新管道。 + * @param func.task + * @en The task handled with pipeline will be transferred to this function. + * @zh 正在被此管线处理的任务。 + * @param func.done + * @en Callback you need to invoke manually when this pipe is finished. if the pipeline is synchronous, callback is unnecessary. + * @zh 当这个管道完成时,你需要手动调用回调。如果管道是同步的,回调就没有必要。 + * @return @en Returns the Pipeline itself, which can be used to make chain calls. @zh 返回 Pipeline 本身,可以用于做链式调用。 * * @example * var pipeline = new Pipeline('test', []); @@ -159,20 +161,20 @@ export class Pipeline { * }); * */ - public append (func: IPipe): Pipeline { + public append (func: ((task: Task, done: ((err?: Error | null) => void)) => void) | ((task: Task) => Error | void)): Pipeline { this.pipes.push(func); return this; } /** * @en - * Remove pipe which at specific point + * Removes pipe which at specific point. * * @zh - * 移除特定位置的管道 + * 移除特定位置的管道。 * - * @param index - The specific point - * @return pipeline + * @param index @en The specific point. @zh 指定位置的索引。 + * @return @en Returns the Pipeline itself, which can be used to make chain calls. @zh 返回 Pipeline 本身,可以用于做链式调用。 * * @example * var pipeline = new Pipeline('test', (task, done) => { @@ -189,13 +191,13 @@ export class Pipeline { /** * @en - * Execute task synchronously + * Executes task synchronously. * * @zh - * 同步执行任务 + * 同步执行任务。 * - * @param task - The task will be executed - * @returns result + * @param task @en The task will be executed. @zh 要执行的任务。 + * @returns @en The execution result. @zh 执行结果。 * * @example * var pipeline = new Pipeline('sync', [(task) => { @@ -210,12 +212,12 @@ export class Pipeline { public sync (task: Task): any { const pipes = this.pipes; if (pipes.length === 0) { return null; } - task.isFinish = false; + task.isFinished = false; for (let i = 0, l = pipes.length; i < l;) { - const pipe = pipes[i] as ISyncPipe; + const pipe = pipes[i] as ((task: Task) => Error | void); const result = pipe(task); if (result) { - task.isFinish = true; + task.isFinished = true; return result; } i++; @@ -224,18 +226,18 @@ export class Pipeline { task.output = null; } } - task.isFinish = true; + task.isFinished = true; return task.output as unknown; } /** * @en - * Execute task asynchronously + * Executes task asynchronously. * * @zh - * 异步执行任务 + * 异步执行任务。 * - * @param task - The task will be executed + * @param task @en The task will be executed. @zh 待执行的任务。 * * @example * var pipeline = new Pipeline('sync', [(task, done) => { @@ -250,7 +252,7 @@ export class Pipeline { public async (task: Task): void { const pipes = this.pipes; if (pipes.length === 0) { return; } - task.isFinish = false; + task.isFinished = false; this._flow(0, task); } @@ -258,7 +260,7 @@ export class Pipeline { const pipe = this.pipes[index]; pipe(task, (result) => { if (result) { - task.isFinish = true; + task.isFinished = true; task.dispatch('complete', result); } else { index++; @@ -268,7 +270,7 @@ export class Pipeline { task.output = null; this._flow(index, task); } else { - task.isFinish = true; + task.isFinished = true; task.dispatch('complete', result, task.output); } } diff --git a/cocos/asset/asset-manager/plist-parser.ts b/cocos/asset/asset-manager/plist-parser.ts index f35d04aafe8..5f240990996 100644 --- a/cocos/asset/asset-manager/plist-parser.ts +++ b/cocos/asset/asset-manager/plist-parser.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -23,9 +23,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { warnID } from '../../core/platform/debug'; +import { warnID } from '../../core'; /** * A SAX Parser @@ -34,7 +34,7 @@ import { warnID } from '../../core/platform/debug'; export class SAXParser { private _parser: DOMParser | null = null; constructor () { - if (window.DOMParser) { + if (globalThis.DOMParser) { this._parser = new DOMParser(); } } diff --git a/cocos/asset/asset-manager/preprocess.ts b/cocos/asset/asset-manager/preprocess.ts index 00d6434ad51..b402a109892 100644 --- a/cocos/asset/asset-manager/preprocess.ts +++ b/cocos/asset/asset-manager/preprocess.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { CompleteCallbackNoData, RequestType, transformPipeline } from './shared'; +import { RequestType, transformPipeline } from './shared'; import Task from './task'; -export default function preprocess (task: Task, done: CompleteCallbackNoData) { +export default function preprocess (task: Task, done: ((err?: Error | null) => void)) { const options = task.options; const subOptions = Object.create(null); const leftOptions = Object.create(null); diff --git a/cocos/asset/asset-manager/release-manager.ts b/cocos/asset/asset-manager/release-manager.ts index 2666754217a..f703cecfbeb 100644 --- a/cocos/asset/asset-manager/release-manager.ts +++ b/cocos/asset/asset-manager/release-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, TEST } from 'internal:constants'; import { Asset } from '../assets/asset'; -import { isValid } from '../../core/data/object'; +import { isValid, js, misc } from '../../core'; import { Node, Scene } from '../../scene-graph'; import Cache from './cache'; import dependUtil from './depend-util'; import { assets, references } from './shared'; -import { callInNextTick } from '../../core/utils/misc'; -import { js } from '../../core/utils/js'; function visitAsset (asset: Asset, deps: string[]) { // Skip assets generated programmatically or by user (e.g. label texture) @@ -219,7 +216,7 @@ class ReleaseManager { if (TEST) return; if (!this._eventListener) { this._eventListener = true; - callInNextTick(this._freeAssets.bind(this)); + misc.callInNextTick(this._freeAssets.bind(this)); } } diff --git a/cocos/asset/asset-manager/request-item.ts b/cocos/asset/asset-manager/request-item.ts index 51fe901f804..96595ff872a 100644 --- a/cocos/asset/asset-manager/request-item.ts +++ b/cocos/asset/asset-manager/request-item.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,25 +20,25 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import Config, { IAssetInfo } from './config'; /** * @en - * A collection of information about a request + * A collection of information about a request. * * @zh - * 请求的相关信息集合 + * 请求的相关信息集合。 * */ export default class RequestItem { /** * @en - * The id of request, combined from uuid and isNative + * The id of request, combined from uuid and isNative. * * @zh - * 请求的 id, 由 uuid 和 isNative 组合而成 + * 请求的 id, 由 uuid 和 isNative 组合而成。 */ get id (): string { if (!this._id) { @@ -48,16 +47,19 @@ export default class RequestItem { return this._id; } + /** + * @engineInternal + */ public static MAX_DEAD_NUM = 500; /** * @en - * Create a new request item from pool + * Create a new request item from pool. * * @zh - * 从对象池中创建 requestItem + * 从对象池中创建 requestItem。 * - * @returns requestItem + * @returns @en return a newly created RequestItem. @zh 返回一个刚创建的 `RequestItem`。 * */ public static create (): RequestItem { @@ -75,84 +77,90 @@ export default class RequestItem { /** * @en - * The uuid of request + * The uuid of request. * * @zh - * 请求资源的uuid + * 所请求资源的 uuid。 * */ public uuid = ''; + /** + * @engineInternal only used for L10N asset replacement. + */ public overrideUuid = ''; /** * @en - * The final url of request + * The final url of request. * * @zh - * 请求的最终url + * 请求的最终 url。 * */ public url = ''; /** * @en - * The extension name of asset + * The extension name of asset. * * @zh - * 资源的扩展名 + * 资源的扩展名。 * */ public ext = '.json'; /** * @en - * The content of asset + * The content of asset. * * @zh - * 资源的内容 + * 资源的内容。 * */ public content: any = null; /** * @en - * The file of asset + * The file of asset. * * @zh - * 资源的文件 + * 资源的文件。 * */ public file: any = null; /** * @en - * The information of asset + * The information of asset. * * @zh - * 资源的相关信息 + * 资源的相关信息。 * */ public info: IAssetInfo | null = null; + /** + * @engineInternal + */ public config: Config | null = null; /** * @en - * Whether or not it is native asset + * Whether or not it is native asset. * * @zh - * 资源是否是原生资源 + * 资源是否是原生资源。 * */ public isNative = false; /** * @en - * Custom options + * Custom options. * * @zh - * 自定义参数 + * 自定义参数。 * */ public options: Record = Object.create(null); @@ -161,10 +169,10 @@ export default class RequestItem { /** * @en - * Recycle this for reuse + * Recycle this to be reused. * * @zh - * 回收 requestItem 用于复用 + * 回收 requestItem 用于复用。 * */ public recycle (): void { diff --git a/cocos/asset/asset-manager/shared.ts b/cocos/asset/asset-manager/shared.ts index f3a8cd5682e..bf32743ca8d 100644 --- a/cocos/asset/asset-manager/shared.ts +++ b/cocos/asset/asset-manager/shared.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,77 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { Asset } from '../assets/asset'; import Bundle from './bundle'; import Cache from './cache'; import { Pipeline } from './pipeline'; -import RequestItem from './request-item'; import WeakCache from './weak-cache'; -export type CompleteCallback = (err: Error | null, data?: T | null) => void; -export type CompleteCallbackNoData = (err?: Error | null) => void; -export type CompleteCallbackWithData = (err: Error | null, data: T) => void; -export type ProgressCallback = (finished: number, total: number, item: RequestItem) => void; -export type Request = string | string[] | IRequest | Array; - -export interface IRequest extends IOptions { - uuid?: string; - url?: string; - path?: string; - dir?: string; - scene?: string; -} - -export interface IOptions extends IBundleOptions, IRemoteOptions { - type?: typeof Asset; - bundle?: string; -} - -export interface IRemoteOptions extends IAssetOptions { - ext?: string; -} - -export interface IXHROptions extends Record { - xhrResponseType?: XMLHttpRequestResponseType; - xhrWithCredentials?: boolean; - xhrTimeout?: number; - xhrHeader?: Record; - xhrMimeType?: string; -} - -export interface IAssetOptions extends INativeAssetOptions { - reloadAsset?: boolean; - cacheAsset?: boolean; -} - -export interface IJsonAssetOptions extends IAssetOptions { - assetId?: string; -} - -export interface IDownloadParseOptions extends IXHROptions { - priority?: number; - audioLoadMode?: number; - onFileProgress?: (loaded: number, total: number) => void; - maxConcurrency?: number; - maxRequestsPerFrame?: number; - maxRetryCount?: number; - cacheEnabled?: boolean; -} - -export interface IBundleOptions extends INativeAssetOptions { - version?: string; - scriptAsyncLoading?: boolean; -} - -export interface INativeAssetOptions extends IDownloadParseOptions { - preset?: string; -} - -export type AssetType = Constructor; - export const assets = EDITOR ? new WeakCache() : new Cache(); export const files = new Cache(); export const parsed = new Cache(); @@ -115,6 +52,14 @@ export enum RequestType { SCENE = 'scene', } +export interface IRequest extends Record { + uuid?: string; + url?: string; + path?: string; + dir?: string; + scene?: string; +} + export const presets: Record> = { default: { diff --git a/cocos/asset/asset-manager/task.ts b/cocos/asset/asset-manager/task.ts index 22207ab1a63..8c6032f8dd0 100644 --- a/cocos/asset/asset-manager/task.ts +++ b/cocos/asset/asset-manager/task.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -export type TaskCompleteCallback = (err: Error | null | undefined, data: any) => void; -export type TaskProgressCallback = (...args: any[]) => void; -export type TaskErrorCallback = (...args: any[]) => void; export interface ITaskOption { - onComplete?: TaskCompleteCallback | null; - onProgress?: TaskProgressCallback | null; - onError?: TaskErrorCallback | null; + onComplete?: ((err: Error | null | undefined, data: any) => void) | null; + onProgress?: ((...args: any[]) => void) | null; + onError?: ((...args: any[]) => void) | null; input: any; progress?: any; options?: Record | null; @@ -37,32 +33,40 @@ export interface ITaskOption { /** * @en - * Task is used to run in the pipeline for some effect + * Tasks are the smallest unit of data running in the pipeline, You can create a task and pass in the input information, + * and then get the output of that task after it has been executed in the pipeline to use. * * @zh - * 任务用于在管线中运行以达成某种效果 + * 任务是在管线中运行的最小数据单位,你可以创建一个任务并传入输入信息,在经过管线执行后获取该任务的输出来使用。 * */ export default class Task { + /** + * @engineInternal + */ public static MAX_DEAD_NUM = 500; /** * @en - * Create a new task from pool + * Create a new task from pool. * * @zh - * 从对象池中创建 task - * - * @static - * @method create - * @param options - Some optional paramters - * @param options.onComplete - Callback when the task complete, if the pipeline is synchronous, onComplete is unnecessary. - * @param options.onProgress - Continuously callback when the task is runing, if the pipeline is synchronous, onProgress is unnecessary. - * @param options.onError - Callback when something goes wrong, if the pipeline is synchronous, onError is unnecessary. - * @param options.input - Something will be handled with pipeline - * @param options.progress - Progress information, you may need to assign it manually when multiple pipeline share one progress - * @param options.options - Custom parameters - * @returns task + * 从对象池中创建 task。 + * + * @param options @en Some optional parameters. @zh 一些可选参数。 + * @param options.onComplete + * @en Callback when the task complete, if the pipeline is synchronous, onComplete is unnecessary. + * @zh 任务完成后的回调,如果流水线是同步的,onComplete 是不必要的。 + * @param options.onProgress + * @en Continuously callback when the task is running, if the pipeline is synchronous, onProgress is unnecessary. + * @zh 在任务运行时持续回调,如果管道是同步的,onProgress 是不必要的。 + * @param options.onError + * @en Callback when something goes wrong, if the pipeline is synchronous, onError is unnecessary. + * @zh 出错时的回调,如果流水线是同步的,onError 是不必要的。 + * @param options.input @en Something will be handled with pipeline. @zh 需要被此管道处理的任务数据。 + * @param options.progress @en Progress information. @zh 进度信息。 + * @param options.options @en Custom parameters. @zh 自定义参数。 + * @returns @en return a newly created task. @zh 返回一个新创建的任务。 * */ public static create (options: ITaskOption): Task { @@ -82,117 +86,138 @@ export default class Task { /** * @en - * The id of task + * The id of task. * * @zh - * 任务id + * 任务 id。 * */ public id: number = Task._taskId++; /** * @en - * The callback when task is completed + * The callback when task is completed. * * @zh - * 完成回调 + * 完成回调。 * */ - public onComplete: TaskCompleteCallback | null = null; + public onComplete: ((err: Error | null | undefined, data: any) => void) | null = null; /** * @en - * The callback of progression + * The callback of progression. * * @zh - * 进度回调 + * 进度回调。 * */ - public onProgress: TaskProgressCallback | null = null; + public onProgress: ((...args: any[]) => void) | null = null; /** * @en - * The callback when something goes wrong + * The callback when something goes wrong. * * @zh - * 错误回调 + * 错误回调。 * */ - public onError: TaskErrorCallback | null = null; + public onError: ((...args: any[]) => void) | null = null; /** * @en - * The source of task + * The source data of task. * * @zh - * 任务的源 + * 任务的源数据。 * */ public source: any = null; /** * @en - * The output of task + * The output of task. * * @zh - * 任务的输出 + * 任务的输出。 */ public output: any = null; /** * @en - * The input of task + * The input of task. * * @zh - * 任务的输入 + * 任务的输入。 * */ public input: any = null; /** * @en - * The progression of task + * The progression of task. * * @zh - * 任务的进度 + * 任务的进度。 * */ public progress: any = null; /** * @en - * Custom options + * Custom options. * * @zh - * 自定义参数 + * 自定义参数。 * */ public options: Record | null = null; + /** + * @deprecated Typo. Since v3.7, please use [[Task.isFinished]] instead. + */ + public get isFinish () { + return this.isFinished; + } + + /** + * @deprecated Typo. Since v3.7, please use [[Task.isFinished]] instead. + */ + public set isFinish (val: boolean) { + this.isFinished = val; + } + /** * @en - * Whether or not this task is completed + * Whether or not this task is completed. * * @zh - * 此任务是否已经完成 + * 此任务是否已经完成。 * */ - public isFinish = true; + public isFinished = true; /** * @en - * Create a new Task + * Create a new Task. * * @zh - * 创建一个任务 - * - * @param options - Some optional paramters - * @param options.onComplete - Callback when the task is completed, if the pipeline is synchronous, onComplete is unnecessary. - * @param options.onProgress - Continuously callback when the task is runing, if the pipeline is synchronous, onProgress is unnecessary. - * @param options.onError - Callback when something goes wrong, if the pipeline is synchronous, onError is unnecessary. - * @param options.input - Something will be handled with pipeline - * @param options.progress - Progress information, you may need to assign it manually when multiple pipeline share one progress - * @param options.options - Custom parameters + * 创建一个任务。 + * + * @param options @en Some optional parameters. @zh 一些可选参数。 + * @param options.onComplete + * @en Callback when the task complete, if the pipeline is synchronous, onComplete is unnecessary. + * @zh 任务完成后的回调,如果流水线是同步的,onComplete 是不必要的。 + * @param options.onProgress + * @en Continuously callback when the task is running, if the pipeline is synchronous, onProgress is unnecessary. + * @zh 在任务运行时持续回调,如果管道是同步的,onProgress 是不必要的。 + * @param options.onError + * @en Callback when something goes wrong, if the pipeline is synchronous, onError is unnecessary. + * @zh 出错时的回调,如果流水线是同步的,onError 是不必要的。 + * @param options.input @en Something will be handled with pipeline. @zh 需要被此管道处理的任务数据。 + * @param options.progress @en Progress information. @zh 进度信息。 + * @param options.options @en Custom parameters. @zh 自定义参数。 + * @returns @en return a newly created task. @zh 返回一个新创建的任务。 */ public constructor (options?: ITaskOption) { this.set(options); @@ -200,21 +225,28 @@ export default class Task { /** * @en - * Set parameters of this task + * Set parameters of this task. * * @zh - * 设置任务的参数 - * - * @param options - Some optional parameters - * @param options.onComplete - Callback when the task is completed, if the pipeline is synchronous, onComplete is unnecessary. - * @param options.onProgress - Continuously callback when the task is running, if the pipeline is synchronous, onProgress is unnecessary. - * @param options.onError - Callback when something goes wrong, if the pipeline is synchronous, onError is unnecessary. - * @param options.input - Something will be handled with pipeline - * @param options.progress - Progress information, you may need to assign it manually when multiple pipeline share one progress - * @param options.options - Custom parameters + * 设置任务的参数。 + * + * @param options @en Some optional parameters. @zh 一些可选参数。 + * @param options.onComplete + * @en Callback when the task complete, if the pipeline is synchronous, onComplete is unnecessary. + * @zh 任务完成后的回调,如果流水线是同步的,onComplete 是不必要的。 + * @param options.onProgress + * @en Continuously callback when the task is running, if the pipeline is synchronous, onProgress is unnecessary. + * @zh 在任务运行时持续回调,如果管道是同步的,onProgress 是不必要的。 + * @param options.onError + * @en Callback when something goes wrong, if the pipeline is synchronous, onError is unnecessary. + * @zh 出错时的回调,如果流水线是同步的,onError 是不必要的。 + * @param options.input @en Something will be handled with pipeline. @zh 需要被此管道处理的任务数据。 + * @param options.progress @en Progress information. @zh 进度信息。 + * @param options.options @en Custom parameters. @zh 自定义参数。 + * @returns @en return a newly created task. @zh 返回一个新创建的任务。 * * @example - * var task = new Task(); + * const task = new Task(); * task.set({input: ['test'], onComplete: (err, result) => console.log(err), onProgress: (finish, total) => console.log(finish / total)}); * */ @@ -231,21 +263,21 @@ export default class Task { /** * @en - * Dispatch event + * Dispatch event with any parameter. * * @zh - * 发布事件 + * 分发事件,可以传递任意参数。 * - * @param event - The event name - * @param param1 - Parameter 1 - * @param param2 - Parameter 2 - * @param param3 - Parameter 3 - * @param param4 - Parameter 4 + * @param event @en The event name. @zh 事件名称。 + * @param param1 @en The parameter 1. @zh 参数 1。 + * @param param2 @en The parameter 2. @zh 参数 2。 + * @param param3 @en The parameter 3. @zh 参数 3。 + * @param param4 @en The parameter 4. @zh 参数 4。 * * @example - * var task = Task.create(); - * Task.onComplete = (msg) => console.log(msg); - * Task.dispatch('complete', 'hello world'); + * const task = Task.create(); + * task.onComplete = (msg) => console.log(msg); + * task.dispatch('complete', 'hello world'); * */ public dispatch (event: string, param1?: any, param2?: any, param3?: any, param4?: any): void { @@ -277,10 +309,10 @@ export default class Task { /** * @en - * Recycle this for reuse + * Recycle this task to be reused. * * @zh - * 回收 task 用于复用 + * 回收 task 用于复用。 * */ public recycle (): void { diff --git a/cocos/asset/asset-manager/url-transformer.ts b/cocos/asset/asset-manager/url-transformer.ts index d563ac2f222..9de1437fc1c 100644 --- a/cocos/asset/asset-manager/url-transformer.ts +++ b/cocos/asset/asset-manager/url-transformer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, PREVIEW } from 'internal:constants'; -import { legacyCC } from '../../core/global-exports'; -import { warnID } from '../../core/platform/debug'; -import { js } from '../../core/utils/js'; -import * as path from '../../core/utils/path'; +import { warnID, js, path, cclegacy } from '../../core'; import Config, { IAddressableInfo, IAssetInfo } from './config'; import { decodeUuid } from './helper'; import RequestItem from './request-item'; @@ -201,9 +197,9 @@ export function combine (task: Task) { let base = ''; const config = item.config; if (item.isNative) { - base = (config && config.nativeBase) ? (config.base + config.nativeBase) : legacyCC.assetManager.generalNativeBase; + base = (config && config.nativeBase) ? (config.base + config.nativeBase) : cclegacy.assetManager.generalNativeBase; } else { - base = (config && config.importBase) ? (config.base + config.importBase) : legacyCC.assetManager.generalImportBase; + base = (config && config.importBase) ? (config.base + config.importBase) : cclegacy.assetManager.generalImportBase; } const uuid = item.overrideUuid || item.uuid; diff --git a/cocos/asset/asset-manager/utilities.ts b/cocos/asset/asset-manager/utilities.ts index 758362c88b6..7fc56dcf6bf 100644 --- a/cocos/asset/asset-manager/utilities.ts +++ b/cocos/asset/asset-manager/utilities.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,29 +20,26 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { Asset } from '../assets/asset'; -import { legacyCC } from '../../core/global-exports'; -import { error } from '../../core/platform/debug'; -import { js } from '../../core/utils/js'; -import { callInNextTick } from '../../core/utils/misc'; +import { cclegacy, error, js, misc } from '../../core'; import Config from './config'; import { dependMap, nativeDependMap } from './depend-maps'; import dependUtil from './depend-util'; import { isScene } from './helper'; import RequestItem from './request-item'; -import { assets, AssetType, CompleteCallbackNoData, CompleteCallback, IOptions, ProgressCallback, references } from './shared'; +import { assets, references } from './shared'; import Task from './task'; -let defaultProgressCallback: ProgressCallback | null = null; +let defaultProgressCallback: ((finished: number, total: number, item: RequestItem) => void) | null = null; declare class WeakRef { constructor (obj: any); } -export function setDefaultProgressCallback (onProgress: ProgressCallback) { +export function setDefaultProgressCallback (onProgress: (finished: number, total: number, item: RequestItem) => void) { defaultProgressCallback = onProgress; } @@ -71,9 +67,9 @@ export function urlAppendTimestamp (url: string, append: boolean): string { return url; } -export type RetryFunction = (times: number, done: CompleteCallback) => void; +export type RetryFunction = (times: number, done: ((err: Error | null, data?: any | null) => void)) => void; -export function retry (process: RetryFunction, times: number, wait: number, onComplete: CompleteCallback, index = 0) { +export function retry (process: RetryFunction, times: number, wait: number, onComplete: ((err: Error | null, data?: any | null) => void), index = 0) { process(index, (err, result) => { index++; if (!err || index > times) { @@ -112,7 +108,7 @@ export function getDepends (uuid: string, data: Asset | Record, exc export function cache (id: string, asset: Asset, cacheAsset?: boolean) { if (!asset) { return; } - cacheAsset = cacheAsset !== undefined ? cacheAsset : legacyCC.assetManager.cacheAsset; + cacheAsset = cacheAsset !== undefined ? cacheAsset : cclegacy.assetManager.cacheAsset; if (!isScene(asset) && cacheAsset && !asset.isDefault) { assets.add(id, asset); } @@ -186,7 +182,7 @@ export function gatherAsset (task: Task) { } } -type ForEachFunction = (item: T, done: CompleteCallbackNoData) => void; +type ForEachFunction = (item: T, done: ((err?: Error | null) => void)) => void; export function forEach (array: T[], process: ForEachFunction, onComplete: (errs: Error[]) => void) { let count = 0; @@ -212,20 +208,20 @@ export function forEach (array: T[], process: ForEachFunction, onCom } interface IParameters { - options: IOptions; - onProgress: ProgressCallback | null; + options: Record; + onProgress: ((finished: number, total: number, item: RequestItem) => void) | null; onComplete: T | null; } interface ILoadResArgs { - type: AssetType | null; - onProgress: ProgressCallback | null; + type: Constructor | null; + onProgress: ((finished: number, total: number, item: RequestItem) => void) | null; onComplete: T | null; } export function parseParameters void> ( - options: IOptions | ProgressCallback | T | null | undefined, - onProgress: ProgressCallback | T | null | undefined, + options: Record | ((finished: number, total: number, item: RequestItem) => void) | T | null | undefined, + onProgress: ((finished: number, total: number, item: RequestItem) => void) | T | null | undefined, onComplete: T | null | undefined): IParameters { let optionsOut: any = options; let onProgressOut: any = onProgress; @@ -243,7 +239,7 @@ export function parseParameters void> ( onProgressOut = null; } if (onProgress !== undefined && isCallback) { - onProgressOut = options as ProgressCallback; + onProgressOut = options as ((finished: number, total: number, item: RequestItem) => void); optionsOut = null; } } @@ -252,14 +248,14 @@ export function parseParameters void> ( } export function parseLoadResArgs void> ( - type: AssetType | ProgressCallback | T | null | undefined, - onProgress: ProgressCallback | T | null | undefined, + type: Constructor | ((finished: number, total: number, item: RequestItem) => void) | T | null | undefined, + onProgress: ((finished: number, total: number, item: RequestItem) => void) | T | null | undefined, onComplete: T | null | undefined): ILoadResArgs { let typeOut: any = type; let onProgressOut: any = onProgress; let onCompleteOut: any = onComplete; if (onComplete === undefined) { - const isValidType = js.isChildClassOf(type as AssetType, Asset); + const isValidType = js.isChildClassOf(type as Constructor, Asset); if (onProgress) { onCompleteOut = onProgress as T; if (isValidType) { @@ -271,7 +267,7 @@ export function parseLoadResArgs void> ( typeOut = null; } if (onProgress !== undefined && !isValidType) { - onProgressOut = type as ProgressCallback; + onProgressOut = type as ((finished: number, total: number, item: RequestItem) => void); typeOut = null; } } @@ -308,7 +304,7 @@ export function asyncify (cb: ((p1?: any, p2?: any) => void) | null): (p1?: any, } else if (p2 instanceof Asset) { refs.push(p2.addRef()); } - callInNextTick(() => { + misc.callInNextTick(() => { refs.forEach((x) => x.decRef(false)); cb(p1, p2); }); diff --git a/cocos/asset/asset-manager/weak-cache.ts b/cocos/asset/asset-manager/weak-cache.ts index dca2e62bfb8..5a6d2a842ad 100644 --- a/cocos/asset/asset-manager/weak-cache.ts +++ b/cocos/asset/asset-manager/weak-cache.ts @@ -1,4 +1,28 @@ -import { js } from '../../core/utils/js'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { js } from '../../core'; import { ICache } from './cache'; declare class WeakRef { diff --git a/cocos/asset/assets/asset-enum.ts b/cocos/asset/assets/asset-enum.ts index 0fbb8df3fec..45c56e7214f 100644 --- a/cocos/asset/assets/asset-enum.ts +++ b/cocos/asset/assets/asset-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Address, Filter as GFXFilter, Format } from '../../gfx'; diff --git a/cocos/asset/assets/asset.jsb.ts b/cocos/asset/assets/asset.jsb.ts index 837b60832eb..55caae9c282 100644 --- a/cocos/asset/assets/asset.jsb.ts +++ b/cocos/asset/assets/asset.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,14 +23,8 @@ */ import { ccclass, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; -import { CallbacksInvoker } from '../../core/event/callbacks-invoker'; -import { applyMixins } from '../../core/event/event-target-factory'; -import { createMap } from '../../core/utils/js-typed'; -import { property } from '../../core/data/class-decorator'; +import { cclegacy, js, _decorator, path, jsbUtils, CallbacksInvoker, applyMixins } from '../../core'; import { getUrlWithUuid } from '../asset-manager/helper'; -import { extname } from '../../core/utils/path'; -import { ExtraEventMethods } from '../../core/utils/jsb-utils' declare const jsb: any; @@ -41,18 +34,19 @@ declare const jsb: any; */ export type CreateNodeCallback = (error: Error | null, node: Node) => void; -applyMixins(jsb.Asset, [CallbacksInvoker, ExtraEventMethods]); +applyMixins(jsb.Asset, [CallbacksInvoker, jsbUtils.ExtraEventMethods]); const assetProto: any = jsb.Asset.prototype; assetProto._ctor = function () { + this.loaded = true; // deprecated in v3.3 this._ref = 0; this.__nativeRefs = {}; this.__jsb_ref_id = undefined; this._iN$t = null; this.__editorExtras__ = { editorOnly: true }; - this._callbackTable = createMap(true); + this._callbackTable = js.createMap(true); this._file = null; // for deserialization // _initializerDefineProperty(_this, "_native", _descriptor$1, _assertThisInitialized(_this)); @@ -82,7 +76,7 @@ Object.defineProperty (assetProto, 'nativeUrl', { this._nativeUrl = getUrlWithUuid(this._uuid, { nativeExt: name, isNative: true }); } else { // imported in an independent dir - this._nativeUrl = getUrlWithUuid(this._uuid, { __nativeName__: name, nativeExt: extname(name), isNative: true }); + this._nativeUrl = getUrlWithUuid(this._uuid, { __nativeName__: name, nativeExt: path.extname(name), isNative: true }); } } return this._nativeUrl; @@ -109,7 +103,7 @@ assetProto.decRef = function (autoRelease = true): Asset { this._ref--; } if (autoRelease) { - legacyCC.assetManager._releaseManager.tryRelease(this); + cclegacy.assetManager._releaseManager.tryRelease(this); } return this; }; @@ -124,11 +118,11 @@ assetProto.createNode = null!; export type Asset = jsb.Asset; export const Asset = jsb.Asset; -legacyCC.Asset = jsb.Asset; +cclegacy.Asset = jsb.Asset; // handle meta data, it is generated automatically const AssetProto = Asset.prototype; -serializable(AssetProto, '_native'); +serializable(AssetProto, '_native', () => ''); const _nativeAssetDescriptor = Object.getOwnPropertyDescriptor(AssetProto, '_nativeAsset'); -property(AssetProto, '_nativeAsset', _nativeAssetDescriptor); +_decorator.property(AssetProto, '_nativeAsset', _nativeAssetDescriptor); ccclass('cc.Asset')(Asset); diff --git a/cocos/asset/assets/asset.ts b/cocos/asset/assets/asset.ts index 32f548a040d..6455de041ac 100644 --- a/cocos/asset/assets/asset.ts +++ b/cocos/asset/assets/asset.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,16 +23,12 @@ THE SOFTWARE. */ -import { ccclass, serializable } from 'cc.decorator'; import { EDITOR, PREVIEW } from 'internal:constants'; -import { property } from '../../core/data/decorators/property'; +import { _decorator, Eventify, path, debug, getError, CCObject, cclegacy } from '../../core'; import { getUrlWithUuid } from '../asset-manager/helper'; -import { Eventify } from '../../core/event'; import { Node } from '../../scene-graph'; -import { legacyCC } from '../../core/global-exports'; -import { extname } from '../../core/utils/path'; -import { debug, getError } from '../../core/platform/debug'; -import { CCObject } from '../../core/data/object'; + +const { ccclass, serializable, property } = _decorator; /** * @en @@ -67,7 +62,7 @@ export class Asset extends Eventify(CCObject) { */ public static deserialize (data) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return legacyCC.deserialize(data); + return cclegacy.deserialize(data); } /** @@ -81,12 +76,24 @@ export class Asset extends Eventify(CCObject) { public loaded = true; /** - * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @en + * The UUID of this asset. + * + * @zh + * 资源的 UUID。 + * + * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future, please use [[Asset.uuid]] instead. */ public declare _uuid: string; /** - * @internal + * @en + * Indicates whether this asset is a default asset. + * + * @zh + * 表明此资源是否是默认资源。 + * + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. */ public declare isDefault: boolean; @@ -101,8 +108,14 @@ export class Asset extends Eventify(CCObject) { */ @serializable public _native = ''; + /** - * @internal + * @en + * Path to native dependency. + * @zh + * 原生依赖的路径。 + * + * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _nativeUrl = ''; @@ -111,9 +124,9 @@ export class Asset extends Eventify(CCObject) { /** * @en - * Returns the url of this asset's native object, if none it will returns an empty string. + * Returns the url of this asset's native object, will return an empty string if this asset does not have any native dependency. * @zh - * 返回该资源对应的目标平台资源的 URL,如果没有将返回一个空字符串。 + * 返回该资源对应的目标平台资源的 URL,如果此资源没有原生依赖将返回一个空字符串。 * @readOnly */ get nativeUrl () { @@ -130,12 +143,23 @@ export class Asset extends Eventify(CCObject) { this._nativeUrl = getUrlWithUuid(this._uuid, { nativeExt: name, isNative: true }); } else { // imported in an independent dir - this._nativeUrl = getUrlWithUuid(this._uuid, { __nativeName__: name, nativeExt: extname(name), isNative: true }); + this._nativeUrl = getUrlWithUuid(this._uuid, { __nativeName__: name, nativeExt: path.extname(name), isNative: true }); } } return this._nativeUrl; } + /** + * @en + * The UUID of this asset. + * + * @zh + * 资源的 UUID。 + */ + get uuid () { + return this._uuid; + } + /** * @en * The underlying native asset of this asset if one is available.
@@ -193,7 +217,7 @@ export class Asset extends Eventify(CCObject) { * 否则,返回空字符串。
* 子类可能会覆盖此方法。 * @method toString - * @return {String} + * @returns @en String representation of this asset. @zh 此资源的字符串表示。 */ public toString () { return this.nativeUrl; @@ -204,7 +228,7 @@ export class Asset extends Eventify(CCObject) { * 返回一个序列化后的对象 * * @method serialize - * @return {String} + * @returns {String} * @private */ public serialize () { } @@ -239,7 +263,15 @@ export class Asset extends Eventify(CCObject) { public createNode? (callback: CreateNodeCallback): void; /** - * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @en + * Get native dependency information. + * + * @zh + * 获取原生依赖信息。 + * + * @returns @en The native dependency information. @zh 原生依赖信息。 + * + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. */ public get _nativeDep () { if (this._native) { @@ -250,10 +282,10 @@ export class Asset extends Eventify(CCObject) { /** * @en - * The number of reference + * Current reference count to this asset. * * @zh - * 引用的数量 + * 当前该资源被引用的数量。 */ public get refCount (): number { return this._ref; @@ -261,12 +293,13 @@ export class Asset extends Eventify(CCObject) { /** * @en - * Add references of asset + * Increase the reference count. This will prevent assets from being automatically recycled. + * When you no longer need to hold the asset, you need to using [[decRef]] to decrease the refCount. * * @zh - * 增加资源的引用 + * 增加资源的引用。这将阻止资源被自动释放。当你不再需要持有该资源时,你需要调用 [[decRef]] 来减少引用计数。 * - * @return itself + * @returns @en The asset itself. @zh 此资源本身。 * */ public addRef (): Asset { @@ -276,12 +309,12 @@ export class Asset extends Eventify(CCObject) { /** * @en - * Reduce references of asset and it will be auto released when refCount equals 0. + * Decrease the reference count and it will be auto released when refCount equals 0. * * @zh - * 减少资源的引用并尝试进行自动释放。 + * 减少资源的引用,如果引用数量为 0,则将自动释放该资源。 * - * @return itself + * @return @en The asset itself. @zh 此资源本身。 * */ public decRef (autoRelease = true): Asset { @@ -289,22 +322,57 @@ export class Asset extends Eventify(CCObject) { this._ref--; } if (autoRelease) { - legacyCC.assetManager._releaseManager.tryRelease(this); + cclegacy.assetManager._releaseManager.tryRelease(this); } return this; } + /** + * @en + * A callback after the asset is loaded that you can use to initialize the asset's internal data. + * + * @zh + * 资源加载后的回调,你可以用于初始化资源的内部数据。 + * + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. + */ public onLoaded () {} + /** + * @en + * Initializes default asset. + * + * @zh + * 初始化为默认资源。 + * + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. + */ public initDefault (uuid?: string) { if (uuid) { this._uuid = uuid; } this.isDefault = true; } + /** + * @en + * Used to verify this asset is an available asset. + * + * @zh + * 用于验证此资源是否为可用资源。 + * + * @returns @zh 是否是可用资源。@en Whether this asset is available or not. + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. + */ public validate (): boolean { return true; } + /** + * @en + * Destroy this asset and its internal data. + * + * @zh + * 销毁此资源以及其内部数据。 + */ public destroy () { debug(getError(12101, this._uuid)); return super.destroy(); @@ -319,4 +387,4 @@ type CreateNodeCallback = (error: Error | null, node: Node) => void; Asset.prototype.createNode = null!; -legacyCC.Asset = Asset; +cclegacy.Asset = Asset; diff --git a/cocos/asset/assets/buffer-asset.jsb.ts b/cocos/asset/assets/buffer-asset.jsb.ts index e0174a4be8c..e62c491d058 100644 --- a/cocos/asset/assets/buffer-asset.jsb.ts +++ b/cocos/asset/assets/buffer-asset.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,13 +22,13 @@ THE SOFTWARE. */ import { ccclass, override } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import './asset'; export type BufferAsset = jsb.BufferAsset; export const BufferAsset = jsb.BufferAsset; -legacyCC.BufferAsset = jsb.BufferAsset; +cclegacy.BufferAsset = jsb.BufferAsset; // handle meta data, it is generated automatically const BufferAssetProto = BufferAsset.prototype; diff --git a/cocos/asset/assets/buffer-asset.ts b/cocos/asset/assets/buffer-asset.ts index 52bed97d78c..c22ac469ba8 100644 --- a/cocos/asset/assets/buffer-asset.ts +++ b/cocos/asset/assets/buffer-asset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,10 +23,16 @@ */ import { ccclass, override } from 'cc.decorator'; -import { assertIsNonNullable } from '../../core/data/utils/asserts'; -import { legacyCC } from '../../core/global-exports'; +import { assertIsNonNullable, cclegacy } from '../../core'; import { Asset } from './asset'; +/** + * @en + * `BufferAsset` is a kind of assets whose internal data is a section of memory buffer + * that you can access through the [[BufferAsset.buffer]] function. + * @zh + * `BufferAsset` 是一类资产,其内部数据是一段内存缓冲,你可以通过 [[BufferAsset.buffer]] 函数获取其内部数据。 + */ @ccclass('cc.BufferAsset') export class BufferAsset extends Asset { private _buffer: ArrayBuffer | null = null; @@ -58,8 +63,8 @@ export class BufferAsset extends Asset { } public validate () { - return !!this.buffer; + return !!this._buffer; } } -legacyCC.BufferAsset = BufferAsset; +cclegacy.BufferAsset = BufferAsset; diff --git a/cocos/asset/assets/deprecation.ts b/cocos/asset/assets/deprecation.ts index 851a0eb8eb6..658d5213820 100644 --- a/cocos/asset/assets/deprecation.ts +++ b/cocos/asset/assets/deprecation.ts @@ -1,29 +1,28 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import { removeProperty, replaceProperty } from '../../core/utils/x-deprecated'; +import { removeProperty, replaceProperty } from '../../core'; import { TextureBase } from './texture-base'; import { RenderTexture } from './render-texture'; diff --git a/cocos/asset/assets/effect-asset.jsb.ts b/cocos/asset/assets/effect-asset.jsb.ts index d18c7750bd5..ebe182c4d9b 100644 --- a/cocos/asset/assets/effect-asset.jsb.ts +++ b/cocos/asset/assets/effect-asset.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,13 +23,13 @@ */ import { ccclass, editable, editorOnly, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; +import{ cclegacy } from '../../core'; import './asset'; export type EffectAsset = jsb.EffectAsset; export const EffectAsset = jsb.EffectAsset; -legacyCC.EffectAsset = EffectAsset; +cclegacy.EffectAsset = EffectAsset; const effectAssetProto: any = EffectAsset.prototype; @@ -41,12 +40,12 @@ effectAssetProto._ctor = function () { // handle meta data, it is generated automatically const EffectAssetProto = EffectAsset.prototype; -editable(EffectAssetProto, 'techniques'); -serializable(EffectAssetProto, 'techniques'); -editable(EffectAssetProto, 'shaders'); -serializable(EffectAssetProto, 'shaders'); -editable(EffectAssetProto, 'combinations'); -serializable(EffectAssetProto, 'combinations'); -editorOnly(EffectAssetProto, 'hideInEditor'); -serializable(EffectAssetProto, 'hideInEditor'); +editable(EffectAssetProto, 'techniques', () => []); +serializable(EffectAssetProto, 'techniques', () => []); +editable(EffectAssetProto, 'shaders', () => []); +serializable(EffectAssetProto, 'shaders', () => []); +editable(EffectAssetProto, 'combinations', () => []); +serializable(EffectAssetProto, 'combinations', () => []); +editorOnly(EffectAssetProto, 'hideInEditor', () => false); +serializable(EffectAssetProto, 'hideInEditor', () => false); ccclass('cc.EffectAsset')(EffectAsset); diff --git a/cocos/asset/assets/effect-asset.ts b/cocos/asset/assets/effect-asset.ts index 8415bb6bb71..4b582464828 100644 --- a/cocos/asset/assets/effect-asset.ts +++ b/cocos/asset/assets/effect-asset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,8 +31,9 @@ import { RenderPassStage } from '../../rendering/define'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { programLib } from '../../render-scene/core/program-lib'; import { Asset } from './asset'; -import { legacyCC } from '../../core/global-exports'; -import { warnID } from '../../core/platform/debug'; +import { cclegacy, warnID } from '../../core'; +import { ProgramLibrary } from '../../rendering/custom/private'; +import { addEffectDefaultProperties, getCombinationDefines } from '../../render-scene/core/program-utils'; export declare namespace EffectAsset { export interface IPropertyInfo { @@ -53,6 +53,7 @@ export declare namespace EffectAsset { blendState?: BlendState; dynamicStates?: DynamicStateFlags; phase?: string | number; + pass?: string; } export interface IPassInfo extends IPassStates { program: string; // auto-generated from 'vert' and 'frag' @@ -144,6 +145,16 @@ export declare namespace EffectAsset { samplerTextures: IBuiltin[]; images: IBuiltin[]; } + export interface IDescriptorInfo { + rate: number; + blocks: IBlockInfo[]; + samplerTextures: ISamplerTextureInfo[]; + samplers: ISamplerInfo[]; + textures: ITextureInfo[]; + buffers: IBufferInfo[]; + images: IImageInfo[]; + subpassInputs: IInputAttachmentInfo[]; + } export interface IShaderInfo { name: string; hash: number; @@ -160,6 +171,7 @@ export declare namespace EffectAsset { buffers: IBufferInfo[]; images: IImageInfo[]; subpassInputs: IInputAttachmentInfo[]; + descriptors: IDescriptorInfo[]; } export interface IPreCompileInfo { [name: string]: boolean[] | number[] | string[]; @@ -199,8 +211,10 @@ const legacyBuiltinEffectNames = [ @ccclass('cc.EffectAsset') export class EffectAsset extends Asset { /** - * @en Register the effect asset to the static map + * @en Register the effect asset to the static map. * @zh 将指定 effect 注册到全局管理器。 + * + * @param asset @en The effect asset to be registered. @zh 待注册的 effect asset。 */ public static register (asset: EffectAsset) { EffectAsset._effects[asset.name] = asset; @@ -210,6 +224,8 @@ export class EffectAsset extends Asset { /** * @en Unregister the effect asset from the static map * @zh 将指定 effect 从全局管理器移除。 + * + * @param asset - @en The effect asset to be removed. @zh 待移除的 effect asset。 */ public static remove (asset: EffectAsset | string) { if (typeof asset !== 'string') { @@ -228,8 +244,11 @@ export class EffectAsset extends Asset { } /** - * @en Get the effect asset by the given name. + * @en Gets the effect asset by the given name. * @zh 获取指定名字的 effect 资源。 + * + * @param name - @en The name of effect you want to get. @zh 想要获取的 effect 的名字。 + * @returns @en The effect. @zh 你查询的 effect. */ public static get (name: string) { if (EffectAsset._effects[name]) { return EffectAsset._effects[name]; } @@ -245,14 +264,28 @@ export class EffectAsset extends Asset { } /** - * @en Get all registered effect assets. + * @en Gets all registered effect assets. * @zh 获取所有已注册的 effect 资源。 + * @returns @en All registered effects. @zh 所有已注册的 effect 资源。 */ public static getAll () { return EffectAsset._effects; } + + /** + * @engineInternal + */ protected static _effects: Record = {}; + /** + * @engineInternal + */ public static isLayoutValid (): boolean { return EffectAsset._layoutValid; } + /** + * @engineInternal + */ public static setLayoutValid (): void { EffectAsset._layoutValid = true; } + /** + * @engineInternal + */ protected static _layoutValid = true; /** @@ -279,35 +312,45 @@ export class EffectAsset extends Asset { @editable public combinations: EffectAsset.IPreCompileInfo[] = []; + /** + * @en Whether to hide in editor mode. + * @zh 是否在编辑器内隐藏。 + */ @serializable @editorOnly public hideInEditor = false; /** - * @en The loaded callback which should be invoked by the [[CCLoader]], will automatically register the effect. - * @zh 通过 [[CCLoader]] 加载完成时的回调,将自动注册 effect 资源。 + * @en The loaded callback which should be invoked by the [[AssetManager]], will automatically register the effect. + * @zh 通过 [[AssetManager]] 加载完成时的回调,将自动注册 effect 资源。 */ public onLoaded () { - programLib.register(this); + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + addEffectDefaultProperties(this); + (cclegacy.rendering.programLib as ProgramLibrary).addEffect(this); + } else { + programLib.register(this); + } EffectAsset.register(this); - if (!EDITOR || legacyCC.GAME_VIEW) { legacyCC.game.once(legacyCC.Game.EVENT_RENDERER_INITED, this._precompile, this); } + if (!EDITOR || cclegacy.GAME_VIEW) { cclegacy.game.once(cclegacy.Game.EVENT_RENDERER_INITED, this._precompile, this); } } + /** + * @engineInternal + */ protected _precompile () { - const root = legacyCC.director.root as Root; + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + (cclegacy.rendering.programLib as ProgramLibrary).precompileEffect(deviceManager.gfxDevice, this); + return; + } + const root = cclegacy.director.root as Root; for (let i = 0; i < this.shaders.length; i++) { const shader = this.shaders[i]; const combination = this.combinations[i]; - if (!combination) { continue; } - const defines = Object.keys(combination).reduce((out, name) => out.reduce((acc, cur) => { - const choices = combination[name]; - for (let i = 0; i < choices.length; ++i) { - const defines = { ...cur }; - defines[name] = choices[i]; - acc.push(defines); - } - return acc; - }, [] as MacroRecord[]), [{}] as MacroRecord[]); + if (!combination) { + continue; + } + const defines = getCombinationDefines(combination); defines.forEach( (defines) => programLib.getGFXShader(deviceManager.gfxDevice, shader.name, defines, root.pipeline), ); @@ -333,4 +376,4 @@ export class EffectAsset extends Asset { } } -legacyCC.EffectAsset = EffectAsset; +cclegacy.EffectAsset = EffectAsset; diff --git a/cocos/asset/assets/image-asset.jsb.ts b/cocos/asset/assets/image-asset.jsb.ts index b43273bd787..de0cffc1042 100644 --- a/cocos/asset/assets/image-asset.jsb.ts +++ b/cocos/asset/assets/image-asset.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,15 +24,13 @@ import { ccclass, override } from 'cc.decorator'; import { ALIPAY, XIAOMI, JSB, TEST, BAIDU } from 'internal:constants'; import { Format, FormatFeatureBit, deviceManager } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; import { PixelFormat } from './asset-enum'; -import { sys } from '../../core/platform/sys'; -import { macro } from '../../core/platform/macro'; -import { warnID } from '../../core/platform/debug'; +import { sys, macro, warnID, cclegacy } from '../../core'; import './asset'; export type ImageAsset = jsb.ImageAsset; export const ImageAsset = jsb.ImageAsset; +const jsbWindow = jsb.window; export interface IMemoryImageSource { _data: ArrayBufferView | null; @@ -41,6 +38,7 @@ export interface IMemoryImageSource { width: number; height: number; format: number; + mipmapLevelDataSize?: number[]; } export type ImageSource = HTMLCanvasElement | HTMLImageElement | IMemoryImageSource | ImageBitmap; @@ -60,7 +58,7 @@ function isNativeImage (imageSource: ImageSource): imageSource is (HTMLImageElem return false; } - return imageSource instanceof HTMLImageElement || imageSource instanceof HTMLCanvasElement || isImageBitmap(imageSource); + return imageSource instanceof jsbWindow.HTMLImageElement || imageSource instanceof jsbWindow.HTMLCanvasElement || isImageBitmap(imageSource); } const imageAssetProto = ImageAsset.prototype; @@ -75,6 +73,7 @@ imageAssetProto._ctor = function (nativeAsset?: ImageSource) { height: 0, format: 0, _compressed: false, + mipmapLevelDataSize:[], }; if (nativeAsset !== undefined) { @@ -89,7 +88,7 @@ Object.defineProperty(imageAssetProto, '_nativeAsset', { return this._nativeData; }, set (value: ImageSource) { - if (!(value instanceof HTMLElement) && !isImageBitmap(value)) { + if (!(value instanceof jsbWindow.HTMLElement) && !isImageBitmap(value)) { // @ts-expect-error internal API usage value.format = value.format || this.format; } @@ -117,19 +116,22 @@ imageAssetProto._setRawAsset = function (filename: string, inLibrary = true) { } }; + imageAssetProto.reset = function (data: ImageSource) { this._nativeData = data; - if (!(data instanceof HTMLElement)) { + if (!(data instanceof jsbWindow.HTMLElement)) { // @ts-expect-error internal api usage - this.format = data.format; + if(data.format !== undefined) { + this.format = (data as any).format; + } } this._syncDataToNative(); }; const superDestroy = jsb.Asset.prototype.destroy; imageAssetProto.destroy = function () { - if(this.data && this.data instanceof HTMLImageElement) { + if(this.data && this.data instanceof jsbWindow.HTMLImageElement) { this.data.src = ''; this._setRawAsset(''); this.data.destroy(); @@ -164,14 +166,24 @@ imageAssetProto._syncDataToNative = function () { this.setHeight(this._height); this.url = this.nativeUrl; - if (data instanceof HTMLCanvasElement) { + if (data instanceof jsbWindow.HTMLCanvasElement) { this.setData(data._data.data); } - else if (data instanceof HTMLImageElement) { + else if (data instanceof jsbWindow.HTMLImageElement) { this.setData(data._data); + if (data._mipmapLevelDataSize){ + this.setMipmapLevelDataSize(data._mipmapLevelDataSize); + } } else { + if(!this._nativeData._data){ + console.error(`[ImageAsset] setData bad argument ${this._nativeData}`); + return; + } this.setData(this._nativeData._data); + if (this._nativeData.mipmapLevelDataSize) { + this.setMipmapLevelDataSize(this._nativeData.mipmapLevelDataSize); + } } }; @@ -258,7 +270,7 @@ imageAssetProto._deserialize = function (data: any) { } }; -legacyCC.ImageAsset = jsb.ImageAsset; +cclegacy.ImageAsset = jsb.ImageAsset; // handle meta data, it is generated automatically const ImageAssetProto = ImageAsset.prototype; diff --git a/cocos/asset/assets/image-asset.ts b/cocos/asset/assets/image-asset.ts index 1551baee702..7620011c450 100644 --- a/cocos/asset/assets/image-asset.ts +++ b/cocos/asset/assets/image-asset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,14 +24,115 @@ // @ts-check import { ccclass, override } from 'cc.decorator'; -import { EDITOR, ALIPAY, XIAOMI, JSB, TEST, BAIDU } from 'internal:constants'; +import { EDITOR, ALIPAY, XIAOMI, JSB, TEST, BAIDU, TAOBAO } from 'internal:constants'; import { Device, Format, FormatFeatureBit, deviceManager } from '../../gfx'; import { Asset } from './asset'; import { PixelFormat } from './asset-enum'; -import { legacyCC } from '../../core/global-exports'; -import { warnID } from '../../core/platform/debug'; -import { macro } from '../../core/platform/macro'; -import { sys } from '../../core/platform/sys'; +import { warnID, macro, sys, cclegacy } from '../../core'; +import { ccwindow } from '../../core/global-exports'; +import { Enum } from '../../core/value-types/enum'; + +// Compress mipmap constants +const COMPRESSED_HEADER_LENGTH = 4; +const COMPRESSED_MIPMAP_DATA_SIZE_LENGTH = 4; +const COMPRESSED_MIPMAP_LEVEL_COUNT_LENGTH = 4; +const COMPRESSED_MIPMAP_MAGIC = 0x50494d43; + +export const compressType = Enum({ + PVR: 0, + PKM: 1, + ASTC: 2, +}); + +// PVR constants // +// https://github.com/toji/texture-tester/blob/master/js/webgl-texture-util.js#L424 +const PVR_HEADER_LENGTH = 13; // The header length in 32 bit ints. +const PVR_MAGIC = 0x03525650; // 0x50565203; + +// Offsets into the header array. +const PVR_HEADER_MAGIC = 0; +const PVR_HEADER_FORMAT = 2; +const PVR_HEADER_HEIGHT = 6; +const PVR_HEADER_WIDTH = 7; +const PVR_HEADER_MIPMAPCOUNT = 11; +const PVR_HEADER_METADATA = 12; + +// ETC constants // +const ETC_PKM_HEADER_LENGTH = 16; + +const ETC_PKM_FORMAT_OFFSET = 6; +const ETC_PKM_ENCODED_WIDTH_OFFSET = 8; +const ETC_PKM_ENCODED_HEIGHT_OFFSET = 10; +const ETC_PKM_WIDTH_OFFSET = 12; +const ETC_PKM_HEIGHT_OFFSET = 14; + +const ETC1_RGB_NO_MIPMAPS = 0; +const ETC2_RGB_NO_MIPMAPS = 1; +const ETC2_RGBA_NO_MIPMAPS = 3; + +//= ==============// +// ASTC constants // +//= ==============// + +// struct astc_header +// { +// uint8_t magic[4]; +// uint8_t blockdim_x; +// uint8_t blockdim_y; +// uint8_t blockdim_z; +// uint8_t xsize[3]; // x-size = xsize[0] + xsize[1] + xsize[2] +// uint8_t ysize[3]; // x-size, y-size and z-size are given in texels; +// uint8_t zsize[3]; // block count is inferred +// }; +const ASTC_MAGIC = 0x5CA1AB13; + +const ASTC_HEADER_LENGTH = 16; // The header length +const ASTC_HEADER_MAGIC = 4; +const ASTC_HEADER_BLOCKDIM = 3; + +const ASTC_HEADER_SIZE_X_BEGIN = 7; +const ASTC_HEADER_SIZE_Y_BEGIN = 10; +const ASTC_HEADER_SIZE_Z_BEGIN = 13; + +function getASTCFormat (xdim, ydim) { + if (xdim === 4) { + return PixelFormat.RGBA_ASTC_4x4; + } if (xdim === 5) { + if (ydim === 4) { + return PixelFormat.RGBA_ASTC_5x4; + } + return PixelFormat.RGBA_ASTC_5x5; + } if (xdim === 6) { + if (ydim === 5) { + return PixelFormat.RGBA_ASTC_6x5; + } + return PixelFormat.RGBA_ASTC_6x6; + } if (xdim === 8) { + if (ydim === 5) { + return PixelFormat.RGBA_ASTC_8x5; + } if (ydim === 6) { + return PixelFormat.RGBA_ASTC_8x6; + } + return PixelFormat.RGBA_ASTC_8x8; + } if (xdim === 10) { + if (ydim === 5) { + return PixelFormat.RGBA_ASTC_10x5; + } if (ydim === 6) { + return PixelFormat.RGBA_ASTC_10x6; + } if (ydim === 8) { + return PixelFormat.RGBA_ASTC_10x8; + } + return PixelFormat.RGBA_ASTC_10x10; + } + if (ydim === 10) { + return PixelFormat.RGBA_ASTC_12x10; + } + return PixelFormat.RGBA_ASTC_12x12; +} + +function readBEUint16 (header, offset: number) { + return (header[offset] << 8) | header[offset + 1]; +} /** * @en Image source in memory @@ -44,6 +144,7 @@ export interface IMemoryImageSource { width: number; height: number; format: number; + mipmapLevelDataSize?: number[]; } /** @@ -62,7 +163,7 @@ function fetchImageSource (imageSource: ImageSource) { // 返回该图像源是否是平台提供的图像对象。 function isNativeImage (imageSource: ImageSource): imageSource is (HTMLImageElement | HTMLCanvasElement | ImageBitmap) { - if (ALIPAY || XIAOMI || BAIDU) { + if (ALIPAY || TAOBAO || XIAOMI || BAIDU) { // We're unable to grab the constructors of Alipay native image or canvas object. return !('_data' in imageSource); } @@ -74,11 +175,287 @@ function isNativeImage (imageSource: ImageSource): imageSource is (HTMLImageElem } /** - * @en Image Asset. - * @zh 图像资源。 + * @en Image Asset. The image resource stores the raw data of the image and you can use this resource to create any Texture resource. + * @zh 图像资源。图像资源存储了图像的原始数据,你可以使用此资源来创建任意 [[TextureBase]] 资源。 */ @ccclass('cc.ImageAsset') export class ImageAsset extends Asset { + /** + * mergeCompressedTextureMips + * ************* hearder *************** + * COMPRESSED_MAGIC: 0x50494d43 * + * ************* document ************** + * chunkCount: n * + * chunkDataSize[0]: xxx * + * ... * + * chunkDataSize[n - 1]: xxx * + * ************* chunks **************** + * ****************************** * + * * * * + * * chunk[0] * * + * * * * + * ****************************** * + * ... + * ****************************** * + * * * * + * * chunk[n - 1] * * + * * * * + * ****************************** * + * ************************************* + * @param files @zh 压缩纹理数组。 @en Compressed Texture Arrays. + * @returns out @zh 合并后的压缩纹理数据。 @en Merged compressed texture data. + */ + public static mergeCompressedTextureMips (files: ArrayBuffer[] | ArrayBufferView[]) { + let out = new Uint8Array(0); + + let err: Error | null = null; + try { + // Create compressed file + // file header length + const fileHeaderLength = COMPRESSED_HEADER_LENGTH + COMPRESSED_MIPMAP_LEVEL_COUNT_LENGTH + files.length * COMPRESSED_MIPMAP_DATA_SIZE_LENGTH; + let fileLength = 0; + for (const file of files) { + fileLength += file.byteLength; + } + fileLength += fileHeaderLength; // add file header length + out = new Uint8Array(fileLength); + const outView = new DataView( + out.buffer, + out.byteOffset, + out.byteLength, + ); + + // Append compresssed header + outView.setUint32(0, COMPRESSED_MIPMAP_MAGIC, true); // add magic + outView.setUint32(COMPRESSED_HEADER_LENGTH, files.length, true); // add count number + let dataOffset = fileHeaderLength; + for (let i = 0; i < files.length; i++) { + const file = files[i]; + outView.setUint32(COMPRESSED_HEADER_LENGTH + COMPRESSED_MIPMAP_LEVEL_COUNT_LENGTH + i * COMPRESSED_MIPMAP_DATA_SIZE_LENGTH, + file.byteLength, true); //add file data size + + // Append compresssed file + if (file instanceof ArrayBuffer) { + const srcArray = new Uint8Array(file); + out.set(srcArray, dataOffset); + } else { + const srcArray = new Uint8Array(file.buffer, file.byteOffset, file.byteLength); + out.set(srcArray, dataOffset); + } + dataOffset += file.byteLength; + } + } catch (e) { + err = e as Error; + console.warn(err); + } + + return out; + } + + /** + * @param file 解析压缩纹理。 + * @param type 压缩纹理类型。 + * @engineInternal + */ + public static parseCompressedTextures (file: ArrayBuffer | ArrayBufferView, type: number) { + const out: IMemoryImageSource = { + _data: new Uint8Array(0), + _compressed: true, + width: 0, + height: 0, + format: 0, + mipmapLevelDataSize: [], + }; + + const buffer = file instanceof ArrayBuffer ? file : file.buffer; + const bufferView = new DataView(buffer); + // Get a view of the arrayBuffer that represents compress header. + const magicNumber = bufferView.getUint32(0, true); + // Do some sanity checks to make sure this is a valid compress file. + if (magicNumber === COMPRESSED_MIPMAP_MAGIC) { + // Get a view of the arrayBuffer that represents compress document. + const mipmapLevelNumber = bufferView.getUint32(COMPRESSED_HEADER_LENGTH, true); + const mipmapLevelDataSize = bufferView.getUint32(COMPRESSED_HEADER_LENGTH + COMPRESSED_MIPMAP_LEVEL_COUNT_LENGTH, true); + const fileHeaderByteLength = COMPRESSED_HEADER_LENGTH + COMPRESSED_MIPMAP_LEVEL_COUNT_LENGTH + + mipmapLevelNumber * COMPRESSED_MIPMAP_DATA_SIZE_LENGTH; + + // Get a view of the arrayBuffer that represents compress chunks. + ImageAsset.parseCompressedTexture(file, 0, fileHeaderByteLength, mipmapLevelDataSize, type, out); + let beginOffset = fileHeaderByteLength + mipmapLevelDataSize; + + for (let i = 1; i < mipmapLevelNumber; i++) { + const endOffset = bufferView.getUint32(COMPRESSED_HEADER_LENGTH + COMPRESSED_MIPMAP_LEVEL_COUNT_LENGTH + + i * COMPRESSED_MIPMAP_DATA_SIZE_LENGTH, true); + ImageAsset.parseCompressedTexture(file, i, beginOffset, endOffset, type, out); + beginOffset += endOffset; + } + } else { + ImageAsset.parseCompressedTexture(file, 0, 0, 0, type, out); + } + return out; + } + + /** + * @zh 解析压缩纹理。 + * @param file @zh 压缩纹理原始数据。 + * @param levelIndex @zh 当前 mipmap 层级。 + * @param beginOffset @zh 压缩纹理开始时的偏移。 + * @param endOffset @zh 压缩纹理结束时的偏移。 + * @param type @zh 压缩纹理类型。 + * @param out @zh 压缩纹理输出。 + * @engineInternal + */ + public static parseCompressedTexture (file: ArrayBuffer | ArrayBufferView, levelIndex: number, + beginOffset: number, endOffset: number, type: number, out: IMemoryImageSource) { + switch (type) { + case compressType.PVR: + ImageAsset.parsePVRTexture(file, levelIndex, beginOffset, endOffset, out); + break; + case compressType.PKM: + ImageAsset.parsePKMTexture(file, levelIndex, beginOffset, endOffset, out); + break; + case compressType.ASTC: + ImageAsset.parseASTCTexture(file, levelIndex, beginOffset, endOffset, out); + break; + default: + break; + } + } + + /** + * @zh 解析 PVR 格式的压缩纹理。 + * @param file @zh 压缩纹理原始数据。 + * @param levelIndex @zh 当前 mipmap 层级。 + * @param beginOffset @zh 压缩纹理开始时的偏移。 + * @param endOffset @zh 压缩纹理结束时的偏移。 + * @param out @zh 压缩纹理输出。 + * @engineInternal + */ + public static parsePVRTexture (file: ArrayBuffer | ArrayBufferView, levelIndex: number, + beginOffset: number, endOffset: number, out: IMemoryImageSource) { + const buffer = file instanceof ArrayBuffer ? file : file.buffer; + // Get a view of the arrayBuffer that represents the DDS header. + const header = new Int32Array(buffer, beginOffset, PVR_HEADER_LENGTH); + + // Do some sanity checks to make sure this is a valid DDS file. + if (header[PVR_HEADER_MAGIC] === PVR_MAGIC) { + // Gather other basic metrics and a view of the raw the DXT data. + const byteOffset = beginOffset + header[PVR_HEADER_METADATA] + 52; + const length = endOffset - header.byteLength; + if (endOffset > 0) { + const srcView = new Uint8Array(buffer, byteOffset, length); + const dstView = new Uint8Array(out._data!.byteLength + srcView.byteLength); + dstView.set(out._data as Uint8Array); + dstView.set(srcView, out._data!.byteLength); + out._data = dstView; + out.mipmapLevelDataSize![levelIndex] = length; + } else { + out._data = new Uint8Array(buffer, byteOffset); + } + out.width = levelIndex > 0 ? out.width : header[PVR_HEADER_WIDTH]; + out.height = levelIndex > 0 ? out.height : header[PVR_HEADER_HEIGHT]; + } else if (header[11] === 0x21525650) { + const byteOffset = beginOffset + header[0]; + const length = endOffset - header.byteLength; + if (endOffset > 0) { + const srcView = new Uint8Array(buffer, byteOffset, length); + const dstView = new Uint8Array(out._data!.byteLength + srcView.byteLength); + dstView.set(out._data as Uint8Array); + dstView.set(srcView, out._data!.byteLength); + out._data = dstView; + out.mipmapLevelDataSize![levelIndex] = length; + } else { + out._data = new Uint8Array(buffer, byteOffset); + } + out.width = levelIndex > 0 ? out.width : header[1]; + out.height = levelIndex > 0 ? out.height : header[2]; + } else { + throw new Error('Invalid magic number in PVR header'); + } + } + + /** + * @zh 解析 PKM 格式的压缩纹理。 + * @param file @zh 压缩纹理原始数据。 + * @param levelIndex @zh 当前 mipmap 层级。 + * @param beginOffset @zh 压缩纹理开始时的偏移。 + * @param endOffset @zh 压缩纹理结束时的偏移。 + * @param out @zh 压缩纹理输出。 + * @engineInternal + */ + public static parsePKMTexture (file: ArrayBuffer | ArrayBufferView, levelIndex: number, + beginOffset: number, endOffset: number, out: IMemoryImageSource) { + const buffer = file instanceof ArrayBuffer ? file : file.buffer; + const header = new Uint8Array(buffer, beginOffset, ETC_PKM_HEADER_LENGTH); + const format = readBEUint16(header, ETC_PKM_FORMAT_OFFSET); + if (format !== ETC1_RGB_NO_MIPMAPS && format !== ETC2_RGB_NO_MIPMAPS && format !== ETC2_RGBA_NO_MIPMAPS) { + throw new Error('Invalid magic number in ETC header'); + } + + const byteOffset = beginOffset + ETC_PKM_HEADER_LENGTH; + const length = endOffset - ETC_PKM_HEADER_LENGTH; + if (endOffset > 0) { + const srcView = new Uint8Array(buffer, byteOffset, length); + const dstView = new Uint8Array(out._data!.byteLength + srcView.byteLength); + dstView.set(out._data as Uint8Array); + dstView.set(srcView, out._data!.byteLength); + out._data = dstView; + out.mipmapLevelDataSize![levelIndex] = length; + } else { + out._data = new Uint8Array(buffer, byteOffset); + } + out.width = levelIndex > 0 ? out.width : readBEUint16(header, ETC_PKM_WIDTH_OFFSET); + out.height = levelIndex > 0 ? out.height : readBEUint16(header, ETC_PKM_HEIGHT_OFFSET); + } + + /** + * @zh 解析 ASTC 格式的压缩纹理。 + * @param file @zh 压缩纹理原始数据。 + * @param levelIndex @zh 当前 mipmap 层级。 + * @param beginOffset @zh 压缩纹理开始时的偏移。 + * @param endOffset @zh 压缩纹理结束时的偏移。 + * @param out @zh 压缩纹理输出。 + * @engineInternal + */ + public static parseASTCTexture (file: ArrayBuffer | ArrayBufferView, levelIndex: number, + beginOffset: number, endOffset: number, out: IMemoryImageSource) { + const buffer = file instanceof ArrayBuffer ? file : file.buffer; + const header = new Uint8Array(buffer, beginOffset, ASTC_HEADER_LENGTH); + + const magicval = header[0] + (header[1] << 8) + (header[2] << 16) + (header[3] << 24); + if (magicval !== ASTC_MAGIC) { + throw new Error('Invalid magic number in ASTC header'); + } + + const xdim = header[ASTC_HEADER_MAGIC]; + const ydim = header[ASTC_HEADER_MAGIC + 1]; + const zdim = header[ASTC_HEADER_MAGIC + 2]; + if ((xdim < 3 || xdim > 6 || ydim < 3 || ydim > 6 || zdim < 3 || zdim > 6) + && (xdim < 4 || xdim === 7 || xdim === 9 || xdim === 11 || xdim > 12 + || ydim < 4 || ydim === 7 || ydim === 9 || ydim === 11 || ydim > 12 || zdim !== 1)) { + throw new Error('Invalid block number in ASTC header'); + } + + const format = getASTCFormat(xdim, ydim); + const byteOffset = beginOffset + ASTC_HEADER_LENGTH; + const length = endOffset - ASTC_HEADER_LENGTH; + if (endOffset > 0) { + const srcView = new Uint8Array(buffer, byteOffset, length); + const dstView = new Uint8Array(out._data!.byteLength + srcView.byteLength); + dstView.set(out._data as Uint8Array); + dstView.set(srcView, out._data!.byteLength); + out._data = dstView; + out.mipmapLevelDataSize![levelIndex] = length; + } else { + out._data = new Uint8Array(buffer, byteOffset); + } + out.width = levelIndex > 0 ? out.width : header[ASTC_HEADER_SIZE_X_BEGIN] + (header[ASTC_HEADER_SIZE_X_BEGIN + 1] << 8) + + (header[ASTC_HEADER_SIZE_X_BEGIN + 2] << 16); + out.height = levelIndex > 0 ? out.height : header[ASTC_HEADER_SIZE_Y_BEGIN] + (header[ASTC_HEADER_SIZE_Y_BEGIN + 1] << 8) + + (header[ASTC_HEADER_SIZE_Y_BEGIN + 2] << 16); + out.format = format; + } + /** * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ @@ -140,6 +517,15 @@ export class ImageAsset extends Asset { || (this._format >= PixelFormat.RGB_A_PVRTC_2BPPV1 && this._format <= PixelFormat.RGBA_ETC1); } + /** + * @en If this image resource is a mipmap, get the data size of each layer + * @zh 此图像资源是 mipmap 时,获取每层数据大小。 + * @engineInternal + */ + get mipmapLevelDataSize (): number[] | undefined { + return (this._nativeData as IMemoryImageSource).mipmapLevelDataSize; + } + /** * @en The original source image URL, it could be empty. * @zh 此图像资源的原始图像源的 URL。当原始图像元不是 HTML 文件时可能为空。 @@ -170,6 +556,7 @@ export class ImageAsset extends Asset { height: 0, format: 0, _compressed: false, + mipmapLevelDataSize: [], }; if (EDITOR) { @@ -184,7 +571,7 @@ export class ImageAsset extends Asset { /** * @en Reset the source of the image asset. * @zh 重置此图像资源使用的原始图像源。 - * @param data The new source + * @param data @en The new source. @zh 新的图片数据源。 */ public reset (data: ImageSource) { if (isImageBitmap(data)) { @@ -215,7 +602,7 @@ export class ImageAsset extends Asset { // SERIALIZATION /** - * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @engineInternal */ // eslint-disable-next-line consistent-return public _serialize () { @@ -244,7 +631,7 @@ export class ImageAsset extends Asset { } /** - * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @engineInternal */ public _deserialize (data: any) { let fmtStr = ''; @@ -304,7 +691,7 @@ export class ImageAsset extends Asset { public initDefault (uuid?: string) { super.initDefault(uuid); if (!ImageAsset._sharedPlaceHolderCanvas) { - const canvas = document.createElement('canvas'); + const canvas = ccwindow.document.createElement('canvas'); const context = canvas.getContext('2d')!; const l = canvas.width = canvas.height = 2; context.fillStyle = '#ff00ff'; @@ -324,4 +711,4 @@ export class ImageAsset extends Asset { function _getGlobalDevice (): Device | null { return deviceManager.gfxDevice; } -legacyCC.ImageAsset = ImageAsset; +cclegacy.ImageAsset = ImageAsset; diff --git a/cocos/asset/assets/index.jsb.ts b/cocos/asset/assets/index.jsb.ts index 5fdc8930b17..3518a821bc2 100644 --- a/cocos/asset/assets/index.jsb.ts +++ b/cocos/asset/assets/index.jsb.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,7 +27,6 @@ import './deprecation'; export { Asset } from './asset'; export { BufferAsset } from './buffer-asset'; -export { Prefab } from './prefab'; export * from './scripts'; export { RenderingSubMesh } from './rendering-sub-mesh'; export { SceneAsset } from './scene-asset'; diff --git a/cocos/asset/assets/index.ts b/cocos/asset/assets/index.ts index 8ce78e1716b..5d070e946e7 100644 --- a/cocos/asset/assets/index.ts +++ b/cocos/asset/assets/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,7 +27,6 @@ import './deprecation'; export { Asset } from './asset'; export { BufferAsset } from './buffer-asset'; -export { Prefab } from './prefab'; export * from './scripts'; export { RenderingSubMesh } from './rendering-sub-mesh'; export { SceneAsset } from './scene-asset'; diff --git a/cocos/asset/assets/json-asset.ts b/cocos/asset/assets/json-asset.ts index 096f55b23cf..2afb8edc08a 100644 --- a/cocos/asset/assets/json-asset.ts +++ b/cocos/asset/assets/json-asset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,7 +24,7 @@ import { ccclass, serializable, editable } from 'cc.decorator'; import { Asset } from './asset'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @en Json asset, it will automatically parse the json to a JS object. @@ -40,7 +39,7 @@ export default class JsonAsset extends Asset { */ @serializable @editable - public json: object | null = null; + public json: Record | null = null; } -legacyCC.JsonAsset = JsonAsset; +cclegacy.JsonAsset = JsonAsset; diff --git a/cocos/asset/assets/material.jsb.ts b/cocos/asset/assets/material.jsb.ts index bcbcc93170a..52c9fcacde7 100644 --- a/cocos/asset/assets/material.jsb.ts +++ b/cocos/asset/assets/material.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,11 +25,9 @@ import { EffectAsset } from './effect-asset'; import { Texture } from '../../gfx'; import { TextureBase } from './texture-base'; -import { legacyCC } from '../../core/global-exports'; -import { PassOverrides, MacroRecord, MaterialProperty } from '../../core/renderer'; - -import { Color, Mat3, Mat4, Quat, Vec2, Vec3, Vec4 } from '../../core/math'; -import { ccclass, serializable, type } from '../../core/data/decorators'; +import { PassOverrides, MacroRecord, MaterialProperty } from '../../render-scene'; +import { Color, Mat3, Mat4, Quat, Vec2, Vec3, Vec4, cclegacy } from '../../core'; +import { type, serializable, ccclass } from '../../core/data/decorators'; import './asset'; /** @@ -128,7 +125,7 @@ matProto.setProperty = function (name: string, val: MaterialPropertyFull | Mater } else if (first instanceof Texture) { wrapSetProperty(this.setPropertyGFXTextureArray, this, name, val, passIdx); } else { - legacyCC.error(`Material.setProperty Unknown type: ${val}`); + cclegacy.error(`Material.setProperty Unknown type: ${val}`); } } else if (typeof val === 'number') { if (Number.isInteger(val)) { @@ -162,7 +159,7 @@ matProto.setProperty = function (name: string, val: MaterialPropertyFull | Mater } } else { - legacyCC.error(`Material.setProperty Unknown type: ${val}`); + cclegacy.error(`Material.setProperty Unknown type: ${val}`); } }; @@ -223,6 +220,8 @@ matProto.getProperty = function (name: string, passIdx?: number) { } return arr || val; + } else if (val === null || val === undefined) { + return null; } let ret; @@ -258,7 +257,7 @@ matProto.getProperty = function (name: string, passIdx?: number) { // @ts-ignore export type Material = jsb.Material; export const Material = jsb.Material; -legacyCC.Material = Material; +cclegacy.Material = Material; const materialProto: any = Material.prototype; @@ -268,11 +267,6 @@ materialProto._ctor = function () { this._passes = []; this._registerPassesUpdatedListener(); - // _initializerDefineProperty(_this, "_effectAsset", _descriptor$d, _assertThisInitialized(_this)); - // _initializerDefineProperty(_this, "_techIdx", _descriptor2$9, _assertThisInitialized(_this)); - // _initializerDefineProperty(_this, "_defines", _descriptor3$7, _assertThisInitialized(_this)); - // _initializerDefineProperty(_this, "_states", _descriptor4$6, _assertThisInitialized(_this)); - // _initializerDefineProperty(_this, "_props", _descriptor5$4, _assertThisInitialized(_this)); this._isCtorCalled = true; }; @@ -303,9 +297,10 @@ Object.defineProperty(materialProto, 'passes', { // handle meta data, it is generated automatically const MaterialProto = Material.prototype; -type(EffectAsset)(MaterialProto, '_effectAsset'); -serializable(MaterialProto, '_techIdx'); -serializable(MaterialProto, '_defines'); -serializable(MaterialProto, '_states'); -serializable(MaterialProto, '_props'); +// @ts-expect-error +type(EffectAsset)(MaterialProto, '_effectAsset', () => null); +serializable(MaterialProto, '_techIdx', () => 0); +serializable(MaterialProto, '_defines', () => []); +serializable(MaterialProto, '_states', () => []); +serializable(MaterialProto, '_props', () => []); ccclass('cc.Material')(Material); diff --git a/cocos/asset/assets/material.ts b/cocos/asset/assets/material.ts index 28bfb93377e..ef14680e7ac 100644 --- a/cocos/asset/assets/material.ts +++ b/cocos/asset/assets/material.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,12 +27,9 @@ import { Asset } from './asset'; import { EffectAsset } from './effect-asset'; import { Texture, Type } from '../../gfx'; import { TextureBase } from './texture-base'; -import { legacyCC } from '../../core/global-exports'; import { IPassInfoFull, Pass, PassOverrides } from '../../render-scene/core/pass'; import { MacroRecord, MaterialProperty } from '../../render-scene/core/pass-utils'; -import { Color } from '../../core/math/color'; -import { warnID } from '../../core/platform/debug'; -import { Vec4 } from '../../core/math'; +import { Color, warnID, Vec4, cclegacy } from '../../core'; import { SRGBToLinear } from '../../rendering/pipeline-funcs'; import { Renderer } from '../../misc/renderer'; @@ -102,23 +98,44 @@ export class Material extends Asset { return hash; } + /** + * @engineInternal + */ @type(EffectAsset) protected _effectAsset: EffectAsset | null = null; + /** + * @internal + */ @serializable protected _techIdx = 0; + /** + * @internal + */ @serializable protected _defines: MacroRecord[] = []; + /** + * @internal + */ @serializable protected _states: PassOverrides[] = []; + /** + * @internal + */ @serializable protected _props: Record[] = []; + /** + * @internal + */ protected _passes: Pass[] = []; + /** + * @internal + */ protected _hash = 0; constructor () { @@ -166,16 +183,16 @@ export class Material extends Asset { } /** - * @en The parent material - * @zh 父材质 + * @en The parent material. + * @zh 父材质。 */ get parent (): Material | null { return null; } /** - * @en The owner render component - * @zh 该材质所归属的渲染组件 + * @en The owner render component. + * @zh 该材质所归属的渲染组件。 */ get owner (): Renderer | null { return null; @@ -184,7 +201,7 @@ export class Material extends Asset { /** * @en Initialize this material with the given information. * @zh 根据所给信息初始化这个材质,初始化正常结束后材质即可立即用于渲染。 - * @param info Material description info. + * @param info @en Material description info. @zh 材质描述信息 */ public initialize (info: IMaterialInfo) { if (this._passes.length) { @@ -199,6 +216,12 @@ export class Material extends Asset { this._update(); } + /** + * @en Reset the material with the given information. + * @zh 使用指定的信息重置该材质。 + * + * @param info @en Material description info. @zh 材质描述信息。 + */ public reset (info: IMaterialInfo) { // to be consistent with other assets this.initialize(info); } @@ -223,8 +246,8 @@ export class Material extends Asset { /** * @en Recompile the shader with the specified macro overrides. Allowed only on material instances. * @zh 使用指定预处理宏重新编译当前 pass(数组)中的 shader。只允许对材质实例执行。 - * @param overrides The shader macro override values. - * @param passIdx The pass to apply to. Will apply to all passes if not specified. + * @param overrides @en The shader macro override values. @zh 宏的覆盖值,用于编译不同 Shader 变体。 + * @param passIdx @en The pass to apply to. Will apply to all passes if not specified. @zh 要重编的 pass 索引,如果没有指定,则重编所有 pass。 */ public recompileShaders (overrides: MacroRecord, passIdx?: number) { console.warn(`Shaders in material asset '${this.name}' cannot be modified at runtime, please instantiate the material first.`); @@ -241,8 +264,8 @@ export class Material extends Asset { } /** - * @en Callback function after material is loaded in [[CCLoader]]. Initialize the resources automatically. - * @zh 通过 [[CCLoader]] 加载完成时的回调,将自动初始化材质资源。 + * @en Callback function after material is loaded in [[AssetManager]]. Initialize the resources automatically. + * @zh 通过 [[AssetManager]] 加载完成时的回调,将自动初始化材质资源。 */ public onLoaded () { this._update(); @@ -251,7 +274,7 @@ export class Material extends Asset { /** * @en Reset all the uniforms to the default value specified in [[EffectAsset]]. * @zh 重置材质的所有 uniform 参数数据为 [[EffectAsset]] 中的默认初始值。 - * @param clearPasses Will the rendering data be cleared too? + * @param clearPasses @en Whether to clear the rendering data too. @zh 是否同时清空渲染数据。 */ public resetUniforms (clearPasses = true) { this._props.length = this._passes.length; @@ -270,9 +293,11 @@ export class Material extends Asset { * @zh * 设置材质 uniform 参数的统一入口。
* 注意如果需要每帧更新 uniform,建议使用 [[renderer.Pass.setUniform]] 以获得更好的性能。 - * @param name The target uniform name. - * @param val The target value. - * @param passIdx The pass to apply to. Will apply to all passes if not specified. + * @param name @en The target uniform name. @zh 目标 Uniform 名称。 + * @param val @en The target value. @zh 需要设置的目标值。 + * @param passIdx + * @en The pass to apply to. Will apply to all passes if not specified. + * @zh 设置此属性的 pass 索引,如果没有指定,则会设置此属性到所有 pass 上。 */ public setProperty (name: string, val: MaterialPropertyFull | MaterialPropertyFull[], passIdx?: number) { let success = false; @@ -301,17 +326,20 @@ export class Material extends Asset { /** * @en - * Get the specified uniform value for this material.
+ * Gets the specified uniform value for this material.
* Note that only uniforms set through [[Material.setProperty]] can be acquired here.
* For the complete rendering data, use [[renderer.Pass.getUniform]] instead. * @zh * 获取当前材质的指定 uniform 参数的值。
* 注意只有通过 [[Material.setProperty]] 函数设置的参数才能从此函数取出,
* 如需取出完整的渲染数据,请使用 [[renderer.Pass.getUniform]]。 - * @param name The property or uniform name. - * @param passIdx The target pass index. If not specified, return the first found value in all passes. + * @param name @en The property or uniform name. @zh 属性或 Uniform 的名称。 + * @param passIdx + * @en The target pass index. If not specified, return the first found value in all passes. + * @zh 目标 pass 索引,如果没指定,则返回所有 pass 中第一个找到的值。 + * @return @en The acquired material properties. @zh 获取的材质属性。 */ - public getProperty (name: string, passIdx?: number) { + public getProperty (name: string, passIdx?: number): Readonly { if (passIdx === undefined) { // try get property in all possible passes const propsArray = this._props; const len = propsArray.length; @@ -330,8 +358,8 @@ export class Material extends Asset { /** * @en Copy the target material, with optional overrides. * @zh 复制目标材质到当前实例,允许提供重载信息。 - * @param mat The material to be copied. - * @param overrides The overriding states on top of the original material. + * @param mat @en The material to be copied. @zh 需要拷贝的原始材质。 + * @param overrides @en The overriding states on top of the original material. @zh 需要在原始材质上覆盖的状态。 */ public copy (mat: Material, overrides?: IMaterialInfo) { this._techIdx = mat._techIdx; @@ -352,6 +380,9 @@ export class Material extends Asset { this._update(); } + /** + * @engineInternal + */ protected _fillInfo (info: IMaterialInfo) { if (info.technique !== undefined) { this._techIdx = info.technique; } if (info.effectAsset) { @@ -363,6 +394,9 @@ export class Material extends Asset { if (info.states) { this._prepareInfo(info.states, this._states); } } + /** + * @engineInternal + */ protected _prepareInfo (patch: Record | Record[], cur: Record[]) { let patchArray = patch; if (!Array.isArray(patchArray)) { // fill all the passes if not specified @@ -374,6 +408,9 @@ export class Material extends Asset { } } + /** + * @engineInternal + */ protected _createPasses () { const tech = this._effectAsset!.techniques[this._techIdx || 0]; if (!tech) { return []; } @@ -391,13 +428,16 @@ export class Material extends Asset { Object.assign(defines, passInfo.embeddedMacros); } if (passInfo.switch && !defines[passInfo.switch]) { continue; } - const pass = new Pass(legacyCC.director.root); + const pass = new Pass(cclegacy.director.root); pass.initialize(passInfo); passes.push(pass); } return passes; } + /** + * @engineInternal + */ protected _update (keepProps = true) { if (this._effectAsset) { this._passes = this._createPasses(); @@ -422,6 +462,9 @@ export class Material extends Asset { this._hash = Material.getHash(this); } + /** + * @engineInternal + */ protected _uploadProperty (pass: Pass, name: string, val: MaterialPropertyFull | MaterialPropertyFull[]) { const handle = pass.getHandle(name); if (!handle) { return false; } @@ -452,6 +495,9 @@ export class Material extends Asset { return true; } + /** + * @engineInternal + */ protected _bindTexture (pass: Pass, handle: number, val: MaterialPropertyFull, index?: number) { const binding = Pass.getBindingFromHandle(handle); if (val instanceof Texture) { @@ -467,6 +513,9 @@ export class Material extends Asset { } } + /** + * @engineInternal + */ protected _doDestroy () { if (this._passes && this._passes.length) { for (const pass of this._passes) { @@ -491,4 +540,4 @@ export class Material extends Asset { } } -legacyCC.Material = Material; +cclegacy.Material = Material; diff --git a/cocos/asset/assets/prefab.jsb.ts b/cocos/asset/assets/prefab.jsb.ts deleted file mode 100644 index c621da472b7..00000000000 --- a/cocos/asset/assets/prefab.jsb.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. - - http://www.cocos.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ -import { ccclass, editable, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; -import { Enum } from '../../core/value-types'; -import './asset'; - -export const Prefab = jsb.Prefab; -export type Prefab = jsb.Prefab; - -const OptimizationPolicy = Enum({ - /** - * @en The optimization policy is automatically chosen based on the number of instantiations. - * When you first create an instance, the behavior is the same as SINGLE_INSTANCE. - * MULTI_INSTANCE will be automatically used after multiple creation. - * @zh 根据创建次数自动调整优化策略。初次创建实例时,行为等同 SINGLE_INSTANCE,多次创建后将自动采用 MULTI_INSTANCE。 - */ - AUTO: 0, - /** - * @en Optimize for single instance creation.
- * This option skips code generation for this prefab. - * When this prefab will usually create only one instances, please select this option. - * @zh 优化单次创建性能。
- * 该选项会跳过针对这个 prefab 的代码生成优化操作。当该 prefab 加载后,一般只会创建一个实例时,请选择此项。 - */ - SINGLE_INSTANCE: 1, - /** - * @en Optimize for creating instances multiple times.
- * This option enables code generation for this prefab. - * When this prefab will usually create multiple instances, please select this option. - * It is also recommended to select this option if the prefab instance in the scene - * has Auto Sync enabled and there are multiple instances in the scene. - * @zh 优化多次创建性能。
- * 该选项会启用针对这个 prefab 的代码生成优化操作。当该 prefab 加载后,一般会创建多个实例时,请选择此项。如果该 prefab 在场景中的节点启用了自动关联,并且在场景中有多份实例,也建议选择此项。 - */ - MULTI_INSTANCE: 2, -}); - -const prefabProto: any = Prefab.prototype; - -prefabProto._ctor = function () { - jsb.Asset.prototype._ctor.apply(this, arguments); - // _initializerDefineProperty(_this, 'data', _descriptor$v, _assertThisInitialized(_this)); - // _initializerDefineProperty(_this, 'optimizationPolicy', _descriptor2$o, _assertThisInitialized(_this)); -}; - -legacyCC.Prefab = Prefab; - -// handle meta data, it is generated automatically -const PrefabProto = Prefab.prototype; -editable(PrefabProto, 'data'); -serializable(PrefabProto, 'data'); -editable(PrefabProto, 'optimizationPolicy'); -serializable(PrefabProto, 'optimizationPolicy'); -editable(PrefabProto, 'persistent'); -serializable(PrefabProto, 'persistent'); -ccclass('cc.Prefab')(Prefab); diff --git a/cocos/asset/assets/render-texture.jsb.ts b/cocos/asset/assets/render-texture.jsb.ts index 6013b0be439..0b416023b4d 100644 --- a/cocos/asset/assets/render-texture.jsb.ts +++ b/cocos/asset/assets/render-texture.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,7 +23,7 @@ */ import { ccclass } from 'cc.decorator'; import { EDITOR, TEST } from 'internal:constants'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { Filter, PixelFormat, WrapMode } from './asset-enum'; import './asset'; @@ -74,7 +73,7 @@ renderTextureProto.readPixels = function readPixels (x: number, y: number, width return buffer; }; -legacyCC.RenderTexture = jsb.RenderTexture; +cclegacy.RenderTexture = jsb.RenderTexture; // handle meta data, it is generated automatically ccclass('cc.RenderTexture')(RenderTexture); diff --git a/cocos/asset/assets/render-texture.ts b/cocos/asset/assets/render-texture.ts index 93e6dda85ee..d18846da0b2 100644 --- a/cocos/asset/assets/render-texture.ts +++ b/cocos/asset/assets/render-texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,14 +24,11 @@ import { ccclass } from 'cc.decorator'; import { EDITOR, TEST } from 'internal:constants'; -import { clamp } from '../../core/math/utils'; -import { Texture, ColorAttachment, DepthStencilAttachment, GeneralBarrierInfo, AccessFlagBit, RenderPassInfo, Format, deviceManager } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; +import { clamp, cclegacy, errorID } from '../../core'; +import { Texture, ColorAttachment, DepthStencilAttachment, GeneralBarrierInfo, AccessFlagBit, RenderPassInfo, Format, deviceManager, BufferTextureCopy } from '../../gfx'; import { RenderWindow, IRenderWindowInfo } from '../../render-scene/core/render-window'; import { Root } from '../../root'; import { TextureBase } from './texture-base'; -import { BufferTextureCopy } from '../../gfx/base/define'; -import { errorID } from '../../core/platform/debug'; export interface IRenderTextureCreateInfo { name?: string; @@ -73,7 +69,7 @@ export class RenderTexture extends TextureBase { /** * @en Initialize the render texture. Using IRenderTextureCreateInfo. * @zh 初始化渲染贴图。设置渲染贴图的名称、尺寸、渲染通道信息。 - * @param info @en The create info of render texture @zh 渲染贴图的创建信息 + * @param info @en The create info of render texture. @zh 渲染贴图的创建信息。 */ public initialize (info: IRenderTextureCreateInfo) { this._name = info.name || ''; @@ -85,7 +81,7 @@ export class RenderTexture extends TextureBase { /** * @en Reset the render texture. User may change the name, size or render pass info of the render texture. * @zh 重新初始化渲染贴图。用户可以更改渲染贴图的名称、尺寸、渲染通道信息。 - * @param info @en The create info of render texture @zh 渲染贴图的创建信息 + * @param info @en The create info of render texture. @zh 渲染贴图的创建信息。 */ public reset (info: IRenderTextureCreateInfo) { // to be consistent with other assets this.initialize(info); @@ -97,7 +93,7 @@ export class RenderTexture extends TextureBase { */ public destroy () { if (this._window) { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; root?.destroyWindow(this._window); this._window = null; } @@ -106,10 +102,10 @@ export class RenderTexture extends TextureBase { } /** - * @en Resize the render texture - * @zh 修改渲染贴图的尺寸 - * @param width The pixel width, the range is from 1 to 2048 - * @param height The pixel height, the range is from 1 to 2048 + * @en Resize the render texture. + * @zh 修改渲染贴图的尺寸。 + * @param width @en The pixel width to resize to, the range is from 1 to 2048. @zh 需要调整到的像素宽度,范围为 1-2048。 + * @param height @en The pixel height to resize to, the range is from 1 to 2048. @zh 需要调整到的像素高度,范围为 1-2048。 */ public resize (width: number, height: number) { this._width = Math.floor(clamp(width, 1, 2048)); @@ -143,16 +139,17 @@ export class RenderTexture extends TextureBase { // To be compatible with material property interface /** - * @en Gets the related [[gfx.Texture]] resource, it's also the color attachment for the render window - * @zh 获取渲染贴图的 GFX 资源,同时也是渲染窗口所指向的颜色缓冲贴图资源 + * @en Gets the related [[gfx.Texture]] resource, it's also the color attachment for the render window. + * @zh 获取渲染贴图的 GFX 资源,同时也是渲染窗口所指向的颜色缓冲贴图资源。 + * @return @en The low level gfx texture. @zh 底层的 gfx 贴图。 */ public getGFXTexture (): Texture | null { return this._window && this._window.framebuffer.colorTextures[0]; } /** - * @en Callback function after render texture is loaded in [[CCLoader]]. Initialize the render texture. - * @zh 通过 [[CCLoader]] 加载完成时的回调,初始化渲染贴图。 + * @en Callback function after render texture is loaded in [[AssetManager]]. Initialize the render texture. + * @zh 通过 [[AssetManager]] 加载完成时的回调,初始化渲染贴图。 */ public onLoaded () { this._initWindow(); @@ -161,10 +158,11 @@ export class RenderTexture extends TextureBase { /** * @en Implementation of the render texture initialization. * @zh 初始化渲染贴图的具体实现。 - * @param info @en The create info of render texture @zh 渲染贴图的创建信息 + * @param info @en The create info of render texture. @zh 渲染贴图的创建信息。 + * @engineInternal */ protected _initWindow (info?: IRenderTextureCreateInfo) { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; _windowInfo.title = this._name; _windowInfo.width = this._width; @@ -186,8 +184,9 @@ export class RenderTexture extends TextureBase { /** * @en Initialize the render texture with uuid. The default size is 1x1. - * @zh 初始化渲染贴图。使用uuid进行初始化,贴图的尺寸为 1x1。 - * @param uuid @en asset uuid @zh 资源 uuid + * @zh 初始化渲染贴图。使用 uuid 进行初始化,贴图的尺寸为 1x1。 + * @param uuid @en asset uuid. @zh 资源 uuid。 + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. */ public initDefault (uuid?: string) { super.initDefault(uuid); @@ -198,20 +197,21 @@ export class RenderTexture extends TextureBase { /** * @en Validate the correctness of the render texture. * @zh 验证渲染贴图的正确性。 + * @deprecated Since v3.7, this is an internal engine interface and you should not call this interface under any circumstances. */ public validate () { return this.width >= 1 && this.width <= 2048 && this.height >= 1 && this.height <= 2048; } /** - * @en Read pixel buffer from render texture @zh 从 render texture 读取像素数据 - * @param x @en The location on x axis @zh 起始位置X轴坐标 - * @param y @en The location on y axis @zh 起始位置Y轴坐标 - * @param width @en The pixel width @zh 像素宽度 - * @param height @en The pixel height @zh 像素高度 - * @param buffer @en The buffer to hold pixel data @zh 像素缓存 + * @en Read pixel buffer from render texture. @zh 从 render texture 读取像素数据。 + * @param x @en The location on x axis. @zh 起始位置X轴坐标。 + * @param y @en The location on y axis. @zh 起始位置Y轴坐标。 + * @param width @en The pixel width. @zh 像素宽度。 + * @param height @en The pixel height. @zh 像素高度。 + * @param buffer @en The buffer to hold pixel data. @zh 像素缓存。 */ - public readPixels (x = 0, y = 0, width?: number, height?: number, buffer?: Uint8Array) : Uint8Array | null { + public readPixels (x = 0, y = 0, width?: number, height?: number, buffer?: Uint8Array): Uint8Array | null { width = width || this.width; height = height || this.height; const gfxTexture = this.getGFXTexture(); @@ -245,4 +245,4 @@ export class RenderTexture extends TextureBase { } } -legacyCC.RenderTexture = RenderTexture; +cclegacy.RenderTexture = RenderTexture; diff --git a/cocos/asset/assets/rendering-sub-mesh.jsb.ts b/cocos/asset/assets/rendering-sub-mesh.jsb.ts index 30ec78aaf32..1fbf56f9c29 100644 --- a/cocos/asset/assets/rendering-sub-mesh.jsb.ts +++ b/cocos/asset/assets/rendering-sub-mesh.jsb.ts @@ -1,4 +1,28 @@ -import { Vec3 } from "../../core/math"; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Vec3 } from "../../core"; import { Attribute, PrimitiveMode, Buffer } from "../../gfx"; /** diff --git a/cocos/asset/assets/rendering-sub-mesh.ts b/cocos/asset/assets/rendering-sub-mesh.ts index ec1982db9bd..d0aec9626b4 100644 --- a/cocos/asset/assets/rendering-sub-mesh.ts +++ b/cocos/asset/assets/rendering-sub-mesh.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,13 +22,12 @@ THE SOFTWARE. */ -import { legacyCC } from '../../core/global-exports'; import { mapBuffer } from '../../3d/misc/buffer'; import { Attribute, Device, InputAssemblerInfo, Buffer, BufferInfo, AttributeName, BufferUsageBit, Format, FormatInfos, MemoryUsageBit, PrimitiveMode, DrawInfo, } from '../../gfx'; -import { Vec3 } from '../../core/math'; +import { Vec3, cclegacy } from '../../core'; import { Mesh } from '../../3d/assets/mesh'; /** @@ -39,38 +37,38 @@ import { Mesh } from '../../3d/assets/mesh'; export type IBArray = Uint8Array | Uint16Array | Uint32Array; /** - * @en The interface of geometric information + * @en The interface of geometric information. * @zh 几何信息。 */ export interface IGeometricInfo { /** - * @en Vertex positions + * @en Vertex positions. * @zh 顶点位置。 */ positions: Float32Array; /** - * @en Indices data + * @en Indices data. * @zh 索引数据。 */ indices?: IBArray; /** - * @en Whether the geometry is treated as double sided + * @en Whether the geometry is treated as double sided. * @zh 是否将图元按双面对待。 */ doubleSided?: boolean; /** - * @en The bounding box + * @en The bounding box. * @zh 此几何体的轴对齐包围盒。 */ boundingBox: { max: Vec3 | Readonly; min: Vec3 | Readonly }; } /** - * @en Flat vertex buffer - * @zh 扁平化顶点缓冲区 + * @en Flat vertex buffer. + * @zh 扁平化顶点缓冲区。 */ export interface IFlatBuffer { stride: number; @@ -85,17 +83,17 @@ export interface IFlatBuffer { export class RenderingSubMesh { /** * @en - * mesh object where this sub mesh locates + * mesh object where this sub mesh locates. * @zh - * 子网格所处的网格模型对象 + * 子网格所处的网格模型对象。 */ public mesh?: Mesh; /** * @en - * sub mesh's index in mesh + * sub mesh's index in mesh. * @zh - * 子网格在网格模型中的索引 + * 子网格在网格模型中的索引。 */ public subMeshIdx?: number; @@ -127,14 +125,14 @@ export class RenderingSubMesh { /** * @en - * sub mesh's constructor + * sub mesh's constructor. * @zh - * 子网格构造函数 - * @param vertexBuffers @en vertex buffers @zh 顶点缓冲区数组 - * @param attributes @en vertex attributes @zh 顶点属性数组 - * @param primitiveMode @en primitive mode @zh 图元类型 - * @param indexBuffer @en index buffer @zh 索引缓冲区 - * @param indirectBuffer @en indirect buffer @zh 间接缓冲区 + * 子网格构造函数。 + * @param vertexBuffers @en vertex buffers. @zh 顶点缓冲区数组。 + * @param attributes @en vertex attributes. @zh 顶点属性数组。 + * @param primitiveMode @en primitive mode. @zh 图元类型。 + * @param indexBuffer @en index buffer. @zh 索引缓冲区。 + * @param indirectBuffer @en indirect buffer. @zh 间接缓冲区。 */ constructor ( vertexBuffers: Buffer[], attributes: Attribute[], primitiveMode: PrimitiveMode, @@ -151,31 +149,31 @@ export class RenderingSubMesh { } /** - * @en All vertex attributes used by the sub mesh + * @en All vertex attributes used by the sub mesh. * @zh 所有顶点属性。 */ get attributes () { return this._attributes; } /** - * @en All vertex buffers used by the sub mesh + * @en All vertex buffers used by the sub mesh. * @zh 使用的所有顶点缓冲区。 */ get vertexBuffers () { return this._vertexBuffers; } /** - * @en Index buffer used by the sub mesh + * @en Index buffer used by the sub mesh. * @zh 使用的索引缓冲区,若未使用则无需指定。 */ get indexBuffer () { return this._indexBuffer; } /** - * @en Indirect buffer used by the sub mesh + * @en Indirect buffer used by the sub mesh. * @zh 间接绘制缓冲区。 */ get indirectBuffer () { return this._indirectBuffer; } /** - * @en Primitive mode used by the sub mesh + * @en Primitive mode used by the sub mesh. * @zh 图元类型。 */ get primitiveMode () { return this._primitiveMode; } @@ -236,8 +234,8 @@ export class RenderingSubMesh { public invalidateGeometricInfo () { this._geometricInfo = undefined; } /** - * @en the draw range - * @zh 渲染范围 + * @en the draw range. + * @zh 渲染范围。 */ set drawInfo (info: DrawInfo | null | undefined) { this._drawInfo = info; @@ -248,13 +246,13 @@ export class RenderingSubMesh { } /** - * @en Flatted vertex buffers + * @en Flatted vertex buffers. * @zh 扁平化的顶点缓冲区。 */ get flatBuffers () { return this._flatBuffers; } /** - * @en generate flatted vertex buffers + * @en generate flatted vertex buffers. * @zh 生成扁平化的顶点缓冲区。 */ public genFlatBuffers () { @@ -294,7 +292,7 @@ export class RenderingSubMesh { } /** - * @en The vertex buffer for joint after mapping + * @en The vertex buffer for joint after mapping. * @zh 骨骼索引按映射表处理后的顶点缓冲。 */ get jointMappedBuffers () { @@ -309,7 +307,7 @@ export class RenderingSubMesh { } let jointFormat: Format; let jointOffset: number; - const { device } = legacyCC.director.root; + const { device } = cclegacy.director.root; for (let i = 0; i < prim.vertexBundelIndices.length; i++) { const bundle = struct.vertexBundles[prim.vertexBundelIndices[i]]; jointOffset = 0; @@ -346,14 +344,14 @@ export class RenderingSubMesh { } /** - * @en The input assembler info - * @zh 输入汇集器信息 + * @en The input assembler info. + * @zh 输入汇集器信息。 */ get iaInfo () { return this._iaInfo; } /** - * @en destroy sub mesh - * @zh 销毁子网格 + * @en Destroys sub mesh. + * @zh 销毁子网格。 */ public destroy () { for (let i = 0; i < this.vertexBuffers.length; i++) { diff --git a/cocos/asset/assets/scene-asset.jsb.ts b/cocos/asset/assets/scene-asset.jsb.ts index 203dab8853b..09b61dfe265 100644 --- a/cocos/asset/assets/scene-asset.jsb.ts +++ b/cocos/asset/assets/scene-asset.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,13 +22,13 @@ THE SOFTWARE. */ import { ccclass, editable, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import './asset'; export const SceneAsset = jsb.SceneAsset; export type SceneAsset = jsb.SceneAsset; -legacyCC.SceneAsset = SceneAsset; +cclegacy.SceneAsset = SceneAsset; const sceneAssetProto: any = SceneAsset.prototype; @@ -55,6 +54,6 @@ sceneAssetProto._ctor = function () { // handle meta data, it is generated automatically const SceneAssetProto = SceneAsset.prototype; -serializable(SceneAssetProto, 'scene'); -editable(SceneAssetProto, 'scene'); +serializable(SceneAssetProto, 'scene', () => null); +editable(SceneAssetProto, 'scene', () => null); ccclass('cc.SceneAsset')(SceneAsset); diff --git a/cocos/asset/assets/scene-asset.ts b/cocos/asset/assets/scene-asset.ts index 04a6d7d5322..967f4a57100 100644 --- a/cocos/asset/assets/scene-asset.ts +++ b/cocos/asset/assets/scene-asset.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,7 +26,7 @@ import { ccclass, editable, serializable } from 'cc.decorator'; import { Scene } from '../../scene-graph/scene'; import { Asset } from './asset'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @en Class for scene loading. @@ -54,4 +53,4 @@ export class SceneAsset extends Asset { } } -legacyCC.SceneAsset = SceneAsset; +cclegacy.SceneAsset = SceneAsset; diff --git a/cocos/asset/assets/scripts.ts b/cocos/asset/assets/scripts.ts index 108a204b298..6c99c16dd05 100644 --- a/cocos/asset/assets/scripts.ts +++ b/cocos/asset/assets/scripts.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ import { ccclass } from 'cc.decorator'; import { Asset } from './asset'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** * @en The script asset base class @@ -35,7 +34,7 @@ import { legacyCC } from '../../core/global-exports'; @ccclass('cc.Script') export class Script extends Asset { } -legacyCC._Script = Script; +cclegacy._Script = Script; /** * @en JavaScript asset. @@ -44,7 +43,7 @@ legacyCC._Script = Script; @ccclass('cc.JavaScript') export class JavaScript extends Script { } -legacyCC._JavaScript = JavaScript; +cclegacy._JavaScript = JavaScript; /** * @en TypeScript asset @@ -53,4 +52,4 @@ legacyCC._JavaScript = JavaScript; @ccclass('cc.TypeScript') export class TypeScript extends Script { } -legacyCC._TypeScript = TypeScript; +cclegacy._TypeScript = TypeScript; diff --git a/cocos/asset/assets/simple-texture.jsb.ts b/cocos/asset/assets/simple-texture.jsb.ts index c71eca30d3e..687541f1054 100644 --- a/cocos/asset/assets/simple-texture.jsb.ts +++ b/cocos/asset/assets/simple-texture.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,11 +22,9 @@ THE SOFTWARE. */ import { ccclass } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; import { Filter, PixelFormat, WrapMode } from './asset-enum'; -import { macro } from '../../core/platform/macro'; import dependUtil from '../asset-manager/depend-util'; -import { fastRemoveAt } from '../../core/utils/array'; +import { js, macro, cclegacy } from '../../core'; import './texture-base'; declare const jsb: any; @@ -36,6 +33,8 @@ declare const jsb: any; export type SimpleTexture = jsb.SimpleTexture; export const SimpleTexture: any = jsb.SimpleTexture; +const jsbWindow = jsb.window; + SimpleTexture.Filter = Filter; SimpleTexture.PixelFormat = PixelFormat; SimpleTexture.WrapMode = WrapMode; @@ -44,10 +43,10 @@ const simpleTextureProto = jsb.SimpleTexture.prototype; const oldUpdateDataFunc = simpleTextureProto.uploadData; simpleTextureProto.uploadData = function (source, level = 0, arrayIndex = 0) { let data; - if (source instanceof HTMLCanvasElement) { + if (source instanceof jsbWindow.HTMLCanvasElement) { // @ts-ignore data = source.data; - } else if (source instanceof HTMLImageElement) { + } else if (source instanceof jsbWindow.HTMLImageElement) { // @ts-ignore data = source._data; } else if (ArrayBuffer.isView(source)) { @@ -81,7 +80,7 @@ simpleTextureProto._onAfterAssignImage = function (image) { const deps = dependUtil.getDeps(this._uuid); const index = deps.indexOf(image._uuid); if (index !== -1) { - fastRemoveAt(deps, index); + js.array.fastRemoveAt(deps, index); image.decRef(); } } @@ -89,4 +88,4 @@ simpleTextureProto._onAfterAssignImage = function (image) { clsDecorator(SimpleTexture); -legacyCC.SimpleTexture = jsb.SimpleTexture; +cclegacy.SimpleTexture = jsb.SimpleTexture; diff --git a/cocos/asset/assets/simple-texture.ts b/cocos/asset/assets/simple-texture.ts index 31f97cac070..dfef7d0295f 100644 --- a/cocos/asset/assets/simple-texture.ts +++ b/cocos/asset/assets/simple-texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; import { DEV } from 'internal:constants'; import { TextureFlagBit, TextureUsageBit, API, Texture, TextureInfo, TextureViewInfo, Device, BufferTextureCopy } from '../../gfx'; -import { assertID, error } from '../../core/platform/debug'; +import { assertID, error, js, macro, cclegacy } from '../../core'; import { Filter } from './asset-enum'; import { ImageAsset } from './image-asset'; import { TextureBase } from './texture-base'; -import { legacyCC } from '../../core/global-exports'; -import { macro } from '../../core/platform/macro'; import dependUtil from '../asset-manager/depend-util'; -import { fastRemoveAt } from '../../core/utils/array'; const _regions: BufferTextureCopy[] = [new BufferTextureCopy()]; @@ -63,27 +59,40 @@ function canGenerateMipmap (device: Device, w: number, h: number) { */ @ccclass('cc.SimpleTexture') export class SimpleTexture extends TextureBase { + /** + * @engineInternal + */ protected _gfxTexture: Texture | null = null; + /** + * @engineInternal + */ protected _gfxTextureView: Texture | null = null; private _mipmapLevel = 1; // Cache these data to reduce JSB invoking. private _textureWidth = 0; private _textureHeight = 0; + /** + * @engineInternal + */ protected _baseLevel = 0; + /** + * @engineInternal + */ protected _maxLevel = 1000; /** - * @en The mipmap level of the texture - * @zh 贴图中的 Mipmap 层级数量 + * @en The mipmap level of the texture. + * @zh 贴图中的 Mipmap 层级数量。 */ get mipmapLevel () { return this._mipmapLevel; } /** - * @en The GFX Texture resource + * @en The GFX Texture resource. * @zh 获取此贴图底层的 GFX 贴图对象。 + * @return @en The low level gfx texture. @zh 底层的 GFX 贴图。 */ public getGFXTexture () { return this._gfxTextureView; @@ -107,8 +116,8 @@ export class SimpleTexture extends TextureBase { * @en Update the given level mipmap image. * @zh 更新指定层级范围内的 Mipmap。当 Mipmap 数据发生了改变时应调用此方法提交更改。 * 若指定的层级范围超出了实际已有的层级范围,只有覆盖的那些层级范围会被更新。 - * @param firstLevel First level to be updated - * @param count Mipmap level count to be updated + * @param firstLevel @en First level to be updated. @zh 更新指定层的 mipmap。 + * @param count @en Mipmap level count to be updated。 @zh 指定要更新层的数量。 */ public updateMipmaps (firstLevel = 0, count?: number) { @@ -127,9 +136,9 @@ export class SimpleTexture extends TextureBase { * - 若图像的尺寸与 Mipmap 的尺寸相同,上传后整个 Mipmap 的数据将与图像数据一致; * - 若图像的尺寸小于指定层级 Mipmap 的尺寸(不管是长或宽),则从贴图左上角开始,图像尺寸范围内的 Mipmap 会被更新; * - 若图像的尺寸超出了指定层级 Mipmap 的尺寸(不管是长或宽),都将引起错误。 - * @param source The source image or image data - * @param level Mipmap level to upload the image to - * @param arrayIndex The array index + * @param source @en The source image or image data. @zh 源图像或图像数据。 + * @param level @en Mipmap level to upload the image to. @zh 要上传的 mipmap 层级。 + * @param arrayIndex @en The array index. @zh 要上传的数组索引。 */ public uploadData (source: HTMLCanvasElement | HTMLImageElement | ArrayBufferView | ImageBitmap, level = 0, arrayIndex = 0) { if (!this._gfxTexture || this._mipmapLevel <= level) { @@ -163,6 +172,9 @@ export class SimpleTexture extends TextureBase { } } + /** + * @engineInternal + */ protected _assignImage (image: ImageAsset, level: number, arrayIndex?: number) { const data = image.data; if (!data) { @@ -175,16 +187,22 @@ export class SimpleTexture extends TextureBase { const deps = dependUtil.getDeps(this._uuid); const index = deps.indexOf(image._uuid); if (index !== -1) { - fastRemoveAt(deps, index); + js.array.fastRemoveAt(deps, index); image.decRef(); } } } + /** + * @engineInternal + */ protected _checkTextureLoaded () { this._textureReady(); } + /** + * @engineInternal + */ protected _textureReady () { this.loaded = true; this.emit('load'); @@ -197,11 +215,16 @@ export class SimpleTexture extends TextureBase { * @zh * 设置此贴图的 mipmap 层级 * @param value The mipmap level. + * @engineInternal + * */ protected _setMipmapLevel (value: number) { this._mipmapLevel = value < 1 ? 1 : value; } + /** + * @engineInternal + */ protected _setMipRange (baseLevel: number, maxLevel: number) { this._baseLevel = baseLevel < 1 ? 0 : baseLevel; this._maxLevel = maxLevel < 1 ? 0 : maxLevel; @@ -210,8 +233,8 @@ export class SimpleTexture extends TextureBase { /** * @en Set mipmap level range for this texture. * @zh 设置当前贴图的 mipmap 范围。 - * @param baseLevel The base mipmap level. - * @param maxLevel The maximum mipmap level. + * @param baseLevel @en The base mipmap level. @zh 最低 mipmap 等级。 + * @param maxLevel @en The maximum mipmap level. @zh 最高 mipmap 等级。 */ public setMipRange (baseLevel: number, maxLevel: number) { assertID(baseLevel <= maxLevel, 3124); @@ -233,6 +256,7 @@ export class SimpleTexture extends TextureBase { * @en This method is override by derived classes to provide GFX texture info. * @zh 这个方法被派生类重写以提供 GFX 纹理信息。 * @param presumed The presumed GFX texture info. + * @engineInternal */ protected _getGfxTextureCreateInfo (presumed: PresumedGFXTextureInfo): TextureInfo | null { return null; @@ -242,11 +266,15 @@ export class SimpleTexture extends TextureBase { * @en This method is overrided by derived classes to provide GFX TextureViewInfo. * @zh 这个方法被派生类重写以提供 GFX 纹理视图信息。 * @param presumed The presumed GFX TextureViewInfo. + * @engineInternal */ protected _getGfxTextureViewCreateInfo (presumed: PresumedGFXTextureViewInfo): TextureViewInfo | null { return null; } + /** + * @engineInternal + */ protected _tryReset () { this._tryDestroyTextureView(); this._tryDestroyTexture(); @@ -263,18 +291,21 @@ export class SimpleTexture extends TextureBase { /** * @en Whether mipmaps are baked convolutional maps. - * @zh mipmaps是否为烘焙出来的卷积图。 + * @zh mipmaps 是否为烘焙出来的卷积图。 */ public isUsingOfflineMipmaps (): boolean { return false; } + /** + * @engineInternal + */ protected _createTexture (device: Device) { if (this._width === 0 || this._height === 0) { return; } let flags = TextureFlagBit.NONE; if (this._mipFilter !== Filter.NONE && canGenerateMipmap(device, this._width, this._height)) { this._mipmapLevel = getMipLevel(this._width, this._height); - if (!this.isUsingOfflineMipmaps()) { + if (!this.isUsingOfflineMipmaps() && !this.isCompressed) { flags = TextureFlagBit.GEN_MIPMAP; } } @@ -295,6 +326,9 @@ export class SimpleTexture extends TextureBase { this._gfxTexture = texture; } + /** + * @engineInternal + */ protected _createTextureView (device: Device): Texture | null { if (!this._gfxTexture) { return null; @@ -313,6 +347,9 @@ export class SimpleTexture extends TextureBase { return device.createTexture(textureViewCreateInfo); } + /** + * @engineInternal + */ protected _tryDestroyTexture () { if (this._gfxTexture) { this._gfxTexture.destroy(); @@ -320,6 +357,9 @@ export class SimpleTexture extends TextureBase { } } + /** + * @engineInternal + */ protected _tryDestroyTextureView () { if (this._gfxTextureView) { this._gfxTextureView.destroy(); @@ -328,4 +368,4 @@ export class SimpleTexture extends TextureBase { } } -legacyCC.SimpleTexture = SimpleTexture; +cclegacy.SimpleTexture = SimpleTexture; diff --git a/cocos/asset/assets/text-asset.jsb.ts b/cocos/asset/assets/text-asset.jsb.ts index 3ae14c686a1..0385ddc3913 100644 --- a/cocos/asset/assets/text-asset.jsb.ts +++ b/cocos/asset/assets/text-asset.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ import { ccclass, editable, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import './asset'; const textAssetProto: any = jsb.TextAsset.prototype; @@ -37,10 +36,10 @@ textAssetProto._ctor = function () { jsb.Asset.prototype._ctor.apply(this, arguments); }; -legacyCC.TextAsset = jsb.TextAsset; +cclegacy.TextAsset = jsb.TextAsset; // handle meta data, it is generated automatically const TextAssetProto = TextAsset.prototype; -editable(TextAssetProto, 'text'); -serializable(TextAssetProto, 'text'); +editable(TextAssetProto, 'text', () => ''); +serializable(TextAssetProto, 'text', () => ''); ccclass('cc.TextAsset')(TextAsset); diff --git a/cocos/asset/assets/text-asset.ts b/cocos/asset/assets/text-asset.ts index c3b3532c9db..400e76de8a7 100644 --- a/cocos/asset/assets/text-asset.ts +++ b/cocos/asset/assets/text-asset.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,10 +25,10 @@ import { ccclass, serializable, editable } from 'cc.decorator'; import { Asset } from './asset'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; /** - * @en Class for text file. + * @en The asset for text file. * @zh 文本资源。 */ @ccclass('cc.TextAsset') @@ -47,4 +46,4 @@ export default class TextAsset extends Asset { } } -legacyCC.TextAsset = TextAsset; +cclegacy.TextAsset = TextAsset; diff --git a/cocos/asset/assets/texture-2d.jsb.ts b/cocos/asset/assets/texture-2d.jsb.ts index d361754226e..b060a3d09eb 100644 --- a/cocos/asset/assets/texture-2d.jsb.ts +++ b/cocos/asset/assets/texture-2d.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,11 +22,10 @@ THE SOFTWARE. */ import { ccclass, type } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; import { ImageAsset } from './image-asset'; import { SimpleTexture } from './simple-texture'; import { TextureBase } from './texture-base.jsb'; -import { js } from '../../core/utils/js'; +import { js, cclegacy } from '../../core'; import { Filter, PixelFormat, WrapMode } from './asset-enum'; import './simple-texture'; @@ -120,7 +118,7 @@ Object.defineProperty(texture2DProto, 'mipmaps', { } }); -legacyCC.Texture2D = jsb.Texture2D; +cclegacy.Texture2D = jsb.Texture2D; // handle meta data, it is generated automatically const Texture2DProto = Texture2D.prototype; diff --git a/cocos/asset/assets/texture-2d.ts b/cocos/asset/assets/texture-2d.ts index 2de43c2a305..a908cb023fd 100644 --- a/cocos/asset/assets/texture-2d.ts +++ b/cocos/asset/assets/texture-2d.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,52 +26,53 @@ import { EDITOR, TEST } from 'internal:constants'; import { ccclass, type } from 'cc.decorator'; import { TextureType, TextureInfo, TextureViewInfo } from '../../gfx'; -import { PixelFormat } from './asset-enum'; +import { Filter, PixelFormat } from './asset-enum'; import { ImageAsset } from './image-asset'; import { PresumedGFXTextureInfo, PresumedGFXTextureViewInfo, SimpleTexture } from './simple-texture'; -import { legacyCC } from '../../core/global-exports'; -import { js } from '../../core/utils/js'; +import { js, cclegacy } from '../../core'; + +const compressedImageAsset: ImageAsset[] = []; /** - * @en The create information for [[Texture2D]] + * @en The create information for [[Texture2D]]. * @zh 用来创建贴图的信息。 */ export interface ITexture2DCreateInfo { /** - * @en The pixel width + * @en The pixel width. * @zh 像素宽度。 */ width: number; /** - * @en The pixel height + * @en The pixel height. * @zh 像素高度。 */ height: number; /** - * @en The pixel format + * @en The pixel format. * @zh 像素格式。 * @default PixelFormat.RGBA8888 */ format?: PixelFormat; /** - * @en The mipmap level count + * @en The mipmap level count. * @zh mipmap 层级。 * @default 1 */ mipmapLevel?: number; /** - * @en The selected base mipmap level + * @en The selected base mipmap level. * @zh 选择使用的最小 mipmap 层级。 * @default 1 */ baseLevel?: number; /** - * @en The selected maximum mipmap level + * @en The selected maximum mipmap level. * @zh 选择使用的最大 mipmap 层级。 * @default 1000 */ @@ -95,6 +95,40 @@ export class Texture2D extends SimpleTexture { return this._mipmaps; } set mipmaps (value) { + if (value.length > 0 && value[0].mipmapLevelDataSize && value[0].mipmapLevelDataSize.length > 0) { + compressedImageAsset.length = 0; + const mipmapLevelDataSize = value[0].mipmapLevelDataSize; + const data: Uint8Array = value[0].data as Uint8Array; + const _width = value[0].width; + const _height = value[0].height; + const _format = value[0].format; + + let byteOffset = 0; + for (let i = 0; i < mipmapLevelDataSize.length; i++) { + // fixme: We can't use srcView, we must make an in-memory copy. The reason is unknown + const srcView = new Uint8Array(data.buffer, byteOffset, mipmapLevelDataSize[i]); + const dstView = new Uint8Array(mipmapLevelDataSize[i]); + dstView.set(srcView); + compressedImageAsset[i] = new ImageAsset({ + _data: dstView, + _compressed: true, + width: _width, + height: _height, + format: _format, + mipmapLevelDataSize: [], + }); + + compressedImageAsset[i]._uuid = value[0]._uuid; + this.setMipFilter(Filter.LINEAR); + byteOffset += mipmapLevelDataSize[i]; + } + this._setMipmapParams(compressedImageAsset); + } else { + this._setMipmapParams(value); + } + } + + private _setMipmapParams (value: ImageAsset[]) { this._mipmaps = value; this._setMipmapLevel(this._mipmaps.length); if (this._mipmaps.length > 0) { @@ -143,6 +177,9 @@ export class Texture2D extends SimpleTexture { @type([ImageAsset]) public _mipmaps: ImageAsset[] = []; + /** + * @engineInternal + */ public initialize () { this.mipmaps = this._mipmaps; } @@ -156,7 +193,7 @@ export class Texture2D extends SimpleTexture { * After reset, the gfx resource will become invalid, you must use [[uploadData]] explicitly to upload the new mipmaps to GPU resources. * @zh 将当前贴图重置为指定尺寸、像素格式以及指定 mipmap 层级。重置后,贴图的像素数据将变为未定义。 * mipmap 图像的数据不会自动更新到贴图中,你必须显式调用 [[uploadData]] 来上传贴图数据。 - * @param info The create information + * @param info @en The create information. @zh 创建贴图的相关信息。 */ public reset (info: ITexture2DCreateInfo) { this._width = info.width; @@ -217,7 +254,7 @@ export class Texture2D extends SimpleTexture { /** * @en If the level 0 mipmap image is a HTML element, then return it, otherwise return null. * @zh 若此贴图 0 级 Mipmap 的图像资源的实际源存在并为 HTML 元素则返回它,否则返回 `null`。 - * @returns HTML element or `null` + * @returns @en HTMLElement or `null`. @zh HTML 元素或者 null。 * @deprecated Please use [[ImageAsset.data]] instead */ public getHtmlElementObj () { @@ -234,9 +271,9 @@ export class Texture2D extends SimpleTexture { } /** - * @en Gets the description of the 2d texture + * @en Gets the description of the 2d texture. * @zh 返回此贴图的描述。 - * @returns The description + * @returns @en The description. @zh 贴图的描述信息。 */ public description () { const url = this._mipmaps[0] ? this._mipmaps[0].url : ''; @@ -246,7 +283,7 @@ export class Texture2D extends SimpleTexture { /** * @en Release used GPU resources. * @zh 释放占用的 GPU 资源。 - * @deprecated please use [[destroy]] instead + * @deprecated please use [[destroy]] instead. */ public releaseTexture () { this.destroy(); @@ -293,6 +330,9 @@ export class Texture2D extends SimpleTexture { } } + /** + * @engineInternal + */ protected _getGfxTextureCreateInfo (presumed: PresumedGFXTextureInfo) { const texInfo = new TextureInfo(TextureType.TEX2D); texInfo.width = this._width; @@ -301,6 +341,9 @@ export class Texture2D extends SimpleTexture { return texInfo; } + /** + * @engineInternal + */ protected _getGfxTextureViewCreateInfo (presumed: PresumedGFXTextureViewInfo) { const texViewInfo = new TextureViewInfo(); texViewInfo.type = TextureType.TEX2D; @@ -320,7 +363,7 @@ export class Texture2D extends SimpleTexture { } } -legacyCC.Texture2D = Texture2D; +cclegacy.Texture2D = Texture2D; export interface ITexture2DSerializeData { base: string; diff --git a/cocos/asset/assets/texture-base.jsb.ts b/cocos/asset/assets/texture-base.jsb.ts index 82a3e8d8bf0..9f94cfe8f9f 100644 --- a/cocos/asset/assets/texture-base.jsb.ts +++ b/cocos/asset/assets/texture-base.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,8 +22,9 @@ THE SOFTWARE. */ import { ccclass, serializable } from 'cc.decorator'; +import { TEST, EDITOR } from 'internal:constants'; import { deviceManager } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { Filter, PixelFormat, WrapMode } from './asset-enum'; import './asset'; @@ -120,9 +120,9 @@ textureBaseProto.getSamplerInfo = function () { const oldDestroy = textureBaseProto.destroy; textureBaseProto.destroy = function () { - if (legacyCC.director.root?.batcher2D) { + if (cclegacy.director.root?.batcher2D) { // legacyCC.director.root.batcher2D._releaseDescriptorSetCache(this.getHash()); - legacyCC.director.root.batcher2D._releaseDescriptorSetCache(this.getGFXTexture(), this.getGFXSampler()); + cclegacy.director.root.batcher2D._releaseDescriptorSetCache(this.getGFXTexture(), this.getGFXSampler()); } // dispatch into C++ virtual function CCObject::destroy return oldDestroy.call(this); @@ -133,16 +133,16 @@ textureBaseProto._onGFXSamplerUpdated = function (gfxSampler, samplerInfo) { this._samplerInfo = samplerInfo; }; -legacyCC.TextureBase = jsb.TextureBase; +cclegacy.TextureBase = jsb.TextureBase; // handle meta data, it is generated automatically const TextureBaseProto = TextureBase.prototype; -serializable(TextureBaseProto, '_format'); -serializable(TextureBaseProto, '_minFilter'); -serializable(TextureBaseProto, '_magFilter'); -serializable(TextureBaseProto, '_mipFilter'); -serializable(TextureBaseProto, '_wrapS'); -serializable(TextureBaseProto, '_wrapT'); -serializable(TextureBaseProto, '_wrapR'); -serializable(TextureBaseProto, '_anisotropy'); +serializable(TextureBaseProto, '_format', () => PixelFormat.RGBA8888); +serializable(TextureBaseProto, '_minFilter', () => Filter.LINEAR); +serializable(TextureBaseProto, '_magFilter', () => Filter.LINEAR); +serializable(TextureBaseProto, '_mipFilter', () => Filter.NONE); +serializable(TextureBaseProto, '_wrapS', () => WrapMode.REPEAT); +serializable(TextureBaseProto, '_wrapT', () => WrapMode.REPEAT); +serializable(TextureBaseProto, '_wrapR', () => WrapMode.REPEAT); +serializable(TextureBaseProto, '_anisotropy', () => 0); ccclass('cc.TextureBase')(TextureBase); diff --git a/cocos/asset/assets/texture-base.ts b/cocos/asset/assets/texture-base.ts index b7e65daffd3..a474b8d7b46 100644 --- a/cocos/asset/assets/texture-base.ts +++ b/cocos/asset/assets/texture-base.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,18 +26,14 @@ // @ts-check import { EDITOR, TEST } from 'internal:constants'; import { ccclass, serializable } from 'cc.decorator'; -import IDGenerator from '../../core/utils/id-generator'; import { Asset } from './asset'; import { Filter, PixelFormat, WrapMode } from './asset-enum'; import { Sampler, Texture, Device, Format, SamplerInfo, Address, Filter as GFXFilter, deviceManager } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; -import { errorID } from '../../core/platform/debug'; -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; -import { ccenum } from '../../core/value-types/enum'; +import { errorID, murmurhash2_32_gc, ccenum, cclegacy, js } from '../../core'; ccenum(Format); -const idGenerator = new IDGenerator('Tex'); +const idGenerator = new js.IDGenerator('Tex'); /** * @en The base texture class, it defines features shared by all textures. * @zh 贴图资源基类。它定义了所有贴图共用的概念。 @@ -55,7 +50,7 @@ export class TextureBase extends Asset { } /** - * @en Pixel width of the texture + * @en Pixel width of the texture. * @zh 此贴图的像素宽度。 */ public get width (): number { @@ -63,7 +58,7 @@ export class TextureBase extends Asset { } /** - * @en Pixel height of the texture + * @en Pixel height of the texture. * @zh 此贴图的像素高度。 */ public get height (): number { @@ -72,47 +67,77 @@ export class TextureBase extends Asset { /** * @en The pixel format enum. - * @zh 像素格式枚举类型 + * @zh 像素格式枚举类型。 */ public static PixelFormat = PixelFormat; /** * @en The wrap mode enum. - * @zh 环绕模式枚举类型 + * @zh 环绕模式枚举类型。 */ public static WrapMode = WrapMode; /** - * @en The texture filter mode enum - * @zh 纹理过滤模式枚举类型 + * @en The texture filter mode enum. + * @zh 纹理过滤模式枚举类型。 */ public static Filter = Filter; + /** + * @engineInternal + */ @serializable protected _format = PixelFormat.RGBA8888; + /** + * @engineInternal + */ @serializable protected _minFilter = Filter.LINEAR; + /** + * @engineInternal + */ @serializable protected _magFilter = Filter.LINEAR; + /** + * @engineInternal + */ @serializable protected _mipFilter = Filter.NONE; + /** + * @engineInternal + */ @serializable protected _wrapS = WrapMode.REPEAT; + /** + * @engineInternal + */ @serializable protected _wrapT = WrapMode.REPEAT; + /** + * @engineInternal + */ @serializable protected _wrapR = WrapMode.REPEAT; + /** + * @engineInternal + */ @serializable protected _anisotropy = 0; + /** + * @engineInternal + */ protected _width = 1; + /** + * @engineInternal + */ protected _height = 1; private _id: string; @@ -132,27 +157,27 @@ export class TextureBase extends Asset { } /** - * @en Gets the id of the texture + * @en Gets the id of the texture. * @zh 获取标识符。 - * @returns The id + * @returns @en The id of this texture. @zh 此贴图的 id。 */ public getId () { return this._id; } /** - * @en Gets the pixel format + * @en Gets the pixel format. * @zh 获取像素格式。 - * @returns The pixel format + * @returns @en The pixel format. @zh 像素格式。 */ public getPixelFormat () { return this._format; } /** - * @en Gets the anisotropy + * @en Gets the anisotropy. * @zh 获取各向异性。 - * @returns The anisotropy + * @returns @en The anisotropy. @zh 各项异性值。 */ public getAnisotropy () { return this._anisotropy; @@ -163,9 +188,9 @@ export class TextureBase extends Asset { * Be noted, if the size of the texture is not power of two, only [[WrapMode.CLAMP_TO_EDGE]] is allowed. * @zh 设置此贴图的缠绕模式。 * 注意,若贴图尺寸不是 2 的整数幂,缠绕模式仅允许 [[WrapMode.CLAMP_TO_EDGE]]。 - * @param wrapS S(U) coordinate wrap mode - * @param wrapT T(V) coordinate wrap mode - * @param wrapR R(W) coordinate wrap mode + * @param wrapS @en S(U) coordinate wrap mode. @zh S(U) 坐标系缠绕模式. + * @param wrapT @en T(V) coordinate wrap mode. @zh T(V) 坐标系缠绕模式. + * @param wrapR @en R(W) coordinate wrap mode. @zh R(W) 坐标系缠绕模式. */ public setWrapMode (wrapS: WrapMode, wrapT: WrapMode, wrapR?: WrapMode) { if (wrapR === undefined) wrapR = wrapS; // wrap modes should be as consistent as possible for performance @@ -183,10 +208,10 @@ export class TextureBase extends Asset { } /** - * @en Sets the texture's filter mode + * @en Sets the texture's filter mode. * @zh 设置此贴图的过滤算法。 - * @param minFilter Filter mode for scale down - * @param magFilter Filter mode for scale up + * @param minFilter @en Filter mode for scale down. @zh 贴图缩小时使用的过滤模式。 + * @param magFilter @en Filter mode for scale up. @zh 贴图放大时使用的过滤模式。 */ public setFilters (minFilter: Filter, magFilter: Filter) { this._minFilter = minFilter; @@ -200,9 +225,9 @@ export class TextureBase extends Asset { } /** - * @en Sets the texture's mip filter - * @zh 设置此贴图的缩小过滤算法。 - * @param mipFilter Filter mode for scale down + * @en Sets the texture's mip filter mode. + * @zh 设置此贴图的多层 mip 过滤算法。 + * @param mipFilter @en Filter mode for multiple mip level. @zh 多层 mip 过滤模式。 */ public setMipFilter (mipFilter: Filter) { this._mipFilter = mipFilter; @@ -214,9 +239,9 @@ export class TextureBase extends Asset { } /** - * @en Sets the texture's anisotropy + * @en Sets the texture's anisotropy. * @zh 设置此贴图的各向异性。 - * @param anisotropy + * @param anisotropy @en The anisotropy to be set. @zh 待设置的各向异性数值。 */ public setAnisotropy (anisotropy: number) { this._anisotropy = anisotropy; @@ -233,8 +258,8 @@ export class TextureBase extends Asset { */ public destroy () { const destroyed = super.destroy(); - if (destroyed && legacyCC.director.root?.batcher2D) { - legacyCC.director.root.batcher2D._releaseDescriptorSetCache(this._textureHash); + if (destroyed && cclegacy.director.root?.batcher2D) { + cclegacy.director.root.batcher2D._releaseDescriptorSetCache(this._textureHash); } return destroyed; } @@ -336,4 +361,4 @@ export class TextureBase extends Asset { } } -legacyCC.TextureBase = TextureBase; +cclegacy.TextureBase = TextureBase; diff --git a/cocos/asset/assets/texture-cube.jsb.ts b/cocos/asset/assets/texture-cube.jsb.ts index 1a4ccb86cf0..bfc9ba5139d 100644 --- a/cocos/asset/assets/texture-cube.jsb.ts +++ b/cocos/asset/assets/texture-cube.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,9 +22,8 @@ THE SOFTWARE. */ import { ccclass, serializable } from 'cc.decorator'; -import { legacyCC } from '../../core/global-exports'; import { Filter, PixelFormat, WrapMode } from './asset-enum'; -import { js } from '../../core/utils/js'; +import { js, cclegacy } from '../../core'; import './simple-texture'; import { EDITOR, TEST } from 'internal:constants'; @@ -225,12 +223,12 @@ textureCubeProto._deserialize = function (serializedData: ITextureCubeSerializeD } } -legacyCC.TextureCube = jsb.TextureCube; +cclegacy.TextureCube = jsb.TextureCube; // handle meta data, it is generated automatically const TextureCubeProto = TextureCube.prototype; -serializable(TextureCubeProto, 'isRGBE'); -serializable(TextureCubeProto, '_mipmaps'); -serializable(TextureCubeProto, '_mipmapMode'); -serializable(TextureCubeProto, '_mipmapAtlas'); +serializable(TextureCubeProto, 'isRGBE', () => false); +serializable(TextureCubeProto, '_mipmaps', () => []); +serializable(TextureCubeProto, '_mipmapMode', () => MipmapMode.NONE); +serializable(TextureCubeProto, '_mipmapAtlas', () => null); ccclass('cc.TextureCube')(TextureCube); diff --git a/cocos/asset/assets/texture-cube.ts b/cocos/asset/assets/texture-cube.ts index d7c0936ff14..110f6fc43d9 100644 --- a/cocos/asset/assets/texture-cube.ts +++ b/cocos/asset/assets/texture-cube.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,14 +22,15 @@ THE SOFTWARE. */ -import { EDITOR, TEST } from 'internal:constants'; +import { EDITOR, TEST, VIVO, WECHAT } from 'internal:constants'; import { ccclass, serializable } from 'cc.decorator'; -import { TextureType, TextureInfo, TextureViewInfo } from '../../gfx'; +import { TextureType, TextureInfo, TextureViewInfo, BufferTextureCopy } from '../../gfx'; import { ImageAsset } from './image-asset'; import { PresumedGFXTextureInfo, PresumedGFXTextureViewInfo, SimpleTexture } from './simple-texture'; import { ITexture2DCreateInfo, Texture2D } from './texture-2d'; -import { legacyCC } from '../../core/global-exports'; -import { js } from '../../core/utils/js'; +import { legacyCC, ccwindow } from '../../core/global-exports'; +import { js, sys } from '../../core'; +import { OS } from '../../../pal/system-info/enum-type'; export type ITextureCubeCreateInfo = ITexture2DCreateInfo; /** @@ -168,10 +168,11 @@ export class TextureCube extends SimpleTexture { } /** - * @en Fill mipmaps with convolutional maps. - * @zh 使用卷积图填充mipmaps。 - * @param value All mipmaps of each face of the cube map are stored in the form of atlas + * @en Fill mipmaps for cube map with atlas. + * @zh 使用 atlas 方式排布的图填充到立方体贴图的 mipmaps。 + * @param value @en All mipmaps of each face of the cube map are stored in the form of atlas * and the value contains the atlas of the 6 faces and the layout information of each mipmap layer. + * @zh 立方体贴图六个面的图,其中每张图中的全部 mip 数据都使用 atlas 方式排布 */ set mipmapAtlas (value: ITextureCubeMipmapAtlas | null) { this._mipmapAtlas = value; @@ -187,14 +188,20 @@ export class TextureCube extends SimpleTexture { if (!imageAtlasAsset.data) { return; } + //In ios wechat mini-game platform drawImage and getImageData can not get correct data,so upload to gfxTexture than use readPixels to get data + //The performance of upload to gfxTexture and readPixels is not good, so only use this way in the ios wechat mini-game platform + if ((WECHAT && sys.os === OS.IOS) || VIVO) { + this._uploadAtlas(); + return; + } const faceAtlas = this._mipmapAtlas.atlas; const layout = this._mipmapAtlas.layout; const mip0Layout = layout[0]; - const ctx = Object.assign(document.createElement('canvas'), { + const ctx = Object.assign(ccwindow.document.createElement('canvas'), { width: imageAtlasAsset.width, height: imageAtlasAsset.height, - }).getContext('2d'); + }).getContext('2d')!; this.reset({ width: mip0Layout.width, @@ -206,10 +213,10 @@ export class TextureCube extends SimpleTexture { for (let j = 0; j < layout.length; j++) { const layoutInfo = layout[j]; _forEachFace(faceAtlas, (face, faceIndex) => { - ctx!.clearRect(0, 0, imageAtlasAsset.width, imageAtlasAsset.height); + ctx.clearRect(0, 0, imageAtlasAsset.width, imageAtlasAsset.height); const drawImg = face.data as HTMLImageElement; - ctx!.drawImage(drawImg, 0, 0); - const rawData = ctx!.getImageData(layoutInfo.left, layoutInfo.top, layoutInfo.width, layoutInfo.height); + ctx.drawImage(drawImg, 0, 0); + const rawData = ctx.getImageData(layoutInfo.left, layoutInfo.top, layoutInfo.width, layoutInfo.height); const bufferAsset = new ImageAsset({ _data: rawData.data, @@ -309,7 +316,7 @@ export class TextureCube extends SimpleTexture { * After reset, the gfx resource will become invalid, you must use [[uploadData]] explicitly to upload the new mipmaps to GPU resources. * @zh 将当前贴图重置为指定尺寸、像素格式以及指定 mipmap 层级。重置后,贴图的像素数据将变为未定义。 * mipmap 图像的数据不会自动更新到贴图中,你必须显式调用 [[uploadData]] 来上传贴图数据。 - * @param info The create information + * @param info @en The create information. @zh 创建贴图的相关信息。 */ public reset (info: ITextureCubeCreateInfo) { this._width = info.width; @@ -323,6 +330,13 @@ export class TextureCube extends SimpleTexture { this._tryReset(); } + /** + * @en Updates the given level mipmap image. + * @zh 更新指定层级范围内的 Mipmap。当 Mipmap 数据发生了改变时应调用此方法提交更改。 + * 若指定的层级范围超出了实际已有的层级范围,只有覆盖的那些层级范围会被更新。 + * @param firstLevel @en First level to be updated. @zh 更新指定层的 mipmap。 + * @param count @en Mipmap level count to be updated。 @zh 指定要更新层的数量。 + */ public updateMipmaps (firstLevel = 0, count?: number) { if (firstLevel >= this._mipmaps.length) { return; @@ -342,7 +356,7 @@ export class TextureCube extends SimpleTexture { } /** - * @en Destroy this texture, clear all mipmaps and release GPU resources + * @en Destroys this texture, clear all mipmaps and release GPU resources * @zh 销毁此贴图,清空所有 Mipmap 并释放占用的 GPU 资源。 */ public destroy () { @@ -492,6 +506,49 @@ export class TextureCube extends SimpleTexture { return texViewInfo; } + protected _uploadAtlas () { + const layout = this._mipmapAtlas!.layout; + const mip0Layout = layout[0]; + this.reset({ + width: mip0Layout.width, + height: mip0Layout.height, + format: this._mipmapAtlas!.atlas.front.format, + mipmapLevel: layout.length, + }); + + _forEachFace(this._mipmapAtlas!.atlas, (face, faceIndex) => { + const tex = new Texture2D(); + tex.image = face; + tex.reset({ + width: face.width, + height: face.height, + format: face.format, + }); + tex.uploadData(face.data!); + + for (let i = 0; i < layout.length; i++) { + const layoutInfo = layout[i]; + + const buffer = new Uint8Array(4 * layoutInfo.width * layoutInfo.height); + const region = new BufferTextureCopy(); + region.texOffset.x = layoutInfo.left; + region.texOffset.y = layoutInfo.top; + region.texExtent.width = layoutInfo.width; + region.texExtent.height = layoutInfo.height; + + this._getGFXDevice()!.copyTextureToBuffers(tex.getGFXTexture()!, [buffer], [region]); + const bufferAsset = new ImageAsset({ + _data: buffer, + _compressed: face.isCompressed, + width: layoutInfo.width, + height: layoutInfo.height, + format: face.format, + }); + this._assignImage(bufferAsset, layoutInfo.level, faceIndex); + } + }); + } + public initDefault (uuid?: string) { super.initDefault(uuid); diff --git a/cocos/audio/audio-clip.ts b/cocos/audio/audio-clip.ts index 4912e59f74e..83a089072cf 100644 --- a/cocos/audio/audio-clip.ts +++ b/cocos/audio/audio-clip.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable, override } from 'cc.decorator'; import { AudioPlayer } from 'pal/audio'; import { Asset } from '../asset/assets/asset'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import { AudioState, AudioType } from '../../pal/audio/type'; export interface AudioMeta { @@ -200,4 +199,4 @@ export class AudioClip extends Asset { // #endregion deprecated method } -legacyCC.AudioClip = AudioClip; +cclegacy.AudioClip = AudioClip; diff --git a/cocos/audio/audio-downloader.ts b/cocos/audio/audio-downloader.ts index 9fa0cb49735..2ace7a22879 100644 --- a/cocos/audio/audio-downloader.ts +++ b/cocos/audio/audio-downloader.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,15 +21,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { AudioPlayer } from 'pal/audio'; import { AudioClip, AudioMeta } from './audio-clip'; -import { CompleteCallback, IDownloadParseOptions } from '../asset/asset-manager/shared'; import downloader from '../asset/asset-manager/downloader'; import factory from '../asset/asset-manager/factory'; -export function loadAudioPlayer (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) { +export function loadAudioPlayer (url: string, options: Record, onComplete: ((err: Error | null, data?: any | null) => void)) { AudioPlayer.load(url, { audioLoadMode: options.audioLoadMode, }).then((player) => { @@ -48,8 +46,8 @@ export function loadAudioPlayer (url: string, options: IDownloadParseOptions, on function createAudioClip (id: string, data: AudioMeta, - options: IDownloadParseOptions, - onComplete: CompleteCallback) { + options: Record, + onComplete: ((err: Error | null, data?: AudioClip | null) => void)) { const out = new AudioClip(); out._nativeUrl = id; out._nativeAsset = data; diff --git a/cocos/audio/audio-manager.ts b/cocos/audio/audio-manager.ts index 91f83c4fa42..ae576417701 100644 --- a/cocos/audio/audio-manager.ts +++ b/cocos/audio/audio-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { AudioPlayer, OneShotAudio } from 'pal/audio'; -import { fastRemoveAt } from '../core/utils/array'; +import { js } from '../core'; type ManagedAudio = AudioPlayer | OneShotAudio; interface AudioInfo { @@ -55,9 +54,7 @@ export class AudioManager { } public addPlaying (audio: ManagedAudio) { if (audio instanceof AudioPlayer) { - if (this._tryAddPlaying(this._audioPlayerInfoList, audio)) { - return; - } + this._tryAddPlaying(this._audioPlayerInfoList, audio); } else { this._tryAddPlaying(this._oneShotAudioInfoList, audio); } @@ -68,14 +65,12 @@ export class AudioManager { if (idx === -1) { return false; } - fastRemoveAt(audioInfoList, idx); + js.array.fastRemoveAt(audioInfoList, idx); return true; } public removePlaying (audio: ManagedAudio) { if (audio instanceof AudioPlayer) { - if (this._tryRemovePlaying(this._audioPlayerInfoList, audio)) { - return; - } + this._tryRemovePlaying(this._audioPlayerInfoList, audio); } else { this._tryRemovePlaying(this._oneShotAudioInfoList, audio); } @@ -106,6 +101,22 @@ export class AudioManager { this.removePlaying(audioInfoToDiscard.audio); } } + + public pause () { + this._oneShotAudioInfoList.forEach((info) => { + info.audio.stop(); + }); + this._audioPlayerInfoList.forEach((info) => { + info.audio.pause().catch((e) => {}); + }); + } + + public resume () { + // onShotAudio can not be resumed + this._audioPlayerInfoList.forEach((info) => { + info.audio.play().catch((e) => {}); + }); + } } export const audioManager = new AudioManager(); diff --git a/cocos/audio/audio-source.ts b/cocos/audio/audio-source.ts index d6927e2a945..98d1f3271dd 100644 --- a/cocos/audio/audio-source.ts +++ b/cocos/audio/audio-source.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { AudioPlayer } from 'pal/audio'; import { ccclass, help, menu, tooltip, type, range, serializable } from 'cc.decorator'; import { AudioPCMDataView, AudioState } from '../../pal/audio/type'; import { Component } from '../scene-graph/component'; -import { clamp } from '../core/math'; +import { clamp } from '../core'; import { AudioClip } from './audio-clip'; import { audioManager } from './audio-manager'; import { Node } from '../scene-graph'; @@ -106,7 +105,6 @@ export class AudioSource extends Component { } private _syncPlayer () { const clip = this._clip; - this._isLoaded = false; if (this._lastSetClip === clip) { return; } @@ -119,6 +117,10 @@ export class AudioSource extends Component { console.error('Invalid audio clip'); return; } + // The state of _isloaded cannot be modified if clip is the wrong argument. + // Because load is an asynchronous function, if it is called multiple times with the same arguments. + // It may cause an illegal state change + this._isLoaded = false; this._lastSetClip = clip; this._operationsBeforeLoading.length = 0; AudioPlayer.load(clip._nativeAsset.url, { diff --git a/cocos/audio/deprecated.ts b/cocos/audio/deprecated.ts index d305e825486..b9cb6b8e225 100644 --- a/cocos/audio/deprecated.ts +++ b/cocos/audio/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { AudioSource } from './audio-source'; -import { replaceProperty, markAsWarning } from '../core/utils/x-deprecated'; +import { replaceProperty, markAsWarning } from '../core'; import { AudioClip } from './audio-clip'; // remove AudioClip static property diff --git a/cocos/audio/index.ts b/cocos/audio/index.ts index 09882e8488e..c73c3c34f7d 100644 --- a/cocos/audio/index.ts +++ b/cocos/audio/index.ts @@ -1,33 +1,31 @@ /* -Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. +Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license -to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - -The software or tools in this License Agreement are licensed, not sold. -Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. */ import './audio-downloader'; import { AudioSource } from './audio-source'; -import { legacyCC } from '../core/global-exports'; -import { js } from '../core/utils/js'; +import { cclegacy, js } from '../core'; import './deprecated'; export { AudioClip } from './audio-clip'; @@ -36,5 +34,5 @@ export { AudioSource }; export { AudioPCMDataView } from '../../pal/audio/type'; export { AudioSource as AudioSourceComponent }; -legacyCC.AudioSourceComponent = AudioSource; +cclegacy.AudioSourceComponent = AudioSource; js.setClassAlias(AudioSource, 'cc.AudioSourceComponent'); diff --git a/cocos/core/algorithm/atob.ts b/cocos/core/algorithm/atob.ts deleted file mode 100644 index dfd0eb04bea..00000000000 --- a/cocos/core/algorithm/atob.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. - - https://www.cocos.com/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -export function atob (input: string): string { - const keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - let output = ''; - let chr1 = 0; let chr2 = 0; let chr3 = 0; - let enc1 = 0; let enc2 = 0; let enc3 = 0; let enc4 = 0; - let i = 0; - // eslint-disable-next-line no-useless-escape - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); - do { - enc1 = keyStr.indexOf(input.charAt(i++)); - enc2 = keyStr.indexOf(input.charAt(i++)); - enc3 = keyStr.indexOf(input.charAt(i++)); - enc4 = keyStr.indexOf(input.charAt(i++)); - chr1 = enc1 << 2 | enc2 >> 4; - chr2 = (enc2 & 15) << 4 | enc3 >> 2; - chr3 = (enc3 & 3) << 6 | enc4; - output += String.fromCharCode(chr1); - if (enc3 !== 64) { - output += String.fromCharCode(chr2); - } - if (enc4 !== 64) { - output += String.fromCharCode(chr3); - } - } while (i < input.length); - return output; -} diff --git a/cocos/core/algorithm/binary-search.ts b/cocos/core/algorithm/binary-search.ts index 26a52540742..bad62deeea1 100644 --- a/cocos/core/algorithm/binary-search.ts +++ b/cocos/core/algorithm/binary-search.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,25 +24,27 @@ */ /** - * Searches the **sorted** number array for an element and returns the index of that element. + * Searches the **ascending sorted** array for an element and returns the index of that element. * @param array The array to search in. * @param value The value to search. - * @return The index of the searched element in the sorted array, if one is found; - * otherwise, a negative number that is the bitwise complement of the index of the next element that is large than the searched value or, - * if there is no larger element(include the case that the array is empty), the bitwise complement of array's length. + * @returns The index of the searched element in the sorted array, if found; + * otherwise, returns the complement of the index of the next element greater than the element to be searched or, + * returns the complement of array's length if no element is greater than the element to be searched or the array is empty. + * @engineInternal */ export function binarySearch (array: number[], value: number) { return binarySearchEpsilon(array, value, 0); } /** - * Searches the **sorted** number array for an element and returns the index of that element. + * Searches the **ascending sorted** number array for an element and returns the index of that element. * @param array The array to search in. * @param value The value to search. * @param EPSILON The epsilon to compare the numbers. Default to `1e-6`. - * @return The index of the searched element in the sorted array, if one is found; - * otherwise, a negative number that is the bitwise complement of the index of the next element that is large than the searched value or, - * if there is no larger element(include the case that the array is empty), the bitwise complement of array's length. + * @returns The index of the searched element in the sorted array, if found; + * otherwise, returns the complement of the index of the next element greater than the element to be searched or, + * returns the complement of array's length if no element is greater than the element to be searched or the array is empty. + * @engineInternal */ export function binarySearchEpsilon (array: Readonly>, value: number, EPSILON = 1e-6) { let low = 0; @@ -63,13 +64,14 @@ export function binarySearchEpsilon (array: Readonly>, value: } /** - * Searches the **sorted** array for an element and returns the index of that element. + * Searches the **ascending sorted** array for an element and returns the index of that element. * @param array The array to search in. * @param value The value to search. - * @param lessThan The predicate which implements the less than semantic. - * @return The index of the searched element in the sorted array, if one is found; - * otherwise, a negative number that is the bitwise complement of the index of the next element that is large than the searched value or, - * if there is no larger element(include the case that the array is empty), the bitwise complement of array's length. + * @param lessThan Comparison function object which returns ​true if the first argument is less than the second. + * @returns The index of the searched element in the sorted array, if found; + * otherwise, returns the complement of the index of the next element greater than the searching element or, + * returns the complement of array's length if no element is greater than the searching element or the array is empty. + * @engineInternal */ export function binarySearchBy (array: T[], value: U, lessThan: (lhs: T, rhs: U) => number) { let low = 0; diff --git a/cocos/core/algorithm/easing.ts b/cocos/core/algorithm/easing.ts index c4b408f1f49..60ed26f4bfa 100644 --- a/cocos/core/algorithm/easing.ts +++ b/cocos/core/algorithm/easing.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,24 +20,50 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ + +// Easing functions specify the speed at which an animation progresses at different points within the animation. +/** + * @en Not any easing effect. + * @zh 没有任何缓动效果。 + */ export function constant () { return 0; } +/** + * @en A linear function, `f(k) = k`. Result correlates to input value one to one. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 线性函数,`f(k) = k`。返回值和输入值一一对应。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function linear (k: number) { return k; } +/** + * @en A quadratic function, f(k) = k * k. The interpolation starts slowly, then progressively speeds up until the end, + * at which point it stops abruptly. Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 一个二次方的函数,f(k) = k * k。插值开始时很慢,然后逐渐加快,直到结束,并突然停止。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quadIn (k: number) { return k * k; } +/** + * @en A quadratic function, f(k) = k * (2-k). The interpolation starts abruptly and then progressively slows down towards the end. Refer to + * [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 一个二次方的函数,f(k) = k * (2-k)。插值开始时很突然,然后在接近尾声时逐渐减慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quadOut (k: number) { return k * (2 - k); } +/** + * @en The interpolation starts slowly, speeds up, and then slows down towards the end. Refer to + * [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) graphic feature. + * @zh 插值开始时很慢,接着加快,然后在接近尾声时减慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quadInOut (k: number) { k *= 2; if (k < 1) { @@ -47,14 +72,28 @@ export function quadInOut (k: number) { return -0.5 * (--k * (k - 2) - 1); } +/** + * @en Starts slowly and accelerates. Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function cubicIn (k: number) { return k * k * k; } +/** + * @en Starts quickly and decelerates. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 起动迅速,减速慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function cubicOut (k: number) { return --k * k * k + 1; } +/** + * @en Accelerates the animation at the beginning, and decelerates the animation at the end. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 在开始时加速动画,在结束时减慢动画的速度。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function cubicInOut (k: number) { k *= 2; if (k < 1) { @@ -63,14 +102,28 @@ export function cubicInOut (k: number) { return 0.5 * ((k -= 2) * k * k + 2); } +/** + * @en Starts slowly and accelerates. Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quartIn (k: number) { return k * k * k * k; } +/** + * @en Starts quickly and decelerates. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 起动迅速,减速慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quartOut (k: number) { return 1 - (--k * k * k * k); } +/** + * @en Accelerates the animation at the beginning, and decelerates the animation at the end. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 在开始时加速动画,在结束时减慢动画的速度。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quartInOut (k: number) { k *= 2; if (k < 1) { @@ -79,14 +132,28 @@ export function quartInOut (k: number) { return -0.5 * ((k -= 2) * k * k * k - 2); } +/** + * @en Starts slowly and accelerates. Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quintIn (k: number) { return k * k * k * k * k; } +/** + * @en Starts quickly and decelerates. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 起动迅速,减速慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quintOut (k: number) { return --k * k * k * k * k + 1; } +/** + * @en Accelerates the animation at the beginning, and decelerates the animation at the end. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 在开始时加速动画,在结束时减慢动画的速度。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function quintInOut (k: number) { k *= 2; if (k < 1) { @@ -95,6 +162,11 @@ export function quintInOut (k: number) { return 0.5 * ((k -= 2) * k * k * k * k + 2); } +/** + * @en Smoothly accelerates the animation. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 平滑地加速动画。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function sineIn (k: number) { if (k === 1) { return 1; @@ -102,22 +174,46 @@ export function sineIn (k: number) { return 1 - Math.cos(k * Math.PI / 2); } +/** + * @en Smoothly decelerates the animation. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 平滑地使动画降速。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function sineOut (k: number) { return Math.sin(k * Math.PI / 2); } +/** + * @en Smoothly accelerates the animation at the beginning, and smoothly decelerates the animation at the end. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 在开始时平滑地加速动画,在结束时平滑地减速动画。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function sineInOut (k: number) { return 0.5 * (1 - Math.cos(Math.PI * k)); } +/** + * @en Starts slowly and accelerates. Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function expoIn (k: number) { return k === 0 ? 0 : Math.pow(1024, k - 1); } +/** + * @en Starts quickly and decelerates. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 起动迅速,减速慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function expoOut (k: number) { return k === 1 ? 1 : 1 - Math.pow(2, -10 * k); } +/** + * @en Accelerates the animation at the beginning, and decelerates the animation at the end. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 在开始时加速动画,在结束时减慢动画的速度。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function expoInOut (k: number) { if (k === 0) { return 0; @@ -132,14 +228,28 @@ export function expoInOut (k: number) { return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2); } +/** + * @en Starts slowly and accelerates. Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function circIn (k: number) { return 1 - Math.sqrt(1 - k * k); } +/** + * @en Starts quickly and decelerates. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 起动迅速,减速慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function circOut (k: number) { return Math.sqrt(1 - (--k * k)); } +/** + * @en Accelerates the animation at the beginning, and decelerates the animation at the end. + * Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 在开始时加速动画,在结束时减慢动画的速度。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function circInOut (k: number) { k *= 2; if (k < 1) { @@ -148,6 +258,10 @@ export function circInOut (k: number) { return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function elasticIn (k: number) { let s; let a = 0.1; @@ -167,6 +281,10 @@ export function elasticIn (k: number) { return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function elasticOut (k: number) { let s; let a = 0.1; @@ -186,6 +304,10 @@ export function elasticOut (k: number) { return (a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function elasticInOut (k: number) { let s; let a = 0.1; @@ -210,6 +332,10 @@ export function elasticInOut (k: number) { return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1; } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function backIn (k: number) { if (k === 1) { return 1; @@ -218,6 +344,10 @@ export function backIn (k: number) { return k * k * ((s + 1) * k - s); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function backOut (k: number) { if (k === 0) { return 0; @@ -226,6 +356,10 @@ export function backOut (k: number) { return --k * k * ((s + 1) * k + s) + 1; } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function backInOut (k: number) { const s = 1.70158 * 1.525; k *= 2; @@ -239,6 +373,10 @@ export function bounceIn (k: number) { return 1 - bounceOut(1 - k); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function bounceOut (k: number) { if (k < (1 / 2.75)) { return 7.5625 * k * k; @@ -251,6 +389,10 @@ export function bounceOut (k: number) { } } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function bounceInOut (k: number) { if (k < 0.5) { return bounceIn(k * 2) * 0.5; @@ -258,6 +400,10 @@ export function bounceInOut (k: number) { return bounceOut(k * 2 - 1) * 0.5 + 0.5; } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function smooth (k: number) { if (k <= 0) { return 0; @@ -268,6 +414,10 @@ export function smooth (k: number) { return k * k * (3 - 2 * k); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export function fade (k: number) { if (k <= 0) { return 0; @@ -278,15 +428,64 @@ export function fade (k: number) { return k * k * k * (k * (k * 6 - 15) + 10); } +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const quadOutIn = _makeOutIn(quadIn, quadOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const cubicOutIn = _makeOutIn(cubicIn, cubicOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const quartOutIn = _makeOutIn(quartIn, quartOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const quintOutIn = _makeOutIn(quintIn, quintOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const sineOutIn = _makeOutIn(sineIn, sineOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const expoOutIn = _makeOutIn(expoIn, expoOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const circOutIn = _makeOutIn(circIn, circOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const elasticOutIn = _makeOutIn(elasticIn, elasticOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const backOutIn = _makeOutIn(backIn, backOut); + +/** + * @en Refer to [this doc](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html) for graphic feature. + * @zh 具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 + */ export const bounceOutIn = _makeOutIn(bounceIn, bounceOut); function _makeOutIn (fnIn: (k: number) => number, fnOut: (k: number) => number) { diff --git a/cocos/core/algorithm/index.ts b/cocos/core/algorithm/index.ts new file mode 100644 index 00000000000..59f939e41fc --- /dev/null +++ b/cocos/core/algorithm/index.ts @@ -0,0 +1,30 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { legacyCC } from '../global-exports'; +import * as easing from './easing'; + +export * from './murmurhash2_gc'; + +export { easing }; +legacyCC.easing = easing; diff --git a/cocos/core/algorithm/move.ts b/cocos/core/algorithm/move.ts index cd541ca0433..89267bd2f54 100644 --- a/cocos/core/algorithm/move.ts +++ b/cocos/core/algorithm/move.ts @@ -1,27 +1,56 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { assertsArrayIndex } from '../data/utils/asserts'; /** - * Moves an array element to new location. - * @param array The array. - * @param index Index to the array element to move. - * @param newIndex New array index it should have. + * @en Circle shift an array once in range [first, last]. If `first < last`, then will do left circle shift; + * If `first > last`, then will do right circle shift; If `first == last`, there is not effect. + * @zh 在 [first, last] 范围做一次环形移动。如果 `first < last`,进行左环形移动;如果 `first > last`,进行右环 + * 形移动;如果 `first == last`,将没有效果。 + * @param array @en The array to be rotated. @zh 被修改的数组。 + * @param first @en The beginning of the original range. @zh 移动区间的起始坐标。 + * @param last @en The end of the original range. @zh 移动区间的结束坐标。 + * @returns @en The input array. @zh 输入的数组。 + * @engineInternal */ -export function move (array: T[], index: number, newIndex: number) { - assertsArrayIndex(array, index); - assertsArrayIndex(array, newIndex); - if (index === newIndex) { +export function shift (array: T[], first: number, last: number) { + assertsArrayIndex(array, first); + assertsArrayIndex(array, last); + if (first === last) { return array; } - const element = array[index]; - if (index < newIndex) { // Shift right - for (let iElement = index + 1; iElement <= newIndex; ++iElement) { + const element = array[first]; + if (first < last) { // Shift left. + for (let iElement = first + 1; iElement <= last; ++iElement) { array[iElement - 1] = array[iElement]; } - } else { // Shift left - for (let iElement = index; iElement !== newIndex; --iElement) { + } else { // Shift right. + for (let iElement = first; iElement !== last; --iElement) { array[iElement] = array[iElement - 1]; } } - array[newIndex] = element; + array[last] = element; return array; } diff --git a/cocos/core/algorithm/murmurhash2_gc.ts b/cocos/core/algorithm/murmurhash2_gc.ts index 18824abd128..3ac32fc8ad7 100644 --- a/cocos/core/algorithm/murmurhash2_gc.ts +++ b/cocos/core/algorithm/murmurhash2_gc.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* * JS Implementation of MurmurHash2 @@ -39,6 +38,13 @@ const getUint8ForString = String.prototype.charCodeAt; function getUint8ForArray (this: Uint8Array, idx: number) { return this[idx]; } +/** + * @en JS Implementation of MurmurHash2. Original implementation is http://github.com/garycourt/murmurhash-js. + * @zh MurmurHash2 的 JS 实现。原始实现是 http://github.com/garycourt/murmurhash-js 。 + * @param input @en ASCII string or a Uint8Array to be hashed. @zh 希望被哈希的 ASCII 字符串或者 Uint8Array. + * @param seed @en Hash seed. Should be a positive integer. @zh 哈希种子。必须是个正整数。 + * @returns @en 32-bit positive integer hash. @zh 32位正整数哈希值。 + */ export function murmurhash2_32_gc (input: string | Uint8Array, seed: number) { let l = input.length; let h = seed ^ l; @@ -62,10 +68,18 @@ export function murmurhash2_32_gc (input: string | Uint8Array, seed: number) { } switch (l) { + // Don't break in case 3 and case 2. case 3: h ^= (getUint8.call(input, i + 2) & 0xff) << 16; + // eslint-disable-next-line no-fallthrough case 2: h ^= (getUint8.call(input, i + 1) & 0xff) << 8; - case 1: h ^= (getUint8.call(input, i) & 0xff); + // eslint-disable-next-line no-fallthrough + case 1: + h ^= (getUint8.call(input, i) & 0xff); h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)); + break; + default: + // do nothing, just make VSCode happy. + break; } h ^= h >>> 13; diff --git a/cocos/core/algorithm/partition.ts b/cocos/core/algorithm/partition.ts new file mode 100644 index 00000000000..4f0efe6502c --- /dev/null +++ b/cocos/core/algorithm/partition.ts @@ -0,0 +1,80 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/** + * @zh + * 就地重新排列数组中的元素, + * 使所有令谓词 `predicate` 返回 `true`的元素都排在所有令谓词 `predicate` 返回 `false`的元素前面。 + * 不会保留元素的相对顺序。 + * @en + * Reorders the elements in array **in place** in such a way that + * all elements for which the predicate `predicate` returns `true` precede + * the elements for which predicates `predicate` returns `false`. + * Relative order of the elements is *NOT* preserved. + * @param array @zh 输入数组。 @en The input array. + * @param predicate @zh 谓词,当元素应该被排列在其它元素前面时返回 `true`。 + * @en The predicate which returns `true` if the element should be ordered before other elements. + * @returns @zh 第一组元素的个数。 + * @en The number of elements in the first group. + * @example + * ```ts + * const array = [7, 1, 2, 4, 3]; + * const nFirstGroupElements = partition(array, (v) => v % 2 === 0); + * log(nFirstGroupElements); // 2 + * log(array); // [2, 4, 7, 1, 3] + * log(array.slice(0, nFirstGroupElements)); // [2, 4] + * log(array.slice(nFirstGroupElements)); // [7, 1, 3] + * ``` + */ +export function partition (array: T[], predicate: (element: T, index: number, array: T[]) => boolean) { + const nElements = array.length; + + // Finds the first element to be placed into second group(predicate to false). + let iFirstGroup2Element = 0; + for (; iFirstGroup2Element < nElements; ++iFirstGroup2Element) { + const element = array[iFirstGroup2Element]; + if (!predicate(element, iFirstGroup2Element, array)) { + break; + } + } + + // If no element should be placed into seconds group. Do nothing. + if (iFirstGroup2Element === nElements) { + return nElements; + } + + let nGroup1 = iFirstGroup2Element; + for (let iElement = iFirstGroup2Element + 1; iElement < nElements; ++iElement) { + const element = array[iElement]; + const isFirstGroupElement = predicate(element, iElement, array); + if (isFirstGroupElement) { + // Swap to front. + const t = element; + array[iElement] = array[nGroup1]; + array[nGroup1] = t; + ++nGroup1; + } + } + return nGroup1; +} diff --git a/cocos/core/curves/bezier.ts b/cocos/core/curves/bezier.ts index d0830732721..0e75dda1eaf 100644 --- a/cocos/core/curves/bezier.ts +++ b/cocos/core/curves/bezier.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { legacyCC } from '../global-exports'; diff --git a/cocos/core/curves/curve-base.ts b/cocos/core/curves/curve-base.ts index 841b4fefb4d..82c6f34a47d 100644 --- a/cocos/core/curves/curve-base.ts +++ b/cocos/core/curves/curve-base.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export interface CurveBase { readonly rangeMin: number; readonly rangeMax: number; diff --git a/cocos/core/curves/curve.ts b/cocos/core/curves/curve.ts index 0791a8b3fc6..fe75283d183 100644 --- a/cocos/core/curves/curve.ts +++ b/cocos/core/curves/curve.ts @@ -1,11 +1,34 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { assertIsTrue } from '../data/utils/asserts'; import { approx, lerp, pingPong, repeat } from '../math'; import { KeyframeCurve } from './keyframe-curve'; -import { ccclass, serializable, uniquelyReferenced } from '../data/decorators'; import { RealInterpolationMode, ExtrapolationMode, TangentWeightMode } from './real-curve-param'; import { binarySearchEpsilon } from '../algorithm/binary-search'; import { solveCubic } from './solve-cubic'; -import { EditorExtendable, EditorExtendableMixin } from '../data/editor-extendable'; +import { EditorExtendable } from '../data/editor-extendable'; import { CCClass, deserializeTag, editorExtrasTag, SerializationContext, SerializationInput, SerializationOutput, serializeTag } from '../data'; import { DeserializationContext } from '../data/custom-serializable'; import { EasingMethod, getEasingFn } from './easing-method'; diff --git a/cocos/core/curves/easing-method.ts b/cocos/core/curves/easing-method.ts index 5e87d3f1dbb..d17a1855bb7 100644 --- a/cocos/core/curves/easing-method.ts +++ b/cocos/core/curves/easing-method.ts @@ -1,6 +1,33 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import * as easing from '../algorithm/easing'; import { assertIsTrue } from '../data/utils/asserts'; +/** + * @engineInternal + */ export enum EasingMethod { LINEAR, CONSTANT, diff --git a/cocos/core/curves/index.ts b/cocos/core/curves/index.ts index 70fdec19461..a4b6f14f079 100644 --- a/cocos/core/curves/index.ts +++ b/cocos/core/curves/index.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export { RealCurve, RealInterpolationMode, diff --git a/cocos/core/curves/keyframe-curve.ts b/cocos/core/curves/keyframe-curve.ts index 9ce1abf87af..23d1e093ceb 100644 --- a/cocos/core/curves/keyframe-curve.ts +++ b/cocos/core/curves/keyframe-curve.ts @@ -1,6 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { binarySearchEpsilon } from '../algorithm/binary-search'; import { CCClass } from '../data/class'; -import { ccclass, serializable } from '../data/decorators'; import { assertIsTrue } from '../data/utils/asserts'; import { approx } from '../math'; import type { CurveBase } from './curve-base'; diff --git a/cocos/core/curves/keys-shared-curves.ts b/cocos/core/curves/keys-shared-curves.ts index 7678b3162bc..f394cdd854e 100644 --- a/cocos/core/curves/keys-shared-curves.ts +++ b/cocos/core/curves/keys-shared-curves.ts @@ -1,8 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { binarySearchEpsilon } from '../algorithm/binary-search'; import { ccclass, serializable } from '../data/decorators'; import { assertIsTrue } from '../data/utils/asserts'; import { approx, IQuatLike, lerp, Quat } from '../math'; -import { RealKeyframeValue, ExtrapolationMode, RealCurve } from './curve'; +import { ExtrapolationMode, RealCurve } from './curve'; import { QuatCurve, QuatInterpolationMode } from './quat-curve'; import { RealInterpolationMode } from './real-curve-param'; diff --git a/cocos/core/curves/object-curve.ts b/cocos/core/curves/object-curve.ts index d2126073fc6..c501a80518d 100644 --- a/cocos/core/curves/object-curve.ts +++ b/cocos/core/curves/object-curve.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass } from '../data/decorators'; import { clamp } from '../math'; import { KeyframeCurve } from './keyframe-curve'; diff --git a/cocos/core/curves/quat-curve.ts b/cocos/core/curves/quat-curve.ts index 67ffc7fafcb..fde7c9cf1a6 100644 --- a/cocos/core/curves/quat-curve.ts +++ b/cocos/core/curves/quat-curve.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { assertIsTrue } from '../data/utils/asserts'; import { IQuatLike, pingPong, Quat, repeat } from '../math'; import { KeyframeCurve } from './keyframe-curve'; diff --git a/cocos/core/curves/real-curve-param.ts b/cocos/core/curves/real-curve-param.ts index 04d2dac803a..d89cf15dff5 100644 --- a/cocos/core/curves/real-curve-param.ts +++ b/cocos/core/curves/real-curve-param.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /** * @en * The method used for interpolation method between value of a keyframe and its next keyframe. diff --git a/cocos/core/curves/solve-cubic.ts b/cocos/core/curves/solve-cubic.ts index b5bae6adb83..5a4174d738c 100644 --- a/cocos/core/curves/solve-cubic.ts +++ b/cocos/core/curves/solve-cubic.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + // cSpell:words Cardano's irreducibilis /** diff --git a/cocos/core/data/class-decorator.ts b/cocos/core/data/class-decorator.ts index 541b7d8de1f..984baf016f0 100644 --- a/cocos/core/data/class-decorator.ts +++ b/cocos/core/data/class-decorator.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -30,3 +29,8 @@ export { property } from './decorators/property'; export { requireComponent, executionOrder, disallowMultiple, allowReplicated } from './decorators/component'; export { executeInEditMode, menu, playOnFocus, inspector, icon, help } from './decorators/editable'; export { type, integer, float, boolean, string } from './decorators/type'; + +// engine internal exports +export { editable, tooltip, visible, displayName, displayOrder, range, rangeStep, slide, disallowAnimation } from './decorators/editable'; +export { override } from './decorators/override'; +export { formerlySerializedAs, serializable } from './decorators/serializable'; diff --git a/cocos/core/data/class-stash.ts b/cocos/core/data/class-stash.ts index 05715a3d7a5..477fa71d378 100644 --- a/cocos/core/data/class-stash.ts +++ b/cocos/core/data/class-stash.ts @@ -1,13 +1,37 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { IExposedAttributes } from './utils/attribute-defines'; /** * Class slash stores information collected from decorators. - * Once class decorator entered, class definition begins. It process the stash and remove it. + * Once the class decorator entered, the class definition begins. It processes the stash and removes it. */ export interface ClassStash { /** - * When extract default values under TypeScript environment, - * we have to construct an object of current class and get its member values. + * When extracting default values under the TypeScript environment, + * We have to construct an object of the current class and get its member values. * This field stores the create-once object. */ default?: unknown; @@ -24,7 +48,7 @@ export interface ClassStash { /** * The error properties. - * We record them here to ensure only once error report is given to each property. + * We record them here to ensure only once an error report is given to each property. */ errorProps?: Record; } @@ -61,17 +85,17 @@ export enum PropertyStashInternalFlag { * Indicates this property is reflected using "standalone property decorators" such as * `@editable`, `@visible`, `serializable`. * All standalone property decorators would set this flag; - * non standalone property decorators won't set this flag. + * non-standalone property decorators won't set this flag. */ STANDALONE = 1 << 0, /** - * Indicates this property is visible, if no other explicit visibility decorators(`@visible`s) attached. + * Indicates this property is visible, if no other explicit visibility decorators(`@visible`s) are attached. */ IMPLICIT_VISIBLE = 1 << 1, /** - * Indicates this property is serializable, if no other explicit visibility decorators(`@serializable`s) attached. + * Indicates this property is serializable, if no other explicit visibility decorators(`@serializable`s) are attached. */ IMPLICIT_SERIALIZABLE = 1 << 2, } diff --git a/cocos/core/data/class.ts b/cocos/core/data/class.ts index 2c075994776..aa128718e17 100644 --- a/cocos/core/data/class.ts +++ b/cocos/core/data/class.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -40,7 +39,15 @@ import { PropertyStash, PropertyStashInternalFlag } from './class-stash'; const DELIMETER = attributeUtils.DELIMETER; const CCCLASS_TAG = '__ctors__'; // Still use this historical name to avoid unsynchronized version issue + +/** + * @engineInternal + */ export const ENUM_TAG = 'Enum'; + +/** + * @engineInternal + */ export const BITMASK_TAG = 'BitMask'; function pushUnique (array, item) { @@ -49,7 +56,7 @@ function pushUnique (array, item) { } } -// both getter and prop must register the name into __props__ array +// both getter and prop must register the name into `__props__` array function appendProp (cls, name) { if (DEV) { // if (!IDENTIFIER_RE.test(name)) { @@ -190,10 +197,10 @@ function define (className, baseClass, options) { window.EditorExtends && window.EditorExtends.Component.addMenu(cls, `hidden:${renderName}/${className}`, -1); } - // Note: `options.ctor` should be same as `cls` except if + // Note: `options.ctor` should be the same as `cls` except if // cc-class is defined by `cc.Class({/* ... */})`. // In such case, `options.ctor` may be `undefined`. - // So we can not use `options.ctor`. Instead we should use `cls` which is the "real" registered cc-class. + // So we can not use `options.ctor`. Instead, we should use `cls` which is the "real" registered cc-class. EditorExtends.emit('class-registered', cls, frame, className); } @@ -236,7 +243,7 @@ function getNewValueTypeCodeJit (value) { // TODO - move escapeForJS, IDENTIFIER_RE, getNewValueTypeCodeJit to misc.js or a new source file -// convert a normal string including newlines, quotes and unicode characters into a string literal +// convert a normal string including newlines, quotes and Unicode characters into a string literal // ready to use in JavaScript source function escapeForJS (s) { return JSON.stringify(s) @@ -351,9 +358,10 @@ CCClass.Attr = attributeUtils; CCClass.attr = attributeUtils.attr; /** - * Returns if the class is a cc-class or is fast defined. + * Returns if the class is a cc-class or is fast-defined. * @param constructor The constructor of the class. * @returns Judge result. + * @engineInternal */ // eslint-disable-next-line @typescript-eslint/ban-types export function isCCClassOrFastDefined (constructor: Constructor) { @@ -470,7 +478,9 @@ function parseAttributes (constructor: Function, attributes: PropertyStash, clas if ('default' in attributes) { (attrs || initAttrs())[`${propertyNamePrefix}default`] = attributes.default; } else if (((EDITOR && !window.Build) || TEST) && warnOnNoDefault && !(attributes.get || attributes.set)) { - warnID(3654, className, propertyName); + // TODO: we close this warning for now: + // issue: https://github.com/cocos/3d-tasks/issues/14887 + // warnID(3654, className, propertyName); } const parseSimpleAttribute = (attributeName: keyof IAcceptableAttributes, expectType: string) => { @@ -506,6 +516,7 @@ function parseAttributes (constructor: Function, attributes: PropertyStash, clas } parseSimpleAttribute('slide', 'boolean'); parseSimpleAttribute('unit', 'string'); + parseSimpleAttribute('userData', 'object'); } const isStandaloneMode = attributes.__internalFlags & PropertyStashInternalFlag.STANDALONE; diff --git a/cocos/core/data/custom-serializable.ts b/cocos/core/data/custom-serializable.ts index 3cf2e3f0532..7eb64aa802a 100644 --- a/cocos/core/data/custom-serializable.ts +++ b/cocos/core/data/custom-serializable.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { assertIsNonNullable, assertIsTrue } from './utils/asserts'; /** @@ -14,7 +38,7 @@ export const deserializeTag = Symbol('[[Deserialize]]'); export interface SerializationInput { /** - * Reads a property from input. + * Reads a property from the input. * @param name Property name. * @returns The property's value, after deserialized. */ @@ -52,21 +76,22 @@ export interface SerializationOutput { export type SerializationContext = { /** - * The main serializing asset or root node in the scene/prefab passed to serialization procedure. + * The main serializing asset or root node in the scene/prefab passed to the serialization procedure. */ root: unknown; - /** * True if the serialization procedure is targeting CCON. */ toCCON: boolean; - /** * Customized arguments passed to serialization procedure. */ - customArguments: Record + customArguments: Record; }; +/** + * @engineInternal + */ export type DeserializationContext = { /** * True if the deserialization procedure is deserializing from CCON. @@ -81,7 +106,7 @@ export interface CustomSerializable { } /** - * Enables the custom serialize/deserialize method only if the (de)serialize procedure is targeting CCON. + * Enables the custom to serialize/deserialize method only if the (de)serialize procedure is targeting CCON. * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ export const enableIfCCON: MethodDecorator = ( diff --git a/cocos/core/data/decorators/ccclass.ts b/cocos/core/data/decorators/ccclass.ts index a8100b82add..f289da59d52 100644 --- a/cocos/core/data/decorators/ccclass.ts +++ b/cocos/core/data/decorators/ccclass.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEV } from 'internal:constants'; -import { js } from '../../utils/js'; +import { getSuper, mixin, getClassName } from '../../utils/js-typed'; import { CCClass } from '../class'; import { doValidateMethodWithProps_DEV } from '../utils/preprocess-class'; import { CACHE_KEY, makeSmartClassDecorator } from './utils'; @@ -52,7 +51,7 @@ import { CACHE_KEY, makeSmartClassDecorator } from './utils'; * ``` */ export const ccclass: ((name?: string) => ClassDecorator) & ClassDecorator = makeSmartClassDecorator((constructor, name) => { - let base = js.getSuper(constructor); + let base = getSuper(constructor); if (base === Object) { base = null; } @@ -67,7 +66,7 @@ export const ccclass: ((name?: string) => ClassDecorator) & ClassDecorator = mak const decoratedProto = cache.proto; if (decoratedProto) { // decoratedProto.properties = createProperties(ctor, decoratedProto.properties); - js.mixin(proto, decoratedProto); + mixin(proto, decoratedProto); } constructor[CACHE_KEY] = undefined; } @@ -83,7 +82,7 @@ export const ccclass: ((name?: string) => ClassDecorator) & ClassDecorator = mak const desc = Object.getOwnPropertyDescriptor(constructor.prototype, prop); const func = desc && desc.value; if (typeof func === 'function') { - doValidateMethodWithProps_DEV(func, prop, js.getClassName(constructor), constructor, base); + doValidateMethodWithProps_DEV(func, prop, getClassName(constructor), constructor, base); } } } diff --git a/cocos/core/data/decorators/component.ts b/cocos/core/data/decorators/component.ts index 3a07b3b90a8..0b80f1a5f01 100644 --- a/cocos/core/data/decorators/component.ts +++ b/cocos/core/data/decorators/component.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEV } from 'internal:constants'; import { CCClass } from '../class'; @@ -29,7 +28,7 @@ import { makeEditorClassDecoratorFn, makeSmartEditorClassDecorator, emptySmartCl /** * @en Declare that the current component relies on another type of component. - * If the required component doesn't exist, the engine will create a new empty instance of the required component and add to the node. + * If the required component doesn't exist, the engine will create a new empty instance of the required component and add it to the node. * @zh 为声明为 CCClass 的组件添加依赖的其它组件。当组件添加到节点上时,如果依赖的组件不存在,引擎将会自动将依赖组件添加到同一个节点,防止脚本出错。该设置在运行时同样有效。 * @param requiredComponent The required component type * @example @@ -47,10 +46,10 @@ import { makeEditorClassDecoratorFn, makeSmartEditorClassDecorator, emptySmartCl export const requireComponent: (requiredComponent: Function | Function[]) => ClassDecorator = makeEditorClassDecoratorFn('requireComponent'); /** - * @en Set the component priority, it decides at which order the life cycle functions of components will be invoked. Smaller priority get invoked before larger priority. + * @en Set the component priority, it decides at which order the life cycle functions of components will be invoked. Smaller priority gets invoked before larger priority. * This will affect `onLoad`, `onEnable`, `start`, `update` and `lateUpdate`, but `onDisable` and `onDestroy` won't be affected. * @zh 设置脚本生命周期方法调用的优先级。优先级小于 0 的组件将会优先执行,优先级大于 0 的组件将会延后执行。优先级仅会影响 onLoad, onEnable, start, update 和 lateUpdate,而 onDisable 和 onDestroy 不受影响。 - * @param priority - The execution order of life cycle methods for Component. Smaller priority get invoked before larger priority. + * @param priority - The execution order of life cycle methods for Component. Smaller priority gets invoked before larger priority. * @example * ```ts * import { _decorator, Component } from 'cc'; @@ -66,7 +65,7 @@ export const requireComponent: (requiredComponent: Function | Function[]) => Cla export const executionOrder: (priority: number) => ClassDecorator = makeEditorClassDecoratorFn('executionOrder'); /** - * @en Forbid add multiple instances of the component to the same node. + * @en Forbid adds multiple instances of the component to the same node. * @zh 防止多个相同类型(或子类型)的组件被添加到同一个节点。 * @example * ```ts @@ -84,4 +83,4 @@ export const disallowMultiple: ClassDecorator & ((yes?: boolean) => ClassDecorat export const allowReplicated: ClassDecorator = (ctor) => { CCClass.Attr.setClassAttr(ctor, 'replicated', 'visible', true); -} +}; diff --git a/cocos/core/data/decorators/editable.ts b/cocos/core/data/decorators/editable.ts index 967b7c12074..98a528cf2c5 100644 --- a/cocos/core/data/decorators/editable.ts +++ b/cocos/core/data/decorators/editable.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { DEV, EDITOR } from 'internal:constants'; +import { DEV } from 'internal:constants'; import { IExposedAttributes } from '../utils/attribute-defines'; import { getOrCreatePropertyStash } from './property'; import { PropertyStash, PropertyStashInternalFlag } from '../class-stash'; @@ -31,7 +30,7 @@ import { PropertyStash, PropertyStashInternalFlag } from '../class-stash'; import { LegacyPropertyDecorator, emptyDecorator, makeSmartEditorClassDecorator, makeEditorClassDecoratorFn, emptySmartClassDecorator, emptyDecoratorFn } from './utils'; /** - * @en Makes a CCClass that inherit from component execute in edit mode.
+ * @en Makes a CCClass that inherits from component execute in edit mode.
* By default, all components are only executed in play mode,
* which means they will not have their callback functions executed while the Editor is in edit mode.
* @zh 允许继承自 Component 的 CCClass 在编辑器里执行。
@@ -53,7 +52,7 @@ export const executeInEditMode: ClassDecorator & ((yes?: boolean) => ClassDecora /** * @en Add the current component to the specific menu path in `Add Component` selector of the inspector panel * @zh 将当前组件添加到组件菜单中,方便用户查找。例如 "Rendering/CameraCtrl"。 - * @param path - The path is the menu represented like a pathname. For example the menu could be "Rendering/CameraCtrl". + * @param path - The path is the menu represented like a pathname. For example, the menu could be "Rendering/CameraCtrl". * @example * ```ts * import { _decorator, Component } from 'cc'; @@ -70,7 +69,7 @@ export const menu: (path: string) => ClassDecorator = DEV ? makeEditorClassDe /** * @en When [[_decorator.executeInEditMode]] is set, - * this decorator will make the editor running in high FPS mode when a node with the component is focused + * This decorator will make the editor run in high FPS mode when a node with the component is focused * @zh 当指定了 [[_decorator.executeInEditMode]] 以后,playOnFocus 可以在选中当前组件所在的节点时,提高编辑器的场景刷新频率到 60 FPS,否则场景就只会在必要的时候进行重绘。 * @example * ```ts @@ -90,7 +89,7 @@ export const playOnFocus: ClassDecorator & ((yes?: boolean) => ClassDecorator) = /** * @en Use a customized inspector page in the **inspector** * @zh 自定义当前组件在 **属性检查器** 中渲染时所用的 UI 页面描述。 - * @param url The url of the page definition in js + * @param url The URL of the page definition in js * @example * ```ts * import { _decorator, Component } from 'cc'; @@ -125,10 +124,10 @@ export const inspector: (url: string) => ClassDecorator = DEV ? makeEditorCla export const icon: (url: string) => ClassDecorator = DEV ? makeEditorClassDecoratorFn('icon') : emptyDecoratorFn; /** - * @en Define the help documentation url, - * if given, the component section in the **Inspector** will have a help documentation icon reference to the web page given. + * @en Define the help documentation URL, + * if given, the component section in the **Inspector** will have a help documentation icon refers to the web page given. * @zh 指定当前组件的帮助文档的 url,设置过后,在 **属性检查器** 中就会出现一个帮助图标,用户点击将打开指定的网页。 - * @param url The url of the help documentation + * @param url The URL of the help documentation * @example * ```ts * import { _decorator, Component } from 'cc'; @@ -148,11 +147,12 @@ export const help: (url: string) => ClassDecorator = DEV ? makeEditorClassDecora * Enables the editor interoperability of the property. * @zh * 允许该属性与编辑器交互。 + * @engineInternal */ export const editable: LegacyPropertyDecorator = !DEV ? emptyDecorator - : (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); + : (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); setImplicitVisible(propertyStash); }; @@ -162,6 +162,7 @@ export const editable: LegacyPropertyDecorator = !DEV * @zh * 设置在编辑器展示该属性的条件。 * @param condition 展示条件,当返回 `true` 时展示;否则不展示。 + * @engineInternal */ export const visible: (condition: boolean | (() => boolean)) => LegacyPropertyDecorator = !DEV ? emptyDecoratorFn @@ -169,7 +170,7 @@ export const visible: (condition: boolean | (() => boolean)) => LegacyPropertyDe /** * @en - * Sets the property to be read only in editor. + * Sets the property to be read-only in the editor. * @zh * 设置该属性在编辑器中仅是可读的。 */ @@ -179,10 +180,11 @@ export const readOnly: LegacyPropertyDecorator = !DEV /** * @en - * Sets the display name of the property in editor. + * Sets the display name of the property in the editor. * @zh * 设置该属性在编辑器中的显示名称。 * @param text 显示名称。 + * @engineInternal */ export const displayName: (text: string) => LegacyPropertyDecorator = !DEV ? emptyDecoratorFn @@ -194,6 +196,7 @@ export const displayName: (text: string) => LegacyPropertyDecorator = !DEV * @zh * 设置该属性在编辑器中的工具提示内容。 * @param text 工具提示。 + * @engineInternal */ export const tooltip: (text: string) => LegacyPropertyDecorator = !DEV ? emptyDecoratorFn @@ -212,10 +215,11 @@ export const group: (options: NonNullable) => Legac /** * @en - * Sets the allowed range of the property in editor. + * Sets the allowed range of the property in the editor. * @zh * 设置该属性在编辑器中允许设置的范围。 * @param values 范围。 + * @engineInternal */ export const range: (values: [number, number, number] | [number, number]) => LegacyPropertyDecorator = !DEV ? emptyDecoratorFn @@ -223,7 +227,7 @@ export const range: (values: [number, number, number] | [number, number]) => Leg /** * @en - * Sets the allowed min value of the property in editor. + * Sets the allowed min value of the property in the editor. * @zh * 设置该属性在编辑器中允许的最小值。 * @param value 最小值。 @@ -234,7 +238,7 @@ export const rangeMin: (value: number) => LegacyPropertyDecorator = !DEV /** * @en - * Sets the allowed max value of the property in editor. + * Sets the allowed max value of the property in the editor. * @zh * 设置该属性在编辑器中允许的最大值。 * @param value 最大值。 @@ -245,10 +249,11 @@ export const rangeMax: (value: number) => LegacyPropertyDecorator = !DEV /** * @en - * Sets the step of the property in editor. + * Sets the step of the property in the editor. * @zh * 设置该属性在编辑器中的步进值。 * @param value 步进值。 + * @engineInternal */ export const rangeStep: (value: number) => LegacyPropertyDecorator = !DEV ? emptyDecoratorFn @@ -256,9 +261,10 @@ export const rangeStep: (value: number) => LegacyPropertyDecorator = !DEV /** * @en - * Enable a slider be given to coordinate the property in editor. + * Enable a slider to be given to coordinate the property in the editor. * @zh * 允许在编辑器中提供滑动条来调节值 + * @engineInternal */ export const slide: LegacyPropertyDecorator = !DEV ? emptyDecorator @@ -266,10 +272,11 @@ export const slide: LegacyPropertyDecorator = !DEV /** * @en - * Sets the display order of the property in editor. + * Sets the display order of the property in the editor. * @zh * 设置该属性在编辑器中的显示顺序。 * @param order 显示顺序。 + * @engineInternal */ export const displayOrder: (order: number) => LegacyPropertyDecorator = !DEV ? emptyDecoratorFn @@ -277,7 +284,7 @@ export const displayOrder: (order: number) => LegacyPropertyDecorator = !DEV /** * @en - * Sets the unit of the property in editor. + * Sets the unit of the property in the editor. * @zh * 设置该属性在编辑器中的计量单位。 * @param name 计量单位的名称。 @@ -292,7 +299,7 @@ export const unit: (name: /** * @en - * Sets to convert the value into radian before feed it to the property in editor. + * Sets to convert the value into radian before feeding it to the property in the editor. * @zh * 设置在编辑器中赋值该属性前将值先转换为弧度制。 */ @@ -312,14 +319,15 @@ export const multiline: LegacyPropertyDecorator = !DEV /** * @en - * Sets the property so that it does not interop with the animation parts in editor. + * Sets the property so that it does not interop with the animation parts in the editor. * @zh * 设置该属性不参与编辑器中动画相关的交互。 + * @engineInternal */ export const disallowAnimation: LegacyPropertyDecorator = !DEV ? emptyDecorator - : (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); + : (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); propertyStash.animatable = false; }; @@ -327,8 +335,8 @@ function setPropertyStashWithImplicitVisible ( key: TKey, value: NonNullable, ): LegacyPropertyDecorator { - return (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); + return (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); propertyStash[key] = value; setImplicitVisible(propertyStash); }; @@ -337,8 +345,8 @@ function setPropertyStashWithImplicitVisible ( function setPropertyStashVar1WithImplicitVisible ( key: TKey, ) { - return (value: NonNullable): LegacyPropertyDecorator => (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); + return (value: NonNullable): LegacyPropertyDecorator => (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); propertyStash[key] = value; setImplicitVisible(propertyStash); }; @@ -351,8 +359,8 @@ function setImplicitVisible (propertyStash: PropertyStash) { function setPropertyStashWithImplicitI18n ( key: TKey, ) { - return (value: NonNullable): LegacyPropertyDecorator => (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); + return (value: NonNullable): LegacyPropertyDecorator => (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); const prefix = 'i18n:'; if (value.startsWith(prefix)) { const extensionPrefix = 'ENGINE.'; diff --git a/cocos/core/data/decorators/index.ts b/cocos/core/data/decorators/index.ts index 0c2f2a065df..290e88ba373 100644 --- a/cocos/core/data/decorators/index.ts +++ b/cocos/core/data/decorators/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export { ccclass } from './ccclass'; export * from './component'; diff --git a/cocos/core/data/decorators/override.ts b/cocos/core/data/decorators/override.ts index 04211fc11e4..642990ce470 100644 --- a/cocos/core/data/decorators/override.ts +++ b/cocos/core/data/decorators/override.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { LegacyPropertyDecorator } from './utils'; import { getOrCreatePropertyStash } from './property'; -export const override: LegacyPropertyDecorator = (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); +/** + * + * @engineInternal + */ +export const override: LegacyPropertyDecorator = (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); propertyStash.override = true; }; diff --git a/cocos/core/data/decorators/property.ts b/cocos/core/data/decorators/property.ts index 9adaf59ea46..2257095766d 100644 --- a/cocos/core/data/decorators/property.ts +++ b/cocos/core/data/decorators/property.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEV, EDITOR, JSB, TEST } from 'internal:constants'; import { CCString, CCInteger, CCFloat, CCBoolean } from '../utils/attribute'; import { IExposedAttributes } from '../utils/attribute-defines'; -import { LegacyPropertyDecorator, getSubDict, getClassCache, BabelPropertyDecoratorDescriptor } from './utils'; +import { LegacyPropertyDecorator, getSubDict, getClassCache, BabelPropertyDecoratorDescriptor, Initializer } from './utils'; import { warnID, errorID } from '../../platform/debug'; -import { js } from '../../utils/js'; import { getFullFormOfProperty } from '../utils/preprocess-class'; import { ClassStash, PropertyStash, PropertyStashInternalFlag } from '../class-stash'; +import { getClassName, mixin } from '../../utils/js-typed'; // eslint-disable-next-line @typescript-eslint/ban-types export type SimplePropertyType = Function | string | typeof CCString | typeof CCInteger | typeof CCFloat | typeof CCBoolean; @@ -66,15 +65,15 @@ export function property (type: PropertyType): LegacyPropertyDecorator; export function property (...args: Parameters): void; export function property ( - target?: Parameters[0], + target?: Parameters[0] | PropertyType, propertyKey?: Parameters[1], - descriptor?: Parameters[2], + descriptorOrInitializer?: Parameters[2], ) { let options: IPropertyOptions | PropertyType | null = null; function normalized ( target: Parameters[0], propertyKey: Parameters[1], - descriptor: Parameters[2], + descriptorOrInitializer: Parameters[2], ) { const classStash = getOrCreateClassStash(target); const propertyStash = getOrCreateEmptyPropertyStash( @@ -88,7 +87,7 @@ export function property ( classConstructor, propertyKey, options, - descriptor, + descriptorOrInitializer, ); } @@ -104,12 +103,12 @@ export function property ( return normalized; } else { // @property - normalized(target, propertyKey, descriptor); + normalized(target as Parameters[0], propertyKey, descriptorOrInitializer); return undefined; } } -function getDefaultFromInitializer (initializer: () => unknown) { +function getDefaultFromInitializer (initializer: Initializer) { let value: unknown; try { value = initializer(); @@ -121,7 +120,7 @@ function getDefaultFromInitializer (initializer: () => unknown) { // string boolean number function undefined null return value; } else { - // The default attribute will not be used in ES6 constructor actually, + // The default attribute will not be used in the ES6 constructor actually, // so we don't need to simplify into `{}` or `[]` or vec2 completely. return initializer; } @@ -134,7 +133,7 @@ function extractActualDefaultValues (classConstructor: new () => unknown) { dummyObj = new classConstructor(); } catch (e) { if (DEV) { - warnID(3652, js.getClassName(classConstructor), e); + warnID(3652, getClassName(classConstructor), e); } return {}; } @@ -160,19 +159,19 @@ function getOrCreateEmptyPropertyStash ( export function getOrCreatePropertyStash ( target: Parameters[0], propertyKey: Parameters[1], - descriptor?: BabelPropertyDecoratorDescriptor, + descriptorOrInitializer?: Parameters[2], ): PropertyStash { const classStash = getClassCache(target.constructor) as ClassStash; const ccclassProto = getSubDict(classStash, 'proto'); const properties = getSubDict(ccclassProto, 'properties'); const propertyStash = properties[(propertyKey as string)] ??= {} as PropertyStash; propertyStash.__internalFlags |= PropertyStashInternalFlag.STANDALONE; - if (descriptor && (descriptor.get || descriptor.set)) { - if (descriptor.get) { - propertyStash.get = descriptor.get; + if (descriptorOrInitializer && typeof descriptorOrInitializer !== 'function' && (descriptorOrInitializer.get || descriptorOrInitializer.set)) { + if (descriptorOrInitializer.get) { + propertyStash.get = descriptorOrInitializer.get; } - if (descriptor.set) { - propertyStash.set = descriptor.set; + if (descriptorOrInitializer.set) { + propertyStash.set = descriptorOrInitializer.set; } } else { setDefaultValue( @@ -180,7 +179,7 @@ export function getOrCreatePropertyStash ( propertyStash, target.constructor as new () => unknown, propertyKey, - descriptor, + descriptorOrInitializer, ); } return propertyStash; @@ -192,15 +191,16 @@ function mergePropertyOptions ( ctor, propertyKey: Parameters[1], options, - descriptor: Parameters[2] | undefined, + descriptorOrInitializer: Parameters[2] | undefined, ) { let fullOptions; - const isGetset = descriptor && (descriptor.get || descriptor.set); + const isGetset = descriptorOrInitializer && typeof descriptorOrInitializer !== 'function' + && (descriptorOrInitializer.get || descriptorOrInitializer.set); if (options) { fullOptions = getFullFormOfProperty(options, isGetset); } // @ts-expect-error enum PropertyStashInternalFlag is used as number - const propertyRecord: PropertyStash = js.mixin(propertyStash, fullOptions || options || {}); + const propertyRecord: PropertyStash = mixin(propertyStash, fullOptions || options || {}); if (isGetset) { // typescript or babel @@ -208,19 +208,19 @@ function mergePropertyOptions ( const errorProps = getSubDict(cache, 'errorProps'); if (!errorProps[(propertyKey as string)]) { errorProps[(propertyKey as string)] = true; - warnID(3655, propertyKey, js.getClassName(ctor), propertyKey, propertyKey); + warnID(3655, propertyKey, getClassName(ctor), propertyKey, propertyKey); } } - if (descriptor!.get) { - propertyRecord.get = descriptor!.get; + if ((descriptorOrInitializer as BabelPropertyDecoratorDescriptor).get) { + propertyRecord.get = (descriptorOrInitializer as BabelPropertyDecoratorDescriptor).get; } - if (descriptor!.set) { - propertyRecord.set = descriptor!.set; + if ((descriptorOrInitializer as BabelPropertyDecoratorDescriptor).set) { + propertyRecord.set = (descriptorOrInitializer as BabelPropertyDecoratorDescriptor).set; } } else { // Target property is non-accessor if (DEV && (propertyRecord.get || propertyRecord.set)) { // Specify "accessor options" for non-accessor property is forbidden. - errorID(3655, propertyKey, js.getClassName(ctor), propertyKey, propertyKey); + errorID(3655, propertyKey, getClassName(ctor), propertyKey, propertyKey); return; } @@ -229,13 +229,13 @@ function mergePropertyOptions ( propertyRecord, ctor, propertyKey, - descriptor, + descriptorOrInitializer, ); if ((EDITOR && !window.Build) || TEST) { // eslint-disable-next-line no-prototype-builtins if (!fullOptions && options && options.hasOwnProperty('default')) { - warnID(3653, propertyKey, js.getClassName(ctor)); + warnID(3653, propertyKey, getClassName(ctor)); } } } @@ -246,24 +246,24 @@ function setDefaultValue ( propertyStash: PropertyStash, classConstructor: new () => T, propertyKey: PropertyKey, - descriptor: BabelPropertyDecoratorDescriptor | undefined, + descriptorOrInitializer: BabelPropertyDecoratorDescriptor | Initializer | undefined | null, ) { - // Default values are needed by editor, and now editor run with web version, so don't - // have to provide default values. - if (JSB) { - return; - } - - if (descriptor) { - // In case of Babel, if an initializer is given for class field. - // That initializer is passed to `descriptor.initializer`. - // babel - if (descriptor.initializer) { - propertyStash.default = getDefaultFromInitializer(descriptor.initializer); + if (descriptorOrInitializer !== undefined) { + if (typeof descriptorOrInitializer === 'function') { + propertyStash.default = getDefaultFromInitializer(descriptorOrInitializer); + } else if (descriptorOrInitializer === null) { + // For some decorated properties we haven't specified the default value, then the initializer should be null. + // We fall back to the behavior of v3.6.3, where we don't specify the default value automatically. + // propertyStash.default = undefined; + } else if (descriptorOrInitializer.initializer) { + // In the case of Babel, if an initializer is given for a class field. + // That initializer is passed to `descriptor.initializer`. + propertyStash.default = getDefaultFromInitializer(descriptorOrInitializer.initializer); } } else { - // In case of TypeScript, we can not directly capture the initializer. + // In the case of TypeScript, we can not directly capture the initializer. // We have to be hacking to extract the value. + // We should fall back to the TypeScript case only when `descriptorOrInitializer` is undefined. const actualDefaultValues = classStash.default || (classStash.default = extractActualDefaultValues(classConstructor)); // eslint-disable-next-line no-prototype-builtins if ((actualDefaultValues as any).hasOwnProperty(propertyKey)) { diff --git a/cocos/core/data/decorators/serializable.ts b/cocos/core/data/decorators/serializable.ts index 66adc61fdb1..93f522f4659 100644 --- a/cocos/core/data/decorators/serializable.ts +++ b/cocos/core/data/decorators/serializable.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, TEST } from 'internal:constants'; import { emptyDecorator, LegacyPropertyDecorator } from './utils'; @@ -30,18 +29,25 @@ import { PropertyStash, PropertyStashInternalFlag } from '../class-stash'; import { getOrCreateSerializationMetadata } from '../serialization-metadata'; /** - * True if serialization feature is enabled in current environment. + * True if the serialization feature is enabled in the current environment. + * @engineInternal */ const WITH_SERIALIZATION = EDITOR || TEST; -export const serializable: LegacyPropertyDecorator = (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); +/** + * @engineInternal + */ +export const serializable: LegacyPropertyDecorator = (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); setImplicitSerializable(propertyStash); }; +/** + * @engineInternal + */ export function formerlySerializedAs (name: string): LegacyPropertyDecorator { - return (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); + return (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); propertyStash.formerlySerializedAs = name; setImplicitSerializable(propertyStash); }; @@ -53,8 +59,8 @@ export function formerlySerializedAs (name: string): LegacyPropertyDecorator { * @zh * 设置该属性仅在编辑器中生效。 */ -export const editorOnly: LegacyPropertyDecorator = (target, propertyKey, descriptor) => { - const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptor); +export const editorOnly: LegacyPropertyDecorator = (target, propertyKey, descriptorOrInitializer) => { + const propertyStash = getOrCreatePropertyStash(target, propertyKey, descriptorOrInitializer); propertyStash.editorOnly = true; setImplicitSerializable(propertyStash); }; @@ -66,9 +72,9 @@ function setImplicitSerializable (propertyStash: PropertyStash) { /** * @en * Marks the target class as "uniquely referenced" which means, in the aspect of serialization, - * no more than one objects should reference to same instance of that class. + * no more than one object should reference the same instance of that class. * When serializing references to objects of such class, - * they're treated as different object even they point to actually the same. + * they're treated as different objects even if they point to actually the same. * While deserializing, these two references would point two distinct objects. * For example: * ```ts diff --git a/cocos/core/data/decorators/type.ts b/cocos/core/data/decorators/type.ts index 1f94d1d38b1..b443de40918 100644 --- a/cocos/core/data/decorators/type.ts +++ b/cocos/core/data/decorators/type.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { LegacyPropertyDecorator } from './utils'; import { property } from './property'; diff --git a/cocos/core/data/decorators/utils.ts b/cocos/core/data/decorators/utils.ts index d5d28785b85..0f8a229523d 100644 --- a/cocos/core/data/decorators/utils.ts +++ b/cocos/core/data/decorators/utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,24 +20,29 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEV } from 'internal:constants'; import { CCClass } from '../class'; import { error } from '../../platform/debug'; -import { js } from '../../utils/js'; +import { getClassName } from '../../utils/js-typed'; + +export type Initializer = () => unknown; -export type BabelPropertyDecoratorDescriptor = PropertyDescriptor & { initializer?: any }; +export type BabelPropertyDecoratorDescriptor = PropertyDescriptor & { initializer?: Initializer }; /** * @en - * The signature compatible with both TypeScript legacy decorator and Babel legacy decorator. - * The `descriptor` argument will only appear in Babel case. + * The signature is compatible with both the TypeScript legacy decorator and the Babel legacy decorator. + * The third argument is `descriptor` in the Babel case. + * For some engine internally optimized decorators, the third argument is the initializer. * @zh * 该签名同时兼容 TypeScript legacy 装饰器以及 Babel legacy 装饰器。 - * `descriptor` 参数只会在 Babel 情况下出现。 + * 第三个参数在 Babel 情况下,会传入 descriptor。对于一些被优化的引擎内部装饰器,会传入 initializer。 */ -export type LegacyPropertyDecorator = (target: Object, propertyKey: string | symbol, descriptor?: BabelPropertyDecoratorDescriptor) => void; +export type LegacyPropertyDecorator = ( + target: Record, propertyKey: string | symbol, descriptorOrInitializer?: BabelPropertyDecoratorDescriptor | Initializer | null, +) => void; /** * @en @@ -50,7 +54,7 @@ export const emptyDecorator: ClassDecorator & LegacyPropertyDecorator = () => {} /** * @en - * A function which ignore all arguments and return the `emptyDecorator`. + * A function that ignores all arguments and returns the `emptyDecorator`. * @zh * 一个忽略所有参数并且返回 `emptyDecorator` 的函数。 */ @@ -71,7 +75,7 @@ export const emptySmartClassDecorator = makeSmartClassDecorator(() => {}); * - `@x` * - `@x(arg0)` * - * and forward both the decorated class and the `arg0` (in first form, `arg0` is forward as `undefined`) to + * and forward both the decorated class and the `arg0` (in the first form, `arg0` is forwarded as `undefined`) to * `decorate`. * @zh * 创建一个智能类装饰器,它能正确地处理以下形式的装饰器语法: @@ -82,7 +86,7 @@ export const emptySmartClassDecorator = makeSmartClassDecorator(() => {}); * @param decorate */ export function makeSmartClassDecorator ( - decorate: (constructor: TFunction, arg?: TArg) => ReturnType, + decorate: (constructor: TFunction, arg?: TArg) => ReturnType, ): ClassDecorator & ((arg?: TArg) => ClassDecorator) { return proxyFn; function proxyFn(...args: Parameters): ReturnType; @@ -92,14 +96,14 @@ export function makeSmartClassDecorator ( // If no parameter specified return decorate(target); } else { - return function (constructor: TFunction) { + return function (constructor: TFunction) { return decorate(constructor, target); }; } } } -function writeEditorClassProperty (constructor: Function, propertyName: string, value: TValue) { +function writeEditorClassProperty (constructor: AnyFunction, propertyName: string, value: TValue) { const cache = getClassCache(constructor, propertyName); if (cache) { const proto = getSubDict(cache, 'proto'); @@ -109,7 +113,7 @@ function writeEditorClassProperty (constructor: Function, propertyName: /** * @en - * Make a function which accept an argument value and return a class decorator. + * Make a function that accepts an argument value and returns a class decorator. * The decorator sets the editor property `propertyName`, on the decorated class, into that argument value. * @zh * 创建一个函数,该函数接受一个参数值并返回一个类装饰器。 @@ -117,7 +121,7 @@ function writeEditorClassProperty (constructor: Function, propertyName: * @param propertyName The editor property. */ export function makeEditorClassDecoratorFn (propertyName: string): (value: TValue) => ClassDecorator { - return (value: TValue) => (constructor: TFunction) => { + return (value: TValue) => (constructor: TFunction) => { writeEditorClassProperty(constructor, propertyName, value); }; } @@ -145,9 +149,10 @@ export const CACHE_KEY = '__ccclassCache__'; export function getClassCache (ctor, decoratorName?) { if (DEV && CCClass._isCCClass(ctor)) { - error('`@%s` should be used after @ccclass for class "%s"', decoratorName, js.getClassName(ctor)); + error('`@%s` should be used after @ccclass for class "%s"', decoratorName, getClassName(ctor)); return null; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return getSubDict(ctor, CACHE_KEY); } diff --git a/cocos/core/data/deserialize-dynamic-empty.ts b/cocos/core/data/deserialize-dynamic-empty.ts deleted file mode 100644 index 9e91fbedb03..00000000000 --- a/cocos/core/data/deserialize-dynamic-empty.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export function deserializeDynamic() { - throw new Error(`Should not called`); -} - -export function parseUuidDependenciesDynamic() { - throw new Error(`Should not called`); -} diff --git a/cocos/core/data/deserialize-symbols.ts b/cocos/core/data/deserialize-symbols.ts deleted file mode 100644 index 6e91702b709..00000000000 --- a/cocos/core/data/deserialize-symbols.ts +++ /dev/null @@ -1 +0,0 @@ -export const onAfterDeserializedTag = Symbol('[[OnAfterDeserialized]]'); diff --git a/cocos/core/data/editor-extendable.ts b/cocos/core/data/editor-extendable.ts index 559b83aa556..38a8cf6f59b 100644 --- a/cocos/core/data/editor-extendable.ts +++ b/cocos/core/data/editor-extendable.ts @@ -1,17 +1,40 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; import { ccclass, editorOnly } from 'cc.decorator'; -import { js } from '../utils/js'; -import { CCClass } from './class'; +import { getClassName } from '../utils/js'; import { EditorExtendableObject, editorExtrasTag } from './editor-extras-tag'; import { assertIsTrue } from './utils/asserts'; // Functions and classes exposed from this module are useful to // make a class to be `EditorExtendableObject`. // -// These helpers are used internally, don't expose them to user. +// These helpers are used internally, don't expose them to the user. /** - * Creates a mixin class which inherits from specific base class and implements the `EditorExtendableObject` interface. + * Creates a mixin class that inherits from the specific base class and implements the `EditorExtendableObject` interface. * @param Base The base class. * @param className Assign an optional cc class name. If the base class is not cc class, this param is required. * @returns The mixin class. @@ -24,6 +47,7 @@ class Empty {} /** * Class which implements the `EditorExtendableObject` interface. + * @engineInternal */ export const EditorExtendable = editorExtendableInternal(); @@ -47,7 +71,7 @@ function editorExtendableInternal (Base?: (new (...args: any[]) => T), classN } else if (!Base) { name = `cc.EditorExtendable`; } else { - const baseName = js.getClassName(Base); + const baseName = getClassName(Base); if (baseName) { name = `cc.EditorExtendable/${baseName}`; } else { diff --git a/cocos/core/data/editor-extras-tag.ts b/cocos/core/data/editor-extras-tag.ts index fe47315fe35..4a06478d653 100644 --- a/cocos/core/data/editor-extras-tag.ts +++ b/cocos/core/data/editor-extras-tag.ts @@ -1,11 +1,34 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /** - * Tag to visit editor extras of an object. Never concern about its value please. - * @internal + * Tag to visit editor extras of an object. Never be concerned about its value, please. */ export const editorExtrasTag = '__editorExtras__'; /** - * Engine classes with this kind of signatures are integrated with editor extendability. + * Engine classes with this kind of signature are integrated with editor extendability. * @internal */ export interface EditorExtendableObject { @@ -14,10 +37,10 @@ export interface EditorExtendableObject { * The editor extras on this object. * * BE CAREFUL: this property is currently governed by Cocos Creator Editor. - * Its definition is not visible and is unknown to both engine code or users codes, - * they SHALL NOT operates it. + * Its definition is not visible and is unknown to both engine code and users codes, + * they SHALL NOT operate it. * - * You should use editor extras tag to visit this property. + * You should use the editor extras tag to visit this property. * @example * ```ts * import { editorExtrasTag } from 'cc'; diff --git a/cocos/core/data/garbage-collection.ts b/cocos/core/data/garbage-collection.ts index d4c4ba7a8d3..be818f15dd1 100644 --- a/cocos/core/data/garbage-collection.ts +++ b/cocos/core/data/garbage-collection.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,7 +18,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { GCObject } from './gc-object'; @@ -80,5 +81,8 @@ class GarbageCollectionManager { } } +/** + * @engineInternal + */ const garbageCollectionManager = new GarbageCollectionManager(); export { garbageCollectionManager }; diff --git a/cocos/core/data/gc-object.ts b/cocos/core/data/gc-object.ts index 065b81c09cb..dd73447291f 100644 --- a/cocos/core/data/gc-object.ts +++ b/cocos/core/data/gc-object.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,6 +21,9 @@ */ import { garbageCollectionManager } from './garbage-collection'; +/** + * @engineInternal + */ export class GCObject { constructor () { return garbageCollectionManager.registerGCObject(this); diff --git a/cocos/core/data/index.ts b/cocos/core/data/index.ts index e348ce597f2..800783cf829 100644 --- a/cocos/core/data/index.ts +++ b/cocos/core/data/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,13 +27,8 @@ import { legacyCC } from '../global-exports'; legacyCC._decorator = _decorator; export { _decorator }; -export { CCClass } from './class'; -export { CCObject, isValid } from './object'; -export { deserialize } from './deserialize'; -export { Details } from './deserialize'; -export { getSerializationMetadata } from './serialization-metadata'; -export type { SerializationMetadata } from './serialization-metadata'; -export { instantiate } from './instantiate'; +export { CCClass, isCCClassOrFastDefined } from './class'; +export { CCObject } from './object'; export { CCInteger, CCFloat, CCBoolean, CCString } from './utils/attribute'; export { CompactValueTypeArray } from './utils/compact-value-type-array'; export { editorExtrasTag } from './editor-extras-tag'; @@ -45,3 +39,6 @@ export type { SerializationContext, CustomSerializable, } from './custom-serializable'; +export { getSerializationMetadata } from './serialization-metadata'; +export type { SerializationMetadata } from './serialization-metadata'; +export { EditorExtendable } from './editor-extendable'; diff --git a/cocos/core/data/object.ts b/cocos/core/data/object.ts index 0d5293da16f..f6b56dada71 100644 --- a/cocos/core/data/object.ts +++ b/cocos/core/data/object.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -384,6 +383,16 @@ class CCObject implements EditorExtendableObject { } if (!EDITOR || legacyCC.GAME_VIEW) { + /*Native properties cannot be reset by _destruct, because the native properties are hung on the prototype and + *hasOwnProperty's detection cannot be passed. + */ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + if (JSB && this.destruct) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + this.destruct(); + } this._destruct(); } @@ -636,6 +645,7 @@ declare namespace CCObject { * @method isCCObject * @param object * @return @en Whether it is a CCObject boolean value. @zh 是否为CCObject的布尔值。 + * @engineInternal */ export function isCCObject (object: any) { return object instanceof CCObject; diff --git a/cocos/core/data/report-missing-class.ts b/cocos/core/data/report-missing-class.ts deleted file mode 100644 index 8de53b33214..00000000000 --- a/cocos/core/data/report-missing-class.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { EDITOR } from 'internal:constants'; -import { errorID } from '../platform/debug'; - -export function reportMissingClass (id: string) { - if (EDITOR && EditorExtends.UuidUtils.isUuid(id)) { - id = EditorExtends.UuidUtils.decompressUuid(id); - errorID(5301, id); - } else { - errorID(5302, id); - } -} diff --git a/cocos/core/data/serialization-metadata.ts b/cocos/core/data/serialization-metadata.ts index 8c4a5106d3a..c2b4e910cd7 100644 --- a/cocos/core/data/serialization-metadata.ts +++ b/cocos/core/data/serialization-metadata.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + const sMetadataTag = Symbol('cc:SerializationMetadata'); /** diff --git a/cocos/core/data/utils/asserts.ts b/cocos/core/data/utils/asserts.ts index 57b5293a845..b85f31229d9 100644 --- a/cocos/core/data/utils/asserts.ts +++ b/cocos/core/data/utils/asserts.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,6 +28,7 @@ import { DEBUG } from 'internal:constants'; * Asserts that the expression is non-nullable, i.e. is neither `null` nor `undefined`. * @param expr Testing expression. * @param message Optional message. + * @engineInternal */ export function assertIsNonNullable (expr: T, message?: string): asserts expr is NonNullable { assertIsTrue(!(expr === null || expr === undefined), message); @@ -38,6 +38,7 @@ export function assertIsNonNullable (expr: T, message?: string): asserts expr * Asserts that the expression evaluated to `true`. * @param expr Testing expression. * @param message Optional message. + * @engineInternal */ export function assertIsTrue (expr: unknown, message?: string): asserts expr { if (DEBUG && !expr) { @@ -47,6 +48,10 @@ export function assertIsTrue (expr: unknown, message?: string): asserts expr { } } +/** + * Assets that the index is valid. + * @engineInternal + */ export function assertsArrayIndex (array: T[], index: number) { assertIsTrue(index >= 0 && index < array.length, `Array index ${index} out of bounds: [0, ${array.length})`); } diff --git a/cocos/core/data/utils/attribute-defines.ts b/cocos/core/data/utils/attribute-defines.ts index 1efe45de27f..00ac68b39d0 100644 --- a/cocos/core/data/utils/attribute-defines.ts +++ b/cocos/core/data/utils/attribute-defines.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ type GroupOptions = { name: string; } & Partial<{ id: string; @@ -142,6 +141,12 @@ export interface IExposedAttributes { * 转换为弧度 */ radian?: boolean; + + /** + * @en User custom data, which can be obtained through the `CCClass.attr()` interface. + * @zh 用户自定义数据,可以通过 `CCClass.attr()` 接口获取自定义数据。 + */ + userData?: Record; } export interface IAcceptableAttributes extends IExposedAttributes { diff --git a/cocos/core/data/utils/attribute.ts b/cocos/core/data/utils/attribute.ts index 2ece3db5812..5316d4196ec 100644 --- a/cocos/core/data/utils/attribute.ts +++ b/cocos/core/data/utils/attribute.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -69,7 +68,7 @@ export function createAttrs (subclass: any) { * Tag the class with any meta attributes, then return all current attributes assigned to it. * This function holds only the attributes, not their implementations. * @param constructor The class or instance. If instance, the attribute will be dynamic and only available for the specified instance. - * @param propertyName The name of property or function, used to retrieve the attributes. + * @param propertyName The name of the property or function, used to retrieve the attributes. * @private */ export function attr (constructor: any, propertyName: string): { [attributeName: string]: any; } { @@ -85,7 +84,7 @@ export function attr (constructor: any, propertyName: string): { [attributeName: } /** - * Returns a readonly meta object. + * Returns a read-only meta-object. */ export function getClassAttrs (constructor: any) { return (constructor.hasOwnProperty('__attrs__') && constructor.__attrs__) || createAttrs(constructor); @@ -112,14 +111,14 @@ export class PrimitiveType { /** * @en - * Indicates that the editor should treats this property or array element as a Integer value. + * Indicates that the editor should treat this property or array element as an Integer value. * @zh * 指定编辑器以整数形式对待该属性或数组元素。 * @example * ```ts * import { CCInteger, _decorator } from "cc"; * - * // in class definition: + * // in the class definition: * * @_decorator.property({type: CCInteger}) * count = 0; @@ -134,14 +133,14 @@ legacyCC.CCInteger = CCInteger; /** * @en - * Indicates that the editor should treats this property or array element as a Float value. + * Indicates that the editor should treat this property or array element as a Float value. * @zh * 指定编辑器以浮点数形式对待该属性或数组元素。 * @example * ```ts * import { CCFloat, _decorator } from "cc"; * - * // in class definition: + * // in the class definition: * * @_decorator.property({type: CCFloat}) * x = 0; @@ -163,14 +162,14 @@ if (EDITOR) { /** * @en - * Indicates that the editor should treats this property or array element as a Boolean value. + * Indicates that the editor should treat this property or array element as a Boolean value. * @zh * 指定编辑器以布尔值形式对待该属性或数组元素。 * * @example * ```ts * import { CCBoolean, _decorator } from "cc"; - * // in class definition + * // in the class definition * @_decorator.property({type: CCBoolean}) * isTrue = false; * @@ -184,14 +183,14 @@ legacyCC.CCBoolean = CCBoolean; /** * @en - * Indicates that the editor should treats this property or array element as a String value. + * Indicates that the editor should treat this property or array element as a String value. * @zh * 指定编辑器以字符串形式对待该属性或数组元素。 * @example * ```ts * import { CCString, _decorator } from "cc"; * - * // in class definition + * // in the class definition * * @_decorator.property({type: CCString}) * name = ''; diff --git a/cocos/core/data/utils/compact-value-type-array.ts b/cocos/core/data/utils/compact-value-type-array.ts index 4594ffc4562..54f41685fc1 100644 --- a/cocos/core/data/utils/compact-value-type-array.ts +++ b/cocos/core/data/utils/compact-value-type-array.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; import { Vec3, Quat, Vec4, Vec2, Mat4 } from '../../math'; @@ -66,7 +65,7 @@ export class CompactValueTypeArray { public static ElementType = ElementType; /** - * Offset into buffer, in bytes. + * Offset into the buffer, in bytes. */ @serializable private _byteOffset = 0; diff --git a/cocos/core/data/utils/compiler.ts b/cocos/core/data/utils/compiler.ts index 7ed108c40d5..36013d8aa76 100644 --- a/cocos/core/data/utils/compiler.ts +++ b/cocos/core/data/utils/compiler.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -40,6 +39,10 @@ function deepFlatten (strList, array) { } } +/** + * + * @engineInternal + */ export function flattenCodeArray (array) { const separator = DEV ? '\n' : ''; const strList = []; diff --git a/cocos/core/data/utils/constget.ts b/cocos/core/data/utils/constget.ts index 73f1277f268..34e59b9b01b 100644 --- a/cocos/core/data/utils/constget.ts +++ b/cocos/core/data/utils/constget.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEBUG } from 'internal:constants'; diff --git a/cocos/core/data/utils/extends-enum.ts b/cocos/core/data/utils/extends-enum.ts index 4feb509a8b2..546ed14c86e 100644 --- a/cocos/core/data/utils/extends-enum.ts +++ b/cocos/core/data/utils/extends-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEV } from 'internal:constants'; import { errorID } from '../../platform/debug'; @@ -32,10 +31,10 @@ import { errorID } from '../../platform/debug'; * 此函数的行为等价于返回了一个新的枚举,其成员囊括了所有源枚举的成员。 * 这些枚举的成员必须各不相同(包括成员名和值),否则行为是未定义的。 * @en - * Combine arbitray number of enumerations. - * It behaves like an enumeration having members that is a combination of members of the source enumerations + * Combine an arbitrary number of enumerations. + * It behaves like an enumeration having members that are a combination of members of the source enumerations * is returned. - * These enumerations shall have non-overlaped member names or member values. + * These enumerations shall have non-overlapped member names or member values. * If not, the behavior is undefined. * @example * ```ts diff --git a/cocos/core/data/utils/preprocess-class.ts b/cocos/core/data/utils/preprocess-class.ts index 61613a5f903..503188ab8b6 100644 --- a/cocos/core/data/utils/preprocess-class.ts +++ b/cocos/core/data/utils/preprocess-class.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/data/utils/requiring-frame.ts b/cocos/core/data/utils/requiring-frame.ts index ded64311834..98dff14dbf1 100644 --- a/cocos/core/data/utils/requiring-frame.ts +++ b/cocos/core/data/utils/requiring-frame.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/deprecated-3.7.0.ts b/cocos/core/deprecated-3.7.0.ts new file mode 100644 index 00000000000..a8c5cb78262 --- /dev/null +++ b/cocos/core/deprecated-3.7.0.ts @@ -0,0 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { js, markAsWarning } from './utils'; + +markAsWarning(js, 'js', [ + { + name: 'js', + suggest: `'js.js' is deprecated since v3.7.0, please access 'js' directly instead.`, + }, +]); diff --git a/cocos/core/deprecated.ts b/cocos/core/deprecated.ts index cb501d39083..bf9f6451ed3 100644 --- a/cocos/core/deprecated.ts +++ b/cocos/core/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { replaceProperty, removeProperty } from './utils/x-deprecated'; import * as math from './math'; import { Scheduler } from './scheduler'; import { legacyCC } from './global-exports'; -import System from './system'; +import { System } from './system'; // VMATH diff --git a/cocos/core/distributed/utils.ts b/cocos/core/distributed/utils.ts deleted file mode 100644 index e9ab1178e4c..00000000000 --- a/cocos/core/distributed/utils.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. - - http://www.cocos.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -import { CCObject, IsClientLoad } from "../data/object"; - -export function isClientLoad (obj: CCObject) { - return !!(obj._objFlags & IsClientLoad); -} -export function setClientLoad (obj: CCObject, value: boolean) { - if (value) { - obj._objFlags |= IsClientLoad; - } else { - obj._objFlags &= ~IsClientLoad; - } -} \ No newline at end of file diff --git a/cocos/core/effect-settings.ts b/cocos/core/effect-settings.ts new file mode 100644 index 00000000000..11843fb0a3b --- /dev/null +++ b/cocos/core/effect-settings.ts @@ -0,0 +1,66 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { HTML5 } from 'internal:constants'; +import { legacyCC } from './global-exports'; + +declare const fsUtils: any; + +export class EffectSettings { + init (path = ''): Promise { + if (!legacyCC.rendering || !legacyCC.rendering.enableEffectImport || !path) { + return Promise.resolve(); + } + return new Promise((resolve, reject) => { + if (!HTML5 && !path.startsWith('http')) { + fsUtils.readArrayBuffer(path, (err: Error, arrayBuffer: ArrayBuffer) => { + if (err) { + reject(err); + return; + } + this._data = arrayBuffer; + resolve(); + }); + } else { + const xhr = new XMLHttpRequest(); + xhr.open('GET', path); + xhr.responseType = 'arraybuffer'; + xhr.onload = () => { + this._data = xhr.response; + resolve(); + }; + xhr.onerror = () => { + reject(new Error('request effect settings failed!')); + }; + xhr.send(null); + } + }); + } + get data (): ArrayBuffer | null { + return this._data; + } + private _data: ArrayBuffer | null = null; +} + +export const effectSettings = new EffectSettings(); +legacyCC.effectSettings = effectSettings; diff --git a/cocos/core/event/async-delegate.ts b/cocos/core/event/async-delegate.ts index a192a6c23ec..3bc2e2990a2 100644 --- a/cocos/core/event/async-delegate.ts +++ b/cocos/core/event/async-delegate.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ -import { js } from '../utils/js'; +import { array } from '../utils/js'; /** * @zh @@ -90,7 +89,7 @@ export class AsyncDelegate (Promise | void) = * @param callback @en The callback to remove. @zh 要移除的某个回调。 */ public remove (callback: T) { - js.array.fastRemove(this._delegates, callback); + array.fastRemove(this._delegates, callback); } /** diff --git a/cocos/core/event/callbacks-invoker.ts b/cocos/core/event/callbacks-invoker.ts index 0fbf588c879..dcaec9cd73a 100644 --- a/cocos/core/event/callbacks-invoker.ts +++ b/cocos/core/event/callbacks-invoker.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -178,6 +177,7 @@ type EventType = string | number; * @zh CallbacksInvoker 用来根据事件名(Key)管理事件监听器列表并调用回调方法。 * @en CallbacksInvoker is used to manager and invoke event listeners with different event keys, * each key is mapped to a CallbackList. + * @engineInternal */ export class CallbacksInvoker { /** diff --git a/cocos/core/event/defines.ts b/cocos/core/event/defines.ts index c208cc9473c..1a8c727a1a7 100644 --- a/cocos/core/event/defines.ts +++ b/cocos/core/event/defines.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/event/event-target-factory.ts b/cocos/core/event/event-target-factory.ts index 32420a9c012..5f15399ffcc 100644 --- a/cocos/core/event/event-target-factory.ts +++ b/cocos/core/event/event-target-factory.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,11 +24,15 @@ import { EventTarget } from './event-target'; +/** + * + * @engineInternal + */ export function applyMixins (derivedCtor: any, baseCtors: any[]) { baseCtors.forEach((baseCtor) => { Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { if (name !== 'constructor') { - Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name)); + Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name)!); } }); }); @@ -39,5 +42,4 @@ export function applyMixins (derivedCtor: any, baseCtors: any[]) { * @en Interface for all classes that self implement the EventTarget protocol, they are normally not sub class of EventTarget * @zh 所有自己实现 EventTarget 功能的类都实现了这个 Interface,他们可能无法直接继承自 EventTarget */ -export interface IEventTarget extends EventTarget { -} +export type IEventTarget = EventTarget diff --git a/cocos/core/event/event-target.ts b/cocos/core/event/event-target.ts index 322c4c1d0a2..010825940cd 100644 --- a/cocos/core/event/event-target.ts +++ b/cocos/core/event/event-target.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/event/eventify.ts b/cocos/core/event/eventify.ts index 78b94e445c7..4ec8ff82abc 100644 --- a/cocos/core/event/eventify.ts +++ b/cocos/core/event/eventify.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { CallbacksInvoker } from './callbacks-invoker'; import { createMap } from '../utils/js'; diff --git a/cocos/core/event/index.ts b/cocos/core/event/index.ts index c49c848761f..e54b8bad8f9 100644 --- a/cocos/core/event/index.ts +++ b/cocos/core/event/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/geometry/aabb.ts b/cocos/core/geometry/aabb.ts index 5516fc30d0b..8c05c908ac7 100644 --- a/cocos/core/geometry/aabb.ts +++ b/cocos/core/geometry/aabb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mat3, Mat4, Quat, Vec3 } from '../math'; import enums from './enums'; @@ -46,22 +45,24 @@ const transform_extent_m4 = (out: Vec3, extent: Vec3, m4: Mat4 | Readonly) /** * @en * Basic Geometry: Axis-aligned bounding box, using center and half extents structure. + * It's a fairly computationally and memory efficient way of checking whether two 3D objects might be touching. * @zh - * 基础几何 轴对齐包围盒,使用中心点和半长宽高的结构。 + * 基础几何:轴对齐包围盒,使用中心点和半长宽高的结构。 + * 这是检查两个 3D 对象是否相交的一种在计算和内存上效率都相当高的方法。 */ export class AABB { /** * @en - * create a new AABB + * Creates a new AABB instance. * @zh * 创建一个新的 AABB 实例。 - * @param px @zh AABB 的原点的 X 坐标。@en The x coordinate of the origin of the AABB. - * @param py @zh AABB 的原点的 Y 坐标。@en The y coordinate of the origin of the AABB. - * @param pz @zh AABB 的原点的 Z 坐标。 @en The z coordinate of the origin of the AABB. + * @param px @zh AABB 原点的 X 坐标。 @en The x coordinate of the origin of the AABB. + * @param py @zh AABB 原点的 Y 坐标。 @en The y coordinate of the origin of the AABB. + * @param pz @zh AABB 原点的 Z 坐标。 @en The z coordinate of the origin of the AABB. * @param hw @zh AABB 宽度的一半。 @en Half the width of the AABB. - * @param hh @zh AABB 高度的一半。@en Half the height of the AABB. - * @param hl @zh AABB 长度的一半。@en Half the length of the AABB. + * @param hh @zh AABB 高度的一半。 @en Half the height of the AABB. + * @param hl @zh AABB 长度的一半。 @en Half the length of the AABB. * @returns @zh 返回新创建的 AABB 实例。 @en A new instance of AABB. */ public static create (px?: number, py?: number, pz?: number, hw?: number, hh?: number, hl?: number) { @@ -70,11 +71,11 @@ export class AABB { /** * @en - * clone a new AABB + * Clones an AABB, which will create a new AABB instance with the same value as the input parameter `a`. Note that each time `clone` is invoked, a new AABB object will be created, so use `copy` method whenever it could to reduce GC pressure. * @zh - * 克隆一个 AABB。 - * @param a @zh 克隆的目标。 @en Target object. - * @returns @zh 克隆出的 AABB。@en The new AABB. + * 克隆一个 AABB,其会创建出一个值跟输入参数`a`一样的 AABB 实例。注意,每次调用 `clone` 都会创建出新实例,尽可能使用 `copy` 方法以减小 GC 压力。 + * @param a @zh 克隆的目标。 @en The target object to be cloned. + * @returns @zh 克隆出的 AABB 实例。@en The cloned AABB instance. */ public static clone (a: AABB | Readonly) { return new AABB(a.center.x, a.center.y, a.center.z, @@ -83,12 +84,12 @@ export class AABB { /** * @en - * copy the values from one AABB to another + * Copies the values from one AABB to another, the process will not generate temporary objects. * @zh - * 将从一个 AABB 的值复制到另一个 AABB。 - * @param out @zh 接受操作的 AABB。 @en The output AABB, copy destination. - * @param a @zh 被复制的 AABB。 @en Source object of copy operation. - * @returns @zh 接受操作的 AABB。 @en The reference of the first parameter `dst`, the new AABB. + * 将一个 AABB 的值复制到另一个 AABB 中,此过程将不会产生临时对象。 + * @param out @zh 接受操作的 AABB。 @en The output AABB which is the copy destination. + * @param a @zh 被复制的 AABB,此为只读参数。 @en The source object of the copy operation, it's readonly. + * @returns @zh 接受操作的 AABB `out` 的引用。 @en The reference to the first parameter `out`. */ public static copy (out: AABB, a: AABB | Readonly): AABB { Vec3.copy(out.center, a.center); @@ -99,13 +100,13 @@ export class AABB { /** * @en - * Construct a new AABB from two corner points + * Constructs a new AABB from two corner points. * @zh * 从两个点创建一个新的 AABB。 - * @param out @zh 接受操作的 AABB。 @en The output AABB - * @param minPos @zh AABB 的最小点。 @en Minimum point of the axis-aligned 3d bounding box. - * @param maxPos @zh AABB 的最大点。 @en Maximum point of the axis-aligned 3d bounding box. - * @returns @zh out 接受操作的 AABB。 @en The new AABB + * @param out @zh 接受操作的 AABB。 @en The output AABB. + * @param minPos @zh AABB 的最小点。 @en Minimum point of the AABB. + * @param maxPos @zh AABB 的最大点。 @en Maximum point of the AABB. + * @returns @zh 接受操作的 AABB `out` 的引用。 @en The reference to the first parameter `out`. */ public static fromPoints (out: AABB, minPos: IVec3, maxPos: IVec3): AABB { Vec3.add(_v3_tmp, maxPos, minPos); @@ -117,17 +118,17 @@ export class AABB { /** * @en - * Set the components of a AABB to the given values + * Sets the components of a AABB to the given values. * @zh * 将 AABB 的属性设置为给定的值。 * @param @zh out 接受操作的 AABB。 @en The output AABB to set. - * @param px @zh - AABB 的原点的 X 坐标。 @en The x coordinate of the origin of the AABB. - * @param py @zh - AABB 的原点的 Y 坐标。 @en The y coordinate of the origin of the AABB. - * @param pz @zh - AABB 的原点的 Z 坐标。 @en The z coordinate of the origin of the AABB. + * @param px @zh - AABB 原点的 X 坐标。 @en The x coordinate of the origin of the AABB. + * @param py @zh - AABB 原点的 Y 坐标。 @en The y coordinate of the origin of the AABB. + * @param pz @zh - AABB 原点的 Z 坐标。 @en The z coordinate of the origin of the AABB. * @param hw @zh - AABB 宽度的一半。 @en Half the width of the AABB. * @param hh @zh - AABB 高度的一半。 @en Half the height of the AABB. - * @param hl @zh - AABB 长度度的一半。 @en Half the length of the AABB. - * @returns @zh out 接受操作的 AABB。 @en The reference fo the first parameter `out`. + * @param hl @zh - AABB 长度的一半。 @en Half the length of the AABB. + * @returns @zh 接受操作的 AABB `out` 的引用。 @en The reference fo the first parameter `out`. */ public static set (out: AABB, px: number, py: number, pz: number, hw: number, hh: number, hl: number): AABB { out.center.set(px, py, pz); @@ -137,13 +138,13 @@ export class AABB { /** * @en - * Merge two AABB into one. + * Merges two AABB instances into one. * @zh - * 合并两个 AABB 到 out。 - * @param out @zh 接受操作的 AABB。 @en The output AABB to storge merge result. - * @param a @zh 输入的 AABB。 @en The first AABB to be merged. - * @param b @zh 输入的 AABB。 @en The second AABB to be merged. - * @returns @zh out 接受操作的 AABB。 @en The reference of the first parameter `out`. + * 合并两个 AABB 到一个目标 AABB 中。 + * @param out @zh 接受操作的目标 AABB。 @en The output AABB to storge the merge result. + * @param a @zh 第一个输入的 AABB,当其与 out 参数不同的时候,此函数内部不会修改其值。 @en The first AABB to be merged, its value will not be modified if `a` is not equal to the `out` paramater. + * @param b @zh 第二个输入的 AABB,当其与 out 参数不同的时候,此函数内部不会修改其值。 @en The second AABB to be merged, its value will not be modified if `b` is not equal to the `out` paramater. + * @returns @zh 接受操作的 AABB `out` 的引用。 @en The reference to the first parameter `out`. */ public static merge (out: AABB, a: AABB | Readonly, b: AABB | Readonly): AABB { Vec3.subtract(_v3_tmp, a.center, a.halfExtents); @@ -157,12 +158,12 @@ export class AABB { /** * @en - * Convert AABB to sphere. + * Converts an AABB to a bounding sphere. * @zh * 包围盒转包围球 - * @param out @zh 接受操作的 sphere。 @en The output sphere. - * @param a @zh 输入的 AABB。 @en The input AABB. - * @returns @zh out 接受的 Sphere @en The reference of the first parameter `out`. + * @param out @zh 接受操作的包围球。 @en The output bounding sphere. + * @param a @zh 输入的 AABB,只读参数。 @en The input AABB,it's readonly. + * @returns @zh 接受操作的包围球 `out` 的引用. @en The reference to the first parameter `out`. */ public static toBoundingSphere (out: Sphere, a: AABB | Readonly) { out.center.set(a.center); @@ -172,13 +173,13 @@ export class AABB { /** * @en - * Transform this AABB. + * Transforms an AABB by a 4x4 matrix and stores the result to the `out` parameter. * @zh - * 变换一个 AABB 到 out 中。 - * @param out @zh 接受操作的 AABB。 @en The output AABB. - * @param a @zh 输入的源 AABB。 @en The input AABB. + * 使用一个 4 乘 4 矩阵变换一个 AABB 并将结果存储于 out 参数中。 + * @param out @zh 接受操作的 AABB。 @en The output AABB to store the result. + * @param a @zh 输入的源 AABB,如果其与 out 参数不是同一个对象,那么 a 将不会被此函数修改。 @en The input AABB, if it's different with the `out` parameter, then `a` will not be changed by this function. * @param matrix @zh 矩阵。 @en The transformation matrix. - * @returns @zh {AABB} out 接受操作的 AABB。 @en The reference of the first parameter `out`. + * @returns @zh 接受操作的 AABB `out` 的引用。 @en The reference of the first parameter `out`. */ public static transform (out: AABB, a: AABB | Readonly, matrix: Mat4 | Readonly): AABB { Vec3.transformMat4(out.center, a.center, matrix); @@ -188,7 +189,7 @@ export class AABB { /** * @en - * The origin point of the AABB + * The center point of this AABB. * @zh * 本地坐标的中心点。 */ @@ -196,7 +197,7 @@ export class AABB { /** * @en - * Half the size of the AABB + * Half the size of this AABB. * @zh * 长宽高的一半。 */ @@ -204,9 +205,9 @@ export class AABB { /** * @en - * Gets the type of the shape. + * Gets the type of this shape. * @zh - * 获取形状的类型。 + * 获取此形状的类型。 */ get type () { return this._type; @@ -222,11 +223,11 @@ export class AABB { /** * @en - * Get the bounding points of this shape + * Gets the bounding points of this AABB. * @zh - * 获取 AABB 的最小点和最大点。 - * @param minPos @zh 最小点。 @en Minimum position of the axis-aligned 3d bounding box. - * @param maxPos @zh 最大点。 @en Maximum position of the axis-aligned 3d bounding box. + * 获取此 AABB 的最小点和最大点。 + * @param minPos @zh 存放此 AABB 最小点的向量。 @en The minimum position of the AABB to be stored to. + * @param maxPos @zh 存放此 AABB 最大点的向量。 @en The maximum position of the AABB to be stored to. */ public getBoundary (minPos: IVec3Like, maxPos: IVec3Like) { Vec3.subtract(minPos, this.center, this.halfExtents); @@ -235,14 +236,14 @@ export class AABB { /** * @en - * Transform this shape + * Transforms this AABB by a 4x4 matrix and stores the result to `out` parameter * @zh - * 将 out 根据这个 AABB 的数据进行变换。 + * 使用 4 乘 4 矩阵变换此 AABB 并将结果存储于 `out` 参数中。 * @param m @zh 变换的矩阵。 @en The transform matrix. * @param pos @zh 变换的位置部分。 @en 3d-vector translation. - * @param rot @zh 变换的旋转部分。 @en Quaternion rotation . + * @param rot @zh 变换的旋转部分。 @en Quaternion rotation. * @param scale @zh 变换的缩放部分。 @en 3d-vector scale. - * @param out @zh 变换的目标。 @en The output AABB. + * @param out @zh 存储结果的 AABB。 @en The output AABB. */ public transform (m: Mat4, pos: Vec3 | null, rot: Quat | null, scale: Vec3 | null, out: AABB) { Vec3.transformMat4(out.center, this.center, m); @@ -251,10 +252,10 @@ export class AABB { /** * @en - * Clones the AABB + * Clones this AABB, which will create a new AABB instance with the same value as this AABB. Note that each time `clone` is invoked, a new AABB object will be created, so use `copy` method whenever it could to reduce GC pressure. * @zh - * 获得克隆。 - * @returns @zh {AABB} @en A copy of the object. + * 克隆一个 AABB,其会创建出一个值跟当前 AABB 一样的实例。注意,每次调用 `clone` 都会创建出新实例,尽可能使用 `copy` 方法以减小 GC 压力。 + * @returns @zh 克隆出的 AABB 实例 @en The cloned AABB instance. */ public clone (): AABB { return AABB.clone(this); @@ -262,20 +263,20 @@ export class AABB { /** * @en - * Copy the input to the receiver object. + * Copies the values from one AABB to this AABB, the process will not generate temporary objects. * @zh - * 拷贝对象。 - * @param a @zh 拷贝的目标。 @en Copy target - * @returns @zh This object @en The reference of this. + * 将一个 AABB 的值复制到当前 AABB 中,此过程将不会产生临时对象。 + * @param a @zh 被复制的 AABB,此为只读参数。 @en The source object of the copy operation, it's readonly. + * @returns @zh 当前 AABB 的引用。 @en The reference of this AABB. */ public copy (a: AABB | Readonly): AABB { return AABB.copy(this, a); } /** - * @en AABB and point merge. - * @zh AABB包围盒合并一个顶点。 - * @param point @zh - 某一个位置的顶点。 @en A point in 3d space. + * @en Merges a point to this AABB. + * @zh 合并一个顶点到当前 AABB 中。 + * @param point @zh 3D 世界中某一个位置的顶点。 @en A point in 3D space. */ public mergePoint (point: IVec3) { // _v3_tmp is min pos @@ -295,9 +296,9 @@ export class AABB { } /** - * @en AABB and points merge. - * @zh AABB包围盒合并一系列顶点。 - * @param points @zh - 某一个位置的顶点。 @en A list of points in 3d space. + * @en Merges some points to this AABB. + * @zh 合并一系列顶点到当前 AABB 中。 + * @param points @zh 3D 世界中的顶点列表。 @en A list of points in 3D space. */ public mergePoints (points: IVec3[]) { if (points.length < 1) { return; } @@ -307,11 +308,11 @@ export class AABB { } /** - * @en AABB and frustum merge. - * @zh Frustum 合并到 AABB。 - * @param frustum @zh 输入的 Frustum。 @en The frustum object. + * @en Merges all points in a frustum to this AABB. + * @zh 合并一个截头锥体的所有顶点到此 AABB 中。 + * @param frustum @zh 输入的截头锥体 @en The frustum object. */ public mergeFrustum (frustum: Frustum | Readonly) { - return this.mergePoints(frustum.vertices); + this.mergePoints(frustum.vertices); } } diff --git a/cocos/core/geometry/capsule.ts b/cocos/core/geometry/capsule.ts index bc8bdd8b674..0e3b4f2cf6a 100644 --- a/cocos/core/geometry/capsule.ts +++ b/cocos/core/geometry/capsule.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec3, Quat, Mat4, absMaxComponent } from '../math'; import enums from './enums'; @@ -36,9 +35,9 @@ import { IVec3Like, IQuatLike } from '../math/type-define'; export class Capsule { /** * @en - * Gets the type of the shape. + * Gets the type of this Capsule, always returns `enums.SHAPE_CAPSULE`. * @zh - * 获取形状的类型。 + * 获取此形状的类型,值固定为 `enums.SHAPE_CAPSULE`。 */ get type () { return this._type; @@ -48,9 +47,9 @@ export class Capsule { /** * @en - * Capsule sphere radius. + * The radius of the sphere in this capsule. * @zh - * 胶囊体球部半径。 + * 胶囊体球部的半径。 */ radius: number; @@ -64,7 +63,7 @@ export class Capsule { /** * @en - * Local orientation of capsule [0,1,2] => [x,y,z]. + * The local orientation of this capsule [0,1,2] => [x,y,z]. * @zh * 胶囊体的本地朝向,映射关系 [0,1,2] => [x,y,z]。 */ @@ -96,6 +95,15 @@ export class Capsule { */ readonly ellipseCenter1: Vec3; + /** + * @en + * Constructs a Capsule instance. + * @zh + * 构造一个胶囊体实例。 + * @param radius @en The radius of the sphere in this capsule. @zh 胶囊体球部的半径。 + * @param halfHeight @en The distance between the center point of the capsule and the center of the sphere. @zh 胶囊体中心点和球部圆心的距离。 + * @param axis @en The local orientation of this capsule [0,1,2] => [x,y,z]. @zh 胶囊体的本地朝向,映射关系 [0,1,2] => [x,y,z]。 + */ constructor (radius = 0.5, halfHeight = 0.5, axis = 1) { this._type = enums.SHAPE_CAPSULE; this.radius = radius; @@ -112,9 +120,9 @@ export class Capsule { /** * @en - * Transform this capsule. + * Transforms this capsule by a 4x4 matrix and RTS. * @zh - * 变换此胶囊体。 + * 使用 4x4 矩阵和 RTS 变换此胶囊体。 */ transform (m: Mat4, pos: IVec3Like, rot: IQuatLike, scale: IVec3Like, out: Capsule) { const ws = scale; @@ -131,6 +139,12 @@ export class Capsule { out.updateCache(); } + /** + * @en + * Updates the cache. + * @zh + * 更新缓存。 + */ updateCache () { this.updateLocalCenter(); Vec3.transformQuat(this.ellipseCenter0, this.ellipseCenter0, this.rotation); @@ -139,6 +153,12 @@ export class Capsule { this.ellipseCenter1.add(this.center); } + /** + * @en + * Updates the center points. + * @zh + * 更新中心点信息。 + */ updateLocalCenter () { const halfHeight = this.halfHeight; const axis = this.axis; diff --git a/cocos/core/geometry/curve.ts b/cocos/core/geometry/curve.ts index d6409bea5f2..85df56ac5d0 100644 --- a/cocos/core/geometry/curve.ts +++ b/cocos/core/geometry/curve.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { CCClass } from '../data/class'; import { clamp, pingPong, repeat } from '../math/utils'; @@ -68,6 +67,9 @@ CCClass.fastDefine('cc.Keyframe', Keyframe, { outTangent: 0, }); +/** + * @engineInternal + */ export class OptimizedKey { public index: number; public time: number; @@ -86,6 +88,9 @@ export class OptimizedKey { } } +/** + * @engineInternal + */ export function evalOptCurve (t: number, coefs: Float32Array | number[]) { return (t * (t * (t * coefs[0] + coefs[1]) + coefs[2])) + coefs[3]; } @@ -381,6 +386,7 @@ function toLegacyWrapMode (extrapolationMode: ExtrapolationMode): WrapModeMask { /** * Same as but more effective than `new LegacyCurve()._internalCurve`. + * @engineInternal */ export function constructLegacyCurveAndConvert () { const curve = new RealCurve(); diff --git a/cocos/core/geometry/deprecated-3.0.0.ts b/cocos/core/geometry/deprecated-3.0.0.ts index 55432581fb2..759153c4e04 100644 --- a/cocos/core/geometry/deprecated-3.0.0.ts +++ b/cocos/core/geometry/deprecated-3.0.0.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { replaceProperty } from '../utils/x-deprecated'; import intersect from './intersect'; diff --git a/cocos/core/geometry/deprecated.ts b/cocos/core/geometry/deprecated.ts index 4d993a79d4a..d52504af5cf 100644 --- a/cocos/core/geometry/deprecated.ts +++ b/cocos/core/geometry/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { replaceProperty, removeProperty } from '../utils/x-deprecated'; import { Line } from './line'; diff --git a/cocos/core/geometry/distance.ts b/cocos/core/geometry/distance.ts index 468b847c20f..22a2764557e 100644 --- a/cocos/core/geometry/distance.ts +++ b/cocos/core/geometry/distance.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec3 } from '../math'; import { AABB } from './aabb'; @@ -39,12 +38,12 @@ const e = new Array(3); /** * @en - * the distance between a point and a plane + * Calculates the distance between a point and a plane. * @zh * 计算点和平面之间的距离。 - * @param {Vec3} point @en Target point @zh 目标点。 - * @param {Plane} plane @en Target plane @zh 目标平面。 - * @return @en The distance in between @zh 距离。 + * @param point @en The target point. @zh 目标点。 + * @param plane @en The target plane. @zh 目标平面。 + * @returns @en The distance between the point and the plane. @zh 点和平面之间的距离。 */ export function point_plane (point: Vec3, plane_: Plane) { return Vec3.dot(plane_.n, point) - plane_.d; @@ -52,13 +51,13 @@ export function point_plane (point: Vec3, plane_: Plane) { /** * @en - * the closest point on plane to a given point + * Calculates the closest point on a plane to a given point. * @zh * 计算平面上最接近给定点的点。 - * @param out @en The closest point, as a result @zh 最近点。 - * @param point @en The given point @zh 给定点。 - * @param plane @en Target plane @zh 平面。 - * @return @en The closest point, same as out @zh 最近点。 + * @param out @en The closest point. @zh 最近点。 + * @param point @en The given point. @zh 给定点。 + * @param plane @en The target plane. @zh 平面。 + * @returns @en The result of the closest point, same as the `out` parameter. @zh 存储最近点的向量,与 `out` 参数为同一个对象。 */ export function pt_point_plane (out: Vec3, point: Vec3, plane_: Plane) { const t = point_plane(point, plane_); @@ -67,13 +66,13 @@ export function pt_point_plane (out: Vec3, point: Vec3, plane_: Plane) { /** * @en - * the closest point on aabb to a given point + * Calculates the closest point on an AABB to a given point. * @zh - * 计算 aabb 上最接近给定点的点。 - * @param {Vec3} out @en The closest point, as a result @zh 最近点。 - * @param {Vec3} point @en The given point @zh 给定点。 - * @param {AABB} aabb @en Target aabb to calculate @zh 轴对齐包围盒。 - * @return {Vec3} @en The closest point, same as out @zh 最近点。 + * 计算 AABB 上最接近给定点的点。 + * @param out @en The closest point. @zh 最近点。 + * @param point @en The given point @zh 给定点。 + * @param aabb @en The target AABB to calculate. @zh 参与计算的 AABB 实例。 + * @returns @en The result of the closest point, same as the `out` parameter. @zh 存储最近点的向量,与 `out` 参数为同一个对象。 */ export function pt_point_aabb (out: Vec3, point: Vec3, aabb_: AABB): Vec3 { Vec3.copy(out, point); @@ -92,13 +91,13 @@ export function pt_point_aabb (out: Vec3, point: Vec3, aabb_: AABB): Vec3 { /** * @en - * the closest point on obb to a given point + * Calculates the closest point on an OBB to a given point. * @zh - * 计算 obb 上最接近给定点的点。 - * @param {Vec3} out @en The closest point, as a result @zh 最近点。 - * @param {Vec3} point @en The given point @zh 给定点。 - * @param {OBB} obb @en Target obb to calculate @zh 方向包围盒。 - * @return {Vec3} @en The closest point, same as out @zh 最近点。 + * 计算 OBB 上最接近给定点的点。 + * @param out @en The closest point. @zh 最近点。 + * @param point @en The given point. @zh 给定点。 + * @param obb @en The target OBB to calculate. @zh 参与计算的 OBB 实例。 + * @returns @en The result of the closest point, same as the `out` parameter. @zh 存储最近点的向量,与 `out` 参数为同一个对象。 */ export function pt_point_obb (out: Vec3, point: Vec3, obb_: OBB): Vec3 { Vec3.set(X, obb_.orientation.m00, obb_.orientation.m01, obb_.orientation.m02); @@ -141,20 +140,20 @@ export function pt_point_obb (out: Vec3, point: Vec3, obb_: OBB): Vec3 { /** * @en - * Calculate the nearest point on the line, which is from A to B, to the given point + * Calculates the closest point on the line, which is from A to B, to the given point. * @zh - * 计算给定点距离线段上最近的一点。线段从A到B。 - * @param out @en The closest point, as a result @zh 最近点 - * @param point @en The given point @zh 给定点 - * @param linePointA @en Point A on the line @zh 线上的某点 A - * @param linePointB @en Point B on the line @zh 线上的某点 B + * 计算给定点距离线段 AB 上最近的一点。 + * @param out @en The closest point. @zh 最近点。 + * @param point @en The given point. @zh 给定点 + * @param linePointA @en Point A on the line. @zh 线上的某点 A。 + * @param linePointB @en Point B on the line. @zh 线上的某点 B。 */ export function pt_point_line (out: Vec3, point: Vec3, linePointA: Vec3, linePointB: Vec3) { Vec3.subtract(X, linePointA, linePointB); const dir = X; const dirSquaredLength = Vec3.lengthSqr(dir); - if (dirSquaredLength == 0) { + if (dirSquaredLength === 0) { // The point is at the segment start. Vec3.copy(out, linePointA); } else { diff --git a/cocos/core/geometry/enums.ts b/cocos/core/geometry/enums.ts index de211f3cc89..2bf8a7fd925 100644 --- a/cocos/core/geometry/enums.ts +++ b/cocos/core/geometry/enums.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * 几何工具模块 diff --git a/cocos/core/geometry/frustum.ts b/cocos/core/geometry/frustum.ts index d1bf76bf0cb..3df74efe268 100644 --- a/cocos/core/geometry/frustum.ts +++ b/cocos/core/geometry/frustum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mat4, Vec3 } from '../math'; import enums from './enums'; @@ -46,13 +45,12 @@ const _temp_v3 = new Vec3(); * @en * Basic Geometry: frustum. * @zh - * 基础几何 截头锥体。 + * 基础几何:视锥体。 */ - export class Frustum { /** * @en - * Create an orthogonal frustum. + * Creates an orthogonal frustum. * @zh * 创建一个正交视锥体。 * @param out @en The result orthogonal frustum. @zh 输出的正交视锥体。 @@ -61,9 +59,9 @@ export class Frustum { * @param near @en The near plane of the frustum. @zh 正交视锥体的近平面值。 * @param far @en The far plane of the frustum. @zh 正交视锥体的远平面值。 * @param transform @en The transform matrix of the frustum. @zh 正交视锥体的变换矩阵。 - * @return @en The out object @zh 返回正交视锥体. + * @returns @en The result frustum, same as the `out` parameter. @zh 存储结果的视锥体,与 `out` 参数为同一个对象。 */ - public static createOrtho = (() => (out: Frustum, width: number, height: number, near: number, far: number, transform: Mat4) => { + public static createOrtho (out: Frustum, width: number, height: number, near: number, far: number, transform: Mat4) { const halfWidth = width / 2; const halfHeight = height / 2; Vec3.set(_temp_v3, halfWidth, halfHeight, -near); @@ -89,16 +87,16 @@ export class Frustum { Plane.fromPoints(out.planes[3], out.vertices[0], out.vertices[5], out.vertices[4]); Plane.fromPoints(out.planes[4], out.vertices[2], out.vertices[0], out.vertices[3]); Plane.fromPoints(out.planes[5], out.vertices[7], out.vertices[5], out.vertices[6]); - })(); + } /** - * @en Create a frustum from an AABB box. - * @zh 从 AABB 包围盒中创建一个视锥体。 - * @param out @en The result frustum @zh 输出的视锥体对象。 - * @param aabb @en The AABB bounding box of the frustum @zh AABB 包围盒。 - * @return @en The out object @zh 返回视锥体. + * @en Creates a frustum from an AABB instance. + * @zh 根据一个 AABB 实例创建一个视锥体。 + * @param out @en The result frustum. @zh 输出的视锥体对象。 + * @param aabb @en The AABB to create the result frustum. @zh 用于创建视锥体 AABB。 + * @returns @en The result frustum, same as the `out` parameter. @zh 存储结果的视锥体,与 `out` 参数为同一个对象。 */ - public static createFromAABB (out: Frustum, aabb: AABB | Readonly) : Frustum { + public static createFromAABB (out: Frustum, aabb: AABB | Readonly): Frustum { const vec3_min = new Vec3(); const vec3_max = new Vec3(); Vec3.subtract(vec3_min, aabb.center, aabb.halfExtents); Vec3.add(vec3_max, aabb.center, aabb.halfExtents); @@ -122,13 +120,13 @@ export class Frustum { } /** - * @en Calculate a split frustum. + * @en Calculates a split frustum. * @zh 计算出一个分割的视锥体。 - * @param start @en The split start position @zh 分割开始位置 - * @param end @en The split end position @zh 分割末尾位置 - * @param aspect @en The aspect ratio of the camera @zh 相机视图的长宽比 - * @param fov @en Field of view of the camera @zh 相机的视角大小 - * @param m @en The transform matrix @zh 变换矩阵 + * @param start @en The split start position. @zh 分割开始位置。 + * @param end @en The split end position. @zh 分割末尾位置。 + * @param aspect @en The aspect ratio of the camera. @zh 相机视图的长宽比。 + * @param fov @en The field of view of the camera. @zh 相机的视角大小。 + * @param m @en The transform matrix. @zh 变换矩阵。 */ public split (start: number, end: number, aspect: number, fov: number, m: Mat4) { // 0: cameraNear 1:cameraFar @@ -163,10 +161,10 @@ export class Frustum { /** * @en - * Create a new frustum. + * Creates a new frustum. * @zh - * 创建一个新的截锥体。 - * @return @en An empty frustum. @zh 一个空截椎体 + * 创建一个新的视椎体。 + * @returns @en An empty frustum. @zh 一个空视椎体。 */ public static create (): Frustum { return new Frustum(); @@ -174,11 +172,11 @@ export class Frustum { /** * @en - * Clone a frustum. + * Clones a frustum. * @zh - * 克隆一个截锥体。 - * @param f @en The frustum to clone from @zh 用于克隆的截锥体 - * @return @en The cloned frustum @zh 克隆出的新截锥体 + * 克隆一个视椎体。 + * @param f @en The frustum to clone from. @zh 用于克隆的视椎体。 + * @return @en The cloned frustum. @zh 克隆出的新视椎体。 */ public static clone (f: Frustum): Frustum { return Frustum.copy(new Frustum(), f); @@ -186,12 +184,12 @@ export class Frustum { /** * @en - * Copy the values from one frustum to another. + * Copies the values from one frustum to another. * @zh * 从一个视锥体拷贝到另一个视锥体。 * @param out @en The result frustum @zh 用于存储拷贝数据的截锥体 * @param f @en The frustum to copy from @zh 用于克隆的截锥体 - * @return @en The out object @zh 传入的 out 对象 + * @returns @en The result frustum, same as the `out` parameter. @zh 存储结果的视锥体,与 `out` 参数为同一个对象。 */ public static copy (out: Frustum, f: Readonly): Frustum { out._type = f.type; @@ -206,7 +204,7 @@ export class Frustum { /** * @en - * Set whether to use accurate intersection testing function on this frustum. + * Sets whether to use accurate intersection testing function on this frustum. * @zh * 设置是否在此截锥体上使用精确的相交测试函数。 */ @@ -216,16 +214,29 @@ export class Frustum { /** * @en - * Gets the type of the shape. + * Gets the type of the shape. The value may be `enums.SHAPE_FRUSTUM_ACCURATE` or `enums.SHAPE_FRUSTUM`. * @zh - * 获取形状的类型。 + * 获取形状的类型。值可能为 `enums.SHAPE_FRUSTUM_ACCURATE` 或 `enums.SHAPE_FRUSTUM`。 * @readonly */ get type () { return this._type; } + /** + * @en + * The 6 planes of the frustum. + * @zh + * 视椎体的 6 个面。 + */ public planes: Plane[]; + + /** + * @en + * The 8 vertices of the frustum. + * @zh + * 视椎体的 8 个顶点。 + */ public vertices: Vec3[]; protected _type: number; @@ -244,12 +255,12 @@ export class Frustum { /** * @en - * Update the frustum information according to the given transform matrix. + * Updates the frustum information according to the given transform matrix. * Note that the resulting planes are not normalized under normal mode. * @zh * 根据给定的变换矩阵更新截锥体信息,注意得到的平面不是在标准模式下归一化的。 - * @param m @en The view-projection matrix @zh 视图投影矩阵 - * @param inv @en The inverse view-projection matrix @zh 视图投影逆矩阵 + * @param m @en The view-projection matrix. @zh 视图投影矩阵。 + * @param inv @en The inverse view-projection matrix. @zh 视图投影逆矩阵。 */ public update (m: Mat4, inv: Mat4) { // RTR4, ch. 22.14.1, p. 983 @@ -292,10 +303,10 @@ export class Frustum { /** * @en - * Transform this frustum. + * Transforms this frustum. * @zh * 变换此视锥体。 - * @param mat @en The transform matrix @zh 变换矩阵 + * @param mat @en The transform matrix. @zh 变换矩阵。 */ public transform (mat: Mat4) { if (this._type !== enums.SHAPE_FRUSTUM_ACCURATE) { @@ -308,8 +319,8 @@ export class Frustum { } /** - * @en Initialize the frustum - * @zh 初始化视锥体 + * @en Makes the frustum empty, all vertices will be zero values. + * @zh 置空此视锥体,所有顶点将被赋值为 0。 */ public zero () { for (let i = 0; i < 8; i++) { @@ -319,8 +330,8 @@ export class Frustum { } /** - * @en Update all six planes of the frustum - * @zh 更新视锥体的所有面数据 + * @en Updates all six planes of the frustum. + * @zh 更新视锥体的所有面数据。 */ public updatePlanes () { // left plane diff --git a/cocos/core/geometry/geometry-native-ext.ts b/cocos/core/geometry/geometry-native-ext.ts new file mode 100644 index 00000000000..7fe2dcd038e --- /dev/null +++ b/cocos/core/geometry/geometry-native-ext.ts @@ -0,0 +1,199 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + http://www.cocos.com + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { NATIVE } from 'internal:constants'; + +import { Line } from './line'; +import { Plane } from './plane'; +import { Ray } from './ray'; +import { Triangle } from './triangle'; +import { Sphere } from './sphere'; +import { AABB } from './aabb'; +import { Capsule } from './capsule'; +import { Frustum } from './frustum'; + +/** + * cache jsb attributes in js, reduce cross language invokations. + */ +function cacheProperty (ctor: Constructor, property: string) { + const propDesc = Object.getOwnPropertyDescriptor(ctor.prototype, property); + const propCacheKey = `_$cache_${property}`; + const propRealKey = `_$_${property}`; + Object.defineProperty(ctor.prototype, propRealKey, propDesc!); + Object.defineProperty(ctor.prototype, property, { + get () { + if (this[propCacheKey] === undefined) { + this[propCacheKey] = this[propRealKey]; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return this[propCacheKey]; + }, + set (value) { + // this[propCacheKey] = value; + this[propRealKey] = value; + }, + configurable: true, + enumerable: true, + }); +} + +/** + * cache native object's `underlyingData()` result in __data + */ +function cacheUnderlyingData (ctor: Constructor) { + // eslint-disable-next-line func-names + ctor.prototype._arraybuffer = function () { + if (!this.__data) { + this.__data = this.underlyingData(); + } + return this.__data as ArrayBuffer; + }; +} + +/** + * linear layout info of JSB attributes + * stored at static field `__nativeFields__` + * see: `DESC_UNDERLINE_DATA_*` in file jsb_geometry_manual.cpp + */ +interface FieldDesc { + fieldName: string; + fieldOffset: number; // offsetof(JSBTYPE, field) + fieldSize: number; // sizeof(jsbinstance.field) +} + +/** + * define accessor for attr, read/write directly to the underlyingData as Float32Array[1] + */ +const defineAttrFloat = (kls: Constructor, attr: string) => { + // __nativeFields__ is defined in jsb_geometry_manual.cpp + const desc: FieldDesc = (kls as any).__nativeFields__[attr]; + const cacheKey = `_$_${attr}`; + console.assert(desc.fieldSize === 4, `field ${attr} size ${desc.fieldSize}`); + Object.defineProperty(kls.prototype, desc.fieldName, { + configurable: true, + enumerable: true, + get () { + if (this[cacheKey] === undefined) { + this[cacheKey] = new Float32Array(this._arraybuffer(), desc.fieldOffset, 1); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return this[cacheKey][0]; + }, + set (v: number) { + if (this[cacheKey] === undefined) { + this[cacheKey] = new Float32Array(this._arraybuffer(), desc.fieldOffset, 1); + } + this[cacheKey][0] = v; + }, + }); +}; + +/** + * define accessor for attr, read/write directly to the underlyingData as Int32Array[1] + */ +const defineAttrInt = (kls: Constructor, attr: string) => { + // __nativeFields__ is defined in jsb_geometry_manual.cpp + const desc: FieldDesc = (kls as any).__nativeFields__[attr]; + if (!desc) { + console.error(`attr ${attr} not defined in class ${kls.toString()}`); + } + const cacheKey = `_$_${attr}`; + console.assert(desc.fieldSize === 4, `field ${attr} size ${desc.fieldSize}`); + Object.defineProperty(kls.prototype, desc.fieldName, { + configurable: true, + enumerable: true, + get () { + if (this[cacheKey] === undefined) { + this[cacheKey] = new Int32Array(this._arraybuffer(), desc.fieldOffset, 1); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return this[cacheKey][0]; + }, + set (v: number) { + if (this[cacheKey] === undefined) { + this[cacheKey] = new Int32Array(this._arraybuffer(), desc.fieldOffset, 1); + } + this[cacheKey][0] = v; + }, + }); +}; + +if (NATIVE) { + // Line + cacheProperty(ns.Line, 's'); + cacheProperty(ns.Line, 'e'); + Object.setPrototypeOf(ns.Line.prototype, Line.prototype); + + // Plane + cacheUnderlyingData(ns.Plane); + cacheProperty(ns.Plane, 'n'); + defineAttrFloat(ns.Plane, 'd'); + Object.setPrototypeOf(ns.Plane.prototype, Plane.prototype); + + // Ray + cacheUnderlyingData(ns.Ray); + cacheProperty(ns.Ray, 'o'); + cacheProperty(ns.Ray, 'd'); + Object.setPrototypeOf(ns.Ray.prototype, Ray.prototype); + + // Triangle + cacheUnderlyingData(ns.Triangle); + cacheProperty(ns.Triangle, 'a'); + cacheProperty(ns.Triangle, 'b'); + cacheProperty(ns.Triangle, 'c'); + Object.setPrototypeOf(ns.Triangle.prototype, Triangle.prototype); + + // Sphere + cacheUnderlyingData(ns.Sphere); + cacheProperty(ns.Sphere, '_center'); + defineAttrFloat(ns.Sphere, '_radius'); + Object.setPrototypeOf(ns.Sphere.prototype, Sphere.prototype); + + // AABB + cacheUnderlyingData(ns.AABB); + cacheProperty(ns.AABB, 'center'); + cacheProperty(ns.AABB, 'halfExtents'); + Object.setPrototypeOf(ns.AABB.prototype, AABB.prototype); + + // Capsule + cacheUnderlyingData(ns.Capsule); + defineAttrFloat(ns.Capsule, 'radius'); + defineAttrFloat(ns.Capsule, 'halfHeight'); + defineAttrInt(ns.Capsule, 'axis'); + cacheProperty(ns.Capsule, 'center'); + cacheProperty(ns.Capsule, 'rotation'); + cacheProperty(ns.Capsule, 'ellipseCenter0'); + cacheProperty(ns.Capsule, 'ellipseCenter1'); + Object.setPrototypeOf(ns.Capsule.prototype, Capsule.prototype); + + // Frustum + // cacheUnderlyingData(ns.Frustum); // no needed + cacheProperty(ns.Frustum, 'vertices'); + cacheProperty(ns.Frustum, 'planes'); + Object.setPrototypeOf(ns.Frustum.prototype, Frustum.prototype); + + // fix `_type` + const descOf_type = Object.getOwnPropertyDescriptor((ns as any).ShapeBase.prototype, '_type'); + for (const kls of [ns.Line, ns.Plane, ns.Ray, ns.Triangle, ns.Sphere, ns.AABB, ns.Capsule, ns.Frustum]) { + Object.defineProperty(kls.prototype, '_type', descOf_type!); + } +} diff --git a/cocos/core/geometry/index.ts b/cocos/core/geometry/index.ts index e7a39e52df3..e0846a52098 100644 --- a/cocos/core/geometry/index.ts +++ b/cocos/core/geometry/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import * as distance from './distance'; import './deprecated'; +import './geometry-native-ext'; + export { default as enums } from './enums'; export { distance }; export { default as intersect } from './intersect'; @@ -43,3 +44,6 @@ export { Keyframe, AnimationCurve, WrapModeMask } from './curve'; export { SplineMode, Spline } from './spline'; export * from './spec'; export * from './deprecated-3.0.0'; + +// engine internal exports +export { constructLegacyCurveAndConvert, OptimizedKey, evalOptCurve } from './curve'; diff --git a/cocos/core/geometry/intersect.ts b/cocos/core/geometry/intersect.ts index 2c245fe99ff..cd98d581312 100644 --- a/cocos/core/geometry/intersect.ts +++ b/cocos/core/geometry/intersect.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EPSILON, Mat3, Vec3 } from '../math'; import { AABB } from './aabb'; @@ -46,9 +45,9 @@ import type { Mesh } from '../../3d'; * ray-plane intersect detect. * @zh * 射线与平面的相交性检测。 - * @param ray @zh 射线 @en The ray to test - * @param plane @zh 平面 @en The plane to test - * @return @zh 0 或 非0 @en 0 or not 0, 0 indicates there is no intersection + * @param ray @zh 要测试的射线。 @en The ray to test. + * @param plane @zh 要测试的平面。 @en The plane to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const rayPlane = (function () { const pt = new Vec3(0, 0, 0); @@ -69,10 +68,10 @@ const rayPlane = (function () { * ray-triangle intersect detect. * @zh * 射线与三角形的相交性检测。 - * @param ray @zh 射线 @en The ray to test - * @param triangle @zh 三角形 @en The triangle to test - * @param doubleSided @zh 三角形是否为双面 @en Indicates whether it is double sided - * @return @zh 0 或 非0 @en 0 or not 0, 0 indicates there is no intersection + * @param ray @zh 要测试的射线。 @en The ray to test. + * @param triangle @zh 用来测试三角形。 @en The triangle to test. + * @param doubleSided @zh 要测试的三角形是否为双面。 @en Indicates whether the triangle to test is double sided. + * @returns @zh 0 或 非 0,0 表示没有相交。@en 0 or not 0, 0 indicates there is no intersection. */ const rayTriangle = (function () { const ab = new Vec3(0, 0, 0); @@ -109,9 +108,9 @@ const rayTriangle = (function () { * ray-sphere intersect detect. * @zh * 射线和球的相交性检测。 - * @param ray @zh 射线 @en The ray to test - * @param sphere @zh 球 @en The sphere to test - * @return @zh 0 或 非0 @en 0 or not 0, 0 indicates there is no intersection + * @param ray @zh 要测试的射线。 @en The ray to test. + * @param sphere @zh 要测试的球。 @en The sphere to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const raySphere = (function () { const e = new Vec3(0, 0, 0); @@ -140,9 +139,9 @@ const raySphere = (function () { * ray-aabb intersect detect. * @zh * 射线和轴对齐包围盒的相交性检测。 - * @param ray @zh 射线 @en The ray to test - * @param aabb @zh 轴对齐包围盒 @en The aabb to test - * @return @zh 0 或 非0 @en 0 or not 0, 0 indicates there is no intersection + * @param ray @zh 要测试的射线。 @en The ray to test. + * @param aabb @zh 要测试的 AABB。 @en The aabb to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const rayAABB = (function () { const min = new Vec3(); @@ -173,10 +172,10 @@ function rayAABB2 (ray: Ray, min: IVec3Like, max: IVec3Like) { * @en * ray-obb intersect detect. * @zh - * 射线和方向包围盒的相交性检测。 - * @param ray @zh 射线 @en The ray - * @param obb @zh 方向包围盒 @en The obb to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * 射线和 OBB 的相交性检测。 + * @param ray @zh 要测试的射线。 @en The ray to test. + * @param obb @zh 要测试的 OBB。 @en The OBB to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const rayOBB = (function () { let center = new Vec3(); @@ -254,9 +253,9 @@ const rayOBB = (function () { * ray-capsule intersect detect. * @zh * 射线和胶囊体的相交性检测。 - * @param ray @zh 射线 @en The ray to test - * @param capsule @zh 胶囊体 @en The capsule to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @param ray @zh 要测试的射线。 @en The ray to test. + * @param capsule @zh 要测试的胶囊体。 @en The capsule to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const rayCapsule = (function () { const v3_0 = new Vec3(); @@ -340,9 +339,9 @@ const rayCapsule = (function () { * line-plane intersect detect. * @zh * 线段与平面的相交性检测。 - * @param line @zh 线段 @en The line to test - * @param plane @zh 平面 @en The plane to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @param line @zh 要测试的线段。 @en The line to test. + * @param plane @zh 要测试的平面。 @en The plane to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const linePlane = (function () { const ab = new Vec3(0, 0, 0); @@ -360,10 +359,10 @@ const linePlane = (function () { * line-triangle intersect detect. * @zh * 线段与三角形的相交性检测。 - * @param line @zh 线段 @en The line to test - * @param triangle @zh 三角形 @en The triangle to test - * @param outPt @zh 可选,相交点 @en Optional out param, indicates the intersection point - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @param line @zh 线段 @en The line to test. + * @param triangle @zh 三角形 @en The triangle to test. + * @param outPt @zh 可选,相交点 @en Optional out param, indicates the intersection point. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value. */ const lineTriangle = (function () { const ab = new Vec3(0, 0, 0); @@ -427,7 +426,7 @@ const r_t = new Ray(); * 线段与轴对齐包围盒的相交性检测 * @param line @zh 线段 @en The line to test * @param aabb @zh 轴对齐包围盒 @en The aabb to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value.no intersection */ function lineAABB (line: Line, aabb: AABB): number { r_t.o.set(line.s); @@ -446,10 +445,10 @@ function lineAABB (line: Line, aabb: AABB): number { * @en * line-obb intersect detect. * @zh - * 线段与方向包围盒的相交性检测 - * @param line @zh 线段 @en The line to test - * @param obb @zh 方向包围盒 @en The obb - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * 线段与OBB的相交性检测。 + * @param line @zh 线段 @en The line to test. + * @param obb @zh OBB @en The OBB to test. + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value.no intersection */ function lineOBB (line: Line, obb: OBB): number { r_t.o.set(line.s); @@ -471,7 +470,7 @@ function lineOBB (line: Line, obb: OBB): number { * 线段与球的相交性检测 * @param line @zh 线段 @en The line to test * @param sphere @zh 球 @en The sphere to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value.no intersection */ function lineSphere (line: Line, sphere: Sphere): number { r_t.o.set(line.s); @@ -493,7 +492,7 @@ function lineSphere (line: Line, sphere: Sphere): number { * 轴对齐包围盒和轴对齐包围盒的相交性检测。 * @param aabb1 @zh 轴对齐包围盒1 @en aabb 1 to test * @param aabb2 @zh 轴对齐包围盒2 @en aabb 2 to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value.no intersection */ const aabbWithAABB = (function () { const aMin = new Vec3(); @@ -571,10 +570,10 @@ function getInterval (vertices: any[] | Vec3[], axis: Vec3) { * @en * aabb-obb intersect detect. * @zh - * 轴对齐包围盒和方向包围盒的相交性检测。 + * 轴对齐包围盒和OBB的相交性检测。 * @param aabb @zh 轴对齐包围盒 @en The aabb to test - * @param obb @zh 方向包围盒 @en The obb to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @param obb @zh OBB @en The OBB to test + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value.no intersection */ const aabbWithOBB = (function () { const test = new Array(15); @@ -627,7 +626,7 @@ const aabbWithOBB = (function () { * 轴对齐包围盒和平面的相交性检测。 * @param aabb @zh 轴对齐包围盒 @en The aabb to test * @param plane @zh 平面 @en The plane to test - * @return @zh 检测结果, 包含为 -1, 不包含为 0, 相交为 1 @en Test result, inside(back) = -1, outside(front) = 0, intersect = 1 + * @returns @zh 检测结果, 包含为 -1, 不包含为 0, 相交为 1 @en Test result, inside(back) = -1, outside(front) = 0, intersect = 1 */ const aabbPlane = function (aabb: AABB, plane: Plane): number { const r = aabb.halfExtents.x * Math.abs(plane.n.x) @@ -645,7 +644,7 @@ const aabbPlane = function (aabb: AABB, plane: Plane): number { * 轴对齐包围盒和锥台相交性检测,速度快,但有错误情况。 * @param aabb @zh 轴对齐包围盒 @en The aabb to test * @param frustum @zh 锥台 @en The frustum to test - * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection + * @returns @zh 如果没有相交,返回 0 ,否则返回非 0。 @en zero if no intersection, otherwise returns a non-zero value.no intersection */ const aabbFrustum = function (aabb: AABB, frustum: Readonly): number { for (let i = 0; i < frustum.planes.length; i++) { @@ -664,7 +663,7 @@ const aabbFrustum = function (aabb: AABB, frustum: Readonly): number { * 轴对齐包围盒和锥台的相交性检测。速度快,但是当锥台完全在aabb中时就会判断出错。 * @param {AABB} aabb 轴对齐包围盒 * @param {Frustum} frustum 锥台 - * @return {number} aabb completely inside the frustum = 1, otherwise = 0 + * @returns {number} aabb completely inside the frustum = 1, otherwise = 0 */ const aabbFrustumCompletelyInside = function (aabb: AABB, frustum: Readonly): number { for (let i = 0; i < frustum.planes.length; i++) { @@ -684,7 +683,7 @@ const aabbFrustumCompletelyInside = function (aabb: AABB, frustum: Readonly { /** * @en - * Basic Geometry: directional bounding box. + * Basic Geometry: Oriented bounding box. * @zh - * 基础几何 方向包围盒。 + * 基础几何:方向包围盒。 */ export class OBB { /** * @en - * create a new obb + * Creates a new OBB instance * @zh - * 创建一个新的 obb 实例。 + * 创建一个新的 OBB 实例。 * @param cx @zh 形状的相对于原点的 X 坐标。 @en The x coordinate of origin. * @param cy @zh 形状的相对于原点的 Y 坐标。 @en The y coordinate of origin. * @param cz @zh 形状的相对于原点的 Z 坐标。 @en The z coordinate of origin. - * @param hw @zh - obb 宽度的一半。 @en Half the width of the OBB. - * @param hh @zh - obb 高度的一半。 @en Half the height of the OBB. - * @param hl @zh - obb 长度的一半。 @en Half the length of the OBB. - * @param ox_1 @zh 方向矩阵参数。 @en The x component of the one axis of the OBB. - * @param ox_2 @zh 方向矩阵参数。 @en The x component of the second axis of the OBB. - * @param ox_3 @zh 方向矩阵参数。 @en The x component of the third axis of the OBB. - * @param oy_1 @zh 方向矩阵参数。 @en The y component of the one axis of the OBB. - * @param oy_2 @zh 方向矩阵参数。 @en The y component of the second axis of the OBB. - * @param oy_3 @zh 方向矩阵参数。 @en The y component of the third axis of the OBB. - * @param oz_1 @zh 方向矩阵参数。 @en The z component of the one axis of the OBB. - * @param oz_2 @zh 方向矩阵参数。 @en The z component of the second axis of the OBB. - * @param oz_3 @zh 方向矩阵参数。 @en The z component of the third axis of the OBB. - * @return @zh 返回一个 obb。 @en A new OBB. + * @param hw @zh - OBB 宽度的一半。 @en Half the width of the OBB. + * @param hh @zh - OBB 高度的一半。 @en Half the height of the OBB. + * @param hl @zh - OBB 长度的一半。 @en Half the length of the OBB. + * @param ox_1 @zh 方向矩阵参数,第 1 条轴的 x 分量。 @en The x component of the first axis of the OBB. + * @param ox_2 @zh 方向矩阵参数,第 2 条轴的 x 分量。 @en The x component of the second axis of the OBB. + * @param ox_3 @zh 方向矩阵参数,第 3 条轴的 x 分量。 @en The x component of the third axis of the OBB. + * @param oy_1 @zh 方向矩阵参数,第 1 条轴的 y 分量。 @en The y component of the first axis of the OBB. + * @param oy_2 @zh 方向矩阵参数,第 2 条轴的 y 分量。 @en The y component of the second axis of the OBB. + * @param oy_3 @zh 方向矩阵参数,第 3 条轴的 y 分量。 @en The y component of the third axis of the OBB. + * @param oz_1 @zh 方向矩阵参数,第 1 条轴的 z 分量。 @en The z component of the first axis of the OBB. + * @param oz_2 @zh 方向矩阵参数,第 2 条轴的 z 分量。 @en The z component of the second axis of the OBB. + * @param oz_3 @zh 方向矩阵参数,第 3 条轴的 z 分量。 @en The z component of the third axis of the OBB. + * @returns @zh 返回新创建的 OBB 实例。 @en A new OBB instance. */ public static create ( cx: number, cy: number, cz: number, @@ -80,11 +79,11 @@ export class OBB { /** * @en - * clone a new obb + * Clones a new OBB instance. * @zh - * 克隆一个 obb。 + * 克隆一个 OBB 实例。 * @param a @zh 克隆的目标。 @en The input OBB. - * @returns @zh The new OBB. @en 克隆出的新对象。 + * @returns @zh The cloned OBB instance. @en 克隆出的新对象。 */ public static clone (a: OBB) { return new OBB(a.center.x, a.center.y, a.center.z, @@ -96,12 +95,12 @@ export class OBB { /** * @en - * copy the values from one obb to another + * Copies the values from one OBB to another. * @zh - * 将从一个 obb 的值复制到另一个 obb。 - * @param out @zh 接受操作的 obb。 @en The output OBB. - * @param a @zh 被复制的 obb。 @en The input OBB. - * @returns @zh out 接受操作的 obb。 @en The reference of the first parameter `out`. + * 复制一个 OBB 的值到另一个 OBB 中。 + * @param out @zh 接受操作的 OBB。 @en The output OBB. + * @param a @zh 被复制的 OBB。 @en The input OBB. + * @returns @zh 接受操作的 OBB,与 `out` 参数相同。 @en The output OBB, same as the `out` parameter. */ public static copy (out: OBB, a: OBB): OBB { Vec3.copy(out.center, a.center); @@ -113,13 +112,13 @@ export class OBB { /** * @en - * create a new obb from two corner points + * Creates a new OBB from two corner points. * @zh - * 用两个点创建一个新的 obb。 - * @param out @zh - 接受操作的 obb。 @en The output OBB. - * @param minPos @zh - obb 的最小点。 @en The minimum position of the AABB. - * @param maxPos @zh - obb 的最大点。 @en The maximum position of the AABB. - * @returns @zh {OBB} out 接受操作的 obb。 @en The reference of the first parameter `out`. + * 用两个点创建一个新的 OBB。 + * @param out @zh - 接受操作的 OBB。 @en The output OBB. + * @param minPos @zh - OBB 的最小点。 @en The minimum position of the AABB. + * @param maxPos @zh - OBB 的最大点。 @en The maximum position of the AABB. + * @returns @zh 接受操作的 OBB,与 `out` 参数相同。 @en The output OBB, same as the `out` parameter. */ public static fromPoints (out: OBB, minPos: Vec3, maxPos: Vec3): OBB { Vec3.multiplyScalar(out.center, Vec3.add(_v3_tmp, minPos, maxPos), 0.5); @@ -130,26 +129,26 @@ export class OBB { /** * @en - * Set the components of a obb to the given values + * Sets the components of an OBB to the given values. * @zh - * 将给定 obb 的属性设置为给定的值。 - * @param out @zh 目标 OBB @en The output OBB. + * 将给定 OBB 的属性设置为给定的值。 + * @param out @zh 目标 OBB @en The output OBB instance. * @param cx @zh 形状的相对于原点的 X 坐标。 @en The x coordinate of origin. * @param cy @zh 形状的相对于原点的 Y 坐标。 @en The y coordinate of origin. * @param cz @zh 形状的相对于原点的 Z 坐标。 @en The z coordinate of origin. * @param hw @zh - obb 宽度的一半。 @en Half the width of the OBB. * @param hh @zh - obb 高度的一半。 @en Half the height of the OBB. * @param hl @zh - obb 长度的一半。 @en Half the length of the OBB. - * @param ox_1 @zh 方向矩阵参数。 @en The x component of the one axis of the OBB. - * @param ox_2 @zh 方向矩阵参数。 @en The x component of the second axis of the OBB. - * @param ox_3 @zh 方向矩阵参数。 @en The x component of the third axis of the OBB. - * @param oy_1 @zh 方向矩阵参数。 @en The y component of the one axis of the OBB. - * @param oy_2 @zh 方向矩阵参数。 @en The y component of the second axis of the OBB. - * @param oy_3 @zh 方向矩阵参数。 @en The y component of the third axis of the OBB. - * @param oz_1 @zh 方向矩阵参数。 @en The z component of the one axis of the OBB. - * @param oz_2 @zh 方向矩阵参数。 @en The z component of the second axis of the OBB. - * @param oz_3 @zh 方向矩阵参数。 @en The z component of the third axis of the OBB. - * @returns @zh out 接受操作的 OBB @en The reference of the first parameter `out`. + * @param ox_1 @zh 方向矩阵参数,第 1 条轴的 x 分量。 @en The x component of the first axis of the OBB. + * @param ox_2 @zh 方向矩阵参数,第 2 条轴的 x 分量。 @en The x component of the second axis of the OBB. + * @param ox_3 @zh 方向矩阵参数,第 3 条轴的 x 分量。 @en The x component of the third axis of the OBB. + * @param oy_1 @zh 方向矩阵参数,第 1 条轴的 y 分量。 @en The y component of the first axis of the OBB. + * @param oy_2 @zh 方向矩阵参数,第 2 条轴的 y 分量。 @en The y component of the second axis of the OBB. + * @param oy_3 @zh 方向矩阵参数,第 3 条轴的 y 分量。 @en The y component of the third axis of the OBB. + * @param oz_1 @zh 方向矩阵参数,第 1 条轴的 z 分量。 @en The z component of the first axis of the OBB. + * @param oz_2 @zh 方向矩阵参数,第 2 条轴的 z 分量。 @en The z component of the second axis of the OBB. + * @param oz_3 @zh 方向矩阵参数,第 3 条轴的 z 分量。 @en The z component of the third axis of the OBB. + * @returns @zh 接受操作的 OBB,与 `out` 参数相同。 @en The output OBB, same as the `out` parameter. */ public static set ( out: OBB, @@ -167,7 +166,7 @@ export class OBB { /** * @en - * Center point of the OBB. + * The center point of an OBB in local coordinate. * @zh * 本地坐标的中心点。 */ @@ -191,9 +190,9 @@ export class OBB { /** * @en - * Gets the type of the shape. + * Gets the type of the OBB. Always returns `enums.SHAPE_OBB`. * @zh - * 获取形状的类型。 + * 获取形状的类型,固定返回 `enums.SHAPE_OBB`。 */ get type () { return this._type; @@ -201,6 +200,23 @@ export class OBB { protected readonly _type: number; + /** + * @param cx @zh 形状的相对于原点的 X 坐标。 @en The x coordinate of origin. + * @param cy @zh 形状的相对于原点的 Y 坐标。 @en The y coordinate of origin. + * @param cz @zh 形状的相对于原点的 Z 坐标。 @en The z coordinate of origin. + * @param hw @zh - OBB 宽度的一半。 @en Half the width of the OBB. + * @param hh @zh - OBB 高度的一半。 @en Half the height of the OBB. + * @param hl @zh - OBB 长度的一半。 @en Half the length of the OBB. + * @param ox_1 @zh 方向矩阵参数,第 1 条轴的 x 分量。 @en The x component of the first axis of the OBB. + * @param ox_2 @zh 方向矩阵参数,第 2 条轴的 x 分量。 @en The x component of the second axis of the OBB. + * @param ox_3 @zh 方向矩阵参数,第 3 条轴的 x 分量。 @en The x component of the third axis of the OBB. + * @param oy_1 @zh 方向矩阵参数,第 1 条轴的 y 分量。 @en The y component of the first axis of the OBB. + * @param oy_2 @zh 方向矩阵参数,第 2 条轴的 y 分量。 @en The y component of the second axis of the OBB. + * @param oy_3 @zh 方向矩阵参数,第 3 条轴的 y 分量。 @en The y component of the third axis of the OBB. + * @param oz_1 @zh 方向矩阵参数,第 1 条轴的 z 分量。 @en The z component of the first axis of the OBB. + * @param oz_2 @zh 方向矩阵参数,第 2 条轴的 z 分量。 @en The z component of the second axis of the OBB. + * @param oz_3 @zh 方向矩阵参数,第 3 条轴的 z 分量。 @en The z component of the third axis of the OBB. + */ constructor (cx = 0, cy = 0, cz = 0, hw = 1, hh = 1, hl = 1, ox_1 = 1, ox_2 = 0, ox_3 = 0, @@ -214,11 +230,11 @@ export class OBB { /** * @en - * Get the bounding points of this shape + * Gets the bounding points of this OBB instance. * @zh - * 获取 obb 的最小点和最大点。 - * @param minPos @zh 最小点。 @en The out minimum position of the OBB. - * @param maxPos @zh 最大点。 @en The out maximum position of the OBB. + * 获取此 OBB 的最小点和最大点。 + * @param minPos @zh 此 OBB 的最小点。 @en The out minimum position of the OBB. + * @param maxPos @zh 此 OBB 的最大点。 @en The out maximum position of the OBB. */ public getBoundary (minPos: Vec3, maxPos: Vec3) { transform_extent_m3(_v3_tmp, this.halfExtents, this.orientation); @@ -228,14 +244,15 @@ export class OBB { /** * @en - * Transform this shape + * Transforms this OBB and store the result to the `out` parameter. * @zh - * 将 out 根据这个 obb 的数据进行变换。 + * 对当前 OBB 的数据进行变换,并存储结果到 `out` 参数中。 * @param m @zh 变换的矩阵。 @en The transform matrix * @param pos @zh 变换的位置部分。 @en 3d-vector translation. * @param rot @zh 变换的旋转部分。 @en Quaternion rotation. * @param scale @zh 变换的缩放部分。 @en 3d-vector scale. - * @param out @zh 变换的目标。 @en The output OBB. + * @param out @zh 变换结果的目标 OBB。 @en The output OBB. + * @note @zh 此方法不会修改当前 OBB 的数据。 @en This method will not modify the data of current OBB. */ public transform (m: Mat4, pos: Vec3, rot: Quat, scale: Vec3, out: OBB) { Vec3.transformMat4(out.center, this.center, m); @@ -246,12 +263,13 @@ export class OBB { /** * @en - * Transform by matrix and rotation. + * Transforms this OBB by a 4x4 matrix and a quaternion. * @zh - * 将 out 根据这个 obb 的数据进行变换。 + * 根据一个 4x4 矩阵和一个四元数变换此 OBB。 * @param m @zh 变换的矩阵。 @en The transform matrix. - * @param rot @zh 变换的旋转部分。 @en Quaternion rotation. + * @param rot @zh 变换的旋转部分。 @en The quaternion for rotation. * @param out @zh 变换的目标。 @en The output OBB. + * @note @zh 此方法不会修改当前 OBB 的数据。 @en This method will not modify the data of current OBB. */ public translateAndRotate (m: Mat4, rot: Quat, out: OBB) { Vec3.transformMat4(out.center, this.center, m); @@ -261,11 +279,12 @@ export class OBB { /** * @en - * Scale OBB by a 3d-vector. + * Scales this OBB by a 3d-vector and store the result to the `out` parameter. * @zh - * 将 out 根据这个 obb 的数据进行缩放。 + * 根据 3D 向量对此 OBB 的数据进行缩放并将结果存储在 out 参数中。 * @param scale @zh 缩放值。 @en 3d-vector scale. * @param out @zh 缩放的目标。 @en The output OBB. + * @note @zh 此方法不会修改当前 OBB 的数据。 @en This method will not modify the data of current OBB. */ public setScale (scale: Vec3, out: OBB) { Vec3.multiply(out.halfExtents, this.halfExtents, scale); diff --git a/cocos/core/geometry/plane.ts b/cocos/core/geometry/plane.ts index 31ed2299a40..7b40b15816e 100644 --- a/cocos/core/geometry/plane.ts +++ b/cocos/core/geometry/plane.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mat4, Vec3, Vec4 } from '../math'; import enums from './enums'; @@ -35,21 +34,23 @@ const temp_vec4 = legacyCC.v4(); /** * @en * Basic Geometry: Plane. + * Plane Equation: a*x + b*y + c*z - d = 0. * @zh - * 基础几何 Plane。 + * 基础几何:平面。 + * 平面方程: a*x + b*y + c*z - d = 0。 */ export class Plane { /** * @en - * create a new plane + * Creates a new plane. * @zh - * 创建一个新的 plane。 - * @param nx @en The x component of normal vector. @zh 法向分量的 x 部分。 - * @param ny @en The y component of normal vector. @zh 法向分量的 y 部分。 - * @param nz @en The z component of normal vector. @zh 法向分量的 z 部分。 + * 创建一个新的平面。 + * @param nx @en The x component of normal vector. @zh 法向量的 x 部分。 + * @param ny @en The y component of normal vector. @zh 法向量的 y 部分。 + * @param nz @en The z component of normal vector. @zh 法向量的 z 部分。 * @param d @en The distance between normal vector and the origin. @zh 与原点的距离。 - * @return + * @returns @en The created plane object. @zh 新创建的平面。 */ public static create (nx: number, ny: number, nz: number, d: number) { return new Plane(nx, ny, nz, d); @@ -57,11 +58,11 @@ export class Plane { /** * @en - * clone a new plane + * Clones a new plane. * @zh - * 克隆一个新的 plane。 - * @param p @en The Plane object to be cloned from. @zh 克隆的来源。 - * @return @en Cloned objects @zh 克隆出的对象。 + * 克隆一个新的平面。 + * @param p @en The Plane object to be cloned from. @zh 克隆的来源平面对象。 + * @returns @en The cloned Plane object @zh 克隆出的平面对象。 */ public static clone (p: Plane) { return new Plane(p.n.x, p.n.y, p.n.z, p.d); @@ -69,12 +70,12 @@ export class Plane { /** * @en - * copy the values from one plane to another + * Copies the values from one plane to another. * @zh * 复制一个平面的值到另一个。 * @param out @en The object to be operated on. @zh 接受操作的对象。 * @param p @en The source of replication. @zh 复制的来源。 - * @return @en The object to be operated on. @zh 接受操作的对象。 + * @returns @en The object to be operated on. @zh 接受操作的对象。 */ public static copy (out: Plane, p: Plane) { Vec3.copy(out.n, p.n); @@ -85,14 +86,14 @@ export class Plane { /** * @en - * create a plane from three points + * Creates a plane from three points * @zh * 用三个点创建一个平面。 - * @param out @en The object to be operated on. @zh 接受操作的对象。 - * @param a @en Point a. @zh 点 a。 - * @param b @en Point b. @zh 点 b。 - * @param c @en Point c. @zh 点 c。 - * @return out @en The object to be operated on. @zh 接受操作的对象。 + * @param out @en The Plane object to be operated on. @zh 接受操作的对象。 + * @param a @en The point a. @zh 点 a。 + * @param b @en The point b. @zh 点 b。 + * @param c @en The point c. @zh 点 c。 + * @returns @en The Plane object to be operated on, same as `out` parameter. @zh 接受操作的对象,与 `out` 相同。 */ public static fromPoints (out: Plane, a: Vec3, b: Vec3, c: Vec3) { Vec3.subtract(v1, b, a); @@ -106,15 +107,15 @@ export class Plane { /** * @en - * Set the components of a plane to the given values + * Sets the components of a plane to the given values. * @zh * 将给定平面的属性设置为给定值。 - * @param out @en The object to be operated on. @zh 接受操作的对象。 - * @param nx @en The x component of normal vector. @zh 法向分量的 x 部分。 - * @param ny @en The y component of normal vector. @zh 法向分量的 y 部分。 - * @param nz @en The z component of normal vector. @zh 法向分量的 z 部分。 + * @param out @en The Plane object to be operated on. @zh 接受操作的对象。 + * @param nx @en The x component of normal vector. @zh 法向量量的 x 部分。 + * @param ny @en The y component of normal vector. @zh 法向量的 y 部分。 + * @param nz @en The z component of normal vector. @zh 法向量的 z 部分。 * @param d @en The distance between normal vector and the origin. @zh 与原点的距离。 - * @return out @en The object to be operated on. @zh 接受操作的对象。 + * @returns @en The object to be operated on, same as the `out` parameter. @zh 接受操作的对象,与 `out` 参数相同。 */ public static set (out: Plane, nx: number, ny: number, nz: number, d: number) { out.n.x = nx; @@ -127,13 +128,13 @@ export class Plane { /** * @en - * create plane from normal and point + * Creates plane from normal and point. * @zh * 用一条法线和一个点创建平面。 * @param out @en The object to be operated on. @zh 接受操作的对象。 - * @param normal @en Normal of the plane. @zh 平面的法线。 + * @param normal @en The normal of the plane. @zh 平面的法线。 * @param point @en A point in the plane. @zh 平面上的一点。 - * @return out @en The object to be operated on. @zh 接受操作的对象。 + * @returns @en The object to be operated on, same as the `out` parameter. @zh 接受操作的对象,与 `out` 参数相同。 */ public static fromNormalAndPoint (out: Plane, normal: Vec3, point: Vec3) { Vec3.copy(out.n, normal); @@ -144,12 +145,12 @@ export class Plane { /** * @en - * normalize a plane + * Normalizes a plane. * @zh * 归一化一个平面。 * @param out @en The object to be operated on. @zh 接受操作的对象。 * @param a @en Source data for the operation. @zh 操作的源数据。 - * @return out @en The object to be operated on. @zh 接受操作的对象。 + * @returns @en The object to be operated on, sames as the `out` parameter. @zh 接受操作的对象,与 `out` 相同。 */ public static normalize (out: Plane, a: Plane) { const len = a.n.length(); @@ -174,13 +175,13 @@ export class Plane { * @zh * 原点到平面的距离。 */ - public d: number; + public declare d: number; /** * @en - * Gets the type of the shape. + * Gets the type of the Plane, its value is `enums.SHAPE_PLANE`. * @zh - * 获取形状的类型。 + * 获取形状的类型,值为 `enums.SHAPE_PLANE`。 */ get type () { return this._type; @@ -196,16 +197,16 @@ export class Plane { set w (val) { this.d = val; } get w () { return this.d; } - protected readonly _type: number; + protected declare readonly _type: number; /** * @en - * Construct a plane. + * Constructs a plane. * @zh * 构造一个平面。 - * @param nx @en The x component of normal vector. @zh 法向分量的 x 部分。 - * @param ny @en The y component of normal vector. @zh 法向分量的 y 部分。 - * @param nz @en The z component of normal vector. @zh 法向分量的 z 部分。 + * @param nx @en The x component of normal vector. @zh 法向量的 x 部分。 + * @param ny @en The y component of normal vector. @zh 法向量的 y 部分。 + * @param nz @en The z component of normal vector. @zh 法向量的 z 部分。 * @param d @en The distance between normal vector and the origin. @zh 与原点的距离。 */ constructor (nx = 0, ny = 1, nz = 0, d = 0) { @@ -216,17 +217,17 @@ export class Plane { /** * @en - * transform this plane. + * Transforms this plane by a 4x4 matrix. * @zh - * 变换一个平面。 - * @param mat + * 使用一个 4x4 矩阵变换此平面。 + * @param mat @en The 4x4 matrix for transformation @zh 用于变换的 4x4 矩阵。 */ public transform (mat: Mat4): void { Mat4.invert(temp_mat, mat); Mat4.transpose(temp_mat, temp_mat); - Vec4.set(temp_vec4, this.n.x, this.n.y, this.n.z, this.d); + Vec4.set(temp_vec4, this.n.x, this.n.y, this.n.z, -this.d); Vec4.transformMat4(temp_vec4, temp_vec4, temp_mat); Vec3.set(this.n, temp_vec4.x, temp_vec4.y, temp_vec4.z); - this.d = temp_vec4.w; + this.d = -temp_vec4.w; } } diff --git a/cocos/core/geometry/ray.ts b/cocos/core/geometry/ray.ts index 65de5c49bea..d22c31957f2 100644 --- a/cocos/core/geometry/ray.ts +++ b/cocos/core/geometry/ray.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec3 } from '../math'; import enums from './enums'; @@ -29,24 +28,24 @@ import { IVec3Like } from '../math/type-define'; /** * @en - * Basic Geometry: ray. + * Basic Geometry: Ray. * @zh - * 基础几何 射线。 + * 基础几何:射线。 */ export class Ray { /** * @en - * create a new ray + * Creates a new ray. * @zh * 创建一条射线。 - * @param {number} ox @en x component of start point @zh 起点的 x 部分。 - * @param {number} oy @en y component of start point @zh 起点的 y 部分。 - * @param {number} oz @en z component of start point @zh 起点的 z 部分。 - * @param {number} dx @en Point in the x direction @zh 方向的 x 部分。 - * @param {number} dy @en Point in the y direction @zh 方向的 y 部分。 - * @param {number} dz @en Point in the z direction @zh 方向的 z 部分。 - * @return {Ray} @en Ray object @zh 射线。 + * @param {number} ox @en The x component of start point. @zh 起点的 x 部分。 + * @param {number} oy @en The y component of start point. @zh 起点的 y 部分。 + * @param {number} oz @en The z component of start point. @zh 起点的 z 部分。 + * @param {number} dx @en The x component of direction point. @zh 方向的 x 部分。 + * @param {number} dy @en The y component of direction point. @zh 方向的 y 部分。 + * @param {number} dz @en The z component of direction point. @zh 方向的 z 部分。 + * @returns {Ray} @en The created ray object. @zh 新创建的射线。 */ public static create (ox = 0, oy = 0, oz = 0, dx = 0, dy = 0, dz = 1): Ray { return new Ray(ox, oy, oz, dx, dy, dz); @@ -54,11 +53,11 @@ export class Ray { /** * @en - * Creates a new ray initialized with values from an existing ray + * Creates a new ray initialized with the values from an existing ray. * @zh * 从一条射线克隆出一条新的射线。 - * @param {Ray} a @en The Ray object to be cloned from @zh 克隆的目标。 - * @return {Ray} @en Clone new ray object @zh 克隆出的新对象。 + * @param a @en The Ray object to be cloned from. @zh 克隆的目标。 + * @returns @en The cloned Ray object. @zh 克隆出的新对象。 */ public static clone (a: Ray): Ray { return new Ray( @@ -69,12 +68,12 @@ export class Ray { /** * @en - * Copy the values from one ray to another + * Copies the values from one ray to another. * @zh - * 将从一个 ray 的值复制到另一个 ray。 - * @param {Ray} out @en The ray object to be modified @zh 接受操作的 ray。 - * @param {Ray} a @en The copied ray object @zh 被复制的 ray。 - * @return {Ray} @en Ray object @zh out 接受操作的 ray。 + * 复制一个 Ray 的值到另一个 Ray 中。 + * @param out @en The Ray object to copy to. @zh 接受操作的射线。 + * @param a @en The Ray object to copy from. @zh 被复制的射线。 + * @returns @en The Ray object to copy to, same as the `out` parameter. @zh 接受操作的射线,与 `out` 参数相同。 */ public static copy (out: Ray, a: Ray): Ray { Vec3.copy(out.o, a.o); @@ -85,13 +84,13 @@ export class Ray { /** * @en - * create a ray from two points + * Creates a ray from two points. * @zh * 用两个点创建一条射线。 - * @param {Ray} out @en The ray object to be modified @zh 接受操作的射线。 - * @param {Vec3} origin @en Starting point of the ray @zh 射线的起点。 - * @param {Vec3} target @en point on the ray @zh 射线上的一点。 - * @return {Ray} @en Ray object @zh out 接受操作的射线。 + * @param out @en The Ray object. @zh 接受操作的射线。 + * @param origin @en The start point of the ray. @zh 射线的起点。 + * @param target @en The target point on the ray. @zh 射线上的一点。 + * @returns @en The Ray object, same as the `out` parameter. @zh 接受操作的射线,与 `out` 参数相同。 */ public static fromPoints (out: Ray, origin: Vec3, target: Vec3): Ray { Vec3.copy(out.o, origin); @@ -101,17 +100,17 @@ export class Ray { /** * @en - * Set the components of a ray to the given values + * Sets the components of a ray to the given values. * @zh * 将给定射线的属性设置为给定的值。 - * @param {Ray} out @en The ray object to be modified @zh 接受操作的射线。 - * @param {number} ox @en x component of start point @zh 起点的 x 部分。 - * @param {number} oy @en y component of start point @zh 起点的 y 部分。 - * @param {number} oz @en z component of start point @zh 起点的 z 部分。 - * @param {number} dx @en Point in the x direction @zh 方向的 x 部分。 - * @param {number} dy @en Point in the y direction @zh 方向的 y 部分。 - * @param {number} dz @en Point in the z direction @zh 方向的 z 部分。 - * @return {Ray} @en Ray object @zh out 接受操作的射线。 + * @param out @en The Ray object to be modified @zh 接受操作的射线。 + * @param ox @en The x component of start point. @zh 起点的 x 部分。 + * @param oy @en The y component of start point. @zh 起点的 y 部分。 + * @param oz @en The z component of start point. @zh 起点的 z 部分。 + * @param dx @en The x component of direction point. @zh 方向的 x 部分。 + * @param dy @en The y component of direction point. @zh 方向的 y 部分。 + * @param dz @en The z component of direction point. @zh 方向的 z 部分。 + * @returns @en The Ray object, same as the `out` parameter. @zh 接受操作的射线,与 `out` 相同。 */ public static set (out: Ray, ox: number, oy: number, oz: number, dx: number, dy: number, dz: number): Ray { out.o.x = ox; @@ -142,9 +141,9 @@ export class Ray { /** * @en - * Gets the type of the shape. + * Gets the type of the ray, its value is `enums.SHAPE_RAY`. * @zh - * 获取形状的类型。 + * 获取形状的类型,其值为`enums.SHAPE_RAY`。 */ get type () { return this._type; @@ -154,15 +153,15 @@ export class Ray { /** * @en - * Construct a ray; + * Constructs a ray. * @zh * 构造一条射线。 - * @param {number} ox @en x component of start point @zh 起点的 x 部分。 - * @param {number} oy @en y component of start point @zh 起点的 y 部分。 - * @param {number} oz @en z component of start point @zh 起点的 z 部分。 - * @param {number} dx @en Point in the x direction @zh 方向的 x 部分。 - * @param {number} dy @en Point in the y direction @zh 方向的 y 部分。 - * @param {number} dz @en Point in the z direction @zh 方向的 z 部分。 + * @param ox @en The x component of start point. @zh 起点的 x 部分。 + * @param oy @en The y component of start point. @zh 起点的 y 部分。 + * @param oz @en The z component of start point. @zh 起点的 z 部分。 + * @param dx @en The x component of direction point. @zh 方向的 x 部分。 + * @param dy @en The y component of direction point. @zh 方向的 y 部分。 + * @param dz @en The z component of direction point. @zh 方向的 z 部分。 */ constructor (ox = 0, oy = 0, oz = 0, dx = 0, dy = 0, dz = -1) { @@ -173,11 +172,11 @@ export class Ray { /** * @en - * Compute a point with the distance between the origin. + * Calculates a point on the ray with the specific distance from the origin point. * @zh - * 根据给定距离计算出射线上的一点。 - * @param out @en Another point on the ray @zh 射线上的另一点。 - * @param distance @en Given distance @zh 给定距离。 + * 根据给定的距离计算出射线上的一点。 + * @param out @en Another point on the ray. @zh 射线上的另一点。 + * @param distance @en The given distance. @zh 给定的距离。 */ public computeHit (out: IVec3Like, distance: number) { Vec3.normalize(out, this.d); diff --git a/cocos/core/geometry/spec.ts b/cocos/core/geometry/spec.ts index 4d8e526d3c1..71cf7f02f4b 100644 --- a/cocos/core/geometry/spec.ts +++ b/cocos/core/geometry/spec.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @en @@ -33,7 +32,7 @@ export enum ERaycastMode { /** * @en - * Detect and record all data. + * Detects and records all data. * @zh * 检测并记录所有的数据。 */ @@ -41,7 +40,7 @@ export enum ERaycastMode { /** * @en - * Detect all, but record only the most recent data. + * Detects all data, but records only the most recent data. * @zh * 检测所有,但只记录最近的数据。 */ @@ -157,7 +156,7 @@ export interface IRayMeshOptions extends IRaySubMeshOptions { /** * @en - * The optional param structure of the `rayModel`. + * The optional parameter structure of the `rayModel`. * @zh * `rayModel`的可选参数结构。 */ diff --git a/cocos/core/geometry/sphere.ts b/cocos/core/geometry/sphere.ts index 923ef493a47..21819892337 100644 --- a/cocos/core/geometry/sphere.ts +++ b/cocos/core/geometry/sphere.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mat4, Quat, Vec3 } from '../math'; import enums from './enums'; @@ -37,20 +36,20 @@ function maxComponent (v: Vec3) { return Math.max(Math.max(v.x, v.y), v.z); } * @en * Basic Geometry: Sphere. * @zh - * 基础几何 轴对齐球。 + * 基础几何:球。 */ export class Sphere { /** * @en - * create a new sphere + * Creates a new sphere instance. * @zh - * 创建一个新的 sphere 实例。 - * @param cx @en X-Coordinate of center point relative to the origin. @zh 中心点的相对于原点的 X 坐标。 - * @param cy @en Y-Coordinate of center point relative to the origin. @zh 中心点的相对于原点的 Y 坐标。 - * @param cz @en Z-Coordinate of center point relative to the origin. @zh 中心点的相对于原点的 Z 坐标。 - * @param r @en Radius of the sphere. @zh 球体的半径 - * @return @en return a new sphere. @zh 返回一个 sphere。 + * 创建一个新的球实例。 + * @param cx @en The X-Coordinate of the center point relative to the origin. @zh 相对于原点的中心点的 X 坐标。 + * @param cy @en The Y-Coordinate of the center point relative to the origin. @zh 相对于原点的中心点的 Y 坐标。 + * @param cz @en The Z-Coordinate of the center point relative to the origin. @zh 相对于原点的中心点的 Z 坐标。 + * @param r @en The radius of the sphere. @zh 球体的半径 + * @returns @en A new sphere instance. @zh 一个新的球实例。 */ public static create (cx: number, cy: number, cz: number, r: number): Sphere { return new Sphere(cx, cy, cz, r); @@ -58,11 +57,11 @@ export class Sphere { /** * @en - * clone a new sphere + * Clones a sphere instance. * @zh - * 克隆一个新的 sphere 实例。 + * 克隆一个新的球实例。 * @param p @en The sphere object to clone from. @zh 克隆的目标。 - * @return @en The sphere object to clone to. @zh 克隆出的示例。 + * @returns @en The sphere object to clone to. @zh 克隆出的实例。 */ public static clone (p: Sphere): Sphere { return new Sphere(p.center.x, p.center.y, p.center.z, p.radius); @@ -70,12 +69,12 @@ export class Sphere { /** * @en - * copy the values from one sphere to another + * Copies the values from one sphere to another. * @zh - * 将从一个 sphere 的值复制到另一个 sphere。 - * @param out @en The sphere object to copy to. @zh 接受操作的 sphere。 - * @param a @en The sphere object to copy from. @zh 被复制的 sphere。 - * @return @en The sphere object to copy to. @zh 接受操作的 sphere。 + * 复制一个球的值到另一个球中。 + * @param out @en The sphere object to copy to. @zh 接受操作的球实例。 + * @param a @en The sphere object to copy from. @zh 被复制的球实例。 + * @returns @en The sphere object to copy to. @zh 接受操作的球实例。 */ public static copy (out: Sphere, p: Sphere): Sphere { Vec3.copy(out.center, p.center); @@ -86,13 +85,13 @@ export class Sphere { /** * @en - * create a new bounding sphere from two corner points + * Creates a new sphere instance from two points. * @zh - * 从两个点创建一个新的 sphere。 - * @param out - @en Sphere created from points. @zh 接受操作的 sphere。 - * @param minPos - @en Lower point of the sphere. @zh sphere 的较小点。 - * @param maxPos - @en Upper point of the sphere. @zh sphere 的较大点。 - * @returns @en The output sphere object to save the created sphere data. @zh 接受操作的 sphere。 + * 从两个点创建一个新的球实例。 + * @param out - @en The sphere created from the two points. @zh 接受操作的球实例。 + * @param minPos - @en The lower point of the sphere. @zh 球的较小点。 + * @param maxPos - @en The upper point of the sphere. @zh 球的较大点。 + * @returns @en The created sphere, same as the `out` parameter. @zh 接受操作的球实例,与 `out` 参数相同。 */ public static fromPoints (out: Sphere, minPos: Vec3, maxPos: Vec3): Sphere { Vec3.multiplyScalar(out.center, Vec3.add(_v3_tmp, minPos, maxPos), 0.5); @@ -102,15 +101,15 @@ export class Sphere { /** * @en - * Set the components of a sphere to the given values + * Sets the components of a sphere to the given values * @zh * 将球体的属性设置为给定的值。 - * @param out @en The sphere to set properties to. @zh 接受操作的 sphere。 - * @param cx @en X-Coordinate of center point relative to the origin. @zh 中心点的相对于原点的 X 坐标。 - * @param cy @en Y-Coordinate of center point relative to the origin. @zh 中心点的相对于原点的 Y 坐标。 - * @param cz @en Z-Coordinate of center point relative to the origin. @zh 中心点的相对于原点的 Z 坐标。 - * @param r @en Radius of the sphere. @zh 半径。 - * @return @en Sphere which the properties will be set to. @zh 接受操作的 sphere。 + * @param out @en The sphere to set values to. @zh 接受操作的球实例。 + * @param cx @en The X-Coordinate of the center point which relative to the origin. @zh 相对于原点的中心点的 X 坐标。 + * @param cy @en The Y-Coordinate of the center point which relative to the origin. @zh 相对于原点的中心点的 Y 坐标。 + * @param cz @en The Z-Coordinate of the center point which relative to the origin. @zh 相对于原点的中心点的 Z 坐标。 + * @param r @en The radius of the sphere. @zh 要设置的球的半径。 + * @returns @en The sphere to set values to, same as the `out` parameter. @zh 接受操作的实例,与 `out` 相同。 * @function */ public static set (out: Sphere, cx: number, cy: number, cz: number, r: number): Sphere { @@ -126,7 +125,7 @@ export class Sphere { * @en * The center of this sphere. * @zh - * 本地坐标的中心点。 + * 当前球在本地坐标中的中心点。 */ protected _center: Vec3 = new Vec3(0, 0, 0); get center (): Vec3 { @@ -143,7 +142,7 @@ export class Sphere { * @en * The radius of this sphere. * @zh - * 半径。 + * 当前球的半径。 */ get radius (): number { return this._radius; @@ -155,9 +154,9 @@ export class Sphere { /** * @en - * Gets the type of the shape. + * Gets the type of the shape, always returns `enums.SHAPE_SPHERE`. * @zh - * 获取形状的类型。 + * 获取球的类型,固定返回 `enums.SHAPE_SPHERE`。 */ get type () { return this._type; @@ -167,13 +166,13 @@ export class Sphere { /** * @en - * Construct a sphere. + * Constructs a sphere instance. * @zh * 构造一个球。 * @param cx @en The X-Coordinate of the sphere. @zh 该球的世界坐标的 X 坐标。 * @param cy @en The Y-Coordinate of the sphere. @zh 该球的世界坐标的 Y 坐标。 * @param cz @en The Z-Coordinate of the sphere. @zh 该球的世界坐标的 Z 坐标。 - * @param r @en The radius. @zh 半径。 + * @param r @en The radius of the sphere. @zh 球的半径。 */ constructor (cx = 0, cy = 0, cz = 0, r = 1) { this._type = enums.SHAPE_SPHERE; @@ -186,9 +185,10 @@ export class Sphere { /** * @en - * Get a clone. + * Clones a sphere instance. * @zh - * 获得克隆。 + * 克隆一个球实例。 + * @returns @en The cloned sphere instance. @zh 克隆的球实例。 */ public clone () { return Sphere.clone(this); @@ -196,9 +196,9 @@ export class Sphere { /** * @en - * Copy a sphere. + * Copies the values from a sphere to the current sphere. * @zh - * 拷贝对象。 + * 复制一个球的值到当前球实例中。 * @param a @en The sphere to copy from. @zh 拷贝的目标。 */ public copy (a: Sphere) { @@ -207,11 +207,11 @@ export class Sphere { /** * @en - * Get the bounding points of this shape + * Gets the bounding points of this sphere. * @zh - * 获取此形状的边界点。 - * @param minPos @en The point with maximum coordinates of the sphere. @zh 最小点。 - * @param maxPos @en The point with minimum coordinates of the sphere. @zh 最大点。 + * 获取此球体的边界点。 + * @param minPos @en The point with maximum coordinates of the sphere. @zh 当前球实例的最小点。 + * @param maxPos @en The point with minimum coordinates of the sphere. @zh 当前球实例的最大点。 */ public getBoundary (minPos: Vec3, maxPos: Vec3) { Vec3.set(minPos, this.center.x - this.radius, this.center.y - this.radius, this.center.z - this.radius); @@ -220,13 +220,13 @@ export class Sphere { /** * @en - * Transform this shape + * Transforms this sphere by a 4x4 matrix and RTS and stores to the `out` parameter. * @zh - * 将 out 根据这个 sphere 的数据进行变换。 - * @param m @en The transform matrix. @zh 变换的矩阵。 - * @param pos @en The position. @zh 变换的位置部分。 - * @param rot @en The rotation. @zh 变换的旋转部分。 - * @param scale @en The scale. @zh 变换的缩放部分。 + * 用一个 4x4 矩阵和一组 RTS 变换此球体,并将结果存储在 `out` 参数中。 + * @param m @en The 4x4 transform matrix. @zh 4x4 变换矩阵。 + * @param pos @en The position part of the transform. @zh 变换的位置部分。 + * @param rot @en The rotation part of the transform. @zh 变换的旋转部分。 + * @param scale @en The scale part of the transform. @zh 变换的缩放部分。 * @param out @en The sphere which the transform will be applied to. @zh 变换的目标。 */ public transform (m: Mat4, pos: Vec3, rot: Quat, scale: Vec3, out: Sphere) { @@ -236,11 +236,11 @@ export class Sphere { /** * @en - * Translate and rotate this sphere. + * Transforms this sphere by a 4x4 matrix and a quaternion, stores the result to the `out` parameter. * @zh - * 将 out 根据这个 sphere 的数据进行变换。 - * @param m @en The transform matrix. @zh 变换的矩阵。 - * @param rot @en The rotation. @zh 变换的旋转部分。 + * 使用一个 4x4 矩阵和一个四元数变换此球体,并将结果存储在 `out` 参数中。 + * @param m @en The 4x4 transform matrix. @zh 4x4 变换矩阵。 + * @param rot @en The rotation part of the transform. @zh 变换的旋转部分。 * @param out @en The sphere which the transform will be applied to. @zh 变换的目标。 */ public translateAndRotate (m: Mat4, rot: Quat, out: Sphere) { @@ -249,10 +249,10 @@ export class Sphere { /** * @en - * Scaling this sphere. + * Scales this sphere and stores the result to the `out` parameter. * @zh - * 将 out 根据这个 sphere 的数据进行缩放。 - * @param scale @en The scale. @zh 缩放值。 + * 对当前球实例进行缩放处理,并将结果存储在 `out` 参数中。 + * @param scale @en The scale value. @zh 缩放值。 * @param out @en The sphere which the scale will be applied to. @zh 缩放的目标。 */ public setScale (scale: Vec3, out: Sphere) { @@ -260,9 +260,9 @@ export class Sphere { } /** - * @en The point to be merged. - * @zh 球跟点合并 - * @param point @en The point to be merged. @zh 点 + * @en Merges a point to this sphere. + * @zh 合并一个点到当前球实例中。 + * @param point @en The point to be merged to this sphere. @zh 要合并到当前球实例的点。 */ public mergePoint (point: Vec3) { // if sphere.radius Less than 0, @@ -285,9 +285,9 @@ export class Sphere { } /** - * @en The sphere and points to be merged. - * @zh 球跟一系列点合并 - * @param points @en The point to be merged. @zh 一系列点 + * @en Merges some points to this sphere. + * @zh 合并一些点到当前球实例中。 + * @param points @en The points to be merged to this sphere. @zh 要合并到当前球实例的点列表。 */ public mergePoints (points: Vec3[]) { const length = points.length; @@ -302,9 +302,9 @@ export class Sphere { } /** - * @en The axis-aligned bounding box to be merged. - * @zh 球跟立方体合并 - * @param a @en Cube. @zh 立方体 + * @en Merges a AABB to this sphere. + * @zh 合并一个 AABB 到当前球实例中。 + * @param a @en The AABB instance to be merged to this sphere. @zh 要合并到当前球实例的 AABB 实例。 */ public mergeAABB (a: AABB) { a.getBoundary(_min, _max); diff --git a/cocos/core/geometry/spline.ts b/cocos/core/geometry/spline.ts index 08024265416..5ac549e486f 100644 --- a/cocos/core/geometry/spline.ts +++ b/cocos/core/geometry/spline.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { assertIsTrue } from '../data/utils/asserts'; import { clamp, Vec3 } from '../math'; @@ -30,12 +29,16 @@ import enums from './enums'; export enum SplineMode { /** + * @en * Broken line: * Each knot is connected with a straight line from the beginning to the end to form a curve. At least two knots. + * @zh + * 每个结从头到尾用一条直线相连,形成一条曲线。 至少存在两个结点。 */ LINEAR = 0, /** + * @en * Piecewise Bezier curve: * Every four knots form a curve. Total knots number must be a multiple of 4. * Each curve passes only the first and fourth knots, and does not pass through the middle two control knots. @@ -44,13 +47,29 @@ export enum SplineMode { * (1) Suppose the four knots of the previous curve are A, B, C, D * (2) The four knots of the next curve must be D, E, F, G * (3) C and E need to be symmetrical about D + * + * @zh + * 分段贝塞尔曲线: + * 每四个结形成一条曲线。 总节数必须是 4 的倍数。 + * 每条曲线只通过第一个和第四个结点,不通过中间两个控制结点。 + * + * 如果你需要一条完整的连续曲线: + * (1) 假设前面曲线的四个结点分别是 A, B, C, D + * (2) 下一条曲线的四个结点必须是 D, E, F, G + * (3) C 和 E 需要关于 D 对称 */ BEZIER = 1, /** + * @en * Catmull Rom curve: * All knots(including start & end knots) form a whole continuous curve. At least two knots. * The whole curve passes through all knots. + * + * @zh + * Catmull Rom 曲线: + * 所有结点(包括起始结点和结束结点)形成一条完整的连续曲线。 至少存在两个结点。 + * 整条曲线穿过所有结点。 */ CATMULL_ROM = 2 } @@ -66,7 +85,7 @@ const _v3 = new Vec3(); * @en * Basic Geometry: Spline. * @zh - * 基础几何 Spline + * 基础几何:Spline。 */ export class Spline { @@ -83,14 +102,40 @@ export class Spline { } } + /** + * @en + * Creates a spline instance. + * @zh + * 创建一个 Spline 实例。 + * @param mode @en The mode to create the Spline instance. @zh 用于创建 Spline 实例的模式。 + * @param knots @en The knots to create the Spline instance. @zh 用于创建 Spline 实例的结点列表。 + * @returns @en The created Spline instance. @zh 创建出的 Spline 实例。 + */ public static create (mode: SplineMode, knots: Vec3[] = []) { return new Spline(mode, knots); } + /** + * @en + * Clones a Spline instance. + * @zh + * 克隆一个 Spline 实例。 + * @param s @en The Spline instance to be cloned. @zh 用于克隆的 Spline 实例。 + * @returns @en The cloned Spline instance. @zh 克隆出的 Spline 实例。 + */ public static clone (s: Spline) { return new Spline(s.mode, s.knots); } + /** + * @en + * Copies the values of a Spline instance to another. + * @zh + * 拷贝一个 Spline 实例的值到另一个中。 + * @param out @en The target Spline instance to copy to. @zh 拷贝目标 Spline 实例。 + * @param s @en The source Spline instance to copy from. @zh 拷贝源 Spline 实例。 + * @returns @en The target Spline instance to copy to, same as the `out` parameter. @zh 拷贝目标 Spline 实例,值与 `out` 参数相同。 + */ public static copy (out: Spline, s: Spline) { out._mode = s.mode; out._knots.length = 0; @@ -104,18 +149,44 @@ export class Spline { return out; } + /** + * @en + * Gets the type of this Spline instance, always returns `enums.SHAPE_SPLINE`. + * @zh + * 获取此 Spline 的类型,固定返回 `enums.SHAPE_SPLINE` + */ get type () { return this._type; } + /** + * @en + * Gets the mode of this Spline instance. + * @zh + * 获取当前 Spline 实例的模式。 + */ get mode () { return this._mode; } + /** + * @en + * Gets all knots of this Spline instance. + * @zh + * 获取当前 Spline 实例的所有结点。 + */ get knots (): Readonly { return this._knots; } + /** + * @en + * Sets the mode and knots to this Spline instance. + * @zh + * 给当前 Spline 实例设置模式和结点。 + * @param mode @en The mode to be set to this Spline instance. @zh 要设置到当前 Spline 实例的模式。 + * @param knots @en The knots to be set to this spline instance. @zh 要设置到当前 Spline 实例的结点列表。 + */ public setModeAndKnots (mode: SplineMode, knots: Vec3[]) { this._mode = mode; this._knots.length = 0; @@ -125,18 +196,46 @@ export class Spline { } } + /** + * @en + * Clears all knots of this Spline instance. + * @zh + * 清空当前 Spline 实例的所有结点。 + */ public clearKnots () { this._knots.length = 0; } + /** + * @en + * Gets the knot count of this Spline instance. + * @zh + * 获取当前 Spline 实例的结点数量。 + * @returns @en The knot count of this Spline instance. @zh 当前 Spline 实例的结点数量。 + */ public getKnotCount () { return this._knots.length; } + /** + * @en + * Adds a knot to this Spline instance. + * @zh + * 给当前 Spline 实例添加一个结点。 + * @param knot @en The knot to add to this Spline instance. @zh 要添加到当前 Spline 实例的结点。 + */ public addKnot (knot: Vec3) { this._knots.push(new Vec3(knot)); } + /** + * @en + * Inserts a knot to the specified position of this Spline instance. + * @zh + * 插入一个结点到当前 Spline 实例的指定位置。 + * @param index @en The position of this Spline instance to be inserted. @zh 要插入到此 Spline 实例的位置。 + * @param knot @en The knot to be inserted. @zh 要插入的结点。 + */ public insertKnot (index: number, knot: Vec3) { const item = new Vec3(knot); if (index >= this._knots.length) { @@ -147,34 +246,65 @@ export class Spline { this._knots.splice(index, 0, item); } + /** + * @en + * Removes a knot at the specified position of this Spline instance. + * @zh + * 移除当前 Spline 实例的指定位置的一个结点。 + * @param index + */ public removeKnot (index: number) { assertIsTrue(index >= 0 && index < this._knots.length, 'Spline: invalid index'); this._knots.splice(index, 1); } + /** + * @en + * Sets a knot to the specified position of this Spline instance. + * @zh + * 为当前 Spline 实例的指定位置设置结点信息。 + * @param index @en The specified position of this Spline instance. @zh 要设置结点的指定位置。 + * @param knot @en The knot to be set to the specified position. @zh 要设置的结点。 + */ public setKnot (index: number, knot: Vec3) { assertIsTrue(index >= 0 && index < this._knots.length, 'Spline: invalid index'); this._knots[index].set(knot); } + /** + * @en + * Gets the knot of the specified position of this Spline instance. + * @zh + * 获取当前 Spline 实例指定位置的结点。 + * @param index @en The specified position of this Spline instance. @zh 要设置结点的指定位置。 + * @returns @en The knot of the specified position of this Spline instance. @zh 当前 Spline 实例指定位置的结点。 + */ public getKnot (index: number): Readonly { assertIsTrue(index >= 0 && index < this._knots.length, 'Spline: invalid index'); return this._knots[index]; } - // get a point at t with repect to the `index` segment of curve or the whole curve. + /** + * @en + * Gets a point at t with repect to the `index` segment of curve or the whole curve. + * @zh + * 获取 t 处相对于某段或整条曲线的点。 + * @param t @en The factor with a range of [0.0, 1.0]. @zh 0.0 到 1.0 的因子。 + * @param index @en The knot index of this Spline instance, default value is the whole curve. @zh 当前 Spline 实例的某个结点索引,默认值为整条曲线。 + * @returns @en The point matches the input `t` factor and `index`. @zh 满足输入 `t` 参数和 `index` 参数的点。 + */ public getPoint (t: number, index: number = SPLINE_WHOLE_INDEX) { t = clamp(t, 0.0, 1.0); const segments = this.getSegments(); - if (segments == 0) { + if (segments === 0) { return new Vec3(0.0, 0.0, 0.0); } - if (index == SPLINE_WHOLE_INDEX) { + if (index === SPLINE_WHOLE_INDEX) { const deltaT = 1.0 / segments; index = Math.floor(t / deltaT); @@ -200,13 +330,21 @@ export class Spline { } } - // get num points from 0 to 1 uniformly with repect to the `index` segment of curve or the whole curve + /** + * @en + * Gets points from 0 to 1 uniformly with repect to the `index` segment of curve or the whole curve. + * @zh + * 获取相对与某段或整条曲线上的 n 个数量的点信息。 + * @param num @en The count of points needed. @zh 需要的点的数量。 + * @param index @en The knot index of this Spline instance, default value is the whole curve. @zh 当前 Spline 实例的某个结点索引,默认值为整条曲线。 + * @returns @en The points with `num` size at the `index` segment or the whole curve. @zh 曲线某段或者整条曲线上的 `num` 个点。 + */ public getPoints (num: number, index: number = SPLINE_WHOLE_INDEX): Vec3[] { - if (num == 0) { + if (num === 0) { return []; } - if (num == 1) { + if (num === 1) { const point = this.getPoint(0.0, index); return [point]; } diff --git a/cocos/core/geometry/triangle.ts b/cocos/core/geometry/triangle.ts index 1bd73c16206..e04d56b85ab 100644 --- a/cocos/core/geometry/triangle.ts +++ b/cocos/core/geometry/triangle.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec3 } from '../math'; import enums from './enums'; @@ -30,25 +29,25 @@ import enums from './enums'; * @en * Basic Geometry: Triangle. * @zh - * 基础几何 三角形。 + * 基础几何:三角形。 */ export class Triangle { /** * @en - * create a new triangle + * Creates a new triangle instance. * @zh - * 创建一个新的 triangle。 - * @param {number} ax @en x component of point a @zh a 点的 x 部分。 - * @param {number} ay @en y component of point a @zh a 点的 y 部分。 - * @param {number} az @en z component of point a @zh a 点的 z 部分。 - * @param {number} bx @en x component of point b @zh b 点的 x 部分。 - * @param {number} by @en y component of point b @zh b 点的 y 部分。 - * @param {number} bz @en z component of point b @zh b 点的 z 部分。 - * @param {number} cx @en x component of point c @zh c 点的 x 部分。 - * @param {number} cy @en y component of point c @zh c 点的 y 部分。 - * @param {number} cz @en z component of point c @zh c 点的 z 部分。 - * @return {Triangle} @en A new triangle. @zh 一个新的 triangle。 + * 创建一个新的三角形。 + * @param {number} ax @en The x component of point a @zh a 点的 x 部分。 + * @param {number} ay @en The y component of point a @zh a 点的 y 部分。 + * @param {number} az @en The z component of point a @zh a 点的 z 部分。 + * @param {number} bx @en The x component of point b @zh b 点的 x 部分。 + * @param {number} by @en The y component of point b @zh b 点的 y 部分。 + * @param {number} bz @en The z component of point b @zh b 点的 z 部分。 + * @param {number} cx @en The x component of point c @zh c 点的 x 部分。 + * @param {number} cy @en The y component of point c @zh c 点的 y 部分。 + * @param {number} cz @en The z component of point c @zh c 点的 z 部分。 + * @returns {Triangle} @en The created Triangle instance. @zh 创建出的三角形实例。 */ public static create (ax = 1, ay = 0, az = 0, bx = 0, by = 0, bz = 0, @@ -58,11 +57,11 @@ export class Triangle { /** * @en - * clone a new triangle + * Clones a triangle instance. * @zh - * 克隆一个新的 triangle。 - * @param {Triangle} @en Triangle object to be cloned from. @zh t 克隆的目标。 - * @return {Triangle} @en A new cloned Triangle object. @zh 克隆出的新对象。 + * 克隆一个新的三角形。 + * @param t @en The Triangle object to be cloned from. @zh 克隆的目标。 + * @returns @en The cloned triangle instance. @zh 克隆出的新对象。 */ public static clone (t: Triangle): Triangle { return new Triangle( @@ -74,12 +73,12 @@ export class Triangle { /** * @en - * copy the values from one triangle to another + * Copies the values from one triangle to another. * @zh - * 将一个 triangle 的值复制到另一个 triangle。 - * @param {Triangle} out @en Target Triangle object to be copied to. @zh 接受操作的 triangle。 - * @param {Triangle} t @en A Triangle object to be copied from. @zh 被复制的 triangle。 - * @return {Triangle} @en The same as out. @zh out 接受操作的 triangle。 + * 复制一个三角形的值到另一个三角形中。 + * @param out @en The target Triangle object to be copied to. @zh 接受操作的三角形。 + * @param t @en A Triangle object to be copied from. @zh 被复制的三角形。 + * @returns @en The target Triangle object to be copied to, same as the `out` parameter. @zh 接受操作的三角形,与 `out` 参数相同。 */ public static copy (out: Triangle, t: Triangle): Triangle { Vec3.copy(out.a, t.a); @@ -91,14 +90,14 @@ export class Triangle { /** * @en - * Create a triangle from three points + * Creates a triangle instance from three points. * @zh - * 用三个点创建一个 triangle。 - * @param {Triangle} out @en The Triangle object to be modified. @zh 接受操作的 triangle。 - * @param {Vec3} a @en The point value to set out.a. @zh a 点。 - * @param {Vec3} b @en The point value to set out.b. @zh b 点。 - * @param {Vec3} c @en The point value to set out.c. @zh c 点。 - * @return {Triangle} @en The same as out. @zh 接受操作的 triangle。 + * 用三个点创建一个三角形。 + * @param out @en The Triangle object to be modified. @zh 接受操作的三角形。 + * @param a @en The point value to set out.a. @zh a 点。 + * @param b @en The point value to set out.b. @zh b 点。 + * @param c @en The point value to set out.c. @zh c 点。 + * @returns @en The Triangle object to be modified, same as the `out` parameter. @zh 接受操作的三角形,与 `out` 参数相同。 */ public static fromPoints (out: Triangle, a: Vec3, b: Vec3, c: Vec3): Triangle { Vec3.copy(out.a, a); @@ -109,21 +108,20 @@ export class Triangle { /** * @en - * Set the components of a triangle to the given values + * Sets the components of a triangle to the given values. * @zh * 将给定三角形的属性设置为给定值。 - * @param {Triangle} out @en The Triangle object to be set. @zh 被修改的三角形。 - * @param {number} ax @en The value to set out.a.x. @zh a 点的 x 部分。 - * @param {number} ay @en The value to set out.a.y. @zh a 点的 y 部分。 - * @param {number} az @en The value to set out.a.z. @zh a 点的 z 部分。 - * @param {number} bx @en The value to set out.b.x. @zh b 点的 x 部分。 - * @param {number} by @en The value to set out.b.y. @zh b 点的 y 部分。 - * @param {number} bz @en The value to set out.b.z. @zh b 点的 z 部分。 - * @param {number} cx @en The value to set out.c.x. @zh c 点的 x 部分。 - * @param {number} cy @en The value to set out.c.y. @zh c 点的 y 部分。 - * @param {number} cz @en The value to set out.c.z. @zh c 点的 z 部分。 - * @return {Triangle} @en The same as out. @zh 传入的 out 对象。 - * @function + * @param out @en The Triangle object to be set. @zh 接受操作的三角形。 + * @param ax @en The value to set out.a.x. @zh a 点的 x 部分。 + * @param ay @en The value to set out.a.y. @zh a 点的 y 部分。 + * @param az @en The value to set out.a.z. @zh a 点的 z 部分。 + * @param bx @en The value to set out.b.x. @zh b 点的 x 部分。 + * @param by @en The value to set out.b.y. @zh b 点的 y 部分。 + * @param bz @en The value to set out.b.z. @zh b 点的 z 部分。 + * @param cx @en The value to set out.c.x. @zh c 点的 x 部分。 + * @param cy @en The value to set out.c.y. @zh c 点的 y 部分。 + * @param cz @en The value to set out.c.z. @zh c 点的 z 部分。 + * @returns @en The Triangle object to be set, same as the `out` parameter. @zh 接受操作的三角形,与 `out` 参数相同。 */ public static set (out: Triangle, ax: number, ay: number, az: number, @@ -170,9 +168,9 @@ export class Triangle { /** * @en - * Gets the type of the shape. + * Gets the type of the triangle, always returns `enums.SHAPE_TRIANGLE`. * @zh - * 获取形状的类型。 + * 获取此三角形的类型,固定返回 `enums.SHAPE_TRIANGLE`。 */ get type () { return this._type; @@ -182,7 +180,7 @@ export class Triangle { /** * @en - * Construct a triangle. + * Constructs a triangle. * @zh * 构造一个三角形。 * @param {number} ax @en x component of point a. @zh a 点的 x 部分。 diff --git a/cocos/core/global-exports.ts b/cocos/core/global-exports.ts index 752121a0b3b..a3a371dffdd 100644 --- a/cocos/core/global-exports.ts +++ b/cocos/core/global-exports.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { DEV } from 'internal:constants'; +import { DEV, EDITOR } from 'internal:constants'; const _global = typeof window === 'undefined' ? global : window; /** * @en - * The main namespace of Cocos2d-JS, all engine core classes, functions, properties and constants are defined in this namespace. + * The main namespace of Cocos engine, all engine core classes, functions, properties and constants are defined in this namespace. * @zh - * Cocos 引擎的主要命名空间,引擎代码中所有的类,函数,属性和常量都在这个命名空间中定义。 + * Cocos引擎的主要命名空间,引擎代码中所有的类,函数,属性和常量都在这个命名空间中定义。 * @deprecated */ export const legacyCC: Record & { @@ -47,15 +46,37 @@ if (DEV) { legacyCC._Test = {}; } -const engineVersion = '3.6.2'; +const engineVersion = '3.8.0'; /** - * The current version of Cocos2d being used.
- * Please DO NOT remove this String, it is an important flag for bug tracking.
+ * @en + * The current version of Cocos engine. + * Please DO NOT remove this String, it is an important flag for bug tracking. * If you post a bug to forum, please attach this flag. + * @zh + * 当前使用的 Cocos 引擎版本。 + * 请不要删除此字符串,它是错误跟踪的重要标志。 + * 如果您将错误发布到论坛,请附上此标志。 */ _global.CocosEngine = legacyCC.ENGINE_VERSION = engineVersion; _global.cc = legacyCC; export { engineVersion as VERSION }; + +if (EDITOR && legacyCC.GAME_VIEW === undefined) { + // Used to indicate whether it is currently in preview mode. + // 'isPreviewProcess' is defined only in the editor's process. + legacyCC.GAME_VIEW = typeof globalThis.isPreviewProcess !== 'undefined' ? globalThis.isPreviewProcess : false; +} + +const ccwindow: typeof window = typeof globalThis.jsb !== 'undefined' ? (typeof jsb.window !== 'undefined' ? jsb.window : globalThis) : globalThis; +_global.ccwindow = ccwindow; + +/** + * @en + * It is jsb.window in native mode, otherwise it is the window object in the web context. + * @zh + * 原生环境下为 jsb.window, 引擎为模拟部分 web 环境所提供. Web 环境这个变量是 window 对象。 + */ +export { ccwindow }; diff --git a/cocos/core/index.ts b/cocos/core/index.ts index 34c58f3c553..941056a4839 100644 --- a/cocos/core/index.ts +++ b/cocos/core/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,15 +24,14 @@ */ import { legacyCC, VERSION } from './global-exports'; -import * as easing from './algorithm/easing'; import * as geometry from './geometry'; import * as math from './math'; import * as memop from './memop'; import './deprecated'; +import './deprecated-3.7.0'; legacyCC.math = math; legacyCC.geometry = geometry; -legacyCC.easing = easing; export { math, memop, geometry, VERSION }; @@ -45,10 +43,12 @@ export * from './data'; export * from './event'; export * from './platform'; export * from './scheduler'; -export * from './algorithm/murmurhash2_gc'; export * from './curves'; export * from './settings'; -export { default as System } from './system'; - +export * from './system'; +export * from './algorithm'; +export { legacyCC as cclegacy } from './global-exports'; export * from './curves/bezier'; -export { easing }; + +// TODO: should not include engine internal exports when module mechanism is implemented. +export * from './internal-index'; diff --git a/cocos/core/internal-index.ts b/cocos/core/internal-index.ts new file mode 100644 index 00000000000..48ab60cf195 --- /dev/null +++ b/cocos/core/internal-index.ts @@ -0,0 +1,57 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +// This file only exports functions/classes that are only visible to engine internal. + +import * as jsbUtils from './utils/jsb-utils'; + +export { editable, tooltip, visible, displayName, displayOrder, range, rangeStep, slide, disallowAnimation } from './data/decorators/editable'; +export { override } from './data/decorators/override'; +export { formerlySerializedAs, serializable } from './data/decorators/serializable'; + +export * from './algorithm/binary-search'; +export { shift } from './algorithm/move'; + +export { garbageCollectionManager } from './data/garbage-collection'; +export { GCObject } from './data/gc-object'; + +export type { DeserializationContext } from './data/custom-serializable'; + +export * from './data/utils/asserts'; +export * from './data/utils/compiler'; + +export { ENUM_TAG, BITMASK_TAG } from './data/class'; +export { isCCObject, isValid } from './data/object'; + +export { EasingMethod } from './curves/easing-method'; + +export { CallbacksInvoker } from './event/callbacks-invoker'; +export { applyMixins } from './event/event-target-factory'; + +export { _resetDebugSetting } from './platform/debug'; + +/** + * @engineInternal + */ +export { jsbUtils }; diff --git a/cocos/core/legacy.ts b/cocos/core/legacy.ts index 756b1aab930..107482b4824 100644 --- a/cocos/core/legacy.ts +++ b/cocos/core/legacy.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import * as debug from './platform/debug'; import { _normalize, basename, changeBasename, changeExtname, dirname, extname, getSeperator, join, mainFileName, stripSep } from './utils/path'; diff --git a/cocos/core/math/affine-transform.ts b/cocos/core/math/affine-transform.ts index e810dc1cc0f..e190046271e 100644 --- a/cocos/core/math/affine-transform.ts +++ b/cocos/core/math/affine-transform.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -33,7 +33,7 @@ import { legacyCC } from '../global-exports'; /** * @en `AffineTransform` class represent an affine transform matrix. It's composed basically by translation, rotation, scale transformations. - * @zh 二维仿射变换矩阵,描述了平移、缩放和缩放。 + * @zh 二维仿射变换矩阵,描述了平移、旋转和缩放。 */ export class AffineTransform { /** @@ -59,7 +59,8 @@ export class AffineTransform { /** * @en Concatenate a transform matrix to another. The results are reflected in the out `AffineTransform`. - * @zh 将两个矩阵相乘的结果赋值给出口矩阵。 + * First apply t1, then t2: out * v = t2 * (t1 * v). + * @zh 将两个矩阵相乘的结果赋值给输出矩阵,先应用t1再应用t2: out * v = t2 * (t1 * v)。 * @param out Out object to store the concat result * @param t1 The first transform object. * @param t2 The transform object to concatenate. @@ -81,7 +82,7 @@ export class AffineTransform { /** * @en Get the invert transform of an `AffineTransform` object. - * @zh 将矩阵求逆的结果赋值给出口矩阵。 + * @zh 将矩阵求逆的结果赋值给输出矩阵。 * @param out Out object to store the invert result * @param t the input `AffineTransform` object */ @@ -97,7 +98,7 @@ export class AffineTransform { /** * @en Get an `AffineTransform` object from a given matrix 4x4. - * @zh 将四维矩阵转换为二维仿射变换矩阵并赋值给出口矩阵。 + * @zh 将四维矩阵转换为二维仿射变换矩阵并赋值给输出矩阵。 * @param out The output matrix to store the result * @param mat transform matrix. */ @@ -112,7 +113,7 @@ export class AffineTransform { /** * @en Apply the `AffineTransform` on a 2D vector. - * @zh 应用二维仿射变换矩阵到二维向量上,并将结果赋值给出口向量。 + * @zh 应用二维仿射变换矩阵到二维向量上,并将结果赋值给输出向量。 * @param out The output vector to store the result * @param point Vector to apply transform. * @param t transform matrix. @@ -121,7 +122,7 @@ export class AffineTransform { /** * @en Apply the `AffineTransform` on a 2D vector. - * @zh 应用二维仿射变换矩阵到二维向量上,并将结果赋值给出口向量。 + * @zh 应用二维仿射变换矩阵到二维向量上,并将结果赋值给输出向量。 * @param out The output vector to store the result * @param x x to apply transform. * @param y y to apply transform. @@ -146,7 +147,7 @@ export class AffineTransform { /** * @en Apply the `AffineTransform` on a size. - * @zh 应用二维仿射变换矩阵到二维尺寸上,并将结果赋值给出口尺寸。 + * @zh 应用二维仿射变换矩阵到二维尺寸上,并将结果赋值给输出尺寸。 * @param out The output size to store the result * @param size The size to apply transform. * @param t transform matrix. @@ -158,7 +159,7 @@ export class AffineTransform { /** * @en Apply the `AffineTransform` on a rect. - * @zh 应用二维仿射变换矩阵到矩形上,并将结果赋值给出口矩形。 + * @zh 应用二维仿射变换矩阵到矩形上,并将结果赋值给输出矩形。 * @param out The output rect object to store the result * @param rect The rect object to apply transform. * @param t transform matrix. @@ -198,7 +199,8 @@ export class AffineTransform { * @param rect The rect object to apply transform. * @param anAffineTransform transform matrix. */ - public static transformObb (out_bl: Vec2, out_tl: Vec2, out_tr: Vec2, out_br: Vec2, rect: Rect, anAffineTransform: AffineTransform) { + public static transformObb (out_bl: Vec2, out_tl: Vec2, out_tr: Vec2, out_br: Vec2, rect: Rect, + anAffineTransform: AffineTransform, flipY = true) { const tx = anAffineTransform.a * rect.x + anAffineTransform.c * rect.y + anAffineTransform.tx; const ty = anAffineTransform.b * rect.x + anAffineTransform.d * rect.y + anAffineTransform.ty; const xa = anAffineTransform.a * rect.width; @@ -206,16 +208,33 @@ export class AffineTransform { const yc = anAffineTransform.c * rect.height; const yd = anAffineTransform.d * rect.height; - out_tl.x = tx; - out_tl.y = ty; - out_tr.x = xa + tx; - out_tr.y = xb + ty; - out_bl.x = yc + tx; - out_bl.y = yd + ty; - out_br.x = xa + yc + tx; - out_br.y = xb + yd + ty; + if (flipY) { + out_tl.x = tx; + out_tl.y = ty; + out_tr.x = xa + tx; + out_tr.y = xb + ty; + out_bl.x = yc + tx; + out_bl.y = yd + ty; + out_br.x = xa + yc + tx; + out_br.y = xb + yd + ty; + } else { + out_bl.x = tx; + out_bl.y = ty; + out_br.x = xa + tx; + out_br.y = xb + ty; + out_tl.x = yc + tx; + out_tl.y = yd + ty; + out_tr.x = xa + yc + tx; + out_tr.y = xb + yd + ty; + } } + /** + * matrix layout + * |a c tx| + * |b d ty| + * |0 0 1 | + */ public declare a: number; public declare b: number; public declare c: number; diff --git a/cocos/core/math/bits.ts b/cocos/core/math/bits.ts index 4ab94bba59b..ecdc24c3f6b 100644 --- a/cocos/core/math/bits.ts +++ b/cocos/core/math/bits.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * Bit twiddling hacks for JavaScript. diff --git a/cocos/core/math/color.ts b/cocos/core/math/color.ts index 81324a4f0ef..4cb5ad99a90 100644 --- a/cocos/core/math/color.ts +++ b/cocos/core/math/color.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -31,6 +30,7 @@ import { clamp, EPSILON } from './utils'; import { legacyCC } from '../global-exports'; import { assertIsTrue } from '../data/utils/asserts'; import { Vec4 } from './vec4'; +import { Vec3 } from './vec3'; const toFloat = 1 / 255; @@ -752,3 +752,49 @@ export function linearToSrgb8Bit (x: number): number { // use table for more consistent conversion between uint8 and float, offline processes only. let SRGB_8BIT_TO_LINEAR: Array = []; for (let i = 0; i < 256; i++) { SRGB_8BIT_TO_LINEAR.push(srgbToLinear(i / 255.0)); } + +export function clampVec3 (val: Vec3, min: Vec3, max: Vec3) { + if (min > max) { + const temp = min; + min = max; + max = temp; + } + return val < min ? min : val > max ? max : val; +} + +export function floorVec3 (val: Vec3) { + const temp = val.clone(); + temp.x = Math.floor(val.x); + temp.y = Math.floor(val.y); + temp.z = Math.floor(val.z); + return temp; +} + +export function stepVec3 (a: Vec3, b: Vec3) { + if (a < b) { + return b; + } else { + return a; + } +} + +/** + * @en Three channel rgb color pack into four channel rbge format. + * @zh 三通道rgb颜色pack成四通道rbge格式 + * @param rgb Vec3 + */ +export function packRGBE (rgb: Vec3) { + const maxComp = Math.max(Math.max(rgb.x, rgb.y), rgb.z); + let e = 128.0; + if (maxComp > 0.0001) { + e = Math.log(maxComp) / Math.log(1.1); + e = Math.ceil(e); + e = clamp(e + 128.0, 0.0, 255.0); + } + // eslint-disable-next-line no-restricted-properties + const sc = 1.0 / Math.pow(1.1, e - 128.0); + const encode = clampVec3(rgb.multiplyScalar(sc), new Vec3(0.0, 0.0, 0.0), new Vec3(1.0, 1.0, 1.0)); + encode.multiplyScalar(255.0); + const encode_rounded = floorVec3(encode).add(stepVec3(encode.subtract(floorVec3(encode)), new Vec3(0.5, 0.5, 0.5))); + return new Vec4(encode_rounded.x / 255.0, encode_rounded.y / 255.0, encode_rounded.z / 255.0, e / 255.0); +} diff --git a/cocos/core/math/deprecated.ts b/cocos/core/math/deprecated.ts index 55b3bf8a4e9..e0a52482f09 100644 --- a/cocos/core/math/deprecated.ts +++ b/cocos/core/math/deprecated.ts @@ -1,27 +1,26 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { removeProperty, replaceProperty } from '../utils/x-deprecated'; import { Color } from './color'; diff --git a/cocos/core/math/index.ts b/cocos/core/math/index.ts index 0568754fcda..8b09ae2438a 100644 --- a/cocos/core/math/index.ts +++ b/cocos/core/math/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,6 +26,7 @@ import * as bits from './bits'; import './deprecated'; +import './math-native-ext'; /** * Export module bits. */ @@ -45,3 +45,6 @@ export { Color, color } from './color'; export * from './utils'; export * from './type-define'; export * from './math-base'; + +// engine internal exports +export { preTransforms } from './mat4'; diff --git a/cocos/core/math/mat3.ts b/cocos/core/math/mat3.ts index 4120097593b..793ec38d974 100644 --- a/cocos/core/math/mat3.ts +++ b/cocos/core/math/mat3.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,7 +26,7 @@ import { CCClass } from '../data/class'; import { ValueType } from '../value-types/value-type'; import { Quat } from './quat'; import { IMat3Like, IMat4Like, IQuatLike, IVec2Like, IVec3Like } from './type-define'; -import { EPSILON } from './utils'; +import { EPSILON, HALF_PI } from './utils'; import { Vec3 } from './vec3'; import { legacyCC } from '../global-exports'; @@ -75,12 +74,12 @@ export class Mat3 extends ValueType { public static set ( out: Out, m00: number, m01: number, m02: number, - m10: number, m11: number, m12: number, - m20: number, m21: number, m22: number, + m03: number, m04: number, m05: number, + m06: number, m07: number, m08: number, ) { out.m00 = m00; out.m01 = m01; out.m02 = m02; - out.m03 = m10; out.m04 = m11; out.m05 = m12; - out.m06 = m20; out.m07 = m21; out.m08 = m22; + out.m03 = m03; out.m04 = m04; out.m05 = m05; + out.m06 = m06; out.m07 = m07; out.m08 = m08; return out; } @@ -181,8 +180,8 @@ export class Mat3 extends ValueType { } /** - * @en Multiply two matrices explicitly and save the results to out matrix - * @zh 矩阵乘法 + * @en Multiply two matrices explicitly and save the results to out matrix: a * b + * @zh 矩阵乘法:a * b */ public static multiply (out: Out, a: Out, b: Out) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; @@ -208,8 +207,8 @@ export class Mat3 extends ValueType { } /** - * @en Take the first third order of the fourth order matrix and multiply by the third order matrix - * @zh 取四阶矩阵的前三阶,与三阶矩阵相乘 + * @en Take the first third order of the fourth order matrix and multiply by the third order matrix: a * b + * @zh 取四阶矩阵的前三阶,与三阶矩阵相乘:a * b */ public static multiplyMat4 (out: Out, a: Out, b: IMat4Like) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; @@ -235,10 +234,21 @@ export class Mat3 extends ValueType { } /** - * @en Multiply a matrix with a translation vector given by a translation offset. - * @zh 在给定矩阵变换基础上加入变换 + * @en Multiply a matrix with a translation vector given by a translation offset, first translate, then transform:a * T(v). + * @zh 在给定矩阵变换基础上加入位移变换,先位移,再变换,即a * T(v)。 + */ + /** + * @deprecated since v3.8.0, the function name is misleading, please use translate instead. */ public static transform (out: Out, a: Out, v: VecLike) { + this.translate(out, a, v); + } + + /** + * @en Multiply a matrix with a translation vector given by a translation offset, first translate, then transform:a * T(v). + * @zh 在给定矩阵变换基础上加入位移变换,先位移,再变换,即a * T(v)。 + */ + public static translate (out: Out, a: Out, v: VecLike) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; const a10 = a.m03; const a11 = a.m04; const a12 = a.m05; const a20 = a.m06; const a21 = a.m07; const a22 = a.m08; @@ -259,8 +269,8 @@ export class Mat3 extends ValueType { } /** - * @en Multiply a matrix with a scale matrix given by a scale vector and save the results to out matrix - * @zh 在给定矩阵变换基础上加入新缩放变换 + * @en Multiply a matrix with a scale matrix given by a scale vector and save the results to out matrix, first scale, then transform:a * S(v). + * @zh 在给定矩阵变换基础上加入新缩放变换,先缩放,再变换,即a * S(v)。 */ public static scale (out: Out, a: Out, v: VecLike) { const x = v.x; const y = v.y; @@ -280,9 +290,9 @@ export class Mat3 extends ValueType { } /** - * @en Rotates the transform by the given angle and save the results into the out matrix - * @zh 在给定矩阵变换基础上加入新旋转变换 - * @param rad radius of rotation + * @en Rotates the transform by the given angle and save the results into the out matrix, first rotate, then transform:a * R(rad). + * @zh 在给定矩阵变换基础上加入新旋转变换,先旋转,再变换,即a * R(rad)。 + * @param rad radian of rotation */ public static rotate (out: Out, a: Out, rad: number) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; @@ -446,6 +456,9 @@ export class Mat3 extends ValueType { return out; } + /** + * @deprecated since v3.8.0, this function is too complicated, and should be split into several functions. + */ /** * @en Calculates the upper-left 3x3 matrix of a 4x4 matrix's inverse transpose * @zh 计算指定四维矩阵的逆转置三维矩阵 @@ -624,6 +637,41 @@ export class Mat3 extends ValueType { ); } + /** + * @en Convert Matrix to euler angle, resulting angle y, z in the range of [-PI, PI], + * x in the range of [-PI/2, PI/2], the rotation order is YXZ, first rotate around Y, then around X, and finally around Z. + * @zh 将矩阵转换成欧拉角, 返回角度 y,z 在 [-PI, PI] 区间内, x 在 [-PI/2, PI/2] 区间内,旋转顺序为 YXZ,即先绕Y旋转,再绕X,最后绕Z旋转。 + */ + public static toEuler (matrix: Mat3, v: Vec3): boolean { + //a[col][row] + const a00 = matrix.m00; const a01 = matrix.m01; const a02 = matrix.m02; + const a10 = matrix.m03; const a11 = matrix.m04; const a12 = matrix.m05; + const a20 = matrix.m06; const a21 = matrix.m07; const a22 = matrix.m08; + + // from http://www.geometrictools.com/Documentation/EulerAngles.pdf + // YXZ order + if (a21 < 0.999) { + if (a21 > -0.999) { + v.x = Math.asin(-a21); + v.y = Math.atan2(a20, a22); + v.z = Math.atan2(a01, a11); + return true; + } else { + // Not unique. YA - ZA = atan2(r01,r00) + v.x = HALF_PI; + v.y = Math.atan2(a10, a00); + v.z = 0.0; + return false; + } + } else { + // Not unique. YA + ZA = atan2(-r01,r00) + v.x = -HALF_PI; + v.y = Math.atan2(-a10, a00); + v.z = 0.0; + return false; + } + } + /** * @en Value at column 0 row 0 of the matrix. * @zh 矩阵第 0 列第 0 行的元素。 @@ -957,8 +1005,8 @@ export class Mat3 extends ValueType { } /** - * @en Multiply the current matrix with a scale matrix given by a scale vector. - * @zh 将当前矩阵左乘缩放矩阵的结果赋值给当前矩阵,缩放矩阵由各个轴的缩放给出。 + * @en Multiply the current matrix with a scale matrix given by a scale vector, that is M * S(vec). + * @zh 将当前矩阵左乘缩放矩阵的结果赋值给当前矩阵,缩放矩阵由各个轴的缩放给出,即M * S(vec)。 * @param vec vector to scale by */ public scale (vec: Vec3) { @@ -979,9 +1027,9 @@ export class Mat3 extends ValueType { } /** - * @en Rotates the current matrix by the given angle. - * @zh 将当前矩阵左乘旋转矩阵的结果赋值给当前矩阵,旋转矩阵由旋转轴和旋转角度给出。 - * @param rad radius of rotation + * @en Rotates the current matrix by the given angle, that is M * R(rad). + * @zh 将当前矩阵左乘旋转矩阵的结果赋值给当前矩阵,旋转矩阵由旋转轴和旋转角度给出,即M * R(rad)。 + * @param rad radian of rotation */ public rotate (rad: number) { const a00 = this.m00; const a01 = this.m01; const a02 = this.m02; diff --git a/cocos/core/math/mat4.ts b/cocos/core/math/mat4.ts index 64c32e5f9bb..cc1d6cc4559 100644 --- a/cocos/core/math/mat4.ts +++ b/cocos/core/math/mat4.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,11 +31,14 @@ import { EPSILON } from './utils'; import { Vec3 } from './vec3'; import { legacyCC } from '../global-exports'; +/** + * @engineInternal + */ export const preTransforms = Object.freeze([ - Object.freeze([1, 0, 0, 1]), // SurfaceTransform.IDENTITY - Object.freeze([0, 1, -1, 0]), // SurfaceTransform.ROTATE_90 - Object.freeze([-1, 0, 0, -1]), // SurfaceTransform.ROTATE_180 - Object.freeze([0, -1, 1, 0]), // SurfaceTransform.ROTATE_270 + Object.freeze([1, 0, 0, 1]), // SurfaceTransform.IDENTITY + Object.freeze([0, 1, -1, 0]), // SurfaceTransform.ROTATE_90 + Object.freeze([-1, 0, 0, -1]), // SurfaceTransform.ROTATE_180 + Object.freeze([0, -1, 1, 0]), // SurfaceTransform.ROTATE_270 ]); /** @@ -64,7 +66,7 @@ export class Mat4 extends ValueType { * @en Copy a matrix into the out matrix * @zh 复制目标矩阵 */ - public static copy (out: Out, a: Out) { + public static copy (out: Out, a: Out) { out.m00 = a.m00; out.m01 = a.m01; out.m02 = a.m02; @@ -88,7 +90,7 @@ export class Mat4 extends ValueType { * @en Sets a matrix with the given values and save the results to out matrix * @zh 设置矩阵值 */ - public static set ( + public static set ( out: Out, m00: number, m01: number, m02: number, m03: number, m10: number, m11: number, m12: number, m13: number, @@ -106,7 +108,7 @@ export class Mat4 extends ValueType { * @en return an identity matrix. * @zh 将目标赋值为单位矩阵 */ - public static identity (out: Out) { + public static identity (out: Out) { out.m00 = 1; out.m01 = 0; out.m02 = 0; @@ -130,7 +132,7 @@ export class Mat4 extends ValueType { * @en Transposes a matrix and save the results to out matrix * @zh 转置矩阵 */ - public static transpose (out: Out, a: Out) { + public static transpose (out: Out, a: Out) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { const a01 = a.m01; const a02 = a.m02; const a03 = a.m03; const a12 = a.m06; const a13 = a.m07; const a23 = a.m11; @@ -171,7 +173,7 @@ export class Mat4 extends ValueType { * @en Inverts a matrix. When matrix is not invertible the matrix will be set to zeros. * @zh 矩阵求逆,注意,在矩阵不可逆时,会返回一个全为 0 的矩阵。 */ - public static invert (out: Out, a: Out) { + public static invert (out: Out, a: Out) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; const a03 = a.m03; const a10 = a.m04; const a11 = a.m05; const a12 = a.m06; const a13 = a.m07; const a20 = a.m08; const a21 = a.m09; const a22 = a.m10; const a23 = a.m11; @@ -226,7 +228,7 @@ export class Mat4 extends ValueType { * @en Calculates the determinant of a matrix * @zh 矩阵行列式 */ - public static determinant (a: InType): number { + public static determinant (a: InType): number { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; const a03 = a.m03; const a10 = a.m04; const a11 = a.m05; const a12 = a.m06; const a13 = a.m07; const a20 = a.m08; const a21 = a.m09; const a22 = a.m10; const a23 = a.m11; @@ -253,7 +255,7 @@ export class Mat4 extends ValueType { * @en Multiply two matrices and save the results to out matrix * @zh 矩阵乘法 */ - public static multiply (out: Out, a: Out, b: Out) { + public static multiply (out: Out, a: Out, b: Out) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; const a03 = a.m03; const a10 = a.m04; const a11 = a.m05; const a12 = a.m06; const a13 = a.m07; const a20 = a.m08; const a21 = a.m09; const a22 = a.m10; const a23 = a.m11; @@ -290,7 +292,7 @@ export class Mat4 extends ValueType { * @en Transform a matrix with the given vector and save results to the out matrix * @zh 在给定矩阵变换基础上加入变换 */ - public static transform (out: Out, a: Out, v: VecLike) { + public static transform (out: Out, a: Out, v: VecLike) { const x = v.x; const y = v.y; const z = v.z; if (a === out) { out.m12 = a.m00 * x + a.m04 * y + a.m08 * z + a.m12; @@ -319,7 +321,7 @@ export class Mat4 extends ValueType { * @en Transform a matrix with the given translation vector and save results to the out matrix * @zh 在给定矩阵变换基础上加入新位移变换 */ - public static translate (out: Out, a: Out, v: VecLike) { + public static translate (out: Out, a: Out, v: VecLike) { if (a === out) { out.m12 += v.x; out.m13 += v.y; @@ -340,7 +342,7 @@ export class Mat4 extends ValueType { * @en Multiply a matrix with a scale matrix given by a scale vector and save the results into the out matrix * @zh 在给定矩阵变换基础上加入新缩放变换 */ - public static scale (out: Out, a: Out, v: VecLike) { + public static scale (out: Out, a: Out, v: VecLike) { const x = v.x; const y = v.y; const z = v.z; out.m00 = a.m00 * x; out.m01 = a.m01 * x; @@ -367,7 +369,7 @@ export class Mat4 extends ValueType { * @param rad Angle of rotation (in radians) * @param axis axis of rotation */ - public static rotate (out: Out, a: Out, rad: number, axis: VecLike) { + public static rotate (out: Out, a: Out, rad: number, axis: VecLike) { let x = axis.x; let y = axis.y; let z = axis.z; let len = Math.sqrt(x * x + y * y + z * z); @@ -424,7 +426,7 @@ export class Mat4 extends ValueType { * @zh 在给定矩阵变换基础上加入绕 X 轴的旋转变换 * @param rad Angle of rotation (in radians) */ - public static rotateX (out: Out, a: Out, rad: number) { + public static rotateX (out: Out, a: Out, rad: number) { const s = Math.sin(rad); const c = Math.cos(rad); const a10 = a.m04; @@ -465,7 +467,7 @@ export class Mat4 extends ValueType { * @zh 在给定矩阵变换基础上加入绕 Y 轴的旋转变换 * @param rad Angle of rotation (in radians) */ - public static rotateY (out: Out, a: Out, rad: number) { + public static rotateY (out: Out, a: Out, rad: number) { const s = Math.sin(rad); const c = Math.cos(rad); const a00 = a.m00; @@ -506,7 +508,7 @@ export class Mat4 extends ValueType { * @zh 在给定矩阵变换基础上加入绕 Z 轴的旋转变换 * @param rad Angle of rotation (in radians) */ - public static rotateZ (out: Out, a: Out, rad: number) { + public static rotateZ (out: Out, a: Out, rad: number) { const s = Math.sin(rad); const c = Math.cos(rad); const a00 = a.m00; @@ -547,7 +549,7 @@ export class Mat4 extends ValueType { * @en Sets the out matrix with a translation vector * @zh 计算位移矩阵 */ - public static fromTranslation (out: Out, v: VecLike) { + public static fromTranslation (out: Out, v: VecLike) { out.m00 = 1; out.m01 = 0; out.m02 = 0; @@ -571,7 +573,7 @@ export class Mat4 extends ValueType { * @en Sets the out matrix with a scale vector * @zh 计算缩放矩阵 */ - public static fromScaling (out: Out, v: VecLike) { + public static fromScaling (out: Out, v: VecLike) { out.m00 = v.x; out.m01 = 0; out.m02 = 0; @@ -595,7 +597,7 @@ export class Mat4 extends ValueType { * @en Sets the out matrix with rotation angle * @zh 计算旋转矩阵 */ - public static fromRotation (out: Out, rad: number, axis: VecLike) { + public static fromRotation (out: Out, rad: number, axis: VecLike) { let x = axis.x; let y = axis.y; let z = axis.z; let len = Math.sqrt(x * x + y * y + z * z); @@ -636,7 +638,7 @@ export class Mat4 extends ValueType { * @en Calculates the matrix representing a rotation around the X axis * @zh 计算绕 X 轴的旋转矩阵 */ - public static fromXRotation (out: Out, rad: number) { + public static fromXRotation (out: Out, rad: number) { const s = Math.sin(rad); const c = Math.cos(rad); // Perform axis-specific matrix multiplication @@ -663,7 +665,7 @@ export class Mat4 extends ValueType { * @en Calculates the matrix representing a rotation around the Y axis * @zh 计算绕 Y 轴的旋转矩阵 */ - public static fromYRotation (out: Out, rad: number) { + public static fromYRotation (out: Out, rad: number) { const s = Math.sin(rad); const c = Math.cos(rad); // Perform axis-specific matrix multiplication @@ -690,7 +692,7 @@ export class Mat4 extends ValueType { * @en Calculates the matrix representing a rotation around the Z axis * @zh 计算绕 Z 轴的旋转矩阵 */ - public static fromZRotation (out: Out, rad: number) { + public static fromZRotation (out: Out, rad: number) { const s = Math.sin(rad); const c = Math.cos(rad); // Perform axis-specific matrix multiplication @@ -717,7 +719,7 @@ export class Mat4 extends ValueType { * @en Calculates the transform representing the combination of a rotation and a translation * @zh 根据旋转和位移信息计算矩阵 */ - public static fromRT (out: Out, q: Quat, v: VecLike) { + public static fromRT (out: Out, q: Quat, v: VecLike) { const x = q.x; const y = q.y; const z = q.z; const w = q.w; const x2 = x + x; const y2 = y + y; @@ -757,7 +759,7 @@ export class Mat4 extends ValueType { * @en Extracts the translation from the matrix, assuming it's composed in order of scale, rotation, translation * @zh 提取矩阵的位移信息, 默认矩阵中的变换以 S->R->T 的顺序应用 */ - public static getTranslation (out: VecLike, mat: InType) { + public static getTranslation (out: VecLike, mat: InType) { out.x = mat.m12; out.y = mat.m13; out.z = mat.m14; @@ -769,7 +771,7 @@ export class Mat4 extends ValueType { * @en Extracts the scale vector from the matrix, assuming it's composed in order of scale, rotation, translation * @zh 提取矩阵的缩放信息, 默认矩阵中的变换以 S->R->T 的顺序应用 */ - public static getScaling (out: VecLike, mat: InType) { + public static getScaling (out: VecLike, mat: InType) { const m00 = m3_1.m00 = mat.m00; const m01 = m3_1.m01 = mat.m01; const m02 = m3_1.m02 = mat.m02; @@ -791,7 +793,7 @@ export class Mat4 extends ValueType { * @en Extracts the rotation from the matrix, assuming it's composed in order of scale, rotation, translation * @zh 提取矩阵的旋转信息, 默认输入矩阵不含有缩放信息,如考虑缩放应使用 `toRTS` 函数。 */ - public static getRotation (out: Quat, mat: InType) { + public static getRotation (out: Quat, mat: InType) { const trace = mat.m00 + mat.m05 + mat.m10; let S = 0; @@ -828,30 +830,44 @@ export class Mat4 extends ValueType { * @en Extracts the scale, rotation and translation from the matrix, assuming it's composed in order of scale, rotation, translation * @zh 提取旋转、位移、缩放信息, 默认矩阵中的变换以 S->R->T 的顺序应用 */ - public static toRTS (m: InType, q: Quat, v: VecLike, s: VecLike) { - s.x = Vec3.set(v3_1, m.m00, m.m01, m.m02).length(); - m3_1.m00 = m.m00 / s.x; - m3_1.m01 = m.m01 / s.x; - m3_1.m02 = m.m02 / s.x; - s.y = Vec3.set(v3_1, m.m04, m.m05, m.m06).length(); - m3_1.m03 = m.m04 / s.y; - m3_1.m04 = m.m05 / s.y; - m3_1.m05 = m.m06 / s.y; - s.z = Vec3.set(v3_1, m.m08, m.m09, m.m10).length(); - m3_1.m06 = m.m08 / s.z; - m3_1.m07 = m.m09 / s.z; - m3_1.m08 = m.m10 / s.z; - const det = Mat3.determinant(m3_1); - if (det < 0) { s.x *= -1; m3_1.m00 *= -1; m3_1.m01 *= -1; m3_1.m02 *= -1; } - Quat.fromMat3(q, m3_1); // already normalized - Vec3.set(v, m.m12, m.m13, m.m14); + public static toRTS (m: InType, q: Quat | null, v: VecLike | null, s: VecLike | null) { + const sx = Vec3.set(v3_1, m.m00, m.m01, m.m02).length(); + const sy = Vec3.set(v3_1, m.m04, m.m05, m.m06).length(); + const sz = Vec3.set(v3_1, m.m08, m.m09, m.m10).length(); + if (s) { + s.x = sx; + s.y = sy; + s.z = sz; + } + if (v) { + Vec3.set(v, m.m12, m.m13, m.m14); + } + if (q) { + m3_1.m00 = m.m00 / sx; + m3_1.m01 = m.m01 / sx; + m3_1.m02 = m.m02 / sx; + m3_1.m03 = m.m04 / sy; + m3_1.m04 = m.m05 / sy; + m3_1.m05 = m.m06 / sy; + m3_1.m06 = m.m08 / sz; + m3_1.m07 = m.m09 / sz; + m3_1.m08 = m.m10 / sz; + const det = Mat3.determinant(m3_1); + if (det < 0) { + if (s) s.x *= -1; + m3_1.m00 *= -1; + m3_1.m01 *= -1; + m3_1.m02 *= -1; + } + Quat.fromMat3(q, m3_1); // already normalized + } } /** * @en Compose a matrix from scale, rotation and translation, applied in order. * @zh 根据旋转、位移、缩放信息计算矩阵,以 S->R->T 的顺序应用 */ - public static fromRTS (out: Out, q: Quat, v: VecLike, s: VecLike) { + public static fromRTS (out: Out, q: Quat, v: VecLike, s: VecLike) { const x = q.x; const y = q.y; const z = q.z; const w = q.w; const x2 = x + x; const y2 = y + y; @@ -898,7 +914,7 @@ export class Mat4 extends ValueType { * @param s Scaling vector * @param o transformation Center */ - public static fromRTSOrigin (out: Out, q: Quat, v: VecLike, s: VecLike, o: VecLike) { + public static fromRTSOrigin (out: Out, q: Quat, v: VecLike, s: VecLike, o: VecLike) { const x = q.x; const y = q.y; const z = q.z; const w = q.w; const x2 = x + x; const y2 = y + y; @@ -946,7 +962,7 @@ export class Mat4 extends ValueType { * @en Sets the out matrix with the given quaternion * @zh 根据指定的旋转信息计算矩阵 */ - public static fromQuat (out: Out, q: Quat) { + public static fromQuat (out: Out, q: Quat) { const x = q.x; const y = q.y; const z = q.z; const w = q.w; const x2 = x + x; const y2 = y + y; @@ -995,7 +1011,7 @@ export class Mat4 extends ValueType { * @param near Z distance to the near plane from the origin in view space. * @param far Z distance to the far plane from the origin in view space. */ - public static frustum (out: Out, left: number, right: number, bottom: number, top: number, near: number, far: number) { + public static frustum (out: Out, left: number, right: number, bottom: number, top: number, near: number, far: number) { const rl = 1 / (right - left); const tb = 1 / (top - bottom); const nf = 1 / (near - far); @@ -1027,7 +1043,7 @@ export class Mat4 extends ValueType { * @param near Near depth clipping plane value. * @param far Far depth clipping plane value. */ - public static perspective ( + public static perspective ( out: Out, fov: number, aspect: number, near: number, far: number, isFOVY = true, minClipZ = -1, projectionSignY = 1, orientation = 0, ) { @@ -1067,7 +1083,7 @@ export class Mat4 extends ValueType { * @param near Near depth clipping plane value. * @param far Far depth clipping plane value. */ - public static ortho ( + public static ortho ( out: Out, left: number, right: number, bottom: number, top: number, near: number, far: number, minClipZ = -1, projectionSignY = 1, orientation = 0, ) { @@ -1110,7 +1126,7 @@ export class Mat4 extends ValueType { * @param center The target point. * @param up The vector describing the up direction. */ - public static lookAt (out: Out, eye: VecLike, center: VecLike, up: VecLike) { + public static lookAt (out: Out, eye: VecLike, center: VecLike, up: VecLike) { const eyex = eye.x; const eyey = eye.y; const eyez = eye.z; @@ -1166,7 +1182,7 @@ export class Mat4 extends ValueType { * @en Calculates the inverse transpose of a matrix and save the results to out matrix * @zh 计算逆转置矩阵 */ - public static inverseTranspose (out: Out, a: Out) { + public static inverseTranspose (out: Out, a: Out) { const a00 = a.m00; const a01 = a.m01; const a02 = a.m02; const a03 = a.m03; const a10 = a.m04; const a11 = a.m05; const a12 = a.m06; const a13 = a.m07; const a20 = a.m08; const a21 = a.m09; const a22 = a.m10; const a23 = a.m11; @@ -1221,7 +1237,7 @@ export class Mat4 extends ValueType { * @zh 矩阵转数组 * @param ofs Array Start Offset */ - public static toArray > (out: Out, m: IMat4Like, ofs = 0) { + public static toArray> (out: Out, m: IMat4Like, ofs = 0) { out[ofs + 0] = m.m00; out[ofs + 1] = m.m01; out[ofs + 2] = m.m02; @@ -1246,7 +1262,7 @@ export class Mat4 extends ValueType { * @zh 数组转矩阵 * @param ofs Array Start Offset */ - public static fromArray (out: Out, arr: IWritableArrayLike, ofs = 0) { + public static fromArray (out: Out, arr: IWritableArrayLike, ofs = 0) { out.m00 = arr[ofs + 0]; out.m01 = arr[ofs + 1]; out.m02 = arr[ofs + 2]; @@ -1270,7 +1286,7 @@ export class Mat4 extends ValueType { * @en Adds two matrices and save the results to out matrix * @zh 逐元素矩阵加法 */ - public static add (out: Out, a: Out, b: Out) { + public static add (out: Out, a: Out, b: Out) { out.m00 = a.m00 + b.m00; out.m01 = a.m01 + b.m01; out.m02 = a.m02 + b.m02; @@ -1294,7 +1310,7 @@ export class Mat4 extends ValueType { * @en Subtracts matrix b from matrix a and save the results to out matrix * @zh 逐元素矩阵减法 */ - public static subtract (out: Out, a: Out, b: Out) { + public static subtract (out: Out, a: Out, b: Out) { out.m00 = a.m00 - b.m00; out.m01 = a.m01 - b.m01; out.m02 = a.m02 - b.m02; @@ -1318,7 +1334,7 @@ export class Mat4 extends ValueType { * @en Multiply each element of a matrix by a scalar number and save the results to out matrix * @zh 矩阵标量乘法 */ - public static multiplyScalar (out: Out, a: Out, b: number) { + public static multiplyScalar (out: Out, a: Out, b: number) { out.m00 = a.m00 * b; out.m01 = a.m01 * b; out.m02 = a.m02 * b; @@ -1342,7 +1358,7 @@ export class Mat4 extends ValueType { * @en Adds two matrices after multiplying each element of the second operand by a scalar number. And save the results to out matrix. * @zh 逐元素矩阵标量乘加: A + B * scale */ - public static multiplyScalarAndAdd (out: Out, a: Out, b: Out, scale: number) { + public static multiplyScalarAndAdd (out: Out, a: Out, b: Out, scale: number) { out.m00 = a.m00 + (b.m00 * scale); out.m01 = a.m01 + (b.m01 * scale); out.m02 = a.m02 + (b.m02 * scale); @@ -1366,7 +1382,7 @@ export class Mat4 extends ValueType { * @en Returns whether the specified matrices are equal. * @zh 矩阵等价判断 */ - public static strictEquals (a: InType, b: InType) { + public static strictEquals (a: InType, b: InType) { return a.m00 === b.m00 && a.m01 === b.m01 && a.m02 === b.m02 && a.m03 === b.m03 && a.m04 === b.m04 && a.m05 === b.m05 && a.m06 === b.m06 && a.m07 === b.m07 && a.m08 === b.m08 && a.m09 === b.m09 && a.m10 === b.m10 && a.m11 === b.m11 @@ -1377,7 +1393,7 @@ export class Mat4 extends ValueType { * @en Returns whether the specified matrices are approximately equal. * @zh 排除浮点数误差的矩阵近似等价判断 */ - public static equals (a: InType, b: InType, epsilon = EPSILON) { + public static equals (a: InType, b: InType, epsilon = EPSILON) { // TAOCP vol.2, 3rd ed., s.4.2.4, p.213-225 // defines a 'close enough' relationship between u and v that scales for magnitude return ( @@ -1404,101 +1420,101 @@ export class Mat4 extends ValueType { * @en Value at column 0 row 0 of the matrix. * @zh 矩阵第 0 列第 0 行的元素。 */ - public m00: number; + public declare m00: number; /** * @en Value at column 0 row 1 of the matrix. * @zh 矩阵第 0 列第 1 行的元素。 */ - public m01: number; + public declare m01: number; /** * @en Value at column 0 row 2 of the matrix. * @zh 矩阵第 0 列第 2 行的元素。 */ - public m02: number; + public declare m02: number; /** * @en Value at column 0 row 3 of the matrix. * @zh 矩阵第 0 列第 3 行的元素。 */ - public m03: number; + public declare m03: number; /** * @en Value at column 1 row 0 of the matrix. * @zh 矩阵第 1 列第 0 行的元素。 */ - public m04: number; + public declare m04: number; /** * @en Value at column 1 row 1 of the matrix. * @zh 矩阵第 1 列第 1 行的元素。 */ - public m05: number; + public declare m05: number; /** * @en Value at column 1 row 2 of the matrix. * @zh 矩阵第 1 列第 2 行的元素。 */ - public m06: number; + public declare m06: number; /** * @en Value at column 1 row 3 of the matrix. * @zh 矩阵第 1 列第 3 行的元素。 */ - public m07: number; + public declare m07: number; /** * @en Value at column 2 row 0 of the matrix. * @zh 矩阵第 2 列第 0 行的元素。 */ - public m08: number; + public declare m08: number; /** * @en Value at column 2 row 1 of the matrix. * @zh 矩阵第 2 列第 1 行的元素。 */ - public m09: number; + public declare m09: number; /** * @en Value at column 2 row 2 of the matrix. * @zh 矩阵第 2 列第 2 行的元素。 */ - public m10: number; + public declare m10: number; /** * @en Value at column 2 row 3 of the matrix. * @zh 矩阵第 2 列第 3 行的元素。 */ - public m11: number; + public declare m11: number; /** * @en Value at column 3 row 0 of the matrix. * @zh 矩阵第 3 列第 0 行的元素。 */ - public m12: number; + public declare m12: number; /** * @en Value at column 3 row 1 of the matrix. * @zh 矩阵第 3 列第 1 行的元素。 */ - public m13: number; + public declare m13: number; /** * @en Value at column 3 row 2 of the matrix. * @zh 矩阵第 3 列第 2 行的元素。 */ - public m14: number; + public declare m14: number; /** * @en Value at column 3 row 3 of the matrix. * @zh 矩阵第 3 列第 3 行的元素。 */ - public m15: number; + public declare m15: number; - constructor (other: Mat4); + constructor(other: Mat4); - constructor ( + constructor( m00?: number, m01?: number, m02?: number, m03?: number, m04?: number, m05?: number, m06?: number, m07?: number, m08?: number, m09?: number, m10?: number, m11?: number, @@ -1543,14 +1559,14 @@ export class Mat4 extends ValueType { * @param other Specified matrix. * @return this */ - public set (other: Mat4): Mat4; + public set(other: Mat4): Mat4; /** * @en Set the matrix with values of all elements * @zh 设置当前矩阵指定元素值。 * @return this */ - public set ( + public set( m00?: number, m01?: number, m02?: number, m03?: number, m04?: number, m05?: number, m06?: number, m07?: number, m08?: number, m09?: number, m10?: number, m11?: number, @@ -1979,7 +1995,7 @@ export class Mat4 extends ValueType { /** * @en Returns the translation vector component of a transformation matrix. - * @zh 从当前矩阵中计算出位移变换的部分,并以各个轴上位移的形式赋值给出口向量。 + * @zh 从当前矩阵中计算出位移变换的部分,并以各个轴上位移的形式赋值给输出向量。 * @param out Vector to receive translation component. */ public getTranslation (out: Vec3) { @@ -1992,7 +2008,7 @@ export class Mat4 extends ValueType { /** * @en Returns the scale factor component of a transformation matrix - * @zh 从当前矩阵中计算出缩放变换的部分,并以各个轴上缩放的形式赋值给出口向量。 + * @zh 从当前矩阵中计算出缩放变换的部分,并以各个轴上缩放的形式赋值给输出向量。 * @param out Vector to receive scale component */ public getScale (out: Vec3) { @@ -2008,47 +2024,38 @@ export class Mat4 extends ValueType { out.x = Math.sqrt(m00 * m00 + m01 * m01 + m02 * m02); out.y = Math.sqrt(m04 * m04 + m05 * m05 + m06 * m06); out.z = Math.sqrt(m08 * m08 + m09 * m09 + m10 * m10); - // account for refections + // account for reflections if (Mat3.determinant(m3_1) < 0) { out.x *= -1; } return out; } /** * @en Returns the rotation factor component of a transformation matrix - * @zh 从当前矩阵中计算出旋转变换的部分,并以四元数的形式赋值给出口四元数。 + * @zh 从当前矩阵中计算出旋转变换的部分,并以四元数的形式赋值给输出四元数。 * @param out Vector to receive rotation component */ public getRotation (out: Quat) { - const trace = this.m00 + this.m05 + this.m10; - let S = 0; - - if (trace > 0) { - S = Math.sqrt(trace + 1.0) * 2; - out.w = 0.25 * S; - out.x = (this.m06 - this.m09) / S; - out.y = (this.m08 - this.m02) / S; - out.z = (this.m01 - this.m04) / S; - } else if ((this.m00 > this.m05) && (this.m00 > this.m10)) { - S = Math.sqrt(1.0 + this.m00 - this.m05 - this.m10) * 2; - out.w = (this.m06 - this.m09) / S; - out.x = 0.25 * S; - out.y = (this.m01 + this.m04) / S; - out.z = (this.m08 + this.m02) / S; - } else if (this.m05 > this.m10) { - S = Math.sqrt(1.0 + this.m05 - this.m00 - this.m10) * 2; - out.w = (this.m08 - this.m02) / S; - out.x = (this.m01 + this.m04) / S; - out.y = 0.25 * S; - out.z = (this.m06 + this.m09) / S; - } else { - S = Math.sqrt(1.0 + this.m10 - this.m00 - this.m05) * 2; - out.w = (this.m01 - this.m04) / S; - out.x = (this.m08 + this.m02) / S; - out.y = (this.m06 + this.m09) / S; - out.z = 0.25 * S; + // Extract rotation matrix first + const sx = Vec3.set(v3_1, this.m00, this.m01, this.m02).length(); + const sy = Vec3.set(v3_1, this.m04, this.m05, this.m06).length(); + const sz = Vec3.set(v3_1, this.m08, this.m09, this.m10).length(); + m3_1.m00 = this.m00 / sx; + m3_1.m01 = this.m01 / sx; + m3_1.m02 = this.m02 / sx; + m3_1.m03 = this.m04 / sy; + m3_1.m04 = this.m05 / sy; + m3_1.m05 = this.m06 / sy; + m3_1.m06 = this.m08 / sz; + m3_1.m07 = this.m09 / sz; + m3_1.m08 = this.m10 / sz; + const det = Mat3.determinant(m3_1); + if (det < 0) { + m3_1.m00 *= -1; + m3_1.m01 *= -1; + m3_1.m02 *= -1; } - return out; + return Quat.fromMat3(out, m3_1); } /** @@ -2167,8 +2174,8 @@ CCClass.fastDefine('cc.Mat4', Mat4, { }); legacyCC.Mat4 = Mat4; -export function mat4 (other: Mat4): Mat4; -export function mat4 ( +export function mat4(other: Mat4): Mat4; +export function mat4( m00?: number, m01?: number, m02?: number, m03?: number, m10?: number, m11?: number, m12?: number, m13?: number, m20?: number, m21?: number, m22?: number, m23?: number, diff --git a/cocos/core/math/math-base.ts b/cocos/core/math/math-base.ts index 8c1134192c5..5e9afc2eb7c 100644 --- a/cocos/core/math/math-base.ts +++ b/cocos/core/math/math-base.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { JSB } from 'internal:constants'; import { ValueType } from '../value-types/value-type'; import { FloatArray } from './type-define'; diff --git a/cocos/core/math/math-native-ext.ts b/cocos/core/math/math-native-ext.ts new file mode 100644 index 00000000000..d9494c8bafe --- /dev/null +++ b/cocos/core/math/math-native-ext.ts @@ -0,0 +1,131 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + http://www.cocos.com + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { NATIVE } from 'internal:constants'; +import { Mat4 } from './mat4'; +import { Mat3 } from './mat3'; +import { Vec3 } from './vec3'; +import { Vec2 } from './vec2'; +import { Vec4 } from './vec4'; +import { Quat } from './quat'; +import { Color } from './color'; + +const defineAttr = (proto, name, offset) => { + Object.defineProperty(proto, name, { + configurable: true, + enumerable: true, + get () { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return this._data()[offset]; + }, + set (v: number) { + this._data()[offset] = v; + }, + }); +}; + +enum MathType { + VEC2 = 0, + VEC3, + VEC4, + QUATERNION, + MAT3, + MAT4, + SIZE, + RECT, + COLOR, +} + +function extendType (proto: any, parentProto: any, typ: MathType) { + proto._data = function () { + if (!this.__data) { + this.__data = new Float32Array(this.underlyingData()); + } + return this.__data as Float32Array; + }; + Object.setPrototypeOf(proto, parentProto); + Object.defineProperty(proto, 'type', { configurable: true, enumerable: true, writable: false, value: typ }); +} + +function inheritCCClass (ctor: Constructor, parentCtor: Constructor) { + for (const attrName of ['__cid__', '__classname__']) { + Object.defineProperty(ctor.prototype, attrName, { + value: parentCtor.prototype[attrName], + writable: false, + enumerable: false, + configurable: true, + }); + } + for (const staticKey of ['__attrs__', '__props__', '__values__']) { + ctor[staticKey] = parentCtor[staticKey]; + } +} + +if (NATIVE) { + extendType(jsb.Mat4.prototype, Mat4.prototype, MathType.MAT4); + + for (let i = 0; i < 16; i++) { + const numb = `0${i}`; + defineAttr(jsb.Mat4.prototype, `m${numb.substring(numb.length - 2)}`, i); + } + + for (let i = 0; i < 9; i++) { + const numb = `0${i}`; + defineAttr(jsb.Mat3.prototype, `m${numb.substring(numb.length - 2)}`, i); + } + extendType(jsb.Mat3.prototype, Mat3.prototype, MathType.MAT3); + + defineAttr(jsb.Vec2.prototype, 'x', 0); + defineAttr(jsb.Vec2.prototype, 'y', 1); + extendType(jsb.Vec2.prototype, Vec2.prototype, MathType.VEC2); + + defineAttr(jsb.Vec3.prototype, 'x', 0); + defineAttr(jsb.Vec3.prototype, 'y', 1); + defineAttr(jsb.Vec3.prototype, 'z', 2); + + extendType(jsb.Vec3.prototype, Vec3.prototype, MathType.VEC3); + + defineAttr(jsb.Vec4.prototype, 'x', 0); + defineAttr(jsb.Vec4.prototype, 'y', 1); + defineAttr(jsb.Vec4.prototype, 'z', 2); + defineAttr(jsb.Vec4.prototype, 'w', 3); + + extendType(jsb.Vec4.prototype, Vec4.prototype, MathType.VEC4); + + defineAttr(jsb.Quat.prototype, 'x', 0); + defineAttr(jsb.Quat.prototype, 'y', 1); + defineAttr(jsb.Quat.prototype, 'z', 2); + defineAttr(jsb.Quat.prototype, 'w', 3); + + extendType(jsb.Quat.prototype, Quat.prototype, MathType.QUATERNION); + + Object.setPrototypeOf(jsb.Color.prototype, Color.prototype); + Object.defineProperty(jsb.Color.prototype, 'type', { configurable: true, enumerable: true, writable: false, value: MathType.COLOR }); + + inheritCCClass(jsb.Vec4, Vec4); + inheritCCClass(jsb.Vec3, Vec3); + inheritCCClass(jsb.Vec2, Vec2); + inheritCCClass(jsb.Mat4, Mat4); + inheritCCClass(jsb.Mat3, Mat3); + inheritCCClass(jsb.Color, Color); + inheritCCClass(jsb.Quat, Quat); +} diff --git a/cocos/core/math/quat.ts b/cocos/core/math/quat.ts index 7595124822f..4f6f8e3015e 100644 --- a/cocos/core/math/quat.ts +++ b/cocos/core/math/quat.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -117,7 +116,7 @@ export class Quat extends ValueType { * @zh 获取四元数的旋转轴和旋转弧度 * @param outAxis output axis * @param q input quaternion - * @return radius of rotation + * @return radian of rotation */ public static getAxisAngle (outAxis: VecLike, q: Out) { const rad = Math.acos(q.w) * 2.0; @@ -136,8 +135,8 @@ export class Quat extends ValueType { } /** - * @en Quaternion multiplication and save the results to out quaternion - * @zh 四元数乘法 + * @en Quaternion multiplication and save the results to out quaternion, that is a * b. + * @zh 四元数乘法,即a * b。 */ public static multiply (out: Out, a: QuatLike_1, b: QuatLike_2) { const x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y; @@ -178,7 +177,7 @@ export class Quat extends ValueType { /** * @en Sets the out quaternion to represent a radian rotation around x axis * @zh 绕 X 轴旋转指定四元数 - * @param rad radius of rotation + * @param rad radian of rotation */ public static rotateX (out: Out, a: Out, rad: number) { rad *= 0.5; @@ -197,7 +196,7 @@ export class Quat extends ValueType { /** * @en Sets the out quaternion to represent a radian rotation around y axis * @zh 绕 Y 轴旋转指定四元数 - * @param rad radius of rotation + * @param rad radian of rotation */ public static rotateY (out: Out, a: Out, rad: number) { rad *= 0.5; @@ -216,7 +215,7 @@ export class Quat extends ValueType { /** * @en Sets the out quaternion to represent a radian rotation around z axis * @zh 绕 Z 轴旋转指定四元数 - * @param rad radius of rotation + * @param rad radian of rotation */ public static rotateZ (out: Out, a: Out, rad: number) { rad *= 0.5; @@ -236,7 +235,7 @@ export class Quat extends ValueType { * @en Sets the out quaternion to represent a radian rotation around a given rotation axis in world space * @zh 绕世界空间下指定轴旋转四元数 * @param axis axis of rotation, normalized by default - * @param rad radius of rotation + * @param rad radian of rotation */ public static rotateAround (out: Out, rot: Out, axis: VecLike, rad: number) { // get inv-axis (local to rot) @@ -252,7 +251,7 @@ export class Quat extends ValueType { * @en Sets the out quaternion to represent a radian rotation around a given rotation axis in local space * @zh 绕本地空间下指定轴旋转四元数 * @param axis axis of rotation - * @param rad radius of rotation + * @param rad radian of rotation */ public static rotateAroundLocal (out: Out, rot: Out, axis: VecLike, rad: number) { Quat.fromAxisAngle(qt_1, axis, rad); @@ -397,8 +396,8 @@ export class Quat extends ValueType { } /** - * @en Normalize the given quaternion - * @zh 归一化四元数 + * @en Normalize the given quaternion, returns a zero quaternion if input is a zero quaternion. + * @zh 归一化四元数,输入零四元数将会返回零四元数。 */ public static normalize (out: Out, a: Out) { let len = a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w; @@ -408,6 +407,11 @@ export class Quat extends ValueType { out.y = a.y * len; out.z = a.z * len; out.w = a.w * len; + } else { + out.x = 0; + out.y = 0; + out.z = 0; + out.w = 0; } return out; } @@ -470,34 +474,34 @@ export class Quat extends ValueType { out.y = (m02 - m20) * s; out.z = (m10 - m01) * s; } else if ((m00 > m11) && (m00 > m22)) { - const s = 2.0 * Math.sqrt(1.0 + m00 - m11 - m22); + const s = 0.5 / Math.sqrt(1.0 + m00 - m11 - m22); - out.w = (m21 - m12) / s; - out.x = 0.25 * s; - out.y = (m01 + m10) / s; - out.z = (m02 + m20) / s; + out.w = (m21 - m12) * s; + out.x = 0.25 / s; + out.y = (m01 + m10) * s; + out.z = (m02 + m20) * s; } else if (m11 > m22) { - const s = 2.0 * Math.sqrt(1.0 + m11 - m00 - m22); + const s = 0.5 / Math.sqrt(1.0 + m11 - m00 - m22); - out.w = (m02 - m20) / s; - out.x = (m01 + m10) / s; - out.y = 0.25 * s; - out.z = (m12 + m21) / s; + out.w = (m02 - m20) * s; + out.x = (m01 + m10) * s; + out.y = 0.25 / s; + out.z = (m12 + m21) * s; } else { - const s = 2.0 * Math.sqrt(1.0 + m22 - m00 - m11); + const s = 0.5 / Math.sqrt(1.0 + m22 - m00 - m11); - out.w = (m10 - m01) / s; - out.x = (m02 + m20) / s; - out.y = (m12 + m21) / s; - out.z = 0.25 * s; + out.w = (m10 - m01) * s; + out.x = (m02 + m20) * s; + out.y = (m12 + m21) * s; + out.z = 0.25 / s; } return out; } /** - * @en Calculates the quaternion with Euler angles, the rotation order is YZX - * @zh 根据欧拉角信息计算四元数,旋转顺序为 YZX + * @en Calculates the quaternion with Euler angles, the rotation order is YZX, first rotate around Y, then around Z, and finally around X. + * @zh 根据欧拉角信息计算四元数,旋转顺序为 YZX,即先绕Y旋转,再绕Z,最后绕X旋转。 */ public static fromEuler (out: Out, x: number, y: number, z: number) { x *= halfToRad; @@ -543,7 +547,7 @@ export class Quat extends ValueType { const fz = 2.0 * q.z; out.x = 1.0 - fy * q.y - fz * q.z; out.y = fy * q.x + fz * q.w; - out.z = fz * q.x + fy * q.w; + out.z = fz * q.x - fy * q.w; return out; } @@ -571,7 +575,7 @@ export class Quat extends ValueType { const fx = 2.0 * q.x; const fy = 2.0 * q.y; const fz = 2.0 * q.z; - out.x = fz * q.x - fy * q.w; + out.x = fz * q.x + fy * q.w; out.y = fz * q.y - fx * q.w; out.z = 1.0 - fx * q.x - fy * q.y; @@ -579,8 +583,9 @@ export class Quat extends ValueType { } /** - * @en Converts the quaternion to angles, result angle x, y in the range of [-180, 180], z in the range of [-90, 90] interval, the rotation order is YZX - * @zh 根据四元数计算欧拉角,返回角度 x, y 在 [-180, 180] 区间内, z 默认在 [-90, 90] 区间内,旋转顺序为 YZX + * @en Converts the quaternion to angles, result angle x, y in the range of [-180, 180], z in the range of [-90, 90] interval, + * the rotation order is YZX, first rotate around Y, then around Z, and finally around X + * @zh 根据四元数计算欧拉角,返回角度 x, y 在 [-180, 180] 区间内, z 默认在 [-90, 90] 区间内,旋转顺序为 YZX,即先绕Y旋转,再绕Z,最后绕X旋转。 * @param outerZ change z value range to [-180, -90] U [90, 180] */ public static toEuler (out: IVec3Like, q: IQuatLike, outerZ?: boolean) { @@ -614,6 +619,19 @@ export class Quat extends ValueType { return out; } + /** + * @en Converts the quaternion to euler angles, result angle y, z in the range of [-180, 180], x in the range of [-90, 90], + * the rotation order is YXZ, first rotate around Y, then around X, and finally around Z. + * @zh 根据四元数计算欧拉角,返回角度 yz 在 [-180, 180], x 在 [-90, 90],旋转顺序为 YXZ,即先绕Y旋转,再绕X,最后绕Z旋转。 + */ + public static toEulerInYXZOrder (out: Vec3, q: IQuatLike) { + Mat3.fromQuat(m3_1, q); + Mat3.toEuler(m3_1, out); + out.x = toDegree(out.x); + out.y = toDegree(out.y); + out.z = toDegree(out.z); + } + /** * @en Converts quaternion to an array * @zh 四元数转数组 @@ -766,7 +784,7 @@ export class Quat extends ValueType { /** * @en Convert quaternion to Euler angles - * @zh 将当前四元数转化为欧拉角(x-y-z)并赋值给出口向量。 + * @zh 将当前四元数转化为欧拉角(x-y-z)并赋值给输出向量。 * @param out the output vector */ public getEulerAngles (out: Vec3) { diff --git a/cocos/core/math/rect.ts b/cocos/core/math/rect.ts index 25f20c306a2..be91f9431e7 100644 --- a/cocos/core/math/rect.ts +++ b/cocos/core/math/rect.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -84,7 +83,7 @@ export class Rect extends ValueType { /** * @en Returns the overlapping portion of 2 rectangles. - * @zh 计算当前矩形与指定矩形重叠部分的矩形,将其赋值给出口矩形。 + * @zh 计算当前矩形与指定矩形重叠部分的矩形,将其赋值给输出矩形。 * @param out Output Rect. * @param one One of the specify Rect. * @param other Another of the specify Rect. @@ -108,7 +107,7 @@ export class Rect extends ValueType { /** * @en Returns the smallest rectangle that contains the current rect and the given rect. - * @zh 创建同时包含当前矩形和指定矩形的最小矩形,将其赋值给出口矩形。 + * @zh 创建同时包含当前矩形和指定矩形的最小矩形,将其赋值给输出矩形。 * @param out Output Rect. * @param one One of the specify Rect. * @param other Another of the specify Rect. diff --git a/cocos/core/math/size.ts b/cocos/core/math/size.ts index 9e8a88587b3..0b75e35b3da 100644 --- a/cocos/core/math/size.ts +++ b/cocos/core/math/size.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/math/type-define.ts b/cocos/core/math/type-define.ts index 430fcea15ae..e83e48775ac 100644 --- a/cocos/core/math/type-define.ts +++ b/cocos/core/math/type-define.ts @@ -1,27 +1,26 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ export interface IColorLike { r: number; diff --git a/cocos/core/math/utils.ts b/cocos/core/math/utils.ts index b5fc723ce93..68e7ff491a0 100644 --- a/cocos/core/math/utils.ts +++ b/cocos/core/math/utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,8 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ +// Fix Circular dependency +import * as bits from './bits'; import { ValueType } from '../value-types'; import { IVec3Like } from './type-define'; @@ -30,6 +31,9 @@ const _d2r = Math.PI / 180.0; const _r2d = 180.0 / Math.PI; +export const HALF_PI = Math.PI * 0.5; +export const TWO_PI = Math.PI * 2.0; + export const EPSILON = 0.000001; /** @@ -191,14 +195,7 @@ export function pseudoRandomRangeInt (seed: number, min: number, max: number) { * @return The the next power of two. */ export function nextPow2 (val: number) { - --val; - val |= (val >> 1); - val |= (val >> 2); - val |= (val >> 4); - val |= (val >> 8); - val |= (val >> 16); - ++val; - return val; + return bits.nextPow2(val); } /** diff --git a/cocos/core/math/vec2.ts b/cocos/core/math/vec2.ts index daff1dcde58..8beffe4cb83 100644 --- a/cocos/core/math/vec2.ts +++ b/cocos/core/math/vec2.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -266,8 +265,8 @@ export class Vec2 extends ValueType { } /** - * @en Sets the normalized vector to the out vector - * @zh 归一化向量 + * @en Sets the normalized vector to the out vector, returns a zero vector if input is a zero vector. + * @zh 归一化向量,输入零向量将会返回零向量。 */ public static normalize (out: Out, a: Vec2Like) { const x = a.x; @@ -277,6 +276,9 @@ export class Vec2 extends ValueType { len = 1 / Math.sqrt(len); out.x = x * len; out.y = y * len; + } else { + out.x = 0; + out.y = 0; } return out; } @@ -295,14 +297,17 @@ export class Vec2 extends ValueType { * @override (a:Vec2, b:Vec2) => number * @override [deprecated] (out:Vec3, a:Vec2, b:Vec2) => Vec3 */ + /** + * @deprecated since v3.8.0, There is no physical meaning. + */ public static cross (a: IVec2Like, b: IVec2Like): number; /** - * @deprecated Consider use another overrides please. + * @deprecated since v3.8.0, There is no physical meaning. */ public static cross (out: Vec3, a: Out, b: Out): Vec3; - public static cross (out: IVec2Like | Vec3, a: IVec2Like, b?: IVec2Like) : number | Vec3 { + public static cross (out: IVec2Like | Vec3, a: IVec2Like, b?: IVec2Like): number | Vec3 { if (out instanceof Vec3) { out.x = out.y = 0; out.z = a.x * b!.y - a.y * b!.x; @@ -313,7 +318,7 @@ export class Vec2 extends ValueType { } /** - * @en Calculates the linear interpolation between two vectors with a given ratio + * @en Calculates the linear interpolation between two vectors with a given ratio: A + t * (B - A) * @zh 逐元素向量线性插值: A + t * (B - A) */ public static lerp (out: Out, a: Out, b: Out, t: number) { @@ -413,19 +418,20 @@ export class Vec2 extends ValueType { } /** - * @en Calculates the radian angle between two vectors - * @zh 求两向量夹角弧度 + * @en Calculates the radian angle between two vectors, returns zero if either vector is a zero vector. + * @zh 求两向量夹角弧度,任意一个向量是零向量则返回零。 */ public static angle (a: Out, b: Out) { - Vec2.normalize(v2_1, a); - Vec2.normalize(v2_2, b); - const cosine = Vec2.dot(v2_1, v2_2); - if (cosine > 1.0) { - return 0; - } - if (cosine < -1.0) { - return Math.PI; + const magSqr1 = a.x * a.x + a.y * a.y; + const magSqr2 = b.x * b.x + b.y * b.y; + + if (magSqr1 === 0 || magSqr2 === 0) { + return 0.0; } + + const dot = a.x * b.x + a.y * b.y; + let cosine = dot / (Math.sqrt(magSqr1 * magSqr2)); + cosine = clamp(cosine, -1.0, 1.0); return Math.acos(cosine); } @@ -713,6 +719,9 @@ export class Vec2 extends ValueType { * @param other specified vector * @return `out` */ + /** + * @deprecated since v3.8.0, There is no physical meaning. + */ public cross (other: Vec2) { return this.x * other.y - this.y * other.x; } @@ -752,24 +761,23 @@ export class Vec2 extends ValueType { } /** - * @en Calculates radian angle between two vectors - * @zh 获取当前向量和指定向量之间的角度。 - * @param other specified vector - * @return The angle between the current vector and the specified vector (in radians); if there are zero vectors in the current vector and the specified vector, 0 is returned. + * @en Calculates radian angle between two vectors, returns zero if either vector is a zero vector. + * @zh 获取当前向量和指定向量之间的角度,任意一个向量是零向量则返回零。 + * @param other specified vector. + * @return The angle between the current vector and the specified vector. */ public angle (other: Vec2) { const magSqr1 = this.lengthSqr(); const magSqr2 = other.lengthSqr(); if (magSqr1 === 0 || magSqr2 === 0) { - console.warn('Can\'t get angle between zero vector'); return 0.0; } const dot = this.dot(other); - let theta = dot / (Math.sqrt(magSqr1 * magSqr2)); - theta = clamp(theta, -1.0, 1.0); - return Math.acos(theta); + let cosine = dot / (Math.sqrt(magSqr1 * magSqr2)); + cosine = clamp(cosine, -1.0, 1.0); + return Math.acos(cosine); } /** @@ -785,9 +793,9 @@ export class Vec2 extends ValueType { } /** - * @en Rotates the current vector by an angle in radian value - * @zh 将当前向量的旋转 - * @param radians radius of rotation + * @en Rotates the current vector by an angle in radian value. Counterclockwise is the positive direction. + * @zh 将当前向量进行旋转,逆时针为正方向。 + * @param radians radians of rotation. */ public rotate (radians: number) { const x = this.x; @@ -827,9 +835,6 @@ export class Vec2 extends ValueType { } } -const v2_1 = new Vec2(); -const v2_2 = new Vec2(); - CCClass.fastDefine('cc.Vec2', Vec2, { x: 0, y: 0 }); legacyCC.Vec2 = Vec2; diff --git a/cocos/core/math/vec3.ts b/cocos/core/math/vec3.ts index e02b052f99f..0400c544dda 100644 --- a/cocos/core/math/vec3.ts +++ b/cocos/core/math/vec3.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,7 +27,7 @@ import { CCClass } from '../data/class'; import { ValueType } from '../value-types/value-type'; import { Mat4 } from './mat4'; import { IMat3Like, IMat4Like, IQuatLike, IVec3Like } from './type-define'; -import { clamp, EPSILON, random } from './utils'; +import { clamp, EPSILON, lerp, random } from './utils'; import { legacyCC } from '../global-exports'; /** @@ -305,8 +304,8 @@ export class Vec3 extends ValueType { } /** - * @en Sets the normalized vector to the out vector - * @zh 归一化向量 + * @en Sets the normalized vector to the out vector, returns a zero vector if input is a zero vector. + * @zh 归一化向量,输入零向量将会返回零向量。 */ public static normalize (out: Out, a: IVec3Like) { const x = a.x; @@ -319,6 +318,10 @@ export class Vec3 extends ValueType { out.x = x * len; out.y = y * len; out.z = z * len; + } else { + out.x = 0; + out.y = 0; + out.z = 0; } return out; } @@ -345,7 +348,7 @@ export class Vec3 extends ValueType { } /** - * @en Calculates the linear interpolation between two vectors with a given ratio + * @en Calculates the linear interpolation between two vectors with a given ratio: A + t * (B - A) * @zh 逐元素向量线性插值: A + t * (B - A) */ public static lerp (out: Out, a: IVec3Like, b: IVec3Like, t: number) { @@ -355,6 +358,77 @@ export class Vec3 extends ValueType { return out; } + /** + * @zh 球面线性插值。多用于插值两个方向向量。 + * @en Spherical linear interpolation. Commonly used in interpolation between directional vectors. + * @param out @zh 输出向量。 @en Output vector. + * @param from @zh 起点向量。 @en Start vector. + * @param to @zh 终点向量。 @en Destination vector. + * @param t @zh 插值参数。@en Interpolation parameter. + * @returns `out` + * @description + * @zh + * - 如果 `from`、`to` 中任何一个接近零向量,则结果就是 `from` 到 `to` 线性插值的结果; + * + * - 否则,如果 `from`、`to` 方向刚好接近相反, + * 则结果向量是满足以下条件的一个向量:结果向量和两个输入向量的夹角之比是 `t`,其长度是 `from` 到 `to` 的长度线性插值的结果; + * + * - 否则,结果是从标准化后的 `from` 到 标准化后的 `to` + * 进行球面线性插值的结果乘以 `from` 到 `to` 的长度线性插值后的长度。 + * @en + * - If either `from` or `to` is close to zero vector, + * the result would be the (non-spherical) linear interpolation result from `from` to `to`. + * + * - Otherwise, if `from` and `to` have almost opposite directions, + * the result would be such a vector so that: + * The angle ratio between result vector and input vectors is `t`, + * the length of result vector is the linear interpolation of lengths from `from` to `to`. + * + * - Otherwise, the result would be the spherical linear interpolation result + * from normalized `from` to normalized `to`, + * then scaled by linear interpolation of lengths from `from` to `to`. + */ + public static slerp= (() => { + const cacheV1 = new Vec3(); + const cacheV2 = new Vec3(); + const cacheV3 = new Vec3(); + return (out: Out, from: Readonly, to: Readonly, t: number) => { + const EPSILON = 1e-5; + const lenFrom = Vec3.len(from); + const lenTo = Vec3.len(to); + if (lenFrom < EPSILON || lenTo < EPSILON) { + return Vec3.lerp(out, from, to, t); + } + const lenLerped = lerp(lenFrom, lenTo, t); + const dot = Vec3.dot(from, to) / (lenFrom * lenTo); + if (dot > 1.0 - EPSILON) { + // If the directions are almost same, slerp should be close to lerp. + return Vec3.lerp(out, from, to, t); + } else if (dot < -1.0 + EPSILON) { + // If the directions are almost opposite, + // every vector that orthonormal to the directions can be the rotation axis. + const fromNormalized = Vec3.multiplyScalar(cacheV1, from, 1.0 / lenFrom); + const axis = chooseAnyPerpendicular(cacheV2, fromNormalized); + const angle = Math.PI * t; + rotateAxisAngle(cacheV3, fromNormalized, axis, angle); + Vec3.multiplyScalar(out, cacheV3, lenLerped); + return out; + } else { + // Do not have to clamp. We done it before. + const dotClamped = dot; + const theta = Math.acos(dotClamped) * t; + const fromNormalized = Vec3.multiplyScalar(cacheV1, from, 1.0 / lenFrom); + const toNormalized = Vec3.multiplyScalar(cacheV2, to, 1.0 / lenTo); + Vec3.scaleAndAdd(cacheV3, toNormalized, fromNormalized, -dotClamped); + Vec3.normalize(cacheV3, cacheV3); + Vec3.multiplyScalar(cacheV3, cacheV3, Math.sin(theta)); + Vec3.scaleAndAdd(cacheV3, cacheV3, fromNormalized, Math.cos(theta)); + Vec3.multiplyScalar(out, cacheV3, lenLerped); + return out; + } + }; + })(); + /** * @en Generates a uniformly distributed random vector points from center to the surface of the unit sphere * @zh 生成一个在单位球体上均匀分布的随机向量 @@ -382,6 +456,8 @@ export class Vec3 extends ValueType { const y = a.y; const z = a.z; let rhw = m.m03 * x + m.m07 * y + m.m11 * z + m.m15; + // Important note by stanley: + // Math.abs needs to be removed later, because the operation will generate a wrong homogeneous coordinate rhw = rhw ? Math.abs(1 / rhw) : 1; out.x = (m.m00 * x + m.m04 * y + m.m08 * z + m.m12) * rhw; out.y = (m.m01 * x + m.m05 * y + m.m09 * z + m.m13) * rhw; @@ -398,6 +474,8 @@ export class Vec3 extends ValueType { const y = a.y; const z = a.z; let rhw = m.m03 * x + m.m07 * y + m.m11 * z; + // Important note by stanley: + // Math.abs needs to be removed later, because the operation will generate a wrong homogeneous coordinate rhw = rhw ? Math.abs(1 / rhw) : 1; out.x = (m.m00 * x + m.m04 * y + m.m08 * z) * rhw; out.y = (m.m01 * x + m.m05 * y + m.m09 * z) * rhw; @@ -434,8 +512,8 @@ export class Vec3 extends ValueType { } /** - * @en Vector quaternion multiplication - * @zh 向量四元数乘法 + * @en Vector quaternion multiplication: q*a*q^{-1}. + * @zh 向量四元数乘法:q*a*q^{-1}。 */ public static transformQuat (out: Out, a: IVec3Like, q: IQuatLike) { // benchmarks: http://jsperf.com/quaternion-transform-Vec3-implementations @@ -494,7 +572,7 @@ export class Vec3 extends ValueType { * @zh 绕 X 轴旋转向量指定弧度 * @param v rotation vector * @param o center of rotation - * @param a radius of rotation + * @param a radiance of rotation */ public static rotateX (out: Out, v: IVec3Like, o: IVec3Like, a: number) { // Translate point to the origin @@ -522,7 +600,7 @@ export class Vec3 extends ValueType { * @zh 绕 Y 轴旋转向量指定弧度 * @param v rotation vector * @param o center of rotation - * @param a radius of rotation + * @param a radiance of rotation */ public static rotateY (out: Out, v: IVec3Like, o: IVec3Like, a: number) { // Translate point to the origin @@ -550,7 +628,7 @@ export class Vec3 extends ValueType { * @zh 绕 Z 轴旋转向量指定弧度 * @param v rotation vector * @param o center of rotation - * @param a radius of rotation + * @param a radiance of rotation */ public static rotateZ (out: Out, v: IVec3Like, o: IVec3Like, a: number) { // Translate point to the origin @@ -573,6 +651,39 @@ export class Vec3 extends ValueType { return out; } + /** + * @en Rotates the vector with specified angle around any n axis + * @zh 绕任意 n 轴旋转向量指定弧度 + * @param v rotation vector + * @param o center of rotation + * @param n axis of rotation + * @param a radiance of rotation + */ + public static rotateN (out: Out, v: IVec3Like, o: IVec3Like, n: IVec3Like, a: number) { + // Translate point to the origin + const x = v.x - o.x; + const y = v.y - o.y; + const z = v.z - o.z; + + // perform rotation + const nx = n.x; + const ny = n.y; + const nz = n.z; + + const cos = Math.cos(a); + const sin = Math.sin(a); + const rx = x * (nx * nx * (1.0 - cos) + cos) + y * (nx * ny * (1.0 - cos) - nx * sin) + z * (nx * nz * (1.0 - cos) + ny * sin); + const ry = x * (nx * ny * (1.0 - cos) + nz * sin) + y * (ny * ny * (1.0 - cos) + cos) + z * (ny * nz * (1.0 - cos) - nx * sin); + const rz = x * (nx * nz * (1.0 - cos) - ny * sin) + y * (ny * nz * (1.0 - cos) + nx * sin) + z * (nz * nz * (1.0 - cos) + cos); + + // translate to correct position + out.x = rx + o.x; + out.y = ry + o.y; + out.z = rz + o.z; + + return out; + } + /** * @en Converts the given vector to an array * @zh 向量转数组 @@ -628,15 +739,16 @@ export class Vec3 extends ValueType { * @zh 求两向量夹角弧度 */ public static angle (a: IVec3Like, b: IVec3Like) { - Vec3.normalize(v3_1, a); - Vec3.normalize(v3_2, b); - const cosine = Vec3.dot(v3_1, v3_2); - if (cosine > 1.0) { - return 0; - } - if (cosine < -1.0) { - return Math.PI; + const magSqr1 = a.x * a.x + a.y * a.y + a.z * a.z; + const magSqr2 = b.x * b.x + b.y * b.y + b.z * b.z; + + if (magSqr1 === 0 || magSqr2 === 0) { + return 0.0; } + + const dot = a.x * b.x + a.y * b.y + a.z * b.z; + let cosine = dot / (Math.sqrt(magSqr1 * magSqr2)); + cosine = clamp(cosine, -1.0, 1.0); return Math.acos(cosine); } @@ -654,7 +766,7 @@ export class Vec3 extends ValueType { * @en Calculates the projection on the specified vector * @zh 计算向量在指定向量上的投影 * @param a projection vector - * @param n target vector + * @param b target vector */ public static project (out: Out, a: IVec3Like, b: IVec3Like) { const sqrLen = Vec3.lengthSqr(b); @@ -748,12 +860,9 @@ export class Vec3 extends ValueType { */ public equals (other: Vec3, epsilon = EPSILON) { return ( - Math.abs(this.x - other.x) - <= epsilon * Math.max(1.0, Math.abs(this.x), Math.abs(other.x)) - && Math.abs(this.y - other.y) - <= epsilon * Math.max(1.0, Math.abs(this.y), Math.abs(other.y)) - && Math.abs(this.z - other.z) - <= epsilon * Math.max(1.0, Math.abs(this.z), Math.abs(other.z)) + Math.abs(this.x - other.x) <= epsilon + && Math.abs(this.y - other.y) <= epsilon + && Math.abs(this.z - other.z) <= epsilon ); } @@ -768,12 +877,9 @@ export class Vec3 extends ValueType { */ public equals3f (x: number, y: number, z: number, epsilon = EPSILON) { return ( - Math.abs(this.x - x) - <= epsilon * Math.max(1.0, Math.abs(this.x), Math.abs(x)) - && Math.abs(this.y - y) - <= epsilon * Math.max(1.0, Math.abs(this.y), Math.abs(y)) - && Math.abs(this.z - z) - <= epsilon * Math.max(1.0, Math.abs(this.z), Math.abs(z)) + Math.abs(this.x - x) <= epsilon + && Math.abs(this.y - y) <= epsilon + && Math.abs(this.z - z) <= epsilon ); } @@ -1023,6 +1129,7 @@ export class Vec3 extends ValueType { this.y = y * len; this.z = z * len; } + return this; } @@ -1044,9 +1151,6 @@ export class Vec3 extends ValueType { } } -const v3_1 = new Vec3(); -const v3_2 = new Vec3(); - CCClass.fastDefine('cc.Vec3', Vec3, { x: 0, y: 0, z: 0 }); legacyCC.Vec3 = Vec3; @@ -1057,4 +1161,47 @@ export function v3 (x?: number | Vec3, y?: number, z?: number) { return new Vec3(x as any, y, z); } +/** + * Chooses an arbitrary unit vector that is perpendicular to input. + */ +function chooseAnyPerpendicular (out: Vec3, v: Readonly) { + const { x, y, z } = v; + // 1. Drop the component with minimal magnitude. + // 2. Negate one of the remain components. + // 3. Swap the remain components. + const absX = Math.abs(x); + const absY = Math.abs(y); + const absZ = Math.abs(z); + if (absX < absY && absX < absZ) { + Vec3.set(out, 0.0, z, -y); + } else if (absY < absZ) { + Vec3.set(out, z, 0.0, -x); + } else { + Vec3.set(out, y, -x, 0.0); + } + return Vec3.normalize(out, out); +} + +/** + * Rotates `input` around `axis` for `angle` radians. + */ +const rotateAxisAngle = (() => { + // TODO: can this cause v8 hidden class problem? + const cacheQ = { x: 0.0, y: 0.0, z: 0.0, w: 0.0 }; + return (out: Vec3, input: Readonly, axis: Readonly, angle: number) => { + // This should be equivalent to `Quat.fromAxisAngle(cacheQ, axis, angle)`. + // Here we duplicate the code to avoid circular reference. + + const rad = angle * 0.5; + const s = Math.sin(rad); + cacheQ.x = s * axis.x; + cacheQ.y = s * axis.y; + cacheQ.z = s * axis.z; + cacheQ.w = Math.cos(rad); + + Vec3.transformQuat(out, input, cacheQ); + return out; + }; +})(); + legacyCC.v3 = v3; diff --git a/cocos/core/math/vec4.ts b/cocos/core/math/vec4.ts index 5023669a68c..d614300d024 100644 --- a/cocos/core/math/vec4.ts +++ b/cocos/core/math/vec4.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -314,8 +313,8 @@ export class Vec4 extends ValueType { } /** - * @en Sets the normalized vector to the out vector - * @zh 归一化向量 + * @en Sets the normalized vector to the out vector, returns a zero vector if input is a zero vector. + * @zh 归一化向量,输入零向量将会返回零向量。 */ public static normalize (out: Out, a: Out) { const x = a.x; @@ -329,6 +328,11 @@ export class Vec4 extends ValueType { out.y = y * len; out.z = z * len; out.w = w * len; + } else { + out.x = 0; + out.y = 0; + out.z = 0; + out.w = 0; } return out; } diff --git a/cocos/core/memop/cached-array.ts b/cocos/core/memop/cached-array.ts index 1bfda8ce540..83f7a815d38 100644 --- a/cocos/core/memop/cached-array.ts +++ b/cocos/core/memop/cached-array.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ScalableContainer } from './scalable-container'; @@ -36,17 +35,17 @@ import { ScalableContainer } from './scalable-container'; export class CachedArray extends ScalableContainer { /** * @en - * The array which stores actual content + * The array which stores actual content. * @zh - * 实际存储数据内容的数组 + * 实际存储数据内容的数组。 */ public array: T[]; /** * @en - * The actual count of data object + * The actual count of data object. * @zh - * 实际数据内容数量 + * 实际存储的元素数量。 */ public length = 0; @@ -54,8 +53,13 @@ export class CachedArray extends ScalableContainer { private _initSize = 0; /** - * @param length Initial length - * @param compareFn Comparison function for sorting + * @en Constructor. @zh 构造函数。 + * @param length @en Initial length of the CachedArray. @zh CachedArray 的初始长度。 + * @param compareFn @en Function used to determine the order of the elements. It is expected to return + * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive + * value otherwise. If omitted, the elements are sorted in ascending, ASCII character order. + * @zh 用来确定元素顺序的函数。如果第一个参数小于第二个参数,它应该返回一个负值,如果它们相等,则返回0,否则返回一个正值。 + * 如果省略,元素将按 ASCII 字符升序排序。 */ constructor (length: number, compareFn?: (a: T, b: T) => number) { super(); @@ -67,10 +71,10 @@ export class CachedArray extends ScalableContainer { /** * @en - * Push an element to the end of the array + * Push an element to the end of the array. * @zh - * 向数组末尾添加一个元素 - * @param item The item to be added + * 向数组末尾添加一个元素。 + * @param item @en The item to be added. @zh 被添加到数组的元素。 */ public push (item: T) { this.array[this.length++] = item; @@ -80,8 +84,9 @@ export class CachedArray extends ScalableContainer { * @en * Pop the last element in the array. The [[length]] will reduce, but the internal array will keep its size. * @zh - * 弹出数组最后一个元素,CachedArray 的 [[length]] 会减少,但是内部数组的实际长度不变 - * @return The last element. + * 弹出数组最后一个元素,CachedArray 的 [[length]] 会减少,但是内部数组的实际长度不变。 + * @returns @en The last element of this CachedArray. If CachedArray is empty, will return undefined. + * @zh 数组的最后一个元素。如果数组为空,将返回 undefined。 */ public pop (): T | undefined { return this.array[--this.length]; @@ -89,11 +94,12 @@ export class CachedArray extends ScalableContainer { /** * @en - * Get the element at the specified index of the array + * Get the element at the specified index of the array. * @zh - * 得到数组中指定位置的元素 - * @param idx The index of the requested element - * @return The element at given index + * 获取数组中指定位置的元素。 + * @param idx @en The index of the requested element. @zh 用于获取数组元素的索引。 + * @returns @en The element at given index. If idx not in [0, [[length]]) or array is empty, will return undefined. + * @zh 数组下标对应的元素。如果 idx 超出 [0, [[length]]),或者数组是空的,将返回 undefined。 */ public get (idx: number): T | undefined { return this.array[idx]; @@ -111,9 +117,9 @@ export class CachedArray extends ScalableContainer { /** * @en - * Clear the cache. The [[length]] will be set to 0, and clear the internal array. + * Destroy the array. The [[length]] will be set to 0, and clear the internal array. * @zh - * 清空数组所有元素。[[length]] 会被设为 0,并且清空内部数组 + * 销毁数组。[[length]] 会被设为 0,并且清空内部数组。 */ public destroy () { this.length = 0; @@ -121,6 +127,10 @@ export class CachedArray extends ScalableContainer { super.destroy(); } + /** + * @en Requests the removal of unused capacity. + * @zh 尝试释放多余的内存。 + */ public tryShrink () { if (this.array.length >> 2 > this.length) { this.array.length = Math.max(this._initSize, this.array.length >> 1); @@ -129,9 +139,10 @@ export class CachedArray extends ScalableContainer { /** * @en - * Sort the existing elements in cache + * Sort the existing elements in cache by [[compareFn]] passed in constructor. + * If [[compareFn]] is not passed in, the elements are sorted in ascending, ASCII character order. * @zh - * 排序所有现有元素 + * 使用构造函数传入的 [[compareFn]] 排序所有现有元素。如果没有传入比较函数,将按照 ASCII 升序排序。 */ public sort () { this.array.length = this.length; @@ -140,10 +151,10 @@ export class CachedArray extends ScalableContainer { /** * @en - * Add all elements of a given array to the end of the current array + * Add all elements of a given array to the end of the current array. * @zh - * 添加一个指定数组中的所有元素到当前数组末尾 - * @param array The given array to be appended + * 添加一个指定数组中的所有元素到当前数组末尾。 + * @param array @en The given array to be appended. @zh 被添加的数组。 */ public concat (array: T[]) { for (let i = 0; i < array.length; ++i) { @@ -154,7 +165,9 @@ export class CachedArray extends ScalableContainer { /** * @en Delete the element at the specified location and move the last element to that location. * @zh 删除指定位置的元素并将最后一个元素移动至该位置。 - * @param idx The index of the element to be deleted + * @param idx @en The index of the element to be deleted. If idx out of range [0, length), there is + * not effect. + * @zh 希望被删除的索引。如果索引超出 [0, length),将没有效果。 */ public fastRemove (idx: number) { if (idx >= this.length || idx < 0) { @@ -165,9 +178,11 @@ export class CachedArray extends ScalableContainer { } /** - * @en Returns the first index at which a given element can be found in the array. - * @zh 返回在数组中可以找到一个给定元素的第一个索引。 - * @param val The element + * @en Returns the first index that compares equal to val. + * @zh 返回在数组中找到的第一个和 val 相等的元素的索引。 + * @param val @en Value to search for. @zh 搜索的值。 + * @returns The index to the first element that compares equal to val. If no elements match, returns -1. + * @zh 第一个和 val 相等的元素的索引。如果没找到,将返回 -1。 */ public indexOf (val: T) { for (let i = 0, len = this.length; i < len; ++i) { diff --git a/cocos/core/memop/container-manager.ts b/cocos/core/memop/container-manager.ts deleted file mode 100644 index a7957042c5b..00000000000 --- a/cocos/core/memop/container-manager.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. - - https://www.cocos.com/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ -import { fastRemoveAt } from '../utils/array'; -import { ScalableContainer } from './scalable-container'; - -class ContainerManager { - private _pools: ScalableContainer[] = []; - private _lastShrinkPassed = 0; - public shrinkTimeSpan = 5; - - addContainer (pool: ScalableContainer) { - if (pool._poolHandle !== -1) return; - pool._poolHandle = this._pools.length; - this._pools.push(pool); - } - - removeContainer (pool: ScalableContainer) { - if (pool._poolHandle === -1) return; - this._pools[this._pools.length - 1]._poolHandle = pool._poolHandle; - fastRemoveAt(this._pools, pool._poolHandle); - pool._poolHandle = -1; - } - - tryShrink () { - for (let i = 0; i < this._pools.length; i++) { - this._pools[i].tryShrink(); - } - } - - update (dt: number) { - this._lastShrinkPassed += dt; - if (this._lastShrinkPassed > this.shrinkTimeSpan) { - this.tryShrink(); - this._lastShrinkPassed -= this.shrinkTimeSpan; - } - } -} - -export const containerManager = new ContainerManager(); diff --git a/cocos/core/memop/index.ts b/cocos/core/memop/index.ts index 95c67962de9..4bb19425bb2 100644 --- a/cocos/core/memop/index.ts +++ b/cocos/core/memop/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './pool'; export * from './recycle-pool'; diff --git a/cocos/core/memop/pool.ts b/cocos/core/memop/pool.ts index 3aac1723b50..991becb542d 100644 --- a/cocos/core/memop/pool.ts +++ b/cocos/core/memop/pool.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { warnID } from '../platform/debug'; import { ScalableContainer } from './scalable-container'; @@ -36,15 +35,20 @@ export class Pool extends ScalableContainer { private _ctor: () => T; private _elementsPerBatch: number; private _nextAvail: number; - private _freepool: T[] = []; + private _freePool: T[] = []; private _dtor: ((obj: T) => void) | null; /** - * @en Constructor with the allocator of elements and initial pool size - * @zh 使用元素的构造器和初始大小的构造函数 - * @param ctor The allocator of elements in pool, it's invoked directly without `new` - * @param elementsPerBatch Initial pool size, this size will also be the incremental size when the pool is overloaded - * @param dtor The finalizer of element, it's invoked when this container is destroyed or shrunk + * @en Constructor with the allocator of elements and initial pool size. + * @zh 使用元素的构造器和初始大小的构造函数。 + * @param ctor @en The allocator of elements in pool, it's invoked directly without `new` in Pool. + * @zh 元素的构造器,Pool 内部使用该构造器直接创建实例。 + * @param elementsPerBatch @en Initial pool size, this size will also be the incremental size when + * the pool is overloaded. + * @zh 对象池的初始大小。当对象池扩容时,也会使用该值。 + * @param dtor @en The finalizer of element, it's invoked when this Pool is destroyed or shrunk if + * it is valid. + * @zh 元素的析构器。如果存在的话,当对象池销毁或者缩容时,会使用该析构器。 */ constructor (ctor: () => T, elementsPerBatch: number, dtor?: (obj: T) => void) { super(); @@ -54,56 +58,63 @@ export class Pool extends ScalableContainer { this._nextAvail = this._elementsPerBatch - 1; for (let i = 0; i < this._elementsPerBatch; ++i) { - this._freepool.push(ctor()); + this._freePool.push(ctor()); } } /** * @en Take an object out of the object pool. * @zh 从对象池中取出一个对象。 - * @return An object ready for use. This function always return an object. + * @returns @en An object ready for use. This function always returns an object. + * @zh 该函数总是返回一个可用的对象。 */ public alloc (): T { if (this._nextAvail < 0) { - this._freepool.length = this._elementsPerBatch; + this._freePool.length = this._elementsPerBatch; for (let i = 0; i < this._elementsPerBatch; i++) { - this._freepool[i] = this._ctor(); + this._freePool[i] = this._ctor(); } this._nextAvail = this._elementsPerBatch - 1; } - return this._freepool[this._nextAvail--]; + return this._freePool[this._nextAvail--]; } /** * @en Put an object back into the object pool. * @zh 将一个对象放回对象池中。 - * @param obj The object to be put back into the pool + * @param obj @en The object to be put back into the pool. + * @zh 放回对象池中的对象。 */ public free (obj: T) { - this._freepool[++this._nextAvail] = obj; + this._freePool[++this._nextAvail] = obj; } /** * @en Put multiple objects back into the object pool. * @zh 将一组对象放回对象池中。 - * @param objs An array of objects to be put back into the pool + * @param objs @en An array of objects to be put back into the pool. + * @zh 放回对象池中的一组对象。 */ public freeArray (objs: T[]) { - this._freepool.length = this._nextAvail + 1; - Array.prototype.push.apply(this._freepool, objs); + this._freePool.length = this._nextAvail + 1; + Array.prototype.push.apply(this._freePool, objs); this._nextAvail += objs.length; } + /** + * @en Try to shrink the object pool to reduce memory usage. + * @zh 尝试缩容对象池,以释放内存。 + */ public tryShrink () { if (this._nextAvail >> 1 > this._elementsPerBatch) { if (this._dtor) { for (let i = this._nextAvail >> 1; i <= this._nextAvail; i++) { - this._dtor(this._freepool[i]); + this._dtor(this._freePool[i]); } } - this._freepool.length = this._nextAvail >> 1; - this._nextAvail = this._freepool.length - 1; + this._freePool.length = this._nextAvail >> 1; + this._nextAvail = this._freePool.length - 1; } } @@ -117,10 +128,10 @@ export class Pool extends ScalableContainer { const readDtor = dtor || this._dtor; if (readDtor) { for (let i = 0; i <= this._nextAvail; i++) { - readDtor(this._freepool[i]); + readDtor(this._freePool[i]); } } - this._freepool.length = 0; + this._freePool.length = 0; this._nextAvail = -1; super.destroy(); } diff --git a/cocos/core/memop/recycle-pool.ts b/cocos/core/memop/recycle-pool.ts index 7ba42726e5e..da32ea8b98b 100644 --- a/cocos/core/memop/recycle-pool.ts +++ b/cocos/core/memop/recycle-pool.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ScalableContainer } from './scalable-container'; @@ -79,8 +78,8 @@ export class RecyclePool extends ScalableContainer { } /** - * @en Resets the object pool. Only changes the length to 0 - * @zh 清空对象池。目前仅仅会设置尺寸为 0 + * @en Resets the object pool. Only changes the length to 0. + * @zh 清空对象池。目前仅仅会设置尺寸为 0。 */ public reset () { this._count = 0; @@ -89,7 +88,7 @@ export class RecyclePool extends ScalableContainer { /** * @en Resize the object poo, and fills with new created elements. * @zh 设置对象池大小,并填充新的元素。 - * @param size The new size of the pool + * @param size @en The new size of the pool. @zh 新的对象池大小。 */ public resize (size: number) { if (size > this._data.length) { @@ -100,9 +99,8 @@ export class RecyclePool extends ScalableContainer { } /** - * @en Expand the object pool, the size will be increment to current size times two, and fills with new created elements. - * @zh 扩充对象池容量,会自动扩充尺寸到两倍,并填充新的元素。 - * @param idx + * @en Expand the array size to 2 times the original size, and fills with new created elements. + * @zh 扩充对象池容量,会自动扩充尺寸到原来的 2 倍,并填充新的元素。 */ public add () { if (this._count >= this._data.length) { @@ -112,6 +110,10 @@ export class RecyclePool extends ScalableContainer { return this._data[this._count++]; } + /** + * @en Destroy the object pool. Please don't use it any more after it is destroyed. + * @zh 销毁对象池。销毁后不能继续使用。 + */ public destroy () { if (this._dtor) { for (let i = 0; i < this._data.length; i++) { @@ -123,6 +125,10 @@ export class RecyclePool extends ScalableContainer { super.destroy(); } + /** + * @en Try to shrink the object pool to free memory. + * @zh 尝试回收没用的对象,释放内存。 + */ public tryShrink () { if (this._data.length >> 2 > this._count) { const length = Math.max(this._initSize, this._data.length >> 1); @@ -136,9 +142,9 @@ export class RecyclePool extends ScalableContainer { } /** - * @en Remove an element of the object pool. This will also decrease size of the pool - * @zh 移除对象池中的一个元素,同时会减小池子尺寸。 - * @param idx The index of the element to be removed + * @en Remove the element with the specified index from the object pool. This will decrease pool size. + * @zh 移除对象池中指定索引的元素,会减小池子尺寸。 + * @param idx @en The index of the element to remove. @zh 被移除的元素的索引。 */ public removeAt (idx: number) { if (idx >= this._count) { diff --git a/cocos/core/memop/scalable-container.ts b/cocos/core/memop/scalable-container.ts index 1ddf85db25a..44e9c3451d0 100644 --- a/cocos/core/memop/scalable-container.ts +++ b/cocos/core/memop/scalable-container.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -import { containerManager } from './container-manager'; +*/ +import { fastRemoveAt } from '../utils/array'; export abstract class ScalableContainer { /** @@ -31,12 +29,72 @@ export abstract class ScalableContainer { */ public _poolHandle = -1; constructor () { - containerManager.addContainer(this); + scalableContainerManager.addContainer(this); } abstract tryShrink (): void; destroy () { - containerManager.removeContainer(this); + scalableContainerManager.removeContainer(this); } } + +/** + * @en ScalableContainerManager is a sequence container that stores ScalableContainers. + * It will shrink all managed ScalableContainer in a fixed interval. + */ +class ScalableContainerManager { + private _pools: ScalableContainer[] = []; + private _lastShrinkPassed = 0; + /** + * @en Shrink interval in seconds. + */ + public shrinkTimeSpan = 5; + + /** + * @en Add a ScalableContainer. Will add the same ScalableContainer instance once. + * @param pool @en The ScalableContainer to add. + */ + addContainer (pool: ScalableContainer) { + if (pool._poolHandle !== -1) return; + pool._poolHandle = this._pools.length; + this._pools.push(pool); + } + + /** + * @en Remove a ScalableContainer. + * @param pool @en The ScalableContainer to remove. + */ + removeContainer (pool: ScalableContainer) { + if (pool._poolHandle === -1) return; + this._pools[this._pools.length - 1]._poolHandle = pool._poolHandle; + fastRemoveAt(this._pools, pool._poolHandle); + pool._poolHandle = -1; + } + + /** + * @en Try to shrink all managed ScalableContainers. + */ + tryShrink () { + for (let i = 0; i < this._pools.length; i++) { + this._pools[i].tryShrink(); + } + } + + /** + * @en An update function invoked every frame. + * @param dt @en Delta time of frame interval in secondes. + */ + update (dt: number) { + this._lastShrinkPassed += dt; + if (this._lastShrinkPassed > this.shrinkTimeSpan) { + this.tryShrink(); + this._lastShrinkPassed -= this.shrinkTimeSpan; + } + } +} + +/** + * @en A global ScalableContainerManager instance. + */ +export const scalableContainerManager = new ScalableContainerManager(); diff --git a/cocos/core/platform/debug.ts b/cocos/core/platform/debug.ts index 8d4bf85f3f0..dfc52af6191 100644 --- a/cocos/core/platform/debug.ts +++ b/cocos/core/platform/debug.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,9 @@ /* eslint-disable no-console */ import { EDITOR, JSB, DEV, DEBUG } from 'internal:constants'; import debugInfos from '../../../DebugInfos'; -import { legacyCC } from '../global-exports'; +import { legacyCC, ccwindow } from '../global-exports'; + +const ccdocument = ccwindow.document; const ERROR_MAP_URL = 'https://github.com/cocos-creator/engine/blob/develop/EngineErrorMap.md'; @@ -47,17 +48,22 @@ let ccAssert = (condition: any, message?: any, ...optionalParams: any[]) => { let ccDebug = ccLog; +/** + * @en Format a string. + * @zh 格式化字符串。 + * @param message @zh 包含零个或多个需要替换的JavaScript字符串。@en JavaScript objects to replace substitution strings in msg. + * @param optionalParams @zh 用来替换在message中需要替换的JavaScript对象。@en JavaScript objects with which to replace substitution strings within msg. + */ function formatString (message?: any, ...optionalParams: any[]) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return legacyCC.js.formatStr.apply(null, [message].concat(optionalParams)); } /** - * @en Outputs a message to the Cocos Creator Console (editor) or Web Console (runtime). - * @zh 输出一条消息到 Cocos Creator 编辑器的 Console 或运行时 Web 端的 Console 中。 - * @param message - A JavaScript string containing zero or more substitution strings. - * @param optionalParams - JavaScript objects with which to replace substitution strings within msg. - * This gives you additional control over the format of the output. + * @en Outputs a message to the Cocos Creator Console (editor) or Web Console (runtime). This gives you additional control over the format of the output. + * @zh 输出一条消息到 Cocos Creator 编辑器的 Console 或运行时 Web 端的 Console 中。这为你提供了对输出格式的额外控制。 + * @param message @zh 包含零个或多个需要替换的JavaScript字符串。@en JavaScript objects to replace substitution strings in msg. + * @param optionalParams @zh 用来替换在message中需要替换的JavaScript对象。@en JavaScript objects with which to replace substitution strings within msg. */ export function log (message?: any, ...optionalParams: any[]) { return ccLog(message, ...optionalParams); @@ -72,8 +78,8 @@ export function log (message?: any, ...optionalParams: any[]) { * 输出警告消息到 Cocos Creator 编辑器的 Console 或运行时 Web 端的 Console 中。
* - 在 Cocos Creator 中,警告信息显示是黄色的。
* - 在 Chrome 中,警告信息有着黄色的图标以及黄色的消息文本。
- * @param message - A JavaScript string containing zero or more substitution strings. - * @param optionalParams - JavaScript objects with which to replace substitution strings within msg. + * @param message @zh 包含零个或多个需要替换的JavaScript字符串。@en JavaScript objects to replace substitution strings in msg. + * @param optionalParams @zh 用来替换在message中需要替换的JavaScript对象。@en JavaScript objects with which to replace substitution strings within msg. * This gives you additional control over the format of the output. */ export function warn (message?: any, ...optionalParams: any[]) { @@ -89,8 +95,8 @@ export function warn (message?: any, ...optionalParams: any[]) { * 输出错误消息到 Cocos Creator 编辑器的 Console 或运行时页面端的 Console 中。
* - 在 Cocos Creator 中,错误信息显示是红色的。
* - 在 Chrome 中,错误信息有红色的图标以及红色的消息文本。
- * @param message - A JavaScript string containing zero or more substitution strings. - * @param optionalParams - JavaScript objects with which to replace substitution strings within msg. + * @param message @zh 包含零个或多个需要替换的JavaScript字符串。@en JavaScript objects to replace substitution strings in msg. + * @param optionalParams @zh 用来替换在message中需要替换的JavaScript对象。@en JavaScript objects with which to replace substitution strings within msg. * This gives you additional control over the format of the output. */ export function error (message?: any, ...optionalParams: any[]) { @@ -102,9 +108,9 @@ export function error (message?: any, ...optionalParams: any[]) { * Assert the condition and output error messages if the condition is not true. * @zh * 对检查测试条件进行检查,如果条件不为 true 则输出错误消息 - * @param value - The condition to check on - * @param message - A JavaScript string containing zero or more substitution strings. - * @param optionalParams - JavaScript objects with which to replace substitution strings within msg. + * @param value @zh 需要检查的条件。 @en The condition to check on. + * @param message @zh 包含零个或多个需要替换的JavaScript字符串。@en JavaScript objects to replace substitution strings in msg. + * @param optionalParams @zh 用来替换在message中需要替换的JavaScript对象。@en JavaScript objects with which to replace substitution strings within msg. * This gives you additional control over the format of the output. */ export function assert (value: any, message?: string, ...optionalParams: any[]): asserts value { @@ -114,11 +120,15 @@ export function assert (value: any, message?: string, ...optionalParams: any[]): /** * @en Outputs a message at the "debug" log level. * @zh 输出一条“调试”日志等级的消息。 + * @param data @zh 输出的消息对象。 @en The output message object. */ export function debug (...data: any[]) { return ccDebug(...data); } +/** + * @engineInternal + */ export function _resetDebugSetting (mode: DebugMode) { // reset ccLog = ccWarn = ccError = ccAssert = ccDebug = () => { @@ -136,7 +146,7 @@ export function _resetDebugSetting (mode: DebugMode) { } if (!logList) { - const logDiv = document.createElement('Div'); + const logDiv = ccdocument.createElement('Div'); logDiv.setAttribute('id', 'logInfoDiv'); logDiv.setAttribute('width', '200'); logDiv.setAttribute('height', legacyCC.game.canvas.height); @@ -145,7 +155,7 @@ export function _resetDebugSetting (mode: DebugMode) { logDivStyle.position = 'absolute'; logDivStyle.top = logDivStyle.left = '0'; - logList = document.createElement('textarea'); + logList = ccdocument.createElement('textarea'); logList.setAttribute('rows', '20'); logList.setAttribute('cols', '30'); logList.setAttribute('disabled', 'true'); @@ -356,6 +366,8 @@ export enum DebugMode { /** * @en Gets error message with the error id and possible parameters. * @zh 通过 error id 和必要的参数来获取错误信息。 + * @param errorId @zh 错误的ID。@en Error id. + * @param param @zh 输出日志。@en Output log. */ export function getError (errorId: number, ...param: any[]): string { // eslint-disable-next-line @typescript-eslint/no-unsafe-return @@ -365,7 +377,7 @@ export function getError (errorId: number, ...param: any[]): string { /** * @en Returns whether or not to display the FPS and debug information. * @zh 是否显示 FPS 信息和部分调试信息。 - * @deprecated Since v3.6, Please use profiler.isShowingStates instead + * @deprecated @zh 从v3.6开始不再支持,请使用 profiler.isShowingStates。@en Since v3.6, Please use profiler.isShowingStates instead. */ export function isDisplayStats (): boolean { // eslint-disable-next-line @typescript-eslint/no-unsafe-return @@ -375,7 +387,7 @@ export function isDisplayStats (): boolean { /** * @en Sets whether display the FPS and debug informations on the bottom-left corner. * @zh 设置是否在左下角显示 FPS 和部分调试。 - * @deprecated Since v3.6, Please use profiler.showStats instead + * @deprecated @zh 从v3.6开始不再支持,请使用 profiler.showStats。@en Since v3.6, Please use profiler.showStats instead. */ export function setDisplayStats (displayStats: boolean) { if (legacyCC.profiler) { diff --git a/cocos/core/platform/deprecated.ts b/cocos/core/platform/deprecated.ts index aeaec72a54a..5b1fdc9b2ea 100644 --- a/cocos/core/platform/deprecated.ts +++ b/cocos/core/platform/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { markAsWarning, removeProperty, replaceProperty } from '../utils'; import { sys } from './sys'; diff --git a/cocos/core/platform/index.ts b/cocos/core/platform/index.ts index 5bad1995f68..9109c0d9f05 100644 --- a/cocos/core/platform/index.ts +++ b/cocos/core/platform/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/platform/macro.ts b/cocos/core/platform/macro.ts index c67cb306b1a..7d1007aa48f 100644 --- a/cocos/core/platform/macro.ts +++ b/cocos/core/platform/macro.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. diff --git a/cocos/core/platform/screen.ts b/cocos/core/platform/screen.ts index 99b586c83c4..dd1fb699efe 100644 --- a/cocos/core/platform/screen.ts +++ b/cocos/core/platform/screen.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -42,7 +42,8 @@ class Screen { public init () { const exactFitScreen = settings.querySettings(Settings.Category.SCREEN, 'exactFitScreen') ?? true; const orientation = settings.querySettings(Settings.Category.SCREEN, 'orientation') ?? 'auto'; - screenAdapter.init({ exactFitScreen, configOrientation: orientation }, () => { + const isHeadlessMode = settings.querySettings(Settings.Category.RENDERING, 'renderMode') === 3; + screenAdapter.init({ exactFitScreen, configOrientation: orientation, isHeadlessMode }, () => { const director = legacyCC.director; if (!director.root?.pipeline) { warnID(1220); @@ -56,7 +57,7 @@ class Screen { * @en the ratio of the resolution in physical pixels to the resolution in CSS pixels for the current display device * NOTE: For performance reasons, the engine will limit the maximum value of DPR on some platforms. * This property returns the DPR after the engine limit. - * @zh 当前显示设备的物理像素分辨率与 CSS 像素分辨率之比 + * @zh 当前显示设备的物理像素分辨率与 CSS 像素分辨率之比。 * 注意:出于性能考虑,引擎在一些平台会限制 DPR 的最高值,这个属性返回的是引擎限制后的 DPR。 */ public get devicePixelRatio () { @@ -107,8 +108,8 @@ class Screen { // } /** - * @en Whether it supports full screen? - * @zh 是否支持全屏? + * @en Whether it supports full screen. + * @zh 是否支持全屏。 * @returns {Boolean} */ public get supportsFullScreen (): boolean { @@ -117,7 +118,7 @@ class Screen { /** * @en Return true if it's in full screen state now. - * @zh 当前是否处在全屏状态下 + * @zh 当前是否处在全屏状态下。 * @returns {boolean} */ public fullScreen (): boolean { @@ -130,9 +131,9 @@ class Screen { * If failed to request fullscreen, another attempt will be made to request fullscreen the next time a user interaction occurs. * @zh 尝试使当前节点进入全屏模式,很多浏览器不允许程序触发这样的行为,必须在一个用户交互回调中才会生效。 * 如果进入全屏失败,会在下一次用户发生交互时,再次尝试进入全屏。 - * @param element The element to request full screen state - * @param onFullScreenChange callback function when full screen state changed - * @param onFullScreenError callback function when full screen error + * @param element @zh 请求全屏状态的html元素。 @en The element to request full screen state. + * @param onFullScreenChange @zh 全屏状态改变的回调函数。 @en callback function when full screen state changed. + * @param onFullScreenError @zh 全屏错误的回调函数。 @en callback function when full screen error. * @return {Promise|undefined} * @deprecated since v3.3, please use `screen.requestFullScreen(): Promise` instead. */ @@ -143,6 +144,9 @@ class Screen { * If failed to request fullscreen, another attempt will be made to request fullscreen the next time a user interaction occurs. * @zh 尝试使当前屏幕进入全屏模式,很多浏览器不允许程序触发这样的行为,必须在一个用户交互回调中才会生效。 * 如果进入全屏失败,会在下一次用户发生交互时,再次尝试进入全屏。 + * @param element @zh 请求全屏状态的html元素。 @en The element to request full screen state. + * @param onFullScreenChange @zh 全屏状态改变的回调函数。 @en callback function when full screen state changed. + * @param onFullScreenError @zh 全屏错误的回调函数。 @en callback function when full screen error. * @return {Promise} */ public requestFullScreen (): Promise; @@ -162,7 +166,7 @@ class Screen { /** * @en Exit the full mode. - * @zh 退出全屏模式 + * @zh 退出全屏模式。 * @return {Promise} */ public exitFullScreen (): Promise { @@ -170,10 +174,10 @@ class Screen { } /** - * @en Automatically request full screen during the next touch/click event - * @zh 自动监听触摸、鼠标事件并在下一次事件触发时尝试进入全屏模式 - * @param element The element to request full screen state - * @param onFullScreenChange callback function when full screen state changed + * @en Automatically request full screen during the next touch/click event. + * @zh 自动监听触摸、鼠标事件并在下一次事件触发时尝试进入全屏模式。 + * @param element @zh 请求全屏状态的html元素。 @en The element to request full screen state. + * @param onFullScreenChange @zh 全屏状态改变的回调函数。 @en callback function when full screen state changed. * * @deprecated since v3.3, please use screen.requestFullScreen() instead. */ diff --git a/cocos/core/platform/sys.ts b/cocos/core/platform/sys.ts index fcd7c3492d2..b0e39455dec 100644 --- a/cocos/core/platform/sys.ts +++ b/cocos/core/platform/sys.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -45,8 +44,8 @@ export declare namespace sys { } /** - * @en A set of system related variables - * @zh 一系列系统相关环境变量 + * @en A set of system related variables. + * @zh 一系列系统相关环境变量。 */ export const sys = { Feature, @@ -56,6 +55,7 @@ export const sys = { * Returns if the specified platform related feature is supported. * @zh * 返回指定的平台相关的特性是否支持。 + * @param feature @zh 系统的特性。 @en Feature of the system. */ hasFeature (feature: sys.Feature): boolean { return systemInfo.hasFeature(feature); @@ -63,77 +63,77 @@ export const sys = { /** * @en - * Network type enumeration + * Network type enumeration. * @zh - * 网络类型枚举 + * 网络类型枚举。 */ NetworkType, /** * @en - * LanguageCode type enumeration + * LanguageCode type enumeration. * @zh - * 语言码类型枚举 + * 语言码类型枚举。 */ Language, /** * @en - * OS type enumeration + * OS type enumeration. * @zh - * 操作系统类型枚举 + * 操作系统类型枚举。 */ OS, /** * @en - * Platform type enumeration + * Platform type enumeration. * @zh - * 平台类型枚举 + * 平台类型枚举。 */ Platform, /** * @en - * Browser type enumeration + * Browser type enumeration. * @zh - * 浏览器类型枚举 + * 浏览器类型枚举。 */ BrowserType, /** - * @en Whether the running platform is native app - * @zh 指示运行平台是否是原生平台 + * @en Whether the running platform is native app. + * @zh 指示运行平台是否是原生平台。 */ isNative: systemInfo.isNative, /** - * @en Whether the running platform is browser - * @zh 指示运行平台是否是浏览器 + * @en Whether the running platform is browser. + * @zh 指示运行平台是否是浏览器。 */ isBrowser: systemInfo.isBrowser, /** - * @en Indicate whether the current running context is a mobile system - * @zh 指示当前运行平台是否是移动端平台 + * @en Indicate whether the current running context is a mobile system. + * @zh 指示当前运行平台是否是移动端平台。 */ isMobile: systemInfo.isMobile, /** - * @en Whether the endianness of current platform is little endian - * @zh 当前平台字节顺序是否是小端序 + * @en Whether the endianness of current platform is little endian. + * @zh 当前平台字节顺序是否是小端序。 */ isLittleEndian: systemInfo.isLittleEndian, /** - * @en The running platform - * @zh 当前运行平台或环境 + * @en The running platform. + * @zh 当前运行平台或环境。 */ platform: systemInfo.platform, /** - * @en Indicate the current language of the running system - * @zh 指示当前运行环境的语言 + * @en Indicate the current language of the running system. + * @zh 指示当前运行环境的语言。 */ language: systemInfo.language, @@ -151,52 +151,52 @@ export const sys = { languageCode: systemInfo.nativeLanguage, /** - * @en Indicate the running os name - * @zh 指示当前运行系统 + * @en Indicate the running os name. + * @zh 指示当前运行系统。 */ os: systemInfo.os, /** - * @en Indicate the running os version string - * @zh 指示当前运行系统版本字符串 + * @en Indicate the running os version string. + * @zh 指示当前运行系统版本字符串。 */ osVersion: systemInfo.osVersion, /** - * @en Indicate the running os main version - * @zh 指示当前系统主版本 + * @en Indicate the running os main version. + * @zh 指示当前系统主版本。 */ osMainVersion: systemInfo.osMainVersion, /** - * @en Indicate the running browser type - * @zh 指示当前运行的浏览器类型 + * @en Indicate the running browser type. + * @zh 指示当前运行的浏览器类型。 */ browserType: systemInfo.browserType, /** - * @en Indicate the running browser version - * @zh 指示当前运行的浏览器版本 + * @en Indicate the running browser version. + * @zh 指示当前运行的浏览器版本。 */ browserVersion: systemInfo.browserVersion, /** - * @en Whether the running platform is xr app - * @zh 指示运行平台是否是XR平台 + * @en Whether the running platform is xr app. + * @zh 指示运行平台是否是XR平台。 */ isXR: systemInfo.isXR, /** - * @en Indicate the real pixel resolution of the whole game window - * @zh 指示游戏窗口的像素分辨率 + * @en Indicate the real pixel resolution of the whole game window. + * @zh 指示游戏窗口的像素分辨率。 * * @deprecated since v3.4.0, please use screen.windowSize instead. */ windowPixelResolution: screen.windowSize, /** - * @en The capabilities of the current platform - * @zh 当前平台的功能可用性 + * @en The capabilities of the current platform. + * @zh 当前平台的功能可用性。 * * @deprecated since v3.4.0, please use sys.hasFeature() instead. */ @@ -212,14 +212,15 @@ export const sys = { }, /** - * @en It is a local storage component based on HTML5 localStorage API, on web platform, it's equal to window.localStorage - * @zh HTML5 标准中的 localStorage 的本地存储功能,在 Web 端等价于 window.localStorage + * @en It is a local storage component based on HTML5 localStorage API, on web platform, it's equal to window.localStorage. + * @zh HTML5 标准中的 localStorage 的本地存储功能,在 Web 端等价于 window.localStorage。 */ localStorage: {} as Storage, /** * @en Get the network type of current device, return `sys.NetworkType.LAN` if failure. - * @zh 获取当前设备的网络类型, 如果网络类型无法获取,默认将返回 `sys.NetworkType.LAN` + * @zh 获取当前设备的网络类型, 如果网络类型无法获取,默认将返回 `sys.NetworkType.LAN`。 + * @return @zh 返回 LAN 或 WWAN。 @en LAN or WWAN. */ getNetworkType (): NetworkType { return systemInfo.networkType; @@ -227,7 +228,7 @@ export const sys = { /** * @en Get the battery level of current device, return 1.0 if failure. - * @zh 获取当前设备的电池电量,如果电量无法获取,默认将返回 1 + * @zh 获取当前设备的电池电量,如果电量无法获取,默认将返回 1。 * @return - 0.0 ~ 1.0 */ getBatteryLevel (): number { @@ -235,8 +236,8 @@ export const sys = { }, /** - * @en Forces the garbage collection, only available in native platforms - * @zh 强制进行 JS 内存垃圾回收,尽在原生平台有效 + * @en Forces the garbage collection, only available in native platforms. + * @zh 强制进行 JS 内存垃圾回收,尽在原生平台有效。 */ garbageCollect () { systemInfo.triggerGC(); @@ -247,8 +248,8 @@ export const sys = { * In web engine, it will return true if the object exist * In native engine, it will return true if the JS object and the correspond native object are both valid * @zh 检查一个对象是否非空或在原生平台有效, - * 在 Web 平台,只要对象非空或非 Undefined 就会返回 true,在原生平台,我们会检查当前 JS 对象和其绑定的原生对象是否都有效 - * @param obj The object to be checked + * 在 Web 平台,只要对象非空或非 Undefined 就会返回 true,在原生平台,我们会检查当前 JS 对象和其绑定的原生对象是否都有效。 + * @param obj @zh 校验的对象。@en The object to be checked. */ isObjectValid (obj: any): boolean { if (obj === null || obj === undefined) { @@ -259,8 +260,8 @@ export const sys = { }, /** - * @en Dump systemInfo informations - * @zh 在控制台打印当前的主要系统信息 + * @en Dump systemInfo informations. + * @zh 在控制台打印当前的主要系统信息。 */ dump () { let str = ''; @@ -268,7 +269,12 @@ export const sys = { str += `language : ${this.language}\r\n`; str += `browserType : ${this.browserType}\r\n`; str += `browserVersion : ${this.browserVersion}\r\n`; - str += `capabilities : ${JSON.stringify(this.capabilities)}\r\n`; + str += `supports webp: ${sys.hasFeature(Feature.WEBP)}\r\n`; + str += `supports bitmap: ${sys.hasFeature(Feature.IMAGE_BITMAP)}\r\n`; + str += `supports touches: ${sys.hasFeature(Feature.INPUT_TOUCH)}\r\n`; + str += `supports mouse: ${sys.hasFeature(Feature.EVENT_MOUSE)}\r\n`; + str += `supports keyboard: ${sys.hasFeature(Feature.EVENT_KEYBOARD)}\r\n`; + str += `supports accelerometer: ${sys.hasFeature(Feature.EVENT_ACCELEROMETER)}\r\n`; str += `os : ${this.os}\r\n`; str += `osVersion : ${this.osVersion}\r\n`; str += `platform : ${this.platform}\r\n`; @@ -277,56 +283,62 @@ export const sys = { }, /** - * @en Try to open a url in browser, may not work in some platforms - * @zh 尝试打开一个 web 页面,并非在所有平台都有效 + * @en Try to open a url in browser, may not work in some platforms. + * @zh 尝试打开一个 web 页面,并非在所有平台都有效。 + * @param url @zh 访问的链接。 @en Visited links. */ openURL (url) { systemInfo.openURL(url); }, /** - * @internal - */ - init () { - try { - let localStorage: Storage | null = sys.localStorage = window.localStorage; - localStorage.setItem('storage', ''); - localStorage.removeItem('storage'); - localStorage = null; - } catch (e) { - const warn = function () { - warnID(5200); - }; - this.localStorage = { - // @ts-expect-error Type '() => void' is not assignable to type '(key: string) => string | null' - getItem: warn, - setItem: warn, - clear: warn, - removeItem: warn, - }; - } - - if (WECHAT) { - // @ts-expect-error HACK: this private property only needed on web & wechat JIT - this.__isWebIOS14OrIPadOS14Env = (sys.os === OS.IOS || sys.os === OS.OSX) && GameGlobal?.isIOSHighPerformanceMode + * @engineInternal + */ + init (): Promise { + return Promise.resolve() + .then(() => systemInfo.init()) + .then(() => { + try { + let localStorage: Storage | null = sys.localStorage = window.localStorage; + localStorage.setItem('storage', ''); + localStorage.removeItem('storage'); + localStorage = null; + } catch (e) { + const warn = function () { + warnID(5200); + }; + this.localStorage = { + // @ts-expect-error Type '() => void' is not assignable to type '(key: string) => string | null' + getItem: warn, + setItem: warn, + clear: warn, + removeItem: warn, + }; + } + + if (WECHAT) { + // @ts-expect-error HACK: this private property only needed on web & wechat JIT + this.__isWebIOS14OrIPadOS14Env = (sys.os === OS.IOS || sys.os === OS.OSX) && GameGlobal?.isIOSHighPerformanceMode && /(OS 1((4\.[0-9])|(5\.[0-3])))|(Version\/1((4\.[0-9])|(5\.[0-3])))/.test(window.navigator.userAgent); - } else { - // @ts-expect-error HACK: this private property only needed on web & wechat JIT - this.__isWebIOS14OrIPadOS14Env = (sys.os === OS.IOS || sys.os === OS.OSX) && systemInfo.isBrowser + } else { + // @ts-expect-error HACK: this private property only needed on web & wechat JIT + this.__isWebIOS14OrIPadOS14Env = (sys.os === OS.IOS || sys.os === OS.OSX) && systemInfo.isBrowser && /(OS 14)|(Version\/14)/.test(window.navigator.userAgent); - } + } + }); }, /** - * @en Get the current time in milliseconds - * @zh 获取当前时间(毫秒为单位) + * @en Get the current time in milliseconds. + * @zh 获取当前时间(毫秒为单位)。 */ now () { return systemInfo.now(); }, /** - * Restart the JS VM, only available in native platforms + * @en Restart the JS VM, only available in native platforms. + * @zh 重启JS虚拟机,仅仅在原生平台有效。 * @private */ restartVM () { @@ -339,7 +351,8 @@ export const sys = { * If the screen is not notched, this method returns a Rect of the same size as visibleSize by default. * Currently supports Android, iOS and WeChat, ByteDance Mini Game platform. * @zh - * 返回基于游戏视图坐标系的手机屏幕安全区域(设计分辨率为单位),如果不是异形屏将默认返回一个和 visibleSize 一样大的 Rect。目前支持安卓、iOS 原生平台和微信、字节小游戏平台。 + * 返回基于游戏视图坐标系的手机屏幕安全区域(设计分辨率为单位),如果不是异形屏将默认返回一个和 visibleSize 一样大的 Rect。 + * 目前支持安卓、iOS 原生平台和微信、字节小游戏平台。 * @method getSafeAreaRect * @return {Rect} */ diff --git a/cocos/core/platform/visible-rect.ts b/cocos/core/platform/visible-rect.ts index d66ffd38487..dc56a446dbe 100644 --- a/cocos/core/platform/visible-rect.ts +++ b/cocos/core/platform/visible-rect.ts @@ -1,16 +1,16 @@ /* Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -28,66 +28,82 @@ import { Rect } from '../math'; import { legacyCC } from '../global-exports'; /** - * `visibleRect` is a singleton object which defines the actual visible rect of the current view + * @zh `visibleRect` is a singleton object which defines the actual visible rect of the current view. + * @en `visibleRect` 是一个定义当前视图的实际可见矩形的单例对象。 + * @engineInternal */ -const visibleRect = { +export const visibleRect = { /** - * Top left coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕左上方坐标。 + * @en Top left coordinate of the screen related to the game scene. */ topLeft: legacyCC.v2(0, 0), /** - * Top right coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕右上方坐标。 + * @en Top right coordinate of the screen related to the game scene. */ topRight: legacyCC.v2(0, 0), /** - * Top center coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕上方中心坐标。 + * @en Top center coordinate of the screen related to the game scene. */ top: legacyCC.v2(0, 0), /** - * Bottom left coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕左下坐标。 + * @en Bottom left coordinate of the screen related to the game scene. */ bottomLeft: legacyCC.v2(0, 0), /** - * Bottom right coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕右下坐标。 + * @en Bottom right coordinate of the screen related to the game scene. */ bottomRight: legacyCC.v2(0, 0), /** - * Bottom center coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕下方中心坐标。 + * @en Bottom center coordinate of the screen related to the game scene. */ bottom: legacyCC.v2(0, 0), /** - * Center coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕中心坐标。 + * @en Center coordinate of the screen related to the game scene. */ center: legacyCC.v2(0, 0), /** - * Left center coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕左边中心坐标。 + * @en Left center coordinate of the screen related to the game scene. */ left: legacyCC.v2(0, 0), /** - * Right center coordinate of the screen related to the game scene. + * @zh 与游戏场景有关的屏幕右边中心坐标。 + * @en Right center coordinate of the screen related to the game scene. */ right: legacyCC.v2(0, 0), /** - * Width of the screen. + * @zh 屏幕宽度。 + * @en Width of the screen. */ width: 0, /** - * Height of the screen. + * @zh 屏幕高度。 + * @en Height of the screen. */ height: 0, /** - * initialize + * @zh 初始化函数。 + * @en Initialization function. + * @param visibleRect_ @zh 当前视图的实际可见区域。@en The actual visible area of the current view. + * @NOTE: @zh 必须是有效的区域。例如区域大小不能为负数。@en It must be a valid region. For example, the region size cannot be negative. */ init (visibleRect_: Rect) { const w = this.width = visibleRect_.width; @@ -128,4 +144,3 @@ const visibleRect = { }; legacyCC.visibleRect = visibleRect; -export default visibleRect; diff --git a/cocos/core/scheduler.ts b/cocos/core/scheduler.ts index 348e460d113..46b8ae23161 100644 --- a/cocos/core/scheduler.ts +++ b/cocos/core/scheduler.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,30 +23,26 @@ THE SOFTWARE. */ -import IdGenerator from './utils/id-generator'; +import { IDGenerator } from './utils/id-generator'; import { createMap } from './utils/js'; -import System from './system'; +import { System } from './system'; import { legacyCC } from './global-exports'; import { errorID, warnID, logID, assertID } from './platform/debug'; const MAX_POOL_SIZE = 20; -const idGenerator = new IdGenerator('Scheduler'); +const idGenerator = new IDGenerator('Scheduler'); export interface ISchedulable { - id?:string; - uuid?:string; + id?: string; + uuid?: string; } // data structures /** - * @en A list double-linked list used for "updates with priority" - * @zh 用于“优先更新”的列表 + * @en A list double-linked list used for "updates with priority". + * @zh 用于“优先更新”的列表。 * @class ListEntry - * @param target not retained (retained by hashUpdateEntry) - * @param priority - * @param paused - * @param markedForDeletion selector will no longer be called and entry will be removed at end of the next tick */ class ListEntry { public static get = (target: ISchedulable, priority: number, paused: boolean, markedForDeletion: boolean) => { @@ -77,6 +72,22 @@ class ListEntry { public paused: boolean; public markedForDeletion: boolean; + /** + * @en The constructor of ListEntry. + * @zh ListEntry 的构造函数。 + * @param target + * @en Target object, which is ISchedulable type, retained by hashUpdateEntry. + * @zh 目标对象, 为ISchedulable类型. 被hashUpdateEntry持有。 + * @param priority + * @en The priority. + * @zh 优先级。 + * @param paused + * @en Whether is paused. + * @zh 是否被暂停。 + * @param markedForDeletion + * @en Mark for deletion. if true, selector will no longer be called and entry will be removed at end of the next tick. + * @zh 删除标记, 当为true时, selector 将不再被调用,并且entry将在下一个tick结束时被删除。 + */ constructor (target: ISchedulable, priority: number, paused: boolean, markedForDeletion: boolean) { this.target = target; this.priority = priority; @@ -86,13 +97,13 @@ class ListEntry { } /** - * @en A update entry list - * @zh 更新条目列表 + * @en The update entry list. + * @zh 更新条目列表。 * @class HashUpdateEntry - * @param list Which list does it belong to ? - * @param entry entry in the list - * @param target hash key (retained) - * @param callback + * @param list @en Which list does it belong to. @zh 所属的列表。 + * @param entry @en Entry in the list. @zh 所述的条目。 + * @param target @en Hash key (retained). @zh 哈希键所对应的目标(被持有的)。 + * @param callback @en The callback function. @zh 所回调的函数。 */ class HashUpdateEntry { public static get = (list: any, entry: ListEntry, target: ISchedulable, callback: any) => { @@ -131,8 +142,8 @@ class HashUpdateEntry { } /** - * @en Hash Element used for "selectors with interval" - * @zh “用于间隔选择”的哈希元素 + * @en Hash Element used for "selectors with interval". + * @zh “用于间隔选择”的哈希元素。 * @param timers * @param target hash key (retained) * @param timerIndex @@ -237,23 +248,29 @@ class CallbackTimer { return true; } /** - * @return returns interval of timer + * @en get interval for timer in seconds. + * @zh 获取计时器的时间间隔, 以秒为单位。 + * @returns + * @en returns interval of timer in seconds. + * @zh 返回计时器的时间间隔, 以秒为单位。 */ public getInterval () { return this._interval; } /** - * @en Set interval in seconds - * @zh 以秒为单位设置时间间隔 + * @en Set interval in seconds. + * @zh 以秒为单位设置时间间隔。 */ public setInterval (interval) { this._interval = interval; } /** - * @en Update function which triggers the timer - * @zh 计时更新函数,用来触发计时器 - * @param dt delta time + * @en Update function which triggers the timer. + * @zh 计时更新函数,用来触发计时器。 + * @param dt + * @en delta time. The unit is seconds. + * @zh 更新间隔时间, 单位是秒。 */ public update (dt: number) { if (this._elapsed === -1) { @@ -315,7 +332,7 @@ class CallbackTimer { *
* There are 2 different types of callbacks (selectors):
* - update callback: the 'update' callback will be called every frame. You can customize the priority.
- * - custom callback: A custom callback will be called every frame, or with a custom interval of time
+ * - custom callback: A custom callback will be called every frame, or with a custom interval of time.
*
* The 'custom selectors' should be avoided when possible. It is faster,
* and consumes less memory to use the 'update callback'. * @@ -347,6 +364,8 @@ export class Scheduler extends System { * @zh 任何需要用 Scheduler 管理任务的对象主体都应该调用这个方法,并且应该在调用任何 Scheduler API 之前调用这个方法。 * 这个方法会给对象添加一个 `id` 属性,如果这个属性不存在的话。 * @param target + * @en The target to enable, which type is ISchedulable. + * @zh 所作用的对象。类型为ISchedulable。 */ public static enableForTarget (target: ISchedulable) { let found = false; @@ -413,7 +432,9 @@ export class Scheduler extends System { /** * @en 'update' the scheduler. (You should NEVER call this method, unless you know what you are doing.) * @zh update 调度函数。(不应该直接调用这个方法,除非完全了解这么做的结果) - * @param dt delta time + * @param dt + * @en delta time. The unit is seconds. + * @zh 更新间隔时间, 单位是秒。 */ public update (dt) { this._updateHashLocked = true; @@ -451,7 +472,7 @@ export class Scheduler extends System { let elt; const arr = this._arrayForTimers; for (i = 0; i < arr.length; i++) { - elt = arr[i]; + elt = arr[i] as HashTimerEntry; this._currentTarget = elt; this._currentTargetSalvaged = false; @@ -507,31 +528,30 @@ export class Scheduler extends System { } /** - * @en - *

- * The scheduled method will be called every 'interval' seconds.
- * If paused is YES, then it won't be called until it is resumed.
- * If 'interval' is 0, it will be called every frame, but if so, it recommended to use 'scheduleUpdateForTarget:' instead.
- * If the callback function is already scheduled, then only the interval parameter will be updated without re-scheduling it again.
- * repeat let the action be repeated repeat + 1 times, use `macro.REPEAT_FOREVER` to let the action run continuously
- * delay is the amount of time the action will wait before it'll start. Unit: s
- *

- * @zh - * 指定回调函数,调用对象等信息来添加一个新的定时器。
- * 如果 paused 值为 true,那么直到 resume 被调用才开始计时。
- * 当时间间隔达到指定值时,设置的回调函数将会被调用。
- * 如果 interval 值为 0,那么回调函数每一帧都会被调用,但如果是这样, - * 建议使用 scheduleUpdateForTarget 代替。
- * 如果回调函数已经被定时器使用,那么只会更新之前定时器的时间间隔参数,不会设置新的定时器。
- * repeat 值可以让定时器触发 repeat + 1 次,使用 `macro.REPEAT_FOREVER` - * 可以让定时器一直循环触发。
- * delay 值指定延迟时间,定时器会在延迟指定的时间之后开始计时,单位: 秒。 + * @en Specify the callback, target and other information to schedule a new timer. + * @zh 指定回调函数,调用对象等信息来规划一个新的定时器。 * @param callback + * @en The specified callback function. + * If the callback function is already scheduled, then only the interval parameter will be updated without re-scheduling it again. + * @zh 所指定的回调函数。 + * 如果回调函数已经被定时器使用,那么只会更新之前定时器的时间间隔参数,不会设置新的定时器。 * @param target + * @en The specified target. + * @zh 所指定的调用对象。 * @param interval + * @en The scheduled method will be called every 'interval' seconds. + * If 'interval' is 0, it will be called every frame, but if so, it recommended to use 'scheduleUpdateForTarget:' instead. + * @zh 当时间间隔达到指定值时,设置的回调函数将会被调用。 + * 如果 interval 值为 0,那么回调函数每一帧都会被调用,但如果是这样,建议使用 scheduleUpdateForTarget 代替。 * @param [repeat] + * @en repeat let the action be repeated repeat + 1 times, use `macro.REPEAT_FOREVER` to let the action run continuously. + * @zh repeat 值可以让定时器触发 repeat + 1 次,使用 `macro.REPEAT_FOREVER` 可以让定时器一直循环触发。 * @param [delay=0] - * @param [paused=fasle] + * @en delay is the amount of time the action will wait before it'll start. Unit: s. + * @zh delay 值指定延迟时间,定时器会在延迟指定的时间之后开始计时,单位: 秒。 + * @param [paused=false] + * @en If paused is YES, then it won't be called until it is resumed. + * @zh 如果 paused 值为 true,那么直到 resume 被调用才开始计时。 */ public schedule (callback: (dt?: number) => void, target: ISchedulable, interval: number, repeat?: number, delay?: number, paused?: boolean) { if (typeof callback !== 'function') { @@ -555,7 +575,7 @@ export class Scheduler extends System { errorID(1510); return; } - let element = this._hashForTimers[targetId]; + let element = this._hashForTimers[targetId] as HashTimerEntry; if (!element) { // Is this the 1st element ? Then set the pause level to all the callback_fns of this target element = HashTimerEntry.get(null, target, 0, null, null, paused); @@ -598,8 +618,11 @@ export class Scheduler extends System { * update 定时器每一帧都会被触发,触发时自动调用指定对象的 "update" 函数。
* 优先级的值越低,定时器被触发的越早。 * @param target + * @en The target bound to the callback. @zh 回调所绑定的目标对象。 * @param priority + * @en The priority. @zh 优先级。 * @param paused + * @en Whether is paused. @zh 是否被暂停。 */ public scheduleUpdate (target: ISchedulable, priority: number, paused: boolean) { const targetId = target.uuid || target.id; @@ -646,15 +669,15 @@ export class Scheduler extends System { /** * @en - * Unschedules a callback for a callback and a given target. + * Unschedule a callback for a callback and a given target. * If you want to unschedule the "update", use `unscheduleUpdate()` * @zh * 取消指定对象定时器。 * 如果需要取消 update 定时器,请使用 unscheduleUpdate()。 - * @param callback The callback to be unscheduled - * @param target The target bound to the callback. + * @param callback @en The callback to be unscheduled @zh 被取消调度的回调。 + * @param target @en The target bound to the callback. @zh 回调所绑定的目标对象。 */ - public unschedule (callback, target:ISchedulable) { + public unschedule (callback, target: ISchedulable) { // callback, target // explicity handle nil arguments when removing an object @@ -697,11 +720,11 @@ export class Scheduler extends System { } /** - * @en Unschedules the update callback for a given target. + * @en Unschedule the update callback for a given target. * @zh 取消指定对象的 update 定时器。 * @param target The target to be unscheduled. */ - public unscheduleUpdate (target:ISchedulable) { + public unscheduleUpdate (target: ISchedulable) { if (!target) { return; } @@ -723,7 +746,7 @@ export class Scheduler extends System { /** * @en - * Unschedules all scheduled callbacks for a given target. + * Unschedule all scheduled callbacks for a given target. * This also includes the "update" callback. * @zh 取消指定对象的所有定时器,包括 update 定时器。 * @param target The target to be unscheduled. @@ -765,10 +788,10 @@ export class Scheduler extends System { /** * @en - * Unschedules all scheduled callbacks from all targets including the system callbacks.
+ * Unschedule all scheduled callbacks from all targets including the system callbacks. * You should NEVER call this method, unless you know what you are doing. * @zh - * 取消所有对象的所有定时器,包括系统定时器。
+ * 取消所有对象的所有定时器,包括系统定时器。 * 不要调用此函数,除非你确定你在做什么。 */ public unscheduleAll () { @@ -777,13 +800,16 @@ export class Scheduler extends System { /** * @en - * Unschedules all callbacks from all targets with a minimum priority.
+ * Unschedule all callbacks from all targets with a minimum priority. * You should only call this with `PRIORITY_NON_SYSTEM_MIN` or higher. * @zh - * 取消所有优先级的值大于指定优先级的定时器。
+ * 取消所有优先级的值大于指定优先级的定时器。 * 你应该只取消优先级的值大于 PRIORITY_NON_SYSTEM_MIN 的定时器。 - * @param minPriority The minimum priority of selector to be unscheduled. Which means, all selectors which - * priority is higher than minPriority will be unscheduled. + * @param minPriority + * @en The minimum priority of selector to be unscheduled. + * Which means, all selectors which priority is higher than minPriority will be unscheduled. + * @zh 要取消调度的选择器的最低优先级。 + * 这意味着,所有优先级高于 minPriority 的选择器将被取消调度。 */ public unscheduleAllWithMinPriority (minPriority: number) { // Custom Selectors @@ -791,7 +817,7 @@ export class Scheduler extends System { let element; const arr = this._arrayForTimers; for (i = arr.length - 1; i >= 0; i--) { - element = arr[i]; + element = arr[i] as HashTimerEntry; this.unscheduleAllForTarget(element.target); } @@ -839,11 +865,11 @@ export class Scheduler extends System { /** * @en Checks whether a callback for a given target is scheduled. * @zh 检查指定的回调函数和回调对象组合是否存在定时器。 - * @param callback The callback to check. - * @param target The target of the callback. - * @return True if the specified callback is invoked, false if not. + * @param callback @en The callback to check. @zh 指定检测的回调。 + * @param target @en The target of the callback. @zh 回调的目标对象。 + * @returns @en True if the specified callback is invoked, false if not. @zh 返回true如果指定回调被调用, 否则返回false。 */ - public isScheduled (callback, target:ISchedulable) : boolean { + public isScheduled (callback, target: ISchedulable): boolean { // key, target // selector, target assertID(callback, 1508); @@ -877,10 +903,10 @@ export class Scheduler extends System { /** * @en - * Pause all selectors from all targets.
+ * Pause all selectors from all targets. * You should NEVER call this method, unless you know what you are doing. * @zh - * 暂停所有对象的所有定时器。
+ * 暂停所有对象的所有定时器。 * 不要调用这个方法,除非你知道你正在做什么。 */ public pauseAllTargets () { @@ -889,12 +915,12 @@ export class Scheduler extends System { /** * @en - * Pause all selectors from all targets with a minimum priority.
+ * Pause all selectors from all targets with a minimum priority. * You should only call this with kCCPriorityNonSystemMin or higher. * @zh - * 暂停所有优先级的值大于指定优先级的定时器。
+ * 暂停所有优先级的值大于指定优先级的定时器。 * 你应该只暂停优先级的值大于 PRIORITY_NON_SYSTEM_MIN 的定时器。 - * @param minPriority + * @param minPriority @en the minimum priority. @zn 最小优先级。 */ public pauseAllTargetsWithMinPriority (minPriority: number) { const idsWithSelectors: ISchedulable[] = []; @@ -978,7 +1004,7 @@ export class Scheduler extends System { * 如果指定的对象没有定时器,什么也不会发生。 * @param target */ - public pauseTarget (target:ISchedulable) { + public pauseTarget (target: ISchedulable) { assertID(target, 1503); const targetId = target.uuid || target.id; if (!targetId) { @@ -1010,7 +1036,7 @@ export class Scheduler extends System { * 如果指定的对象没有定时器,什么也不会发生。 * @param target */ - public resumeTarget (target:ISchedulable) { + public resumeTarget (target: ISchedulable) { assertID(target, 1504); const targetId = target.uuid || target.id; if (!targetId) { @@ -1036,7 +1062,7 @@ export class Scheduler extends System { * @zh 返回指定对象的定时器是否处于暂停状态。 * @param target */ - public isTargetPaused (target:ISchedulable) { + public isTargetPaused (target: ISchedulable) { assertID(target, 1505); const targetId = target.uuid || target.id; if (!targetId) { @@ -1045,13 +1071,13 @@ export class Scheduler extends System { } // Custom selectors - const element = this._hashForTimers[targetId]; + const element = this._hashForTimers[targetId] as HashTimerEntry; if (element) { - return element.paused; + return element.paused as boolean; } const elementUpdate = this._hashForUpdates[targetId]; if (elementUpdate) { - return elementUpdate.entry.paused; + return elementUpdate.entry.paused as boolean; } return false; } diff --git a/cocos/core/settings.ts b/cocos/core/settings.ts index cc397149b42..3d06ea62944 100644 --- a/cocos/core/settings.ts +++ b/cocos/core/settings.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { HTML5 } from 'internal:constants'; +import { HTML5, TAOBAO } from 'internal:constants'; import { legacyCC } from './global-exports'; declare const fsUtils: any; @@ -47,6 +46,7 @@ enum Category { ANIMATION = 'animation', PROFILING = 'profiling', PLUGINS = 'plugins', + XR = 'xr', } /** @@ -76,12 +76,24 @@ export class Settings { if (!path) return Promise.resolve(); return new Promise((resolve, reject) => { if (!HTML5 && !path.startsWith('http')) { - const result = fsUtils.readJsonSync(path); - if (result instanceof Error) { - reject(result); + // TODO: readJsonSync not working on Taobao IDE + if (TAOBAO) { + globalThis.fsUtils.readJson(path, (err, result) => { + if (err) { + reject(err); + return; + } + this._settings = result; + resolve(); + }); } else { - this._settings = result; - resolve(); + const result = fsUtils.readJsonSync(path); + if (result instanceof Error) { + reject(result); + } else { + this._settings = result; + resolve(); + } } } else { const xhr = new XMLHttpRequest(); diff --git a/cocos/core/system.ts b/cocos/core/system.ts index c144f65f00e..741ed750a91 100644 --- a/cocos/core/system.ts +++ b/cocos/core/system.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -30,7 +29,7 @@ import { Enum } from './value-types/enum'; * @en Base class for all functional system managed by [[Director]]. * @zh 功能系统的基类,由 [[Director]] 管理。 */ -export default class System implements ISchedulable { +export class System implements ISchedulable { static Priority = Enum({ LOW: 0, MEDIUM: 100, diff --git a/cocos/core/utils/array.ts b/cocos/core/utils/array.ts index 2c597e8bed2..01d7c75cbfb 100644 --- a/cocos/core/utils/array.ts +++ b/cocos/core/utils/array.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,8 +31,8 @@ export { default as MutableForwardIterator } from './mutable-forward-iterator'; * 移除指定索引的数组元素。 * @en * Removes the array item at the specified index. - * @param array 数组。 - * @param index 待移除元素的索引。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param index @zh 待移除元素的索引。@en The index of the element to be removed. */ export function removeAt (array: T[], index: number) { array.splice(index, 1); @@ -46,8 +45,8 @@ export function removeAt (array: T[], index: number) { * @en * Removes the array item at the specified index. * It's faster but the order of the array will be changed. - * @param array 数组。 - * @param index 待移除元素的索引。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param index @zh 待移除元素的索引。@en The index of the element to be removed. */ export function fastRemoveAt (array: T[], index: number) { const length = array.length; @@ -64,8 +63,8 @@ export function fastRemoveAt (array: T[], index: number) { * @en * Removes the first occurrence of a specific object from the array. * Decision of the equality of elements is similar to `Array.prototype.indexOf`. - * @param array 数组。 - * @param value 待移除元素。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param value @zh 待移除元素。@en The value to be removed. */ export function remove (array: T[], value: T) { const index = array.indexOf(value); @@ -85,8 +84,8 @@ export function remove (array: T[], value: T) { * Removes the first occurrence of a specific object from the array. * Decision of the equality of elements is similar to `Array.prototype.indexOf`. * It's faster but the order of the array will be changed. - * @param array 数组。 - * @param value 待移除元素。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param value @zh 待移除元素。@en The value to be removed. */ export function fastRemove (array: T[], value: T) { const index = array.indexOf(value); @@ -101,8 +100,8 @@ export function fastRemove (array: T[], value: T) { * 移除首个使谓词满足的数组元素。 * @en * Removes the first occurrence of a specific object from the array where `predicate` is `true`. - * @param array 数组。 - * @param predicate 谓词。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param predicate @zh 一元谓词,如果要元素的话,需要返回 true。@en unary predicate which returns true if the element should be removed. */ export function removeIf (array: T[], predicate: (value: T) => boolean) { const index = array.findIndex(predicate); @@ -120,9 +119,9 @@ export function removeIf (array: T[], predicate: (value: T) => boolean) { * @en * Verify array's Type. * This function tests each element using `instanceof` operator. - * @param array 数组。 - * @param type 类型。 - * @returns 当每一个元素都是指定类型时返回 `true`,否则返回 `false`。 + * @param array @zh 待验证的数组。@en The array to be verified. + * @param type @zh 用来判断数组元素的数据类型。@en The type used to verify the element type. + * @returns @zh 当每一个元素都是指定类型时返回 `true`,否则返回 `false`。@en Return true if all elements of the array is the same type, false others. */ export function verifyType (array: any[], type: T): array is T[] { if (array && array.length > 0) { @@ -141,8 +140,9 @@ export function verifyType (array: any[], type: T): array is * 移除多个数组元素。 * @en * Removes multiple array elements. - * @param array 源数组。 - * @param removals 所有待移除的元素。此数组的每个元素所对应的首个源数组的元素都会被移除。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param removals @zh 所有待移除的元素。此数组的每个元素所对应的首个源数组的元素都会被移除。 + * @en The values to be removed. If a value appears multiple times in the array, only the first math element will be removed. */ export function removeArray (array: T[], removals: T[]) { for (let i = 0, l = removals.length; i < l; i++) { @@ -155,10 +155,10 @@ export function removeArray (array: T[], removals: T[]) { * 在数组的指定索引上插入对象。 * @en * Inserts some objects at specified index. - * @param array 数组。 - * @param objects 插入的所有对象。 - * @param index 插入的索引。 - * @returns `array`。 + * @param array @zh 被操作的数组。@en The array to be operated. + * @param objects @zh 插入的所有对象。@en The objects to be inserted. + * @param index @zh 插入的索引。@en The index to insert at. + * @returns @zh 传入的 `array`。@en The passed in `array`. */ export function appendObjectsAt (array: T[], objects: T[], index: number) { array.splice.apply(array, [index, 0, ...objects]); @@ -170,7 +170,9 @@ export function appendObjectsAt (array: T[], objects: T[], index: number) { * 返回数组是否包含指定的元素。 * @en * Determines whether the array contains a specific element. - * @returns 返回数组是否包含指定的元素。 + * @param array @zh 被查询的数组 @en The array to be checked. + * @param value @zh 用来查询的值 @en The value used to check for. + * @returns @zh true 如果包含该元素,否则返回 false。@en true if contains the value, false else. */ export function contains (array: T[], value: T) { return array.indexOf(value) >= 0; @@ -181,8 +183,8 @@ export function contains (array: T[], value: T) { * 拷贝数组。 * @en * Copy an array. - * @param 源数组。 - * @returns 数组的副本。 + * @param array @zh 用来拷贝的数组。@en The array to be copied from. + * @returns @zh 数组的副本。@en A new array has the same values as `array`. */ export function copy (array: T[]) { const len = array.length; diff --git a/cocos/core/utils/coordinates-converts-utils.ts b/cocos/core/utils/coordinates-converts-utils.ts index 42a9413e938..0ccd3fce0cc 100644 --- a/cocos/core/utils/coordinates-converts-utils.ts +++ b/cocos/core/utils/coordinates-converts-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Camera } from '../../misc/camera-component'; import { Vec3 } from '../math'; diff --git a/cocos/core/utils/decode-uuid.ts b/cocos/core/utils/decode-uuid.ts index 4d21bd16dae..0b270679e63 100644 --- a/cocos/core/utils/decode-uuid.ts +++ b/cocos/core/utils/decode-uuid.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,21 +27,23 @@ import { TEST } from 'internal:constants'; import { BASE64_VALUES } from './misc'; import { legacyCC } from '../global-exports'; +const separator = '@'; + const HexChars = '0123456789abcdef'.split(''); const _t = ['', '', '', '']; const UuidTemplate = _t.concat(_t, '-', _t, '-', _t, '-', _t, '-', _t, _t, _t); -const Indices = UuidTemplate.map((x, i) => (x === '-' ? NaN : i)).filter(isFinite); +const Indices = UuidTemplate.map((x, i) => (x === '-' ? NaN : i)).filter(Number.isFinite); /** * @en - * Decode uuid, returns the original uuid + * Decode base64-compressed uuid. * * @zh - * 解码 uuid,返回原始 uuid + * 解码用 base64 压缩过的 uuid。 * - * @param base64 - the encoded uuid - * @returns the original uuid + * @param base64 @en Base-64 compressed uuid. @zh 用 base-64 压缩过的 uuid。 + * @returns @en Original uuid. @zh 未压缩过的 uuid。 * * @example * ```ts @@ -51,7 +52,7 @@ const Indices = UuidTemplate.map((x, i) => (x === '-' ? NaN : i)).filter(isFinit * ``` */ export default function decodeUuid (base64: string) { - const strs = base64.split('@'); + const strs = base64.split(separator); const uuid = strs[0]; if (uuid.length !== 22) { return base64; diff --git a/cocos/core/utils/deprecated-3.6.0.ts b/cocos/core/utils/deprecated-3.6.0.ts index 34da21b7572..40096f8c8ca 100644 --- a/cocos/core/utils/deprecated-3.6.0.ts +++ b/cocos/core/utils/deprecated-3.6.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { deprecateModuleExportedName } from './x-deprecated'; diff --git a/cocos/core/utils/id-generator.ts b/cocos/core/utils/id-generator.ts index a584ccf9c44..07761d7e6aa 100644 --- a/cocos/core/utils/id-generator.ts +++ b/cocos/core/utils/id-generator.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,9 +31,9 @@ const NonUuidMark = '.'; * ID generator for runtime. * * @zh - * 运行时 ID 生成器 + * 运行时 ID 生成器。 */ -export default class IDGenerator { +export class IDGenerator { /** * @en * The global id generator might have a conflict problem once every 365 days, @@ -45,26 +44,42 @@ export default class IDGenerator { */ public static global = new IDGenerator('global'); + /** + * @en A number to record current id. It may increase when invoke `getNewId()`. Should use + * `getNewId()` to get a unique id. + * @zh 记录当前 id 值。调用 `getNewId()` 时,它可能被加1。应该使用 `getNewId()` 获取唯一的 id。 + */ public id: number; + /** + * @en A string value indicates the category this IDGenerator belongs to. It will be an empty + * string if not be assigned by passed parameter in constructor. + * @zh 用于标识该 IDGenerator 所属的类别。如果构造函数没有传参数对它赋值的话,它将是一个空字符串。 + */ public prefix: string; /** - * @en Construct a new id generator - * @zh 构造一个新的 id 生成器 + * @en Construct a new id generator. + * @zh 构造一个新的 id 生成器。 * - * @param [category] @en You can specify a unique category to avoid id collision with other instance of IdGenerator. @zh 你能指定一个唯一的标识用于避免与其他 id 生成器冲突 + * @param category @en You can specify a unique category to avoid id collision with other instance of IdGenerator. + * @zh 你能指定一个唯一的标识用于避免与其他 id 生成器冲突。 */ constructor (category?: string) { - // Tnit with a random id to emphasize that the returns id should not be stored in persistence data. + // Initialize with a random id to emphasize that the returns id should not be stored in persistence data. this.id = 0 | (Math.random() * 998); this.prefix = category ? (category + NonUuidMark) : ''; } + /** + * @en Gets a unique id. @zh 获取唯一的 id。 + * @returns @en The unique id. It has the form `prefix+id`, for example `scene55`, `scene` is `prefix`, `55` is `id`. + * @zh 唯一的 id。它的形式是 `prefix+id`,比如 `scene55`,`scene` 是 prefix,`55` 是 `id`。 + */ public getNewId () { if (EDITOR && (this.prefix === 'Node.' || this.prefix === 'Comp.')) { return EditorExtends.UuidUtils.uuid(); } - return this.prefix + (++this.id); + return this.prefix + (++this.id).toString(); } } diff --git a/cocos/core/utils/index.ts b/cocos/core/utils/index.ts index 93e813152d1..9167f05d6ce 100644 --- a/cocos/core/utils/index.ts +++ b/cocos/core/utils/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,12 +27,12 @@ import './deprecated-3.6.0'; import * as js from './js'; /** - * 杂项工具函数 + * Some useful functions. */ import * as misc from './misc'; /** - * 用于处理文件与目录的路径的模块 + * A module to handle files and directories. */ import * as path from './path'; @@ -46,6 +45,3 @@ export { }; export * from './coordinates-converts-utils'; - -// export const js = cc.js; -// export const path = cc.path; diff --git a/cocos/core/utils/internal.ts b/cocos/core/utils/internal.ts new file mode 100644 index 00000000000..b1bdf67ab56 --- /dev/null +++ b/cocos/core/utils/internal.ts @@ -0,0 +1,100 @@ +/** + * @zh + * 重命名对象[自身的、可枚举的](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable)指定属性,并且保持原本的属性顺序。 + * @en + * Renames an [enumerable own](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable) + * property but also retains the original property order. + * + * @param object @zh 原始对象。 @en The original object. + * @param originalPropertyKey @zh 要重命名的属性的原始键。@en Original key of the property to rename. + * @param newPropertyKey @zh 要重命名的属性的新键。@en New key of the property to rename. + * @returns + * @zh 若重命名成功,返回新的对象;否则返回原始对象。 + * @en A new object which is a copy of original object if rename succeed, otherwise the original object. + * + * @description + * @zh + * 若原始键不存在、原始属性不是自身可枚举属性或新键已存在,此函数视重命名为失败,会直接返回原始对象。 + * 若可以重命名,则此函数返回原始对象的 **拷贝**。 + * 在拷贝时,使用 `[[Set]]` 语义,且仅会拷贝那些自身的、可枚举的属性,因此,本函数更适合用来重命名纯字典对象的属性。 + * @en + * If the original key does not exist, + * or the original property is not enumerable own property, + * or the new property has already existed, + * this function treats the renaming as failure and returns the original object directly. + * Otherwise, the rename succeeds, this function returns a **copy** of original object. + * For the copying, `[[Set]]` semantic would be used. Only those enumerable own properties would be copied. + * That's why this function is suggested to used to rename properties of pure dictionary objects. + * + * @example + * @zh + * ```ts + * // 成功重命名,属性顺序保留 + * const original = { a: 1, b: 2, c: 3 }; + * Object.defineProperty(original, 'x', { value: '', enumerable: false }); + * console.log(original); // {a: 1, b: 2, c: 3, x: ''} + * + * const renamed = renameObjectProperty(original, 'b', 'd'); + * console.log(original === renamed) // false + * console.log(original); // {a: 1, d: 2, c: 3} + * console.log(Object.entries(renamed)) // [['a', 1], ['d', 2], ['c', 3]] + * + * // 重命名失败:原始键不存在 + * console.log(renameObjectProperty(original, 'e', 'f') === original); // true + * // 重命名失败:新键已存在 + * console.log(renameObjectProperty(original, 'e', 'a') === original); // true + * // 重命名失败:原始键对应的属性不是自身可枚举的 + * console.log(renameObjectProperty(original, 'x', 'x1') === original); // true + * ``` + * @en + * ```ts + * // Rename succeed, key order is retained. + * const original = { a: 1, b: 2, c: 3 }; + * Object.defineProperty(original, 'x', { value: '', enumerable: false }); + * console.log(original); // {a: 1, b: 2, c: 3, x: ''} + * + * const renamed = renameObjectProperty(original, 'b', 'd'); + * console.log(original === renamed) // false + * console.log(original); // {a: 1, d: 2, c: 3} + * console.log(Object.entries(renamed)) // [['a', 1], ['d', 2], ['c', 3]] + * + * // Rename failed: the original key does not exist. + * console.log(renameObjectProperty(original, 'e', 'f') === original); // true + * // Rename failed: the new key has already existed. + * console.log(renameObjectProperty(original, 'e', 'a') === original); // true + * // Rename failed: the corresponding original property is not enumerable own property. + * console.log(renameObjectProperty(original, 'x', 'x1') === original); // true + * ``` + */ +export function renameObjectProperty> ( + object: T, + originalPropertyKey: keyof T, + newPropertyKey: keyof T, +): T { + if (!Object.prototype.propertyIsEnumerable.call(object, originalPropertyKey)) { + return object; + } + if (newPropertyKey in object) { + return object; + } + + const result = {} as T; + + if (typeof originalPropertyKey === 'symbol') { + (Object.entries(object)).forEach(([k, v]) => { + result[k as keyof T] = v; + }); + Object.getOwnPropertySymbols(object).forEach((k) => { + result[k === originalPropertyKey ? newPropertyKey : k as keyof T] = object[k as keyof T]; + }); + } else { + Object.entries(object).forEach(([k, v]) => { + result[k === originalPropertyKey ? newPropertyKey : k as keyof T] = v; + }); + Object.getOwnPropertySymbols(object).forEach((k) => { + result[k as keyof T] = object[k as keyof T]; + }); + } + + return result; +} diff --git a/cocos/core/utils/js-typed.ts b/cocos/core/utils/js-typed.ts index 08fa712be5e..0cb880e42c7 100644 --- a/cocos/core/utils/js-typed.ts +++ b/cocos/core/utils/js-typed.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR, DEV, TEST } from 'internal:constants'; import { warnID, error, errorID } from '../platform/debug'; -import IDGenerator from './id-generator'; +import { IDGenerator } from './id-generator'; const tempCIDGenerator = new IDGenerator('TmpCId.'); @@ -35,13 +34,20 @@ const classIdTag = '__cid__'; /** * @en - * Check the object whether is number or not - * If a number is created by using 'new Number(10086)', the typeof it will be "object"... - * Then you can use this function if you care about this case. + * Checks if an object is `number`. * @zh - * 检查对象是否是 number 类型,如果通过 'new Number(10086)' 创建了一个数字,则使用 typeof 判断此数字时,将返回 'object' 类型,此时你可以通过此方法来进行判断 - * @param object object to be checked - * @return whether this object is number or not + * 检查对象是否是 number 类型。 + * @param object @en The object to check. @zh 要检查的对象。 + * @returns @en True if it is a number primitive or a `Number` instance, false else. + * @zh 如果该对象是基础数字类型或者是 `Number` 实例,返回 `true`;否则返回 `false`。 + * @example + * ```ts + * var obj = 10; + * isNumber(obj); // returns true + * + * obj = new Number(10); + * isNumber(obj); // returns true + * ``` */ export function isNumber (object: any) { return typeof object === 'number' || object instanceof Number; @@ -49,13 +55,20 @@ export function isNumber (object: any) { /** * @en - * Check the object whether is string or not. - * If a string is created by using 'new String("blabla")', the typeof it will be "object"... - * Then you can use this function if you care about this case. + * Checks if an object is `string`. * @zh - * 检查对象是否是 string 类型,如果通过 'new String("blabla")' 创建了一个字符串,则使用 typeof 判断此字符串时,将返回 'object' 类型,此时你可以通过此方法来进行判断 - * @param object object to be checked - * @return whether this object is string or not + * 检查对象是否是 string 类型。 + * @param object @en The object to check. @zh 要检查的对象。 + * @returns @en True if it is a string primitive or a `String` instance, false else. + * @zh 如果该对象是基础字符串类型或者是 `String` 实例,返回 `true`;否则返回 `false`。 + * @example + * ```ts + * var obj = "it is a string"; + * isString(obj); // returns true + * + * obj = new String("it is a string"); + * isString(obj); // returns true + * ``` */ export function isString (object: any) { return typeof object === 'string' || object instanceof String; @@ -63,11 +76,13 @@ export function isString (object: any) { /** * @en - * Checks if the object `obj` does not have one or more enumerable properties (including properties from proto chain). + * Checks if an object is empty object. If an object does not have any enumerable property + * (including properties inherits from prototype chains), then it is an empty object. * @zh - * 检查此对象是否为空对象 - * @param obj The object. - * @returns The result. Note that if the `obj` is not of type `'object'`, `true` is returned. + * 检查对象是否为空对象。空对象的定义是:没有任何可被枚举的属性(包括从原型链继承的属性)的对象。 + * @param obj @en The object to check. @zh 要检查的对象。 + * @returns @en True if it is not an empty object or not an object, false else. + * @zh 如果不是空对象或者不是一个对象,返回 `true`;否则返回 `false`。 */ export function isEmptyObject (obj: any) { for (const key in obj) { @@ -77,14 +92,15 @@ export function isEmptyObject (obj: any) { } /** - * @en - * Define value, just help to call Object.defineProperty.
- * The configurable will be true. - * @zh - * 定义值,帮助调用 Object.defineProperty. - * 该属性默认可读写 - * @param [writable=false] - * @param [enumerable=false] + * @en A helper function to add a property to an object, or modifies attributes + * of an existing property. The property is configurable. + * @zh 为对象添加属性或者修改已有属性的辅助函数。该属性是可配置的。 + * @param object @en The object to add or modify attributes. @zh 要添加或者修改属性的对象。 + * @param propertyName @en The property name to add or modify. @zh 要添加或修改的属性名。 + * @param value_ @en The property value to add or new value to replace a existing attribute. + * @zh 要添加的属性值,或者取代现有属性的新值。 + * @param writable @en If the property is writable. @zh 属性是否可写。 + * @param enumerable @en If the property is enumerable. @zh 属性是否可枚举。 */ export const value = (() => { const descriptor: PropertyDescriptor = { @@ -103,13 +119,14 @@ export const value = (() => { })(); /** - * @en - * Define get set accessor, just help to call Object.defineProperty(...). - * @zh - * 定义 get set 访问器,帮助调用 Object.defineProperty() - * @param [setter=null] - * @param [enumerable=false] - * @param [configurable=false] + * @en A helper function to add or modify `get`, `set`, `enumerable` or `configurable` of a property. + * @zh 添加或修改属性的 `get`, `set`, `enumerable` 或者 `configurable`。 + * @param object @en The object to add or modify attributes. @zh 要添加或者修改属性的对象。 + * @param propertyName @en The property name to add or modify. @zh 要添加或修改的属性名。 + * @param getter @en The getter of a property. @zh 属性的获取函数。 + * @param setter @en The setter of a property. @zh 属性的设置函数。 + * @param enumerable @en If the property is enumerable. @zh 属性是否可列举。 + * @param configurable @en If the property is configurable. @zh 属性是否可配置。 */ export const getset = (() => { const descriptor: PropertyDescriptor = { @@ -119,6 +136,7 @@ export const getset = (() => { }; return (object: Record, propertyName: string, getter: Getter, setter?: Setter | boolean, enumerable = false, configurable = false) => { if (typeof setter === 'boolean') { + console.log('Set `setter` to boolean is deprecated. Please don not use like this again.'); enumerable = setter; setter = undefined; } @@ -133,12 +151,13 @@ export const getset = (() => { })(); /** - * @en - * Define get accessor, just help to call Object.defineProperty(...). - * @zh - * 定义 get 访问器,帮助调用 Object.defineProperty() - * @param [enumerable=false] - * @param [configurable=false] + * @en A helper function to add or modify `get`, `enumerable` or `configurable` of a property. + * @zh 添加或修改属性的 `get`, `enumerable` 或者 `configurable`。 + * @param object @en The object to add or modify attributes. @zh 要添加或者修改属性的对象。 + * @param propertyName @en The property name to add or modify. @zh 要添加或修改的属性名。 + * @param getter @en The getter of a property. @zh 属性的获取函数。 + * @param enumerable @en If the property is enumerable. @zh 属性是否可列举。 + * @param configurable @en If the property is configurable. @zh 属性是否可配置。 */ export const get = (() => { const descriptor: PropertyDescriptor = { @@ -156,12 +175,13 @@ export const get = (() => { })(); /** - * @en - * Define set accessor, just help to call Object.defineProperty(...) - * @zh - * 定义 set 访问器,帮助调用 Object.defineProperty - * @param [enumerable=false] - * @param [configurable=false] + * @en A helper function to add or modify `get`, `enumerable` or `configurable` of a property. + * @zh 添加或修改属性的 `get`, `enumerable` 或者 `configurable`。 + * @param object @en The object to add or modify attributes. @zh 要添加或者修改属性的对象。 + * @param propertyName @en The property name to add or modify. @zh 要添加或修改的属性名。 + * @param setter @en The setter of a property. @zh 属性的设置函数。 + * @param enumerable @en If the property is enumerable. @zh 属性是否可列举。 + * @param configurable @en If the property is configurable. @zh 属性是否可配置。 */ export const set = (() => { const descriptor: PropertyDescriptor = { @@ -188,9 +208,11 @@ export const set = (() => { * `Object.create(null)` 用于创建无 prototype (也就无继承)的空对象。 * 这样我们在该对象上查找属性时,就不用进行 `hasOwnProperty` 判断,此时对性能提升有帮助。 * - * @param [forceDictMode=false] Apply the delete operator to newly created map object. - * This causes V8 to put the object in "dictionary mode" and disables creation of hidden classes - * which are very expensive for objects that are constantly changing shape. + * @param forceDictMode @en Apply the delete operator to newly created map object. This will let V8 put the object in + * "dictionary mode" and disables creation of hidden classes. This will improve the performance of objects that are + * constantly changing shape. + * @zh 对新创建的地图对象应用删除操作。这将让V8将对象置于 "字典模式",并禁止创建隐藏类。这将提高那些不断变化形状对象的性能。 + * @returns @en A newly map object. @zh 一个新的 map 对象。 */ export function createMap (forceDictMode?: boolean): any { const map = Object.create(null); @@ -208,11 +230,13 @@ export function createMap (forceDictMode?: boolean): any { /** * @en - * Get class name of the object, if object is just a {} (and which class named 'Object'), it will return "". - * (modified from
the code from this stackoverflow post) + * Gets class name of the object, if object is just a {} (and which class named 'Object'), it will return "". + * (modified from the code of stackoverflow post) * @zh - * 获取对象的类型名称,如果对象是 {} 字面量,将会返回 "" - * @param objOrCtor instance or constructor + * 获取对象的类型名称,如果对象是 {} 字面量,将会返回 ""。参考了 stackoverflow 的代码实现: + * stackoverflow 的实现 + * @param objOrCtor @en An object instance or constructor. @zh 类实例或者构造函数。 + * @returns @en The class name. @zh 类名。 */ export function getClassName (objOrCtor: any): string { if (typeof objOrCtor === 'function') { @@ -221,10 +245,10 @@ export function getClassName (objOrCtor: any): string { if (prototype && prototype.hasOwnProperty(classNameTag) && prototype[classNameTag]) { return prototype[classNameTag] as string; } - let retval = ''; + let ret = ''; // for browsers which have name property in the constructor of the object, such as chrome if (objOrCtor.name) { - retval = objOrCtor.name; + ret = objOrCtor.name; } if (objOrCtor.toString) { let arr; @@ -239,10 +263,10 @@ export function getClassName (objOrCtor: any): string { arr = /function\s*(\w+)/.exec(str); } if (arr && arr.length === 2) { - retval = arr[1]; + ret = arr[1]; } } - return retval !== 'Object' ? retval : ''; + return ret !== 'Object' ? ret : ''; } else if (objOrCtor && objOrCtor.constructor) { return getClassName(objOrCtor.constructor); } @@ -250,14 +274,16 @@ export function getClassName (objOrCtor: any): string { } /** - * @en - * Defines a polyfill field for obsoleted codes. - * @zh - * 为废弃代码定义一个填充字段 - * @param object - YourObject or YourClass.prototype - * @param obsoleted - "OldParam" or "YourClass.OldParam" - * @param newExpr - "NewParam" or "YourClass.NewParam" - * @param [writable=false] + * @en Deprecates a property. It will print waring message if the deprecated property is accessed. + * The warning message includes new property name to use. + * @zh 废弃一个属性。如果被废弃属性还在使用的话,会打印警告消息。警告消息包含新的属性名。 + * @param object @en The object or class of the property to deprecate. + * @zh 被废弃属性的对象或者类。 + * @param obsoleted @en The property name to deprecate. It could be a property name or `className.propertyName`. + * @zh 要废弃的属性名。可以直接传属性名或者是 `类名.属性名` 的形式。 + * @param newExpr @en New property name to use. It could be a property name or `className.propertyName`. + * @zh 新的属性名。可以直接传属性名或者是 `类名.属性名` 的形式。 + * @param writable @en Whether the property is writable. Default is false. @zh 该属性是否可写。默认不可写。 */ export function obsolete (object: any, obsoleted: string, newExpr: string, writable?: boolean) { const extractPropName = /([^.]+)$/; @@ -284,14 +310,15 @@ export function obsolete (object: any, obsoleted: string, newExpr: string, writa } /** - * @en - * Defines all polyfill fields for obsoleted codes corresponding to the enumerable properties of props. - * @zh - * 为所有可废弃属性定义填充字段 - * @param obj - YourObject or YourClass.prototype - * @param objName - "YourObject" or "YourClass" - * @param props - * @param [writable=false] + * @en Deprecates some properties. It will print waring message if any deprecated property is accessed. + * The warning message includes new property name to use. + * @zh 废弃一组属性。如果被废弃属性还在使用的话,会打印警告消息。警告消息包含新的属性名。 + * @param obj @en The object or class of these properties to deprecate. + * @zh 被废弃属性的对象或者类。 + * @param objName @en The object name or class name of these properties to deprecate. + * @zh 被废弃属性的对象名或者类名。 + * @param props @en The property names to deprecate. @zh 被废弃的一组属性名。 + * @param writable @en Whether these properties are writable. @zh 被废弃的属性是否可写。 */ export function obsoletes (obj, objName, props, writable) { for (const obsoleted in props) { @@ -307,10 +334,12 @@ const REGEXP_STR = /%s/; * @en * A string tool to construct a string with format string. * @zh - * 通过格式字符串构造一个字符串 - * @param msg - A JavaScript string containing zero or more substitution strings (%s). - * @param subst - JavaScript objects with which to replace substitution strings within msg. - * This gives you additional control over the format of the output. + * 根据格式字符串构造一个字符串。 + * @param msg @en A JavaScript string containing zero or more substitution strings (%s). + * @zh 包含有 0 个或者多个格式符的字符串。 + * @param subst @en JavaScript objects with which to replace substitution strings within msg. + * @zh 替换 `msg` 里格式符的表达式。 + * @returns @en A new formatted string. @zh 格式化后的新字符串。 * @example * ``` * import { js } from 'cc'; @@ -318,7 +347,7 @@ const REGEXP_STR = /%s/; * js.formatStr(a, b, c); * ``` */ -export function formatStr (msg: string, ...subst: any[]) { +export function formatStr (msg: string, ...subst: any[]): string { if (arguments.length === 0) { return ''; } @@ -346,6 +375,11 @@ export function formatStr (msg: string, ...subst: any[]) { } // see https://github.com/petkaantonov/bluebird/issues/1389 +/** + * @en Removes the first argument. @zh 移除第一个参数。 + * @returns @en An Array that contains all arguments except the first one. + * @zh 新的参数数组,该数组不包含第一个参数。 + */ export function shiftArguments () { const len = arguments.length - 1; const args = new Array(len); @@ -357,9 +391,15 @@ export function shiftArguments () { } /** - * Get property descriptor in object and all its ancestors. + * @en Gets a property descriptor by property name of an object or its prototypes. + * @zh 根据属性名从一个对象或者它的原型链中获取属性描述符。 + * @param object @en The object to get property descriptor. @zh 获取描述符的对象。 + * @param propertyName @en The property name to get property descriptor. + * @zh 获取属性描述符的属性名。 + * @returns @en A `PropertyDescriptor` instance or null if not found. + * @zh 属性描述符对象。如果没找到的话,返回 null。 */ -export function getPropertyDescriptor (object: any, propertyName: string) { +export function getPropertyDescriptor (object: any, propertyName: string): PropertyDescriptor | null { while (object) { const pd = Object.getOwnPropertyDescriptor(object, propertyName); if (pd) { @@ -370,13 +410,20 @@ export function getPropertyDescriptor (object: any, propertyName: string) { return null; } -function _copyprop (name: string, source: any, target: any) { +function _copyProp (name: string, source: any, target: any) { const pd = getPropertyDescriptor(source, name); if (pd) { Object.defineProperty(target, name, pd); } } +/** + * @en Copies all properties except those in `excepts` from `source` to `target`. + * @zh 把 `source` 的所有属性,除了那些定义在 `excepts`的属性,拷贝到 `target`。 + * @param source @en Source object to copy from. @zh 拷贝的源对象。 + * @param target @en Target object to copy to. @zh 拷贝到目标对象。 + * @param excepts @en Properties are not copied. @zh 不拷贝到属性。 + */ export function copyAllProperties (source: any, target: any, excepts: Array) { const propertyNames: Array = Object.getOwnPropertyNames(source); for (let i = 0, len = propertyNames.length; i < len; ++i) { @@ -385,18 +432,17 @@ export function copyAllProperties (source: any, target: any, excepts: Array, ...sources: any[]) { object = object || {}; @@ -408,7 +454,7 @@ export function addon (object?: Record, ...sources: any[]) } for (const name in source) { if (!(name in object)) { - _copyprop(name, source, object); + _copyProp(name, source, object); } } } @@ -417,11 +463,12 @@ export function addon (object?: Record, ...sources: any[]) } /** - * @en - * Copy all properties from arguments[1...n] to object. - * @zh - * 拷贝源对象所有属性到目标对象上,如果有属性冲突,则以源对象为准 - * @return The result object. + * @en Copies all the properties in "sources" from "sources" to "object". + * @zh 将 "sources" 中的所有属性从 "sources" 复制到 "object"。 + * @param object @en Object to copy properties to. @zh 拷贝的目标对象。 + * @param sources @en Source objects to copy properties from. @zh 拷贝到源对象数组。 + * @return @en The passing `object` or a new object if passing object is not valid. + * @zh 传入的对象。如果传入的对象无效或者没传入,将返回一个新对象。 */ export function mixin (object?: Record, ...sources: any[]) { object = object || {}; @@ -432,7 +479,7 @@ export function mixin (object?: Record, ...sources: any[]) continue; } for (const name in source) { - _copyprop(name, source, object); + _copyProp(name, source, object); } } } @@ -441,14 +488,12 @@ export function mixin (object?: Record, ...sources: any[]) /** * @en - * Derive the class from the supplied base class. - * Both classes are just native javascript constructors, not created by `Class`, so - * usually you will want to inherit using [[CCClass]] instead. + * Makes a class inherit from the supplied base class. * @zh - * 将一个类型继承另一个类型 - * 两个类型都需要是 javascript 的构建函数,而不是 `Class`, 所以你通常可以用 [[CCClass]] 来代替 - * @param base The baseclass to inherit. - * @return The result class. + * 将一个类型继承另一个类型。 + * @param cls @en The class to inherit. @zh 要继承的类。 + * @param base @en The class to inherit from. @zh 被继承的类。 + * @returns @en Passed in `cls`. @zh 传入的 `cls`。 */ // eslint-disable-next-line @typescript-eslint/ban-types export function extend (cls: Function, base: Function) { @@ -479,15 +524,15 @@ export function extend (cls: Function, base: Function) { } /** - * @en - * Get super class. - * @zh - * 获取父类 - * @param constructor The constructor of subclass. + * @en Get super class. + * @zh 获取父类。 + * @param constructor @en The constructor to get super class. + * @zh 要获取父类的构造函数。 + * @returns @en Super class. @zh 父类。 */ // eslint-disable-next-line @typescript-eslint/ban-types export function getSuper (constructor: Function) { - const proto = constructor.prototype; // binded function do not have prototype + const proto = constructor.prototype; // bound function do not have prototype const dunderProto = proto && Object.getPrototypeOf(proto); // eslint-disable-next-line @typescript-eslint/no-unsafe-return return dunderProto && dunderProto.constructor; @@ -495,16 +540,16 @@ export function getSuper (constructor: Function) { /** * @en - * Checks whether subclass is child of superclass or equals to superclass. - * @zh - * 判断一类型是否是另一类型的子类或本身 - * @param subclass sub class to be checked - * @param superclass super class to be checked - * @return whether subclass is child of superclass + * Checks whether a class is child of another class, or is the same type as another class. + * @zh 判断一类型是否是另一类型的子类或本身。 + * @param subclass @en Sub class to check. @zh 子类类型。 + * @param superclass @en Super class to check. @zh 父类类型。 + * @return @en True if sub class is child of super class, or they are the same type. False else. + * @zh 如果子类类型是父类类型的子类,或者二者是相同类型,那么返回 true,否则返回 false。 */ export function isChildClassOf(subclass: unknown, superclass: T): subclass is T; export function isChildClassOf(subclass: unknown, superclass: unknown): boolean; -export function isChildClassOf(subclass: unknown, superclass: unknown) { +export function isChildClassOf (subclass: unknown, superclass: unknown) { if (subclass && superclass) { if (typeof subclass !== 'function') { return false; @@ -533,10 +578,10 @@ export function isChildClassOf(subclass: unknown, superclass: unknown) { } /** - * @en - * Removes all enumerable properties from object. - * @zh - * 移除对象中所有可枚举属性 + * @en Removes all enumerable properties from a object. + * @zh 移除对象中所有可枚举属性. + * @param object @en The object to remove enumerable properties from. + * @zh 要删除可枚举属性的对象。 */ export function clear (object: Record) { for (const key of Object.keys(object)) { @@ -603,13 +648,10 @@ export const _setClassId = setup('__cid__', _idToClass, false); const doSetClassName = setup('__classname__', _nameToClass, true); /** - * @en - * Register the class by specified name manually - * @zh - * 通过指定的名称手动注册类型 - * @method setClassName - * @param className - * @param constructor + * @en Registers a class by specified name manually. + * @zh 通过指定的名称手动注册类型 + * @param className @en Class name to register. @zh 注册的类名。 + * @param constructor @en Constructor to register. @zh 注册的构造函数。 */ export function setClassName (className: string, constructor: Constructor) { doSetClassName(className, constructor); @@ -624,17 +666,16 @@ export function setClassName (className: string, constructor: Constructor) { } /** - * @en Set an alias name for class. - * If `setClassAlias(target, alias)`, `alias` will be a single way short cut for class `target`. - * If you try `js.getClassByName(alias)`, you will get target. - * But `js.getClassName(target)` will return the original name of `target`, not the alias. - * @zh 为类设置别名。 - * 当 `setClassAlias(target, alias)` 后, - * `alias` 将作为类 `target`的“单向 ID” 和“单向名称”。 - * 因此,`getClassById(alias)` 和 `getClassByName(alias)` 都会得到 `target`。 - * 这种映射是单向的,意味着 `getClassName(target)` 和 `getClassId(target)` 将不会是 `alias`。 - * @param target Constructor of target class. - * @param alias Alias to set. The name shall not have been set as class name or alias of another class. + * @en Sets an alias for a class. + * After executing `setClassAlias(target, alias)`, `alias` will be a single way short cut for class `target`. + * `js.getClassByName(alias)` and `getClassById(alias)` will return `target`. But `js.getClassName(target)` + * will return the original class name of `target`, not the alias. + * @zh 为类设置别名。执行 `setClassAlias(target, alias)` 后,`alias` 将作为类 `target` 的 “单向 ID” 和 “单向名称”。 + * 因此,`getClassById(alias)` 和 `getClassByName(alias)` 都会得到 `target`。这种映射是单向的,这意味着 `getClassName(target)` + * 和 `getClassId(target)` 将不会返回 `alias`。 + * @param target @en Constructor of a class to set an alias. @zh 设置别名的类的构造函数。 + * @param alias @en Alias to set. The name shall not have been set as class name or alias of another class. + * @zh 类的别名。别名不能重复,也不能是已有类的名字。 */ export function setClassAlias (target: Constructor, alias: string) { const nameRegistry = _nameToClass[alias]; @@ -662,15 +703,14 @@ export function setClassAlias (target: Constructor, alias: string) { /** * @en - * Unregister a class from cocos. - * - * If you dont need a registered class anymore, you should unregister the class so that cocos will not keep its reference anymore. - * Please note that its still your responsibility to free other references to the class. + * Unregister some classes from engine. + * If you don't need a registered class anymore, you should unregister the class or engine will keep its reference. + * Please note that it‘s your responsibility to remove other references to the class. * @zh - * 取消注册类型,如果你不再需要一个注册的类,你应该取消注册这个类,这样 cocos 就不会再保留它的引用。 - * 请注意,你仍然有责任释放对该类的其他引用。 + * 取消注册类型。如果你不再需要一个注册的类,你应该取消注册这个类,否则引擎会还有对它的引用。 + * 请注意,你仍然有责任释放其他地方对该类的引用。 * - * @param ...constructor - the class you will want to unregister, any number of classes can be added + * @param ...constructor @en The classes to unregister. @zh 取消注册的类型列表。 */ // eslint-disable-next-line @typescript-eslint/ban-types export function unregisterClass (...constructors: Function[]) { @@ -696,25 +736,22 @@ export function unregisterClass (...constructors: Function[]) { } /** - * @en - * Get the registered class by id - * @zh - * 通过 id 获取已注册的类型 - * @param classId + * @en Gets a registered class by id. + * @zh 通过 id 获取已注册的类型。 + * @param classId @en An id to get class. * @return constructor * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * Please use `getClassById()` instead. */ export function _getClassById (classId) { return getClassById(classId); } /** - * @en - * Get the registered class by id - * @zh - * 通过 id 获取已注册的类型 - * @param classId - * @return constructor + * @en Gets the registered class by id. + * @zh 通过 id 获取已注册的类型。 + * @param classId @en The class id used to get class. @zh 获取类的 id。 + * @returns @en The constructor of the registered class. @zh 注册的类构造函数。 */ export function getClassById (classId) { return _idToClass[classId]; @@ -722,11 +759,11 @@ export function getClassById (classId) { /** * @en - * Get the registered class by name + * Gets the registered class by class name. * @zh - * 通过名字获取已注册的类型 - * @param classname - * @return constructor of the class + * 通过类名获取已注册的类型。 + * @param classname @en The class name used to get class. @zh 获取类的类名。 + * @returns @en The constructor of the registered class. @zh 注册的类构造函数。 */ export function getClassByName (classname) { return _nameToClass[classname]; @@ -740,7 +777,8 @@ export function getClassByName (classname) { * @param obj - instance or constructor * @param [allowTempId = true] - can return temp id in editor * @return - * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @deprecated since v3.5.0. this is an engine private interface that will be removed in the future. + * Please use `getClassId()` instead. */ export function _getClassId (obj, allowTempId?: boolean) { return getClassId(obj, allowTempId); @@ -748,12 +786,14 @@ export function _getClassId (obj, allowTempId?: boolean) { /** * @en - * Get class id of the object + * Gets class id of an object * @zh - * 获取对象的 class id - * @param obj - instance or constructor - * @param [allowTempId = true] - can return temp id in editor - * @return + * 获取对象的 class id。 + * @param obj @en An object instance to get class id. @zh 获取类标识的对象。 + * @param allowTempId @en Whether allow to return a temple class id in editor. + * @zh 在编辑器时,是否允许返回一个临时的类标识。 + * @returns @en Class id if found, empty string else. + * @zh 找到的类标识。如果没找到的话,返回空字符串。 */ export function getClassId (obj, allowTempId?: boolean) { allowTempId = (typeof allowTempId !== 'undefined' ? allowTempId : true); diff --git a/cocos/core/utils/js.ts b/cocos/core/utils/js.ts index 36097e7e6c4..54bb8b977fa 100644 --- a/cocos/core/utils/js.ts +++ b/cocos/core/utils/js.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -25,8 +25,7 @@ THE SOFTWARE. */ -import * as jsarray from './array'; -import IDGenerator from './id-generator'; +import { IDGenerator } from './id-generator'; import { _idToClass, _nameToClass, @@ -60,19 +59,22 @@ import { unregisterClass, value, } from './js-typed'; -import Pool from './pool'; - +import { Pool } from './pool'; +import * as array from './array'; import { legacyCC } from '../global-exports'; export * from './js-typed'; -export { default as IDGenerator } from './id-generator'; -export { default as Pool } from './pool'; -export const array = jsarray; +export { IDGenerator } from './id-generator'; +export { Pool } from './pool'; +export { array }; +/** + * @deprecated since v3.7.0, `js.js` is deprecated, please access `js` directly instead. + */ export const js = { IDGenerator, Pool, - array: jsarray, + array, isNumber, isString, isEmptyObject, diff --git a/cocos/core/utils/jsb-utils.ts b/cocos/core/utils/jsb-utils.ts index 1c13624be05..29724ea0fc6 100644 --- a/cocos/core/utils/jsb-utils.ts +++ b/cocos/core/utils/jsb-utils.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import type { Node } from '../../scene-graph'; // export interface IArrayProxy { diff --git a/cocos/core/utils/misc.ts b/cocos/core/utils/misc.ts index 31bdf6d6013..7648639fdd5 100644 --- a/cocos/core/utils/misc.ts +++ b/cocos/core/utils/misc.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ /* eslint-disable no-new-func */ -import { EDITOR, DEV } from 'internal:constants'; +import { DEV } from 'internal:constants'; import { getClassName, getset, isEmptyObject } from './js'; import { legacyCC } from '../global-exports'; import { warnID } from '../platform/debug'; @@ -35,7 +34,7 @@ import { macro } from '../platform/macro'; export const BUILTIN_CLASSID_RE = /^(?:cc|dragonBones|sp|ccsg)\..+/; const BASE64_KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; -const values:number[] = new Array(123); // max char code in base64Keys +const values: number[] = new Array(123); // max char code in base64Keys for (let i = 0; i < 123; ++i) { values[i] = 64; } // fill with placeholder('=') index for (let i = 0; i < 64; ++i) { values[BASE64_KEYS.charCodeAt(i)] = i; } @@ -43,10 +42,13 @@ for (let i = 0; i < 64; ++i) { values[BASE64_KEYS.charCodeAt(i)] = i; } export const BASE64_VALUES = values; /** + * @en Defines properties for a class, or replaces getter, setter of existing properties. + * @param ctor @en Class to modify. + * @param sameNameGetSets @en Getters and setters of properties. The getter and setter + * have the same name. So a property getter and setter occupy one position in `sameNameGetSets`. + * @param diffNameGetSets @en Getters and setters of properties. The getter and setter + * have different names. So a property getter and setter occupy two positions in `diffNameGetSets`. * @engineInternal - * @param ctor - * @param sameNameGetSets - * @param diffNameGetSets */ export function propertyDefine (ctor, sameNameGetSets, diffNameGetSets) { function define (np, propName, getter, setter) { @@ -78,7 +80,15 @@ export function propertyDefine (ctor, sameNameGetSets, diffNameGetSets) { } } -// set value to map, if key exists, push to array +/** + * @en Inserts a new element into a map. All values corresponding to the same key are stored in an array. + * @zh 往 map 插入一个元素。同一个关键字对应的所有值存储在一个数组里。 + * @param map @en The map to insert element. @zh 插入元素的 map。 + * @param key @en The key of new element. @zh 新插入元素的关键字。 + * @param value @en The value of new element. @zh 新插入元素的值。 + * @param pushFront @en Whether to put new value in front of the vector if key exists. + * @zh 如果关键字已经存在,是否把新插入的值放到数组第一个位置。 + */ export function pushToMap (map, key, value, pushFront) { const exists = map[key]; if (exists) { @@ -97,6 +107,15 @@ export function pushToMap (map, key, value, pushFront) { } } +/** + * @en Checks whether a node is a descendant of a given node, that is the node itself, one of its direct + * children (childNodes), one of the children's direct children, and so on. + * @zh 检查节点是否是一个给定的节点的后代,即节点本身、它的一个直接子节点(childNodes)、该子节点的一个直接子节点,依此类推。 + * @param refNode @en The node to check. @zh 检查的节点。 + * @param otherNode @en The node to test with. @zh 用来测试的节点。 + * @returns @en True if otherNode is contained in refNode, false if not. + * @zh 如果 refNode 包含 otherNode,返回 true;否则返回 false。 + */ export function contains (refNode, otherNode) { if (typeof refNode.contains === 'function') { return refNode.contains(otherNode) as boolean; @@ -117,19 +136,31 @@ export function contains (refNode, otherNode) { } } -export function isDomNode (obj) { +/** + * @en Checks whether a node is a DOM node. @zh 检查一个节点是否是一个 DOM 节点。 + * @param node @en The node the check. @zh 被检查节点。 + * @returns @en True if node is a DOM node, false else. + * @zh 如果 DOM 节点,返回 true;否则返回 false。 + */ +export function isDomNode (node) { if (typeof window === 'object' && typeof Node === 'function') { // If "TypeError: Right-hand side of 'instanceof' is not callback" is thrown, // it should because window.Node was overwritten. - return obj instanceof Node; + return node instanceof Node; } else { - return !!obj - && typeof obj === 'object' - && typeof obj.nodeType === 'number' - && typeof obj.nodeName === 'string'; + return !!node + && typeof node === 'object' + && typeof node.nodeType === 'number' + && typeof node.nodeName === 'string'; } } +/** + * @en Invoke a function in next frame. @zh 在下一帧执行传入的函数。 + * @param callback @en The function to be invoked next frame. @zh 下一帧要执行的函数。 + * @param p1 @en The first parameter passed to `callback`. @zh 传给回调函数的第一个参数。 + * @param p2 @en The seconde parameter passed to `callback`. @zh 传给回调函数的第二个参数。 + */ export function callInNextTick (callback, p1?: any, p2?: any) { if (callback) { setTimeout(() => { @@ -139,6 +170,14 @@ export function callInNextTick (callback, p1?: any, p2?: any) { } // use anonymous function here to ensure it will not being hoisted without EDITOR +/** + * @en Create a new function that will invoke `functionName` with try catch. + * @zh 创建一个新函数,该函数会使用 try catch 机制调用 `functionName`. + * @param funcName @en The function name to be invoked with try catch. + * @zh 被 try catch 包裹的函数名。 + * @returns @en A new function that will invoke `functionName` with try catch. + * @zh 使用 try catch 机制调用 `functionName` 的新函数. + */ export function tryCatchFunctor_EDITOR (funcName) { // eslint-disable-next-line @typescript-eslint/no-implied-eval return Function('target', @@ -150,6 +189,13 @@ export function tryCatchFunctor_EDITOR (funcName) { + `}`); } +/** + * @en Checks whether an object is an empty object. + * @zh 检查一个对象是否为空对象。 + * @param obj @en The object to check. @zh 要检查的对象。 + * @returns @en True if it is an empty object. False if it is not an empty object, not Object type, null or undefined. + * @ 如果是空对象,返回 true。如果不是空对象,不是Object类型,空或未定义,则为假。 + */ export function isPlainEmptyObj_DEV (obj) { if (!obj || obj.constructor !== Object) { return false; @@ -158,18 +204,18 @@ export function isPlainEmptyObj_DEV (obj) { } /** - * @en Clamp a value between from and to.
- * if the original value is larger than max_inclusive, return max_inclusive.
- * if the original value is smaller than min_inclusive, return min_inclusive.
- * else return the original value. + * @en Clamps a value between a min and a max value.
+ * If the original value is greater than max_inclusive, returns max_inclusive.
+ * If the original value is less than min_inclusive, returns min_inclusive.
+ * Else returns the original value. * @zh 限定浮点数的最大最小值。
- * 数值大于 max_inclusive 则返回 max_inclusive。
- * 数值小于 min_inclusive 则返回 min_inclusive。
+ * 如果数值大于 max_inclusive 则返回 max_inclusive。
+ * 如果数值小于 min_inclusive 则返回 min_inclusive。
* 否则返回自身。 - * @param value @en Original value @zh 初始值 - * @param min_inclusive @en Minimum value in between @zh 最小值 - * @param max_inclusive @en Maximum value in between @zh 最大值 - * @return {Number} @en The value clamped @zh 目标值 + * @param value @en Original value. @zh 初始值。 + * @param min_inclusive @en Minimum value in range. @zh 最小值。 + * @param max_inclusive @en Maximum value in range. @zh 最大值。 + * @returns @en The clamped value. @zh 目标值。 * @example * var v1 = clampf(20, 0, 20); // 20; * var v2 = clampf(-1, 0, 20); // 0; @@ -185,20 +231,20 @@ export function clampf (value: number, min_inclusive: number, max_inclusive: num } /** - * @en converts degrees to radians - * @zh 角度转弧度 - * @param angle @en The degree to convert @zh 角度 - * @return {Number} The radian. @zh 弧度 + * @en Converts degree to radian. + * @zh 将度数转换为弧度。 + * @param angle @en The degree to convert. @zh 角度。 + * @returns @en The radian. @zh 弧度。 */ export function degreesToRadians (angle: number) { return angle * macro.RAD; } /** - * @en converts radians to degrees - * @zh 弧度转角度 - * @param angle @en The radian to convert @zh 弧度 - * @return {Number} @en The degree @zh 角度 + * @en Converts radian to degree. + * @zh 将弧度转换为角度。 + * @param angle @en The radian to convert. @zh 弧度。 + * @returns @en The degree. @zh 角度。 */ export function radiansToDegrees (angle) { return angle * macro.DEG; diff --git a/cocos/core/utils/mutable-forward-iterator.ts b/cocos/core/utils/mutable-forward-iterator.ts index f324c709e26..0201f8e7f03 100644 --- a/cocos/core/utils/mutable-forward-iterator.ts +++ b/cocos/core/utils/mutable-forward-iterator.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -35,6 +34,7 @@ * ... * } * ``` + * @engineInternal */ export default class MutableForwardIterator { public i = 0; diff --git a/cocos/core/utils/path.ts b/cocos/core/utils/path.ts index cdc452d3273..964a33d0213 100644 --- a/cocos/core/utils/path.ts +++ b/cocos/core/utils/path.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,11 +31,13 @@ const DIRNAME_RE = /((.*)(\/|\\|\\\\))?(.*?\..*$)?/; const NORMALIZE_RE = /[^\.\/]+\/\.\.\//; /** - * @en Join strings to be a path. + * @en Joins strings to be a path. * @zh 拼接字符串为路径。 + * @param segments @en Strings to be joined. @zh 被拼接的字符串数组。 + * @returns @en The final path. @zh 拼接后的路径。 * @example {@link cocos/core/utils/CCPath/join.js} */ -export function join (...segments: string[]) { +export function join (...segments: string[]): string { let result = ''; for (const segment of segments) { result = (result + (result === '' ? '' : '/') + segment).replace(/(\/|\\\\)$/, ''); @@ -45,21 +46,23 @@ export function join (...segments: string[]) { } /** - * @en Get the ext name of a path including '.', like '.png'. + * @en Gets the extension name of a path including '.', like '.png'. * @zh 返回 Path 的扩展名,包括 '.',例如 '.png'。 + * @param path @en A file path. @zh 文件路径。 + * @returns @en The extension name. @zh 扩展名。 * @example {@link cocos/core/utils/CCPath/extname.js} */ -export function extname (path: string) { +export function extname (path: string): string { const temp = EXTNAME_RE.exec(path); return temp ? temp[1] : ''; } /** - * @en Get the main name of a file name. + * @en Gets the main name of a file name, exclude extension name. * @zh 获取文件名的主名称。 * @deprecated */ -export function mainFileName (fileName: string) { +export function mainFileName (fileName: string): string { if (fileName) { const idx = fileName.lastIndexOf('.'); if (idx !== -1) { @@ -70,8 +73,11 @@ export function mainFileName (fileName: string) { } /** - * @en Get the file name of a file path. - * @zh 获取文件路径的文件名。 + * @en Gets the file name of a file path, exclude extension name and directory name. + * @zh 获取文件路径的文件名,不包含扩展名和目录名。 + * @param path @en A file path. @zh 文件路径。 + * @param extName @en File extension name. @zh 文件扩展名。 + * @returns @en The file name. @zh 文件名。 * @example {@link cocos/core/utils/CCPath/basename.js} */ export function basename (path: string, extName?: string) { @@ -92,21 +98,26 @@ export function basename (path: string, extName?: string) { } /** - * @en Get dirname of a file path. + * @en Gets directory name of a file path. * @zh 获取文件路径的目录名。 + * @param path @en A file path. @zh 文件路径。 + * @returns @en Directory name. @zh 文件目录名。 * @example {@link cocos/core/utils/CCPath/dirname.js} */ -export function dirname (path: string) { +export function dirname (path: string): string { const temp = DIRNAME_RE.exec(path); return temp ? temp[2] : ''; } /** - * @en Change extname of a file path. - * @zh 更改文件路径的扩展名。 + * @en Changes file extension name. + * @zh 更改文件的扩展名。 + * @param path @en A file path. @zh 文件路径。 + * @param extName @en New file extension name. @zh 新文件扩展名。 + * @returns @en New file path. @zh 新的文件路径。 * @example {@link cocos/core/utils/CCPath/changeExtname.js} */ -export function changeExtname (path: string, extName?: string) { +export function changeExtname (path: string, extName?: string): string { extName = extName || ''; let index = path.indexOf('?'); let tempStr = ''; @@ -122,24 +133,28 @@ export function changeExtname (path: string, extName?: string) { } /** - * @en Change file name of a file path. + * @en Changes file name of a file path. * @zh 更改文件路径的文件名。 + * @param path @en A file path. @zh 文件路径。 + * @param newBaseName @en New file name. @zh 新文件名。 + * @param keepExt @en Whether to keep extension name. @zh 是否保留扩展名。 + * @returns @en New file path. @zh 新文件路径。 * @example {@link cocos/core/utils/CCPath/changeBasename.js} */ -export function changeBasename (path: string, baseName: string, isSameExt?: boolean) { - if (baseName.indexOf('.') === 0) { - return changeExtname(path, baseName); +export function changeBasename (path: string, newBaseName: string, keepExt?: boolean): string { + if (newBaseName.indexOf('.') === 0) { + return changeExtname(path, newBaseName); } let index = path.indexOf('?'); let tempStr = ''; - const ext = isSameExt ? extname(path) : ''; + const ext = keepExt ? extname(path) : ''; if (index > 0) { tempStr = path.substring(index); path = path.substring(0, index); } index = path.lastIndexOf('/'); index = index <= 0 ? 0 : index + 1; - return path.substring(0, index) + baseName + ext + tempStr; + return path.substring(0, index) + newBaseName + ext + tempStr; } // todo make public after verification @@ -154,10 +169,23 @@ export function _normalize (url) { return url; } +/** + * @en Removes the last path separator('/' or '\') of a path if exist. + * @zh 如果存在的话,删除文件路径的最后一个分隔符('/' 或者 '\')。 + * @param path @en A file path to modify. @zh 要修改的文件路径。 + * @returns @en A new file path without last file separator. + * @zh 路径最后分隔符的新路径。 + */ export function stripSep (path: string) { return path.replace(/[\/\\]$/, ''); } +/** + * @en Gets file separator for different platforms. It is `/` on unix like platforms, + * and `\` on windows. + * @zh 获取不同平台的文件分割符。类 unix 系统是 `/`,windows 系统是 `\`。 + * @returns @en File separator. @zh 文件分割符。 + */ export function getSeperator () { return systemInfo.os === OS.WINDOWS ? '\\' : '/'; } diff --git a/cocos/core/utils/pool.ts b/cocos/core/utils/pool.ts index 7a75264bfa4..a0c8d71df4b 100644 --- a/cocos/core/utils/pool.ts +++ b/cocos/core/utils/pool.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,8 +27,8 @@ type CleanUpFunction = (value: T) => boolean | void; /** * @en * A fixed-length object pool designed for general type.
- * The implementation of this object pool is very simple, - * it can helps you to improve your game performance for objects which need frequent release and recreate operations
+ * The implementation of this object pool is very simple. + * It can help you to improve your game performance for objects which need frequent release and recreate operations.
* @zh * 长度固定的对象缓存池,可以用来缓存各种对象类型。
* 这个对象池的实现非常精简,它可以帮助您提高游戏性能,适用于优化对象的反复创建和销毁。 @@ -77,10 +76,10 @@ type CleanUpFunction = (value: T) => boolean | void; * ... * ``` */ -export default class Pool { +export class Pool { /** * @en - * The current number of available objects, the default is 0, it will gradually increase with the recycle of the object, + * The current number of available objects, the default is 0. It will gradually increase with the recycle of the object, * the maximum will not exceed the size specified when the constructor is called. * @zh * 当前可用对象数量,一开始默认是 0,随着对象的回收会逐渐增大,最大不会超过调用构造函数时指定的 size。 @@ -90,12 +89,12 @@ export default class Pool { /** * @en - * Get and initialize an object from pool. This method defaults to null and requires the user to implement it. - * @zh - * 获取并初始化对象池中的对象。这个方法默认为空,需要用户自己实现。 - * @param args - parameters to used to initialize the object + * Gets an object from pool. + * @zh 从对象池中获取一个对象。 + * @returns @en An object or null if this pool doesn't contain any object. + * @zh 获取的对象。如果对象池中没有对象,返回 null。 */ - public get () { + public get (): T | null { return this._get(); } @@ -103,23 +102,26 @@ export default class Pool { private _cleanup: CleanUpFunction | null; /** - * 使用构造函数来创建一个指定对象类型的对象池,您可以传递一个回调函数,用于处理对象回收时的清理逻辑。 - * @method constructor - * @param {Function} [cleanupFunc] - the callback method used to process the cleanup logic when the object is recycled. - * @param {Object} cleanupFunc.obj - * @param {Number} size - initializes the length of the array + * @en Constructor. @zh 构造函数。 + * @param cleanupFunc @en Callback method used to process the cleanup logic when the object is recycled. + * @zh 当对象放入对象池时,用来执行清理逻辑的回调函数。 + * @param size @en Pool size. @zh 对象池大小。 */ constructor (cleanup: CleanUpFunction, size: number); /** - * 使用构造函数来创建一个指定对象类型的对象池,您可以传递一个回调函数,用于处理对象回收时的清理逻辑。 - * @method constructor - * @param {Function} [cleanupFunc] - the callback method used to process the cleanup logic when the object is recycled. - * @param {Object} cleanupFunc.obj - * @param {Number} size - initializes the length of the array + * @en Constructor. @zh 构造函数。 + * @param size @en Pool size. @zh 对象池大小。 */ constructor (size: number); + /** + * @en Constructor. @zh 构造函数。 + * @param _0 @en If it is a number, it is the array size. Or it is a callback function used to process + * the cleanup logic when the object is recycled. + * @zh 如果是 number,那么它是对象池大小。否则是当对象放入对象池时,用来执行清理逻辑的回调函数。 + * @param _1 @en Array size if it is a valid number. @zh 如果是个有效的 number 类型,那么是对象池大小。 + */ constructor (_0: CleanUpFunction | number, _1?: number) { const size = (_1 === undefined) ? (_0 as number) : _1; const cleanupFunc = (_1 === undefined) ? null : (_0 as CleanUpFunction); @@ -130,10 +132,10 @@ export default class Pool { /** * @en - * Get an object from pool, if no available object in the pool, null will be returned. - * @zh - * 获取对象池中的对象,如果对象池没有可用对象,则返回空。 - * + * Gets an object from pool. + * @zh 从对象池中获取一个对象。 + * @returns @en An object or null if this pool doesn't contain any object. + * @zh 获取的对象。如果对象池中没有对象,返回 null。 * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _get () { @@ -164,6 +166,8 @@ export default class Pool { /** * @en Resize the pool. * @zh 设置对象池容量。 + * @param length @en New pool size. + * @zh 新对象池大小。 */ public resize (length: number) { if (length >= 0) { diff --git a/cocos/core/utils/prefab/index.ts b/cocos/core/utils/prefab/index.ts deleted file mode 100644 index 9563ff3bcf1..00000000000 --- a/cocos/core/utils/prefab/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './prefab-info'; -export * from './utils'; diff --git a/cocos/core/utils/x-deprecated.ts b/cocos/core/utils/x-deprecated.ts index 1f06c27e876..91f37e3452d 100644 --- a/cocos/core/utils/x-deprecated.ts +++ b/cocos/core/utils/x-deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable import/no-mutable-exports */ @@ -43,41 +42,41 @@ export function setDefaultLogTimes (times: number): void { } interface IReplacement { - /** 废弃属性的名称 */ + /** Deprecated property name. */ name: string; - /** 警告的次数 */ + /** Times to print log when accessing deprecated property. */ logTimes?: number; - /** 替换属性的名称 */ + /** New property name. */ newName?: string; - /** 废弃属性的所属对象 */ + /** The object to deprecate this property. */ target?: object; - /** 废弃属性的所属对象的名称 */ + /** The name of the object to deprecate this property. */ targetName?: string; - /** 自定义替换属性(函数) */ + /** New function to access the property. If it is valid, `customSetter` and `customGetter` will be ignored. */ customFunction?: Function; - /** 自定义替换属性的 setter */ + /** New setter. */ customSetter?: (v: any) => void; - /** 自定义替换属性的 getter */ + /** New getter. */ customGetter?: () => any; - /** 额外建议 */ + /** Property description used in warning log. */ suggest?: string; } interface IRemoveItem { - /** 废弃属性的名称 */ + /** Removed property name. */ name: string; - /** 警告的次数 */ + /** Times to print log when accessing removed property. */ logTimes?: number; - /** 额外建议 */ + /** Property description used in warning log. */ suggest?: string; } interface IMarkItem { - /** 废弃属性的名称 */ + /** Deprecated property name. */ name: string; - /** 警告的次数 */ + /** Times to print log when accessing deprecated property. */ logTimes?: number; - /** 额外建议 */ + /** Property description used in warning log. */ suggest?: string; } diff --git a/cocos/core/value-types/bitmask.ts b/cocos/core/value-types/bitmask.ts index acacd57a414..24fa6547923 100644 --- a/cocos/core/value-types/bitmask.ts +++ b/cocos/core/value-types/bitmask.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -30,13 +29,33 @@ import { errorID } from '../platform/debug'; /** * @en - * Define an BitMask type. + * Defines a BitMask type. The editor will display different inspector depending on this data type. It may define some properties to the object. + * The keys of new properties are the integer type values, and the values are corresponding keys. See the example below. + * keys. * @zh - * 定义一个位掩码类型。 + * 定义一个位掩码类型。编辑器会根据这个数据类型显示不同的显示界面。它可能会在对象添加新属性。新属性的 key 是原来的整型 value,value 是对应的 key。参考下面的例子。 * @param obj * @en A JavaScript literal object containing BitMask names and values. * @zh 包含 BitMask 名称和值的 JavaScript 文字对象。 - * @return @en The defined BitMask type @zh 定义的位掩码类型。 + * @returns @en The defined BitMask type @zh 定义的位掩码类型。 + * @example + * ```ts + * // `type1` and `type2` are single-selected. + * let obj = { + * type1: 0, + * type2: 1 << 2, + * } + * + * // `type1` and `type2` are multiple-selected. + * // New properties are added to obj, obj now is + * // { + * // type1: 0, + * // type2: 1<< 2, + * // 0: type1, + * // 4: type2 + * // } + * BitMask(obj); + * ``` */ export function BitMask (obj: T): T { if ('__bitmask__' in obj) { @@ -70,8 +89,19 @@ export function BitMask (obj: T): T { return obj; } +/** + * @en Checks if an object is BitMask. @zh 检查一个对象是否是 BitMask。 + * @param BitMaskType @en The object to check. @zh 待检查对象。 + * @returns @en True if it is a BitMask, false else. + * @zh 如果是 BitMask,返回 true;否则返回 false。 + */ BitMask.isBitMask = (BitMaskType) => BitMaskType && BitMaskType.hasOwnProperty('__bitmask__'); +/** + * + * @param BitMaskDef + * @returns @en A sorted array with integer values. @zh 存储整型属性值的数组。该数组已排序。 + */ BitMask.getList = (BitMaskDef) => { if (BitMaskDef.__bitmask__) { return BitMaskDef.__bitmask__; @@ -89,6 +119,12 @@ BitMask.getList = (BitMaskDef) => { return bitlist; }; +/** + * @en Similar to [[BitMask]], but it doesn't add properties to the object. + * @zh 和 [[BitMask]] 类似功能,但不会往对象添加属性。 + * @param bitmaskx @en An object to make BitMask type. @zh 要标记为 BitMask 类型的对象。 + * @returns @en The passed in object. @zh 传入的对象。 + */ export function ccbitmask (bitmaskx) { if ('__bitmask__' in bitmaskx) { return; diff --git a/cocos/core/value-types/enum.ts b/cocos/core/value-types/enum.ts index 56c898ffb6e..bc5740f4741 100644 --- a/cocos/core/value-types/enum.ts +++ b/cocos/core/value-types/enum.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/core/value-types/index.ts b/cocos/core/value-types/index.ts index 364cfe807f5..da711f4d2cb 100644 --- a/cocos/core/value-types/index.ts +++ b/cocos/core/value-types/index.ts @@ -1,27 +1,26 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. */ export { BitMask } from './bitmask'; diff --git a/cocos/core/value-types/value-type.ts b/cocos/core/value-types/value-type.ts index 530002a5762..93b023626f5 100644 --- a/cocos/core/value-types/value-type.ts +++ b/cocos/core/value-types/value-type.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/deprecated.ts b/cocos/deprecated.ts index 3875d6df43d..63055416151 100644 --- a/cocos/deprecated.ts +++ b/cocos/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. */ -import { replaceProperty, markAsWarning } from './core/utils/x-deprecated'; +import { replaceProperty } from './core'; import { Root } from './root'; // Root diff --git a/cocos/dragon-bones/ArmatureCache.ts b/cocos/dragon-bones/ArmatureCache.ts index d2ebd5147a3..f01780663f9 100644 --- a/cocos/dragon-bones/ArmatureCache.ts +++ b/cocos/dragon-bones/ArmatureCache.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Armature, BlendMode, Matrix } from '@cocos/dragonbones-js'; import { Texture2D } from '../asset/assets'; diff --git a/cocos/dragon-bones/ArmatureDisplay.ts b/cocos/dragon-bones/ArmatureDisplay.ts index 34dab892cf0..e4430c016f7 100644 --- a/cocos/dragon-bones/ArmatureDisplay.ts +++ b/cocos/dragon-bones/ArmatureDisplay.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { Armature, Bone, EventObject } from '@cocos/dragonbones-js'; -import { ccclass, executeInEditMode, help, menu } from '../core/data/class-decorator'; import { UIRenderer } from '../2d/framework/ui-renderer'; -import { CCClass, Color, Enum, ccenum, errorID, RecyclePool, js, CCObject } from '../core'; -import { EventTarget } from '../core/event'; +import { CCClass, Color, Enum, ccenum, errorID, RecyclePool, js, CCObject, EventTarget, cclegacy, _decorator } from '../core'; import { BlendFactor } from '../gfx'; -import { displayName, displayOrder, editable, override, serializable, tooltip, type, visible } from '../core/data/decorators'; import { AnimationCache, ArmatureCache, ArmatureFrame } from './ArmatureCache'; import { AttachUtil } from './AttachUtil'; import { CCFactory } from './CCFactory'; @@ -39,7 +35,6 @@ import { DragonBonesAtlasAsset } from './DragonBonesAtlasAsset'; import { Graphics } from '../2d/components'; import { CCArmatureDisplay } from './CCArmatureDisplay'; import { MaterialInstance } from '../render-scene/core/material-instance'; -import { legacyCC } from '../core/global-exports'; import { ArmatureSystem } from './ArmatureSystem'; import { Batcher2D } from '../2d/renderer/batcher-2d'; import { RenderEntity, RenderEntityType } from '../2d/renderer/render-entity'; @@ -93,6 +88,8 @@ export enum AnimationCacheMode { } ccenum(AnimationCacheMode); +const { ccclass, serializable, editable, type, help, menu, tooltip, visible, displayName, override, displayOrder, executeInEditMode } = _decorator; + function setEnumAttr (obj, propName, enumDef) { CCClass.Attr.setClassAttr(obj, propName, 'type', 'Enum'); CCClass.Attr.setClassAttr(obj, propName, 'enumList', Enum.getList(enumDef)); @@ -183,7 +180,7 @@ export class ArmatureDisplay extends UIRenderer { this._dragonAsset = value; this.destroyRenderData(); this._refresh(); - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { this._defaultArmatureIndex = 0; this._animationIndex = 0; } @@ -218,7 +215,7 @@ export class ArmatureDisplay extends UIRenderer { const animNames = this.getAnimationNames(this._armatureName); if (!this.animationName || animNames.indexOf(this.animationName) < 0) { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { this.animationName = animNames[0]; } else { // Not use default animation name at runtime @@ -593,11 +590,10 @@ export class ArmatureDisplay extends UIRenderer { } private getMaterialTemplate () : Material { - let material = this.customMaterial; - if (material === null) { - material = builtinResMgr.get('default-spine-material'); - } - return material; + if (this.customMaterial !== null) return this.customMaterial; + if (this.material) return this.material; + this.updateMaterial(); + return this.material!; } public getMaterialForBlend (src: BlendFactor, dst: BlendFactor): MaterialInstance { @@ -626,6 +622,11 @@ export class ArmatureDisplay extends UIRenderer { return inst; } + protected _updateBuiltinMaterial (): Material { + const material = builtinResMgr.get('default-spine-material'); + return material; + } + @override @type(Material) @displayOrder(0) @@ -635,11 +636,18 @@ export class ArmatureDisplay extends UIRenderer { } set customMaterial (val) { this._customMaterial = val; - this._cleanMaterialCache(); - this.setMaterial(this._customMaterial, 0); + this.updateMaterial(); this.markForUpdateRenderData(); } + protected updateMaterial () { + let mat; + if (this._customMaterial) mat = this._customMaterial; + else mat = this._updateBuiltinMaterial(); + this.setMaterial(mat, 0); + this._cleanMaterialCache(); + } + protected _render (batcher: Batcher2D) { let indicesCount = 0; if (this.renderData && this._drawList) { @@ -669,7 +677,7 @@ export class ArmatureDisplay extends UIRenderer { } _init () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { const Flags = CCObject.Flags; this._objFlags |= (Flags.IsAnchorLocked | Flags.IsSizeLocked); // this._refreshInspector(); @@ -746,7 +754,7 @@ export class ArmatureDisplay extends UIRenderer { * @return {Boolean} */ isAnimationCached () { - if (EDITOR && !legacyCC.GAME_VIEW) return false; + if (EDITOR && !cclegacy.GAME_VIEW) return false; return this._cacheMode !== AnimationCacheMode.REALTIME; } @@ -780,11 +788,10 @@ export class ArmatureDisplay extends UIRenderer { } updateAnimation (dt) { + this.markForUpdateRenderData(); if (!this.isAnimationCached()) return; if (!this._frameCache) return; - this.markForUpdateRenderData(); - const frameCache = this._frameCache; if (!frameCache.isInited()) { return; @@ -861,7 +868,7 @@ export class ArmatureDisplay extends UIRenderer { this._materialInstances = this._materialInstances.filter((instance) => !!instance); this._inited = false; - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this._cacheMode === AnimationCacheMode.PRIVATE_CACHE) { this._armatureCache!.dispose(); this._armatureCache = null; @@ -911,7 +918,7 @@ export class ArmatureDisplay extends UIRenderer { // Switch Asset or Atlas or cacheMode will rebuild armature. if (this._armature) { // dispose pre build armature - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this._preCacheMode === AnimationCacheMode.PRIVATE_CACHE) { this._armatureCache!.dispose(); } else if (this._preCacheMode === AnimationCacheMode.REALTIME) { @@ -930,7 +937,7 @@ export class ArmatureDisplay extends UIRenderer { this._preCacheMode = -1; } - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this._cacheMode === AnimationCacheMode.SHARED_CACHE) { this._armatureCache = ArmatureCache.sharedCache; } else if (this._cacheMode === AnimationCacheMode.PRIVATE_CACHE) { @@ -951,7 +958,7 @@ export class ArmatureDisplay extends UIRenderer { } this._preCacheMode = this._cacheMode; - if (EDITOR && !legacyCC.GAME_VIEW || this._cacheMode === AnimationCacheMode.REALTIME) { + if (EDITOR && !cclegacy.GAME_VIEW || this._cacheMode === AnimationCacheMode.REALTIME) { this._displayProxy = this._factory!.buildArmatureDisplay(this.armatureName, this._armatureKey, '', atlasUUID) as CCArmatureDisplay; if (!this._displayProxy) return; this._displayProxy._ccNode = this.node; @@ -1014,7 +1021,7 @@ export class ArmatureDisplay extends UIRenderer { _refresh () { this._buildArmature(); this._indexBoneSockets(); - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { // update inspector this._updateArmatureEnum(); this._updateAnimEnum(); @@ -1384,4 +1391,4 @@ export class ArmatureDisplay extends UIRenderer { } } -legacyCC.internal.ArmatureDisplay = ArmatureDisplay; +cclegacy.internal.ArmatureDisplay = ArmatureDisplay; diff --git a/cocos/dragon-bones/ArmatureSystem.ts b/cocos/dragon-bones/ArmatureSystem.ts index 1d800df5ddd..5d1c85b8155 100644 --- a/cocos/dragon-bones/ArmatureSystem.ts +++ b/cocos/dragon-bones/ArmatureSystem.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { director } from '../game/director'; -import { System } from '../core'; +import { System, cclegacy } from '../core'; import { ArmatureDisplay } from './ArmatureDisplay'; -import { legacyCC } from '../core/global-exports'; export class ArmatureSystem extends System { /** @@ -92,4 +90,4 @@ export class ArmatureSystem extends System { } } -legacyCC.internal.ArmatureSystem = ArmatureSystem; +cclegacy.internal.ArmatureSystem = ArmatureSystem; diff --git a/cocos/dragon-bones/AttachUtil.ts b/cocos/dragon-bones/AttachUtil.ts index fb6c32860fd..f442c533f19 100644 --- a/cocos/dragon-bones/AttachUtil.ts +++ b/cocos/dragon-bones/AttachUtil.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Armature, Matrix } from '@cocos/dragonbones-js'; -import { Mat4, Vec3 } from '../core'; -import { ccclass } from '../core/data/class-decorator'; +import { Mat4, Vec3, _decorator } from '../core'; import { Node } from '../scene-graph'; import { ArmatureFrameBoneInfo } from './ArmatureCache'; import { ArmatureDisplay } from './ArmatureDisplay'; const _tempMat4 = new Mat4(); +const { ccclass } = _decorator; /** * @en Attach node tool diff --git a/cocos/dragon-bones/CCArmatureDisplay.ts b/cocos/dragon-bones/CCArmatureDisplay.ts index a893b9b728e..58e05a409ab 100644 --- a/cocos/dragon-bones/CCArmatureDisplay.ts +++ b/cocos/dragon-bones/CCArmatureDisplay.ts @@ -1,19 +1,18 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,17 +21,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Armature, DisplayData, IEventDispatcher, Slot } from '@cocos/dragonbones-js'; -import { ccclass } from '../core/data/class-decorator'; -import { Vec3 } from '../core'; -import { EventTarget } from '../core/event'; +import { Vec3, EventTarget, _decorator } from '../core'; // eslint-disable-next-line import/named import { CCSlot } from './CCSlot'; import { ArmatureDisplay } from './ArmatureDisplay'; import { Node } from '../scene-graph'; +const { ccclass } = _decorator; + /** * @deprecated since v3.5.1, this is an engine private interface that will be removed in the future. */ diff --git a/cocos/dragon-bones/CCFactory.ts b/cocos/dragon-bones/CCFactory.ts index 427df9c2013..8dd3e0ed99c 100644 --- a/cocos/dragon-bones/CCFactory.ts +++ b/cocos/dragon-bones/CCFactory.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,21 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { Armature, BaseObject, Animation, BaseFactory, DragonBones } from '@cocos/dragonbones-js'; -import { ISchedulable, Scheduler, System } from '../core'; -import { ccclass } from '../core/data/class-decorator'; +import { ISchedulable, Scheduler, System, cclegacy, _decorator } from '../core'; import { CCTextureAtlasData } from './CCTextureData'; import { TextureBase } from '../asset/assets/texture-base'; import { CCSlot } from './CCSlot'; import { ArmatureDisplay } from './ArmatureDisplay'; import { CCArmatureDisplay } from './CCArmatureDisplay'; -import { legacyCC } from '../core/global-exports'; import { Node } from '../scene-graph'; import { director, Game, game } from '../game'; +const { ccclass } = _decorator; + /** * DragonBones factory * @class CCFactory @@ -92,7 +91,7 @@ export class CCFactory extends BaseFactory implements ISchedulable { } update (dt: number) { - if (EDITOR && !legacyCC.GAME_VIEW) return; + if (EDITOR && !cclegacy.GAME_VIEW) return; this._dragonBones.advanceTime(dt); } diff --git a/cocos/dragon-bones/CCSlot.ts b/cocos/dragon-bones/CCSlot.ts index 18a98d5e17f..1451ed8ad7b 100644 --- a/cocos/dragon-bones/CCSlot.ts +++ b/cocos/dragon-bones/CCSlot.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BoneType, BinaryOffset, Slot } from '@cocos/dragonbones-js'; import { Texture2D } from '../asset/assets'; -import { Color, Mat4 } from '../core'; -import { ccclass } from '../core/data/class-decorator'; +import { Color, Mat4, _decorator } from '../core'; import { CCTextureData } from './CCTextureData'; +const { ccclass } = _decorator; + // @skipLibCheck /** * @deprecated since v3.5.1, this is an engine private interface that will be removed in the future. diff --git a/cocos/dragon-bones/CCTextureData.ts b/cocos/dragon-bones/CCTextureData.ts index 5286736826e..a0656ff9380 100644 --- a/cocos/dragon-bones/CCTextureData.ts +++ b/cocos/dragon-bones/CCTextureData.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BaseObject, TextureAtlasData, TextureData } from '@cocos/dragonbones-js'; import { SpriteFrame } from '../2d'; import { TextureBase } from '../asset/assets/texture-base'; -import { ccclass } from '../core/data/decorators'; -import { Rect } from '../core/math/rect'; +import { Rect, _decorator } from '../core'; + +const { ccclass } = _decorator; /** * @deprecated since v3.5.1, this is an engine private interface that will be removed in the future. diff --git a/cocos/dragon-bones/DragonBonesAsset.ts b/cocos/dragon-bones/DragonBonesAsset.ts index fd384a495f3..d322fd1e6af 100644 --- a/cocos/dragon-bones/DragonBonesAsset.ts +++ b/cocos/dragon-bones/DragonBonesAsset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { Asset } from '../asset/assets'; -import { ccclass, serializable } from '../core/data/decorators'; import { ArmatureCache } from './ArmatureCache'; -import { Enum } from '../core'; +import { Enum, cclegacy, _decorator } from '../core'; import { CCFactory } from './CCFactory'; -import { legacyCC } from '../core/global-exports'; import { Node } from '../scene-graph'; +const { ccclass, serializable } = _decorator; + /** * @en The skeleton data of dragonBones. * @zh dragonBones 的 骨骼数据。 @@ -79,7 +78,7 @@ export class DragonBonesAsset extends Asset { reset () { this._clear(); - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { this._armaturesEnum = null; } } @@ -173,4 +172,4 @@ export class DragonBonesAsset extends Asset { } } -legacyCC.internal.DragonBonesAsset = DragonBonesAsset; +cclegacy.internal.DragonBonesAsset = DragonBonesAsset; diff --git a/cocos/dragon-bones/DragonBonesAtlasAsset.ts b/cocos/dragon-bones/DragonBonesAtlasAsset.ts index 48362c69935..317963abfd6 100644 --- a/cocos/dragon-bones/DragonBonesAtlasAsset.ts +++ b/cocos/dragon-bones/DragonBonesAtlasAsset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { JSB } from 'internal:constants'; import { TextureAtlasData } from '@cocos/dragonbones-js'; -import { ccclass, serializable, type } from '../core/data/decorators'; import { ArmatureCache } from './ArmatureCache'; import { ArmatureDisplay } from './ArmatureDisplay'; import { CCFactory } from './CCFactory'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy, _decorator } from '../core'; import { Asset, Texture2D } from '../asset/assets'; import { Node } from '../scene-graph'; +const { ccclass, serializable, type } = _decorator; + /** * @en The skeleton atlas data of dragonBones. * @zh dragonBones 的骨骼纹理数据。 @@ -121,4 +121,4 @@ export class DragonBonesAtlasAsset extends Asset { } } -legacyCC.internal.DragonBonesAtlasAsset = DragonBonesAtlasAsset; +cclegacy.internal.DragonBonesAtlasAsset = DragonBonesAtlasAsset; diff --git a/cocos/dragon-bones/assembler/index.ts b/cocos/dragon-bones/assembler/index.ts index 63e7c389e6f..e95cf8f67e5 100644 --- a/cocos/dragon-bones/assembler/index.ts +++ b/cocos/dragon-bones/assembler/index.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { IAssemblerManager } from '../../2d/renderer/base'; diff --git a/cocos/dragon-bones/assembler/simple.ts b/cocos/dragon-bones/assembler/simple.ts index e26b0e4ccc3..f18e141cf51 100644 --- a/cocos/dragon-bones/assembler/simple.ts +++ b/cocos/dragon-bones/assembler/simple.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Armature, BlendMode } from '@cocos/dragonbones-js'; -import { Color, Mat4, Vec3 } from '../../core'; +import { Color, Mat4, Vec3, cclegacy } from '../../core'; import { BlendFactor } from '../../gfx'; import { vfmtPosUvColor } from '../../2d/renderer/vertex-format'; import { MaterialInstance } from '../../render-scene/core/material-instance'; @@ -33,7 +32,6 @@ import { Batcher2D } from '../../2d/renderer/batcher-2d'; import { ArmatureFrame } from '../ArmatureCache'; import { ArmatureDisplay } from '../ArmatureDisplay'; import { CCSlot } from '../CCSlot'; -import { legacyCC } from '../../core/global-exports'; import { StaticVBAccessor } from '../../2d/renderer/static-vb-accessor'; import { RenderData } from '../../2d/renderer/render-data'; import { Texture2D } from '../../asset/assets'; @@ -494,4 +492,4 @@ function updateComponentRenderData (comp: ArmatureDisplay, batcher: Batcher2D) { _comp = undefined; } -legacyCC.internal.DragonBonesAssembler = simple; +cclegacy.internal.DragonBonesAssembler = simple; diff --git a/cocos/dragon-bones/deprecated.ts b/cocos/dragon-bones/deprecated.ts deleted file mode 100644 index f1e1704c1ae..00000000000 --- a/cocos/dragon-bones/deprecated.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. - - https://www.cocos.com/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import { removeProperty } from '../core/utils/x-deprecated'; -import { ArmatureDisplay } from './ArmatureDisplay'; - -removeProperty(ArmatureDisplay.prototype, 'ArmatureDisplay', [ - { - name: '_enableBatch', - suggest: 'Not support batch render mode', - }, -]); diff --git a/cocos/dragon-bones/index.jsb.ts b/cocos/dragon-bones/index.jsb.ts index 193e2a6dfcb..688db1b528d 100644 --- a/cocos/dragon-bones/index.jsb.ts +++ b/cocos/dragon-bones/index.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export enum ExtensionType { FFD = 0, @@ -53,8 +52,7 @@ export * from './ArmatureDisplay'; export * from './AttachUtil'; export * from './assembler'; -declare const window: any; -const dragonBones = window.dragonBones; +const dragonBones = globalThis.dragonBones; export const Slot = dragonBones.Slot; export const Matrix = dragonBones.Matrix; diff --git a/cocos/dragon-bones/index.ts b/cocos/dragon-bones/index.ts index f61305b53b3..e2ac430f9ae 100644 --- a/cocos/dragon-bones/index.ts +++ b/cocos/dragon-bones/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export enum ExtensionType { FFD = 0, @@ -72,6 +71,5 @@ export * from './DragonBonesAtlasAsset'; export * from './ArmatureDisplay'; export * from './AttachUtil'; export * from './assembler'; -export * from './deprecated'; export * from '@cocos/dragonbones-js'; diff --git a/cocos/game/deprecated.ts b/cocos/game/deprecated.ts index e0a143120a5..be18b48f9b9 100644 --- a/cocos/game/deprecated.ts +++ b/cocos/game/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { removeProperty, markAsWarning } from '../core/utils/x-deprecated'; -import { Director } from './director'; +import { removeProperty, markAsWarning, replaceProperty } from '../core/utils/x-deprecated'; +import { Director, director } from './director'; import { game } from './game'; +import { assetManager } from '../asset/asset-manager'; +import type { ISceneInfo } from '../asset/asset-manager/config'; // Director @@ -87,6 +88,20 @@ removeProperty(Director.prototype, 'director', [ }, ]); +replaceProperty(director, 'director', [ + { + name: '_getSceneUuid', + targetName: 'assetManager.main', + newName: 'getSceneInfo', + customFunction: (sceneName) => { + if (assetManager.main) { + return assetManager.main.getSceneInfo(sceneName)?.uuid; + } + return ''; + }, + }, +]); + // game markAsWarning(game, 'game', [ @@ -97,3 +112,20 @@ markAsWarning(game, 'game', [ name: 'groupList', }, ]); + +replaceProperty(game, 'game', [ + { + name: '_sceneInfos', + targetName: 'assetManager.main', + newName: 'getSceneInfo', + customGetter: () => { + const scenes: ISceneInfo[] = []; + if (assetManager.main) { + assetManager.main.config.scenes.forEach((val) => { + scenes.push(val); + }); + } + return scenes; + }, + }, +]); diff --git a/cocos/game/director.ts b/cocos/game/director.ts index 8b3b7dc0112..0c49e4af736 100644 --- a/cocos/game/director.ts +++ b/cocos/game/director.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -29,23 +29,16 @@ import { DEBUG, EDITOR, BUILD, TEST } from 'internal:constants'; import { SceneAsset } from '../asset/assets/scene-asset'; -import System from '../core/system'; -import { CCObject } from '../core/data/object'; -import { EventTarget } from '../core/event'; +import { System, EventTarget, Scheduler, js, errorID, error, assertID, warnID, macro, CCObject, cclegacy, isValid } from '../core'; import { input } from '../input'; import { Root } from '../root'; import { Node, Scene } from '../scene-graph'; import { ComponentScheduler } from '../scene-graph/component-scheduler'; import NodeActivator from '../scene-graph/node-activator'; -import { Scheduler } from '../core/scheduler'; -import { js } from '../core/utils/js'; -import { legacyCC } from '../core/global-exports'; -import { errorID, error, assertID, warnID } from '../core/platform/debug'; -import { containerManager } from '../core/memop/container-manager'; +import { scalableContainerManager } from '../core/memop/scalable-container'; import { uiRendererManager } from '../2d/framework/ui-renderer-manager'; +import { assetManager } from '../asset/asset-manager'; import { deviceManager } from '../gfx'; -import { PipelineBuilder } from '../rendering/custom/pipeline'; -import { macro } from '../core/platform/macro'; // ---------------------------------------------------------------------------------------------------------------------- @@ -169,12 +162,19 @@ export class Director extends EventTarget { public static readonly EVENT_BEFORE_COMMIT = 'director_before_commit'; /** - * @en The event which will be triggered before the pipeline render. - * @zh 当前渲染帧渲染前所触发的事件。 + * @en The event which will be triggered before the render pipeline processes the render scene. + * @zh 当前帧将渲染场景提交到渲染管线之前所触发的事件。 * @event Director.EVENT_BEFORE_RENDER */ public static readonly EVENT_BEFORE_RENDER = 'director_before_render'; + /** + * @en The event which will be triggered after the render pipeline finishes the rendering process on CPU. + * @zh 当前帧渲染管线渲染流程完成后所触发的事件。 + * @event Director.EVENT_AFTER_RENDER + */ + public static readonly EVENT_AFTER_RENDER = 'director_after_render'; + /** * @en The event which will be triggered before the physics process.
* @zh 物理过程之前所触发的事件。 @@ -296,7 +296,7 @@ export class Director extends EventTarget { this._nodeActivator.reset(); if (!EDITOR) { - if (legacyCC.isValid(this._scene)) { + if (isValid(this._scene)) { this._scene!.destroy(); } this._scene = null; @@ -305,7 +305,7 @@ export class Director extends EventTarget { this.stopAnimation(); // Clear all caches - legacyCC.assetManager.releaseAll(); + assetManager.releaseAll(); } /** @@ -379,7 +379,7 @@ export class Director extends EventTarget { if (BUILD && DEBUG) { console.time('Destroy'); } - if (legacyCC.isValid(oldScene)) { + if (isValid(oldScene)) { oldScene!.destroy(); } if (!EDITOR) { @@ -387,7 +387,8 @@ export class Director extends EventTarget { if (BUILD && DEBUG) { console.time('AutoRelease'); } - legacyCC.assetManager._releaseManager._autoRelease(oldScene, scene, this._persistRootNodes); + // @ts-expect-error Using private API in editor + assetManager._releaseManager._autoRelease(oldScene!, scene, this._persistRootNodes); if (BUILD && DEBUG) { console.timeEnd('AutoRelease'); } @@ -460,7 +461,7 @@ export class Director extends EventTarget { warnID(1208, sceneName, this._loadingScene); return false; } - const bundle = legacyCC.assetManager.bundles.find((bundle) => !!bundle.getSceneInfo(sceneName)); + const bundle = assetManager.bundles.find((bundle) => !!bundle.getSceneInfo(sceneName)); if (bundle) { this.emit(Director.EVENT_BEFORE_SCENE_LOADING, sceneName); this._loadingScene = sceneName; @@ -518,8 +519,9 @@ export class Director extends EventTarget { onProgress?: Director.OnLoadSceneProgress | Director.OnSceneLoaded, onLoaded?: Director.OnSceneLoaded, ) { - const bundle = legacyCC.assetManager.bundles.find((bundle) => !!bundle.getSceneInfo(sceneName)); + const bundle = assetManager.bundles.find((bundle) => !!bundle.getSceneInfo(sceneName)); if (bundle) { + // @ts-expect-error Manual checked parameter mapping bundle.preloadScene(sceneName, null, onProgress, onLoaded); } else { const err = `Can not preload the scene "${sceneName}" because it is not in the build settings.`; @@ -565,7 +567,7 @@ export class Director extends EventTarget { * @deprecated since v3.3.0, please use game.deltaTime instead */ public getDeltaTime () { - return legacyCC.game.deltaTime as number; + return cclegacy.game.deltaTime as number; } /** @@ -574,7 +576,7 @@ export class Director extends EventTarget { * @deprecated since v3.3.0, please use game.totalTime instead */ public getTotalTime () { - return legacyCC.game.totalTime as number; + return cclegacy.game.totalTime as number; } /** @@ -583,7 +585,7 @@ export class Director extends EventTarget { * @deprecated since v3.3.0, please use game.frameStartTime instead */ public getCurrentTime () { - return legacyCC.game.frameStartTime as number; + return cclegacy.game.frameStartTime as number; } /** @@ -652,7 +654,7 @@ export class Director extends EventTarget { * @deprecated since 3.0.0 */ public getAnimationManager (): any { - return this.getSystem(legacyCC.AnimationManager.ID); + return this.getSystem(cclegacy.AnimationManager.ID); } // Loop management @@ -679,10 +681,10 @@ export class Director extends EventTarget { */ public mainLoop (now: number) { let dt; - if (EDITOR && !legacyCC.GAME_VIEW || TEST) { + if (EDITOR && !cclegacy.GAME_VIEW || TEST) { dt = now; } else { - dt = legacyCC.game._calculateDT(now); + dt = cclegacy.game._calculateDT(now); } this.tick(dt); } @@ -695,7 +697,7 @@ export class Director extends EventTarget { public tick (dt: number) { if (!this._invalid) { this.emit(Director.EVENT_BEGIN_FRAME); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { // @ts-expect-error _frameDispatchEvents is a private method. input._frameDispatchEvents(); } @@ -730,7 +732,7 @@ export class Director extends EventTarget { Node.resetHasChangedFlags(); Node.clearNodeArray(); - containerManager.update(dt); + scalableContainerManager.update(dt); this.emit(Director.EVENT_END_FRAME); this._totalFrames++; } @@ -739,15 +741,15 @@ export class Director extends EventTarget { private buildRenderPipeline () { if (this._root) { this._root.customPipeline.beginSetup(); - const builder = legacyCC.rendering.getCustomPipeline(macro.CUSTOM_PIPELINE_NAME); + const builder = cclegacy.rendering.getCustomPipeline(macro.CUSTOM_PIPELINE_NAME); builder.setup(this._root.cameraList, this._root.customPipeline); this._root.customPipeline.endSetup(); } } private setupRenderPipelineBuilder () { - if (this._root && this._root.usesCustomPipeline && legacyCC.rendering) { - legacyCC.director.on(legacyCC.Director.EVENT_BEFORE_RENDER, this.buildRenderPipeline, this); + if (macro.CUSTOM_PIPELINE_NAME !== '' && cclegacy.rendering && this._root && this._root.usesCustomPipeline) { + this.on(Director.EVENT_BEFORE_RENDER, this.buildRenderPipeline, this); } } @@ -783,14 +785,14 @@ export class Director extends EventTarget { * @param node - The node to be made persistent */ public addPersistRootNode (node: Node) { - if (!legacyCC.Node.isNode(node) || !node.uuid) { + if (!Node.isNode(node) || !node.uuid) { warnID(3800); return; } const id = node.uuid; if (!this._persistRootNodes[id]) { const scene = this._scene as any; - if (legacyCC.isValid(scene)) { + if (isValid(scene)) { if (!node.parent) { node.parent = scene; node._originalSceneId = scene.uuid; @@ -806,7 +808,8 @@ export class Director extends EventTarget { } this._persistRootNodes[id] = node; node._persistNode = true; - legacyCC.assetManager._releaseManager._addPersistNodeRef(node); + // @ts-expect-error Using private API + assetManager._releaseManager._addPersistNodeRef(node); } } @@ -821,7 +824,8 @@ export class Director extends EventTarget { delete this._persistRootNodes[id]; node._persistNode = false; node._originalSceneId = ''; - legacyCC.assetManager._releaseManager._removePersistNodeRef(node); + // @ts-expect-error Using private API + assetManager._releaseManager._removePersistNodeRef(node); } } @@ -852,10 +856,10 @@ export declare namespace Director { export type OnLoadSceneProgress = (completedCount: number, totalCount: number, item: any) => void; } -legacyCC.Director = Director; +cclegacy.Director = Director; /** * @en Director of the game, used to control game update loop and scene management * @zh 游戏的导演,用于控制游戏更新循环与场景管理。 */ -export const director: Director = Director.instance = legacyCC.director = new Director(); +export const director: Director = Director.instance = cclegacy.director = new Director(); diff --git a/cocos/game/game.ts b/cocos/game/game.ts index b88c8e3d582..a12330345b7 100644 --- a/cocos/game/game.ts +++ b/cocos/game/game.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,34 +23,24 @@ THE SOFTWARE. */ -import { DEBUG, EDITOR, NATIVE, PREVIEW, TEST, WEBGPU } from 'internal:constants'; +import { BUILD, DEBUG, EDITOR, HTML5, JSB, NATIVE, PREVIEW, RUNTIME_BASED, TEST, WEBGPU, TAOBAO } from 'internal:constants'; import { systemInfo } from 'pal/system-info'; import { findCanvas, loadJsFile } from 'pal/env'; import { Pacer } from 'pal/pacer'; import { ConfigOrientation } from 'pal/screen-adapter'; import assetManager, { IAssetManagerOptions } from '../asset/asset-manager/asset-manager'; -import { EventTarget } from '../core/event'; -import { AsyncDelegate } from '../core/event/async-delegate'; +import { EventTarget, AsyncDelegate, sys, macro, VERSION, cclegacy, screen, Settings, settings, assert, garbageCollectionManager, DebugMode, warn, log, _resetDebugSetting } from '../core'; import { input } from '../input'; -import * as debug from '../core/platform/debug'; -import { deviceManager } from '../gfx'; -import { sys } from '../core/platform/sys'; -import { macro } from '../core/platform/macro'; -import { legacyCC, VERSION } from '../core/global-exports'; +import { deviceManager, LegacyRenderMode } from '../gfx'; import { SplashScreen } from './splash-screen'; import { RenderPipeline } from '../rendering'; import { Layers, Node } from '../scene-graph'; -import { garbageCollectionManager } from '../core/data/garbage-collection'; -import { screen } from '../core/platform/screen'; import { builtinResMgr } from '../asset/asset-manager/builtin-res-mgr'; -import { Settings, settings } from '../core/settings'; import { Director, director } from './director'; import { bindingMappingInfo } from '../rendering/define'; -import { assert } from '../core/platform/debug'; -import { IBundleOptions } from '../asset/asset-manager/shared'; import { ICustomJointTextureLayout } from '../3d/skeletal-animation/skeletal-animation-utils'; import { IPhysicsConfig } from '../physics/framework/physics-config'; - +import { effectSettings } from '../core/effect-settings'; /** * @zh * 游戏配置。 @@ -67,13 +56,21 @@ export interface IGameConfig { */ settingsPath?: string; + /** + * @zh + * 引擎内 Effect 配置文件路径 + * @en + * The path of effectSettings.json + */ + effectSettingsPath?: string; + /** * @zh * 设置 debug 模式,在浏览器中这个选项会被忽略。 * @en * Set debug mode, only valid in non-browser environment. */ - debugMode?: debug.DebugMode; + debugMode?: DebugMode; /** * @zh @@ -176,7 +173,7 @@ export interface IGameConfig { * 是否让游戏外框对齐到屏幕上,目前只在 web 平台生效 * @deprecated Since v3.6, Please use ```overrideSettings: { Settings.Category.SCREEN: { 'exactFitScreen': true }}``` to set this. */ - exactFitScreen: boolean, + exactFitScreen?: boolean, } /** @@ -193,10 +190,9 @@ export class Game extends EventTarget { * 在原生平台,它对应的是应用被切换到后台事件,下拉菜单和上拉状态栏等不一定会触发这个事件,这取决于系统行为。 * @example * ```ts - * import { game, audioEngine } from 'cc'; + * import { game } from 'cc'; * game.on(Game.EVENT_HIDE, function () { - * audioEngine.pauseMusic(); - * audioEngine.pauseAllEffects(); + * * }); * ``` */ @@ -291,6 +287,31 @@ export class Game extends EventTarget { */ public static readonly EVENT_RESTART = 'game_on_restart'; + /** + * @en Triggered when the game is paused.
+ * @zh 游戏暂停时触发该事件。
+ * @example + * ```ts + * import { game } from 'cc'; + * game.on(Game.EVENT_PAUSE, function () { + * //pause audio or video + * }); + * ``` + */ + public static readonly EVENT_PAUSE = 'game_on_pause'; + + /** + * @en Triggered when the game is resumed.
+ * @zh 游戏恢复时触发该事件。
+ */ + public static readonly EVENT_RESUME = 'game_on_resume'; + + /** + * @en Triggered when the game will be closed.
+ * @zh 游戏将要关闭时触发的事件。
+ */ + public static readonly EVENT_CLOSE = 'game_on_close'; + /** * @en Web Canvas 2d API as renderer backend. * @zh 使用 Web Canvas 2d API 作为渲染器后端。 @@ -432,6 +453,7 @@ export class Game extends EventTarget { private _engineInited = false; // whether the engine has inited private _rendererInitialized = false; private _paused = true; + private _pausedByEngine = false; // frame control private _frameRate = 60; private _pacer: Pacer | null = null; @@ -518,6 +540,27 @@ export class Game extends EventTarget { director.tick(this.frameTime / 1000); } + /** + * @en Called by the engine to pause the game. + * @zh 提供给引擎调用暂停游戏接口。 + */ + private pauseByEngine () { + if (this._paused) { return; } + this._pausedByEngine = true; + this.pause(); + } + + /** + * @en Resume paused game by engine call. + * @zh 提供给引擎调用恢复暂停游戏接口。 + */ + private resumeByEngine () { + if (this._pausedByEngine) { + this.resume(); + this._pausedByEngine = false; + } + } + /** * @en Pause the game main loop. This will pause: * - game logic execution @@ -537,6 +580,7 @@ export class Game extends EventTarget { if (this._paused) { return; } this._paused = true; this._pacer?.stop(); + this.emit(Game.EVENT_PAUSE); } /** @@ -550,6 +594,7 @@ export class Game extends EventTarget { input._clearEvents(); this._paused = false; this._pacer?.start(); + this.emit(Game.EVENT_RESUME); } /** @@ -568,7 +613,7 @@ export class Game extends EventTarget { const endFramePromise = new Promise((resolve) => { director.once(Director.EVENT_END_FRAME, () => resolve()); }); return endFramePromise.then(() => { director.reset(); - legacyCC.Object._deferredDestroy(); + cclegacy.Object._deferredDestroy(); this.pause(); this.resume(); this._shouldLoadLaunchScene = true; @@ -676,9 +721,11 @@ export class Game extends EventTarget { if (DEBUG) { console.time('Init Base'); } - const debugMode = config.debugMode || debug.DebugMode.NONE; - debug._resetDebugSetting(debugMode); - sys.init(); + const debugMode = config.debugMode || DebugMode.NONE; + _resetDebugSetting(debugMode); + }) + .then(() => sys.init()) + .then(() => { this._initEvents(); }) .then(() => settings.init(config.settingsPath, config.overrideSettings)) @@ -710,6 +757,9 @@ export class Game extends EventTarget { screen.init(); garbageCollectionManager.init(); deviceManager.init(this.canvas, bindingMappingInfo); + if (macro.CUSTOM_PIPELINE_NAME === '') { + cclegacy.rendering = undefined; + } assetManager.init(); builtinResMgr.init(); Layers.init(); @@ -728,6 +778,24 @@ export class Game extends EventTarget { this.emit(Game.EVENT_PRE_SUBSYSTEM_INIT); return this.onPreSubsystemInitDelegate.dispatch(); }) + .then(() => effectSettings.init(settings.querySettings(Settings.Category.RENDERING, 'effectSettingsPath') as string)) + .then(() => { + // initialize custom render pipeline + if (!cclegacy.rendering || !cclegacy.rendering.enableEffectImport) { + return; + } + const renderMode = settings.querySettings(Settings.Category.RENDERING, 'renderMode'); + if (renderMode === LegacyRenderMode.HEADLESS) { + cclegacy.rendering.init(deviceManager.gfxDevice, null); + return; + } + const data = effectSettings.data; + if (data === null) { + console.error('Effect settings not found, effects will not be imported.'); + return; + } + cclegacy.rendering.init(deviceManager.gfxDevice, data); + }) .then(() => { if (DEBUG) { console.time('Init SubSystem'); @@ -743,7 +811,7 @@ export class Game extends EventTarget { return this.onPostSubsystemInitDelegate.dispatch(); }) .then(() => { - debug.log(`Cocos Creator v${VERSION}`); + console.log(`Cocos Creator v${VERSION}`); this.emit(Game.EVENT_ENGINE_INITED); this._engineInited = true; }) @@ -797,6 +865,12 @@ export class Game extends EventTarget { } private _initXR () { + if (typeof globalThis.__globalXR === 'undefined') { + globalThis.__globalXR = {}; + } + const globalXR = globalThis.__globalXR; + globalXR.webxrCompatible = settings.querySettings(Settings.Category.XR, 'webxrCompatible') ?? false; + if (sys.isXR) { // XrEntry must not be destroyed xr.entry = xr.XrEntry.getInstance(); @@ -884,7 +958,7 @@ export class Game extends EventTarget { const preloadBundles = settings.querySettings<{ bundle: string, version: string }[]>(Settings.Category.ASSETS, 'preloadBundles'); if (!preloadBundles) return Promise.resolve([]); return Promise.all(preloadBundles.map(({ bundle, version }) => new Promise((resolve, reject) => { - const opts: IBundleOptions = {}; + const opts: Record = {}; if (version) opts.version = version; assetManager.loadBundle(bundle, opts, (err) => { if (err) { @@ -905,7 +979,7 @@ export class Game extends EventTarget { if (onStart) { this.onStart = onStart; } - if (!this._inited || (EDITOR && !legacyCC.GAME_VIEW)) { + if (!this._inited || (EDITOR && !cclegacy.GAME_VIEW)) { return; } this.resume(); @@ -959,16 +1033,23 @@ export class Game extends EventTarget { private _initEvents () { systemInfo.on('show', this._onShow, this); systemInfo.on('hide', this._onHide, this); + systemInfo.on('close', this._onClose, this); } private _onHide () { this.emit(Game.EVENT_HIDE); - this.pause(); + this.pauseByEngine(); } private _onShow () { this.emit(Game.EVENT_SHOW); - this.resume(); + this.resumeByEngine(); + } + + private _onClose () { + this.emit(Game.EVENT_CLOSE); + // TODO : Release Resources. + systemInfo.exit(); } // @ Persist root node section @@ -1018,8 +1099,8 @@ export class Game extends EventTarget { }).then((asset) => { this._setRenderPipeline(asset); }).catch((reason) => { - debug.warn(reason); - debug.warn(`Failed load render pipeline: ${renderPipeline}, engine failed to initialize, will fallback to default pipeline`); + warn(reason); + warn(`Failed load render pipeline: ${renderPipeline}, engine failed to initialize, will fallback to default pipeline`); this._setRenderPipeline(); }); } @@ -1038,7 +1119,7 @@ export class Game extends EventTarget { try { this.emit(event); } catch (e) { - debug.warn(e); + warn(e); } } else { this.emit(event); @@ -1050,7 +1131,7 @@ export declare namespace Game { export type OnStart = () => void; } -legacyCC.Game = Game; +cclegacy.Game = Game; /** * @en @@ -1058,4 +1139,4 @@ legacyCC.Game = Game; * @zh * 这是一个 Game 类的实例,包含游戏主体信息并负责驱动游戏的游戏对象。 */ -export const game = legacyCC.game = new Game(); +export const game = cclegacy.game = new Game(); diff --git a/cocos/game/index.ts b/cocos/game/index.ts index af2dcd186ce..900b1337930 100644 --- a/cocos/game/index.ts +++ b/cocos/game/index.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/game/splash-screen.ts b/cocos/game/splash-screen.ts index 80008e434b0..fd4adb4242d 100644 --- a/cocos/game/splash-screen.ts +++ b/cocos/game/splash-screen.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,38 +20,37 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { EDITOR, PREVIEW } from 'internal:constants'; -import * as easing from '../core/algorithm/easing'; +import { EDITOR, TAOBAO } from 'internal:constants'; import { Material } from '../asset/assets/material'; -import { clamp01 } from '../core/math/utils'; +import { clamp01, Mat4, Vec2, Settings, settings, sys, cclegacy, easing } from '../core'; import { Sampler, SamplerInfo, Shader, Texture, TextureInfo, Device, InputAssembler, InputAssemblerInfo, Attribute, Buffer, BufferInfo, Rect, Color, BufferTextureCopy, CommandBuffer, BufferUsageBit, Format, MemoryUsageBit, TextureType, TextureUsageBit, Address, SurfaceTransform, Swapchain, } from '../gfx'; import { PipelineStateManager } from '../rendering'; -import { legacyCC } from '../core/global-exports'; import { SetIndex } from '../rendering/define'; -import { Mat4, Vec2 } from '../core/math'; -import { Settings, settings } from '../core/settings'; -import { sys } from '../core/platform/sys'; +import { ccwindow } from '../core/global-exports'; const v2_0 = new Vec2(); -type SplashEffectType = 'NONE' | 'FADE-INOUT'; +type SplashEffectType = 'default' | 'custom' | 'off'; +type WatermarkLocationType = 'default' | 'topLeft' | 'topRight' | 'topCenter' | 'bottomLeft' | 'bottomCenter' | 'bottomRight'; + interface ISplashSetting { - enabled: boolean; + displayRatio: number; totalTime: number; + watermarkLocation: WatermarkLocationType; + autoFit: boolean; + + url?: string; + type?: SplashEffectType; + + bgBase64: string; base64src: string; - effect: SplashEffectType; - clearColor: Color; - displayRatio: number; - displayWatermark: boolean; } -type Writable = { -readonly [K in keyof T]: T[K] }; - export class SplashScreen { private settings!: ISplashSetting; private _curTime = 0; @@ -68,6 +66,11 @@ export class SplashScreen { private renderArea!: Rect; private clearColors!: Color[]; private projection!: Mat4; + private isMobile = false; + + private bgMat!: Material; + private bgImage!: TexImageSource; + private bgTexture!: Texture; private logoMat!: Material; private logoImage!: TexImageSource; @@ -76,40 +79,74 @@ export class SplashScreen { private watermarkMat!: Material; private watermarkTexture!: Texture; - public get isFinished () { + // layout + private bgWidth = 1920; + private bgHeight = 1080; + private bgRatio = 16 / 9; + private logoWidthTemp = 140; + private logoHeightTemp = 200; + private logoWidth = 0; + private logoHeight = 0; + private logoXTrans = 1 / 2;// Percent + private logoYTrans = 1 / 6 + 2.5 / 6;// Percent + + private textSize = 24; // font size + private textHeight = 24; // line height + private textXTrans = 1 / 2;// Percent + private textYExtraTrans = 32;// px + private textExpandSize = 4;// px + + private scaleSize = 1; + + public get isFinished() { return this._curTime >= this.settings.totalTime; } - set curTime (val) { + set curTime(val) { this._curTime = val; } - get curTime () { + get curTime() { return this._curTime; } - public init (): Promise | undefined { + public init(): Promise | undefined { this.settings = { - enabled: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'enabled') ?? true, + displayRatio: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'displayRatio') ?? 0.4, totalTime: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'totalTime') ?? 3000, + watermarkLocation: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'watermarkLocation') ?? 'default', + autoFit: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'autoFit') ?? true, + url: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'url') ?? '', + type: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'type') ?? 'default', + bgBase64: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'bgBase64') ?? '', base64src: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'base64src') ?? '', - effect: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'effect') ?? 'FADE-INOUT', - clearColor: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'clearColor') ?? new Color(0.88, 0.88, 0.88, 1), - displayRatio: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'displayRatio') ?? 0.4, - displayWatermark: settings.querySettings(Settings.Category.SPLASH_SCREEN, 'displayWatermark') ?? true, }; this._curTime = 0; - if (EDITOR || PREVIEW || !this.settings.enabled || this.settings.base64src === '' || this.settings.totalTime <= 0) { + // TODO: Image can't load with base64 data on Taobao platform. + if (EDITOR || TAOBAO || this.settings.base64src === '' || this.settings.totalTime <= 0) { this.settings.totalTime = 0; } else { - this.device = legacyCC.director.root!.device; - this.swapchain = legacyCC.director.root!.mainWindow!.swapchain; + this.device = cclegacy.director.root!.device; + this.swapchain = cclegacy.director.root!.mainWindow!.swapchain; this.preInit(); - if (this.settings.displayWatermark) this.initWarterMark(); - return new Promise((resolve, reject) => { - this.logoImage = new Image(); + this.initLayout(); + + this.initWaterMark(); + const bgPromise = new Promise((resolve, reject) => { + this.bgImage = new ccwindow.Image(); + this.bgImage.onload = () => { + this.initBG(); + resolve(); + }; + this.bgImage.onerror = () => { + reject(); + }; + this.bgImage.src = this.settings.bgBase64; + }); + const logoPromise = new Promise((resolve, reject) => { + this.logoImage = new ccwindow.Image(); this.logoImage.onload = () => { this.initLogo(); resolve(); @@ -119,15 +156,13 @@ export class SplashScreen { }; this.logoImage.src = this.settings.base64src; }); + return Promise.all([bgPromise, logoPromise]); } - return Promise.resolve(); + return Promise.resolve([]); } - private preInit () { - // this.setting.clearColor may not an instance of Color, so should create - // Color manually, or will have problem on native. - const clearColor = this.settings.clearColor; - this.clearColors = [new Color(clearColor.x, clearColor.y, clearColor.z, clearColor.w)]; + private preInit() { + this.clearColors = [new Color(0, 0, 0, 255)]; // clean to black const { device, swapchain } = this; this.renderArea = new Rect(0, 0, swapchain.width, swapchain.height); this.cmdBuff = device.commandBuffer; @@ -163,50 +198,111 @@ export class SplashScreen { this.projection = new Mat4(); Mat4.ortho(this.projection, -1, 1, -1, 1, -1, 1, device.capabilities.clipSpaceMinZ, device.capabilities.clipSpaceSignY, swapchain.surfaceTransform); + + this.isMobile = sys.isMobile; + } + + private initLayout() { + if (this.isMobile) { + this.bgWidth = 812; + this.bgHeight = 375; + + this.logoWidthTemp = 70; + this.logoHeightTemp = 100; + this.logoXTrans = 1 / 2;// Percent + this.logoYTrans = 2 / 3;// Percent + + this.textSize = 12; // font size + this.textHeight = this.textSize + this.textExpandSize; // line height + this.textXTrans = 1 / 2;// Percent + this.textYExtraTrans = 16;// px + } else { + this.bgWidth = 1920; + this.bgHeight = 1080; + + this.logoWidthTemp = 140; + this.logoHeightTemp = 200; + this.logoXTrans = 1 / 2;// Percent + this.logoYTrans = 1 / 6 + 2.5 / 6;// Percent + + this.textSize = 24; // font size + this.textHeight = this.textSize + this.textExpandSize; // line height + this.textXTrans = 1 / 2;// Percent + this.textYExtraTrans = 32;// px + } + this.initScale(); } - public update (deltaTime: number) { + private initScale() { + const dw = this.swapchain.width; const dh = this.swapchain.height; + let desiredWidth = this.isMobile ? 375 : 1080; + let desiredHeight = this.isMobile ? 812 : 1920; + if (dw > dh) { + const temp = desiredHeight; + desiredHeight = desiredWidth; + desiredWidth = temp; + } + if (dw / dh > 16 / 9) { + this.scaleSize = dh / desiredHeight; + } else { + this.scaleSize = dw / desiredWidth; + } + } + + public update(deltaTime: number) { const settings = this.settings; const { device, swapchain } = this; Mat4.ortho(this.projection, -1, 1, -1, 1, -1, 1, device.capabilities.clipSpaceMinZ, device.capabilities.clipSpaceSignY, swapchain.surfaceTransform); const dw = swapchain.width; const dh = swapchain.height; - const refW = dw < dh ? dw : dh; - // update logo uniform + this.initScale(); + this._curTime += deltaTime * 1000; const percent = clamp01(this._curTime / settings.totalTime); - let u_p = easing.cubicOut(percent); - if (settings.effect === 'NONE') u_p = 1.0; - const logoTW = this.logoTexture.width; const logoTH = this.logoTexture.height; - const logoW = refW * settings.displayRatio; - let scaleX = logoW * logoTW / logoTH; - let scaleY = logoW; - if (swapchain.surfaceTransform === SurfaceTransform.ROTATE_90 - || swapchain.surfaceTransform === SurfaceTransform.ROTATE_270) { - scaleX = logoW * dw / dh; - scaleY = logoW * logoTH / logoTW * dh / dw; + const u_p = easing.cubicOut(percent); + + // update bg uniform + let scaleX = 1; + let scaleY = 1; + if (dw < dh) { + scaleX = dh * this.bgRatio; + scaleY = dh; + } else { + scaleX = dw; + scaleY = dw * this.bgRatio; } + + this.bgMat.setProperty('resolution', v2_0.set(dw, dh), 0); + this.bgMat.setProperty('scale', v2_0.set(scaleX, scaleY), 0); + this.bgMat.setProperty('translate', v2_0.set(dw * 0.5, dh * 0.5), 0); + this.bgMat.setProperty('percent', 1.0); + this.bgMat.setProperty('u_projection', this.projection); + this.bgMat.passes[0].update(); + + // update logo uniform + scaleX = 1; + scaleY = 1; + scaleX = this.logoWidth * this.scaleSize * settings.displayRatio; + scaleY = this.logoHeight * this.scaleSize * settings.displayRatio; + const logoYTrans = dh * this.logoYTrans; + this.logoMat.setProperty('resolution', v2_0.set(dw, dh), 0); this.logoMat.setProperty('scale', v2_0.set(scaleX, scaleY), 0); - this.logoMat.setProperty('translate', v2_0.set(dw * 0.5, dh * 0.5), 0); + this.logoMat.setProperty('translate', v2_0.set(dw * this.logoXTrans, logoYTrans), 0); this.logoMat.setProperty('percent', u_p); this.logoMat.setProperty('u_projection', this.projection); this.logoMat.passes[0].update(); - // update wartermark uniform - if (settings.displayWatermark && this.watermarkMat) { - const wartermarkW = refW * 0.5; - const wartermarkTW = this.watermarkTexture.width; const wartermarkTH = this.watermarkTexture.height; - let scaleX = wartermarkW; - let scaleY = wartermarkW * wartermarkTH / wartermarkTW; - if (swapchain.surfaceTransform === SurfaceTransform.ROTATE_90 - || swapchain.surfaceTransform === SurfaceTransform.ROTATE_270) { - scaleX = wartermarkW * 0.5; - scaleY = wartermarkW * dw / dh * 0.5; - } + // update watermark uniform + if (this.watermarkMat) { + const watermarkTW = this.watermarkTexture.width; const watermarkTH = this.watermarkTexture.height; + scaleX = watermarkTW; + scaleY = watermarkTH; + const textYTrans = logoYTrans - (this.logoHeight * 0.5 * settings.displayRatio + this.textYExtraTrans) + * this.scaleSize - watermarkTH * 0.5; this.watermarkMat.setProperty('resolution', v2_0.set(dw, dh), 0); this.watermarkMat.setProperty('scale', v2_0.set(scaleX, scaleY), 0); - this.watermarkMat.setProperty('translate', v2_0.set(dw * 0.5, dh * 0.1), 0); + this.watermarkMat.setProperty('translate', v2_0.set(dw * this.textXTrans, textYTrans), 0); this.watermarkMat.setProperty('percent', u_p); this.watermarkMat.setProperty('u_projection', this.projection); this.watermarkMat.passes[0].update(); @@ -214,7 +310,42 @@ export class SplashScreen { this.frame(); } - private initLogo () { + private initBG() { + const device = this.device; + + this.bgMat = new Material(); + this.bgMat.initialize({ effectName: 'util/splash-screen' }); + + const samplerInfo = new SamplerInfo(); + samplerInfo.addressU = Address.CLAMP; + samplerInfo.addressV = Address.CLAMP; + samplerInfo.addressW = Address.CLAMP; + this.sampler = device.getSampler(samplerInfo); + + this.bgTexture = device.createTexture(new TextureInfo( + TextureType.TEX2D, + TextureUsageBit.SAMPLED | TextureUsageBit.TRANSFER_DST, + Format.RGBA8, + this.bgImage.width, + this.bgImage.height, + )); + + const pass = this.bgMat.passes[0]; + const binding = pass.getBinding('mainTexture'); + pass.bindTexture(binding, this.bgTexture); + this.shader = pass.getShaderVariant()!; + const descriptorSet = pass.descriptorSet; + descriptorSet.bindSampler(binding, this.sampler); + descriptorSet.update(); + + const region = new BufferTextureCopy(); + region.texExtent.width = this.bgImage.width; + region.texExtent.height = this.bgImage.height; + region.texExtent.depth = 1; + device.copyTexImagesToTexture([this.bgImage], this.bgTexture, [region]); + } + + private initLogo() { const device = this.device; this.logoMat = new Material(); @@ -247,28 +378,40 @@ export class SplashScreen { region.texExtent.height = this.logoImage.height; region.texExtent.depth = 1; device.copyTexImagesToTexture([this.logoImage], this.logoTexture, [region]); + + const logoRatio = this.logoImage.width / this.logoImage.height; + if (logoRatio < 1) { + this.logoWidth = this.logoWidthTemp; + this.logoHeight = this.logoWidthTemp / logoRatio; + } else { + this.logoWidth = this.logoHeightTemp * logoRatio; + this.logoHeight = this.logoHeightTemp; + } } - private initWarterMark () { + private initWaterMark() { // create texture from image - const wartemarkImg = document.createElement('canvas'); - wartemarkImg.width = 330; wartemarkImg.height = 30; - wartemarkImg.style.width = `${wartemarkImg.width}`; - wartemarkImg.style.height = `${wartemarkImg.height}`; - const ctx = wartemarkImg.getContext('2d')!; - ctx.font = `${18}px Arial`; ctx.textBaseline = 'top'; ctx.textAlign = 'left'; ctx.fillStyle = '`#424242`'; - const text = 'Powered by Cocos Creator'; - const textMetrics = ctx.measureText(text); - ctx.fillText(text, (330 - textMetrics.width) / 2, 6); + const watermarkImg = ccwindow.document.createElement('canvas'); + watermarkImg.height = this.textHeight * this.scaleSize; + watermarkImg.style.width = `${watermarkImg.width}`; + watermarkImg.style.height = `${watermarkImg.height}`; + + const text = 'Created with Cocos'; + const ctx = watermarkImg.getContext('2d')!; + ctx.font = `${this.textSize * this.scaleSize}px Arial`; ctx.textBaseline = 'top'; ctx.textAlign = 'center'; ctx.fillStyle = '#707070'; + const textLength = ctx.measureText(text).width + 10; + watermarkImg.width = textLength; // Tips: Set canvas width will clean context style + ctx.font = `${this.textSize * this.scaleSize}px Arial`; ctx.textBaseline = 'top'; ctx.textAlign = 'center'; ctx.fillStyle = '#707070'; + ctx.fillText(text, watermarkImg.width / 2, 0); const region = new BufferTextureCopy(); - region.texExtent.width = wartemarkImg.width; - region.texExtent.height = wartemarkImg.height; + region.texExtent.width = watermarkImg.width; + region.texExtent.height = watermarkImg.height; region.texExtent.depth = 1; this.watermarkTexture = this.device.createTexture(new TextureInfo( TextureType.TEX2D, TextureUsageBit.SAMPLED | TextureUsageBit.TRANSFER_DST, - Format.RGBA8, wartemarkImg.width, wartemarkImg.height, + Format.RGBA8, watermarkImg.width, watermarkImg.height, )); - this.device.copyTexImagesToTexture([wartemarkImg], this.watermarkTexture, [region]); + this.device.copyTexImagesToTexture([watermarkImg], this.watermarkTexture, [region]); // create material this.watermarkMat = new Material(); this.watermarkMat.initialize({ effectName: 'util/splash-screen' }); @@ -278,7 +421,7 @@ export class SplashScreen { pass.descriptorSet.update(); } - private frame () { + private frame() { const { device, swapchain } = this; if (!sys.isXR || xr.entry.isRenderAllowable()) { @@ -286,12 +429,31 @@ export class SplashScreen { for (let xrEye = 0; xrEye < renderSize; xrEye++) { if (sys.isXR) { xr.entry.renderLoopStart(xrEye); + const xrConfigDeviceVendor = 13; + const compatibleDevice = 4; + if (xr.entry.getXRIntConfig(xrConfigDeviceVendor) !== compatibleDevice) { + const xrFov = xr.entry.getEyeFov(xrEye); + const left = Math.tan(xrFov[0]); + const right = Math.tan(xrFov[1]); + const bottom = Math.tan(xrFov[2]); + const top = Math.tan(xrFov[3]); + Mat4.ortho(this.projection, left, right, bottom, top, -1, 1, device.capabilities.clipSpaceMinZ, + device.capabilities.clipSpaceSignY, swapchain.surfaceTransform); + this.bgMat.setProperty('u_projection', this.projection); + this.bgMat.passes[0].update(); + this.logoMat.setProperty('u_projection', this.projection); + this.logoMat.passes[0].update(); + if (this.watermarkMat) { + this.watermarkMat.setProperty('u_projection', this.projection); + this.watermarkMat.passes[0].update(); + } + } } device.acquire([swapchain]); // record command const cmdBuff = this.cmdBuff; - const framebuffer = legacyCC.director.root!.mainWindow!.framebuffer; + const framebuffer = cclegacy.director.root!.mainWindow!.framebuffer; const renderArea = this.renderArea; renderArea.width = swapchain.width; @@ -300,6 +462,15 @@ export class SplashScreen { cmdBuff.begin(); cmdBuff.beginRenderPass(framebuffer.renderPass, framebuffer, renderArea, this.clearColors, 1.0, 0); + const bgPass = this.bgMat.passes[0]; + const bgPso = PipelineStateManager.getOrCreatePipelineState(device, bgPass, this.shader, framebuffer.renderPass, + this.quadAssmebler); + + cmdBuff.bindPipelineState(bgPso); + cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, bgPass.descriptorSet); + cmdBuff.bindInputAssembler(this.quadAssmebler); + cmdBuff.draw(this.quadAssmebler); + const logoPass = this.logoMat.passes[0]; const logoPso = PipelineStateManager.getOrCreatePipelineState(device, logoPass, this.shader, framebuffer.renderPass, this.quadAssmebler); @@ -309,7 +480,7 @@ export class SplashScreen { cmdBuff.bindInputAssembler(this.quadAssmebler); cmdBuff.draw(this.quadAssmebler); - if (this.settings.displayWatermark && this.watermarkMat) { + if (this.watermarkMat) { const wartermarkPass = this.watermarkMat.passes[0]; const watermarkPso = PipelineStateManager.getOrCreatePipelineState(device, wartermarkPass, this.shader, framebuffer.renderPass, this.quadAssmebler); @@ -332,10 +503,16 @@ export class SplashScreen { } } - private destroy () { + private destroy() { this.device = null!; this.swapchain = null!; this.clearColors = null!; + if ((this.bgImage as any).destroy) (this.bgImage as any).destroy(); + this.bgImage = null!; + this.bgMat.destroy(); + this.bgMat = null!; + this.bgTexture.destroy(); + this.bgTexture = null!; if ((this.logoImage as any).destroy) (this.logoImage as any).destroy(); this.logoImage = null!; this.renderArea = null!; @@ -366,14 +543,14 @@ export class SplashScreen { private static _ins?: SplashScreen; - public static get instance () { + public static get instance() { if (!SplashScreen._ins) { SplashScreen._ins = new SplashScreen(); } return SplashScreen._ins; } - private constructor () { } + private constructor() { } } -legacyCC.internal.SplashScreen = SplashScreen; +cclegacy.internal.SplashScreen = SplashScreen; diff --git a/cocos/gfx/base/buffer.ts b/cocos/gfx/base/buffer.ts index 683f2cc0dcc..88e8a435a1f 100644 --- a/cocos/gfx/base/buffer.ts +++ b/cocos/gfx/base/buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BufferFlagBit, diff --git a/cocos/gfx/base/command-buffer.ts b/cocos/gfx/base/command-buffer.ts index 176b64d1021..332e0da1e83 100644 --- a/cocos/gfx/base/command-buffer.ts +++ b/cocos/gfx/base/command-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Buffer } from './buffer'; import { DescriptorSet } from './descriptor-set'; @@ -37,7 +36,7 @@ import { StencilFace, CommandBufferType, CommandBufferInfo, - BufferTextureCopy, Color, Rect, Viewport, DrawInfo, + BufferTextureCopy, Color, Rect, Viewport, DrawInfo, Filter, TextureBlit, } from './define'; import { GeneralBarrier } from './states/general-barrier'; import { TextureBarrier } from './states/texture-barrier'; @@ -268,4 +267,15 @@ export abstract class CommandBuffer extends GFXObject { buffers?: Readonly, textureBarriers?: Readonly, textures?: Readonly): void; + + /** + * @en blit data from regions of source texture to regions of destination texture. + * @zh 将数据从源纹理的区域拷贝到目标纹理的区域。 + * + * @param srcTexture The source texture. + * @param dstTexture The destination texture. + * @param regions The region descriptions. + * @param filter The filter to use. + */ + public abstract blitTexture(srcTexture: Readonly, dstTexture: Texture, regions: Readonly, filter: Filter): void; } diff --git a/cocos/gfx/base/define.ts b/cocos/gfx/base/define.ts index 748b77c137b..2f99290d7c9 100644 --- a/cocos/gfx/base/define.ts +++ b/cocos/gfx/base/define.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Queue } from './queue'; import { Buffer } from './buffer'; @@ -34,7 +33,7 @@ import { Sampler } from './states/sampler'; import { GeneralBarrier } from './states/general-barrier'; import { TextureBarrier } from './states/texture-barrier'; import { BufferBarrier } from './states/buffer-barrier'; -import { GCObject } from '../../core/data/gc-object'; +import { GCObject } from '../../core'; interface ICopyable { copy (info: ICopyable): ICopyable; } @@ -736,6 +735,8 @@ export class DeviceCaps { public maxUniformBlockSize: number = 0, public maxTextureSize: number = 0, public maxCubeMapTextureSize: number = 0, + public maxArrayTextureLayers: number = 0, + public max3DTextureSize: number = 0, public uboOffsetAlignment: number = 1, public maxComputeSharedMemorySize: number = 0, public maxComputeWorkGroupInvocations: number = 0, @@ -761,6 +762,8 @@ export class DeviceCaps { this.maxUniformBlockSize = info.maxUniformBlockSize; this.maxTextureSize = info.maxTextureSize; this.maxCubeMapTextureSize = info.maxCubeMapTextureSize; + this.maxArrayTextureLayers = info.maxArrayTextureLayers; + this.max3DTextureSize = info.max3DTextureSize; this.uboOffsetAlignment = info.uboOffsetAlignment; this.maxComputeSharedMemorySize = info.maxComputeSharedMemorySize; this.maxComputeWorkGroupInvocations = info.maxComputeWorkGroupInvocations; @@ -1254,6 +1257,7 @@ export class UniformBlock { public name: string = '', public members: Uniform[] = [], public count: number = 0, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1262,6 +1266,7 @@ export class UniformBlock { this.name = info.name; deepCopy(this.members, info.members, Uniform); this.count = info.count; + this.flattened = info.flattened; return this; } } @@ -1275,6 +1280,7 @@ export class UniformSamplerTexture { public name: string = '', public type: Type = Type.UNKNOWN, public count: number = 0, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1283,6 +1289,7 @@ export class UniformSamplerTexture { this.name = info.name; this.type = info.type; this.count = info.count; + this.flattened = info.flattened; return this; } } @@ -1295,6 +1302,7 @@ export class UniformSampler { public binding: number = 0, public name: string = '', public count: number = 0, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1302,6 +1310,7 @@ export class UniformSampler { this.binding = info.binding; this.name = info.name; this.count = info.count; + this.flattened = info.flattened; return this; } } @@ -1315,6 +1324,7 @@ export class UniformTexture { public name: string = '', public type: Type = Type.UNKNOWN, public count: number = 0, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1323,6 +1333,7 @@ export class UniformTexture { this.name = info.name; this.type = info.type; this.count = info.count; + this.flattened = info.flattened; return this; } } @@ -1337,6 +1348,7 @@ export class UniformStorageImage { public type: Type = Type.UNKNOWN, public count: number = 0, public memoryAccess: MemoryAccess = MemoryAccessBit.READ_WRITE, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1346,6 +1358,7 @@ export class UniformStorageImage { this.type = info.type; this.count = info.count; this.memoryAccess = info.memoryAccess; + this.flattened = info.flattened; return this; } } @@ -1359,6 +1372,7 @@ export class UniformStorageBuffer { public name: string = '', public count: number = 0, public memoryAccess: MemoryAccess = MemoryAccessBit.READ_WRITE, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1367,6 +1381,7 @@ export class UniformStorageBuffer { this.name = info.name; this.count = info.count; this.memoryAccess = info.memoryAccess; + this.flattened = info.flattened; return this; } } @@ -1379,6 +1394,7 @@ export class UniformInputAttachment { public binding: number = 0, public name: string = '', public count: number = 0, + public flattened: number = 0, ) {} public copy (info: Readonly) { @@ -1386,6 +1402,7 @@ export class UniformInputAttachment { this.binding = info.binding; this.name = info.name; this.count = info.count; + this.flattened = info.flattened; return this; } } diff --git a/cocos/gfx/base/descriptor-set-layout.ts b/cocos/gfx/base/descriptor-set-layout.ts index afd53e3b178..0258a7b54db 100644 --- a/cocos/gfx/base/descriptor-set-layout.ts +++ b/cocos/gfx/base/descriptor-set-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { GFXObject, ObjectType, DescriptorSetLayoutBinding, DescriptorSetLayoutInfo } from './define'; diff --git a/cocos/gfx/base/descriptor-set.ts b/cocos/gfx/base/descriptor-set.ts index 2fc14bbd389..23796d21a99 100644 --- a/cocos/gfx/base/descriptor-set.ts +++ b/cocos/gfx/base/descriptor-set.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Buffer } from './buffer'; import { DescriptorSetLayout } from './descriptor-set-layout'; diff --git a/cocos/gfx/base/device.ts b/cocos/gfx/base/device.ts index 83fe68140cf..3ccf22f4c00 100644 --- a/cocos/gfx/base/device.ts +++ b/cocos/gfx/base/device.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { API, Feature, MemoryStatus, CommandBufferInfo, BufferInfo, BufferViewInfo, TextureInfo, TextureViewInfo, SamplerInfo, DescriptorSetInfo, ShaderInfo, InputAssemblerInfo, RenderPassInfo, FramebufferInfo, DescriptorSetLayoutInfo, PipelineLayoutInfo, QueueInfo, BufferTextureCopy, DeviceInfo, DeviceCaps, GeneralBarrierInfo, TextureBarrierInfo, BufferBarrierInfo, - SwapchainInfo, BindingMappingInfo, Format, FormatFeature, + SwapchainInfo, BindingMappingInfo, Format, FormatFeature, TextureType, TextureUsageBit, + TextureFlagBit, Offset, Extent, SampleCount, TextureSubresLayers, } from './define'; import { Buffer } from './buffer'; import { CommandBuffer } from './command-buffer'; @@ -353,3 +353,88 @@ export abstract class Device { return this._formatFeatures[format]; } } + +export class DefaultResource { + private _texture2D: Texture | null = null; + private _texture3D: Texture | null = null; + private _textureCube: Texture | null = null; + private _texture2DArray: Texture | null = null; + + constructor (device: Device) { + const bufferSize = 64; + // create a new buffer and fill it with a white pixel + const buffer = new Uint8Array(bufferSize); + buffer.fill(255); + if (device.capabilities.maxTextureSize >= 2) { + this._texture2D = device.createTexture(new TextureInfo( + TextureType.TEX2D, + TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, + Format.RGBA8, + 2, 2, + TextureFlagBit.NONE, + )); + const copyRegion = new BufferTextureCopy(0, 0, 0, new Offset(0, 0, 0), new Extent(2, 2, 1)); + device.copyBuffersToTexture([buffer], this._texture2D, [copyRegion]); + } + if (device.capabilities.maxTextureSize >= 2) { + this._textureCube = device.createTexture(new TextureInfo( + TextureType.CUBE, + TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, + Format.RGBA8, + 2, 2, + TextureFlagBit.NONE, + 6, + )); + const copyRegion = new BufferTextureCopy(0, 0, 0, new Offset(0, 0, 0), new Extent(2, 2, 1)); + device.copyBuffersToTexture([buffer], this._textureCube, [copyRegion]); + copyRegion.texSubres.baseArrayLayer = 1; + device.copyBuffersToTexture([buffer], this._textureCube, [copyRegion]); + copyRegion.texSubres.baseArrayLayer = 2; + device.copyBuffersToTexture([buffer], this._textureCube, [copyRegion]); + copyRegion.texSubres.baseArrayLayer = 3; + device.copyBuffersToTexture([buffer], this._textureCube, [copyRegion]); + copyRegion.texSubres.baseArrayLayer = 4; + device.copyBuffersToTexture([buffer], this._textureCube, [copyRegion]); + copyRegion.texSubres.baseArrayLayer = 5; + device.copyBuffersToTexture([buffer], this._textureCube, [copyRegion]); + } + if (device.capabilities.max3DTextureSize >= 2) { + this._texture3D = device.createTexture(new TextureInfo( + TextureType.TEX3D, + TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, + Format.RGBA8, + 2, 2, + TextureFlagBit.NONE, + 1, 1, + SampleCount.ONE, + 2, + )); + const copyRegion = new BufferTextureCopy(0, 0, 0, new Offset(0, 0, 0), new Extent(2, 2, 2), new TextureSubresLayers(0, 0, 1)); + device.copyBuffersToTexture([buffer], this._texture3D, [copyRegion]); + } + if (device.capabilities.maxArrayTextureLayers >= 2) { + this._texture2DArray = device.createTexture(new TextureInfo( + TextureType.TEX2D_ARRAY, + TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, + Format.RGBA8, + 2, 2, + TextureFlagBit.NONE, + 2, + )); + const copyRegion = new BufferTextureCopy(0, 0, 0, new Offset(0, 0, 0), new Extent(2, 2, 1), new TextureSubresLayers(0, 0, 1)); + device.copyBuffersToTexture([buffer], this._texture2DArray, [copyRegion]); + copyRegion.texSubres.baseArrayLayer = 1; + device.copyBuffersToTexture([buffer], this._texture2DArray, [copyRegion]); + } + } + + public getTexture (type: TextureType) { + switch (type) { + case TextureType.TEX2D: return this._texture2D; + case TextureType.TEX3D: return this._texture3D; + case TextureType.CUBE: return this._textureCube; + case TextureType.TEX2D_ARRAY: return this._texture2DArray; + default: return null; + } + } +} diff --git a/cocos/gfx/base/framebuffer.ts b/cocos/gfx/base/framebuffer.ts index b5e89ac207c..71c04e1f54b 100644 --- a/cocos/gfx/base/framebuffer.ts +++ b/cocos/gfx/base/framebuffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { RenderPass } from './render-pass'; import { Texture } from './texture'; diff --git a/cocos/gfx/base/input-assembler.ts b/cocos/gfx/base/input-assembler.ts index 826b9cce401..66ca33015c3 100644 --- a/cocos/gfx/base/input-assembler.ts +++ b/cocos/gfx/base/input-assembler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; +import { murmurhash2_32_gc } from '../../core'; import { Buffer } from './buffer'; import { Attribute, GFXObject, ObjectType, InputAssemblerInfo, DrawInfo } from './define'; diff --git a/cocos/gfx/base/pipeline-layout.ts b/cocos/gfx/base/pipeline-layout.ts index 413ef52ae3b..4e29fc9bc48 100644 --- a/cocos/gfx/base/pipeline-layout.ts +++ b/cocos/gfx/base/pipeline-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSetLayout } from './descriptor-set-layout'; import { GFXObject, ObjectType, PipelineLayoutInfo } from './define'; diff --git a/cocos/gfx/base/pipeline-state.editor.ts b/cocos/gfx/base/pipeline-state.editor.ts new file mode 100644 index 00000000000..ad665bb785c --- /dev/null +++ b/cocos/gfx/base/pipeline-state.editor.ts @@ -0,0 +1,310 @@ +/* + Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated engine source code (the "Software"), a limited, + worldwide, royalty-free, non-assignable, revocable and non-exclusive license + to use Cocos Creator solely to develop games on your target platforms. You shall + not use Cocos Creator software for developing other software or tools that's + used for developing games. You are not granted to publish, distribute, + sublicense, and/or sell copies of Cocos Creator. + + The software or tools in this License Agreement are licensed, not sold. + Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +import { ccclass, serializable, type, editable } from 'cc.decorator'; + +import { + RasterizerState, + DepthStencilState, + BlendTarget, + BlendState, +} from './pipeline-state'; + +import { + PolygonMode, + ShadeModel, + CullMode, + ComparisonFunc, + StencilOp, + BlendFactor, + BlendOp, + ColorMask, + PrimitiveMode, + DynamicStateFlagBit, + Color, +} from './define'; + +import { EffectAsset } from '../../asset/assets/effect-asset'; +import { RenderPassStage } from '../../rendering/define'; +import { CCString } from '../../core'; + +@ccclass('RasterizerState') +export class RasterizerStateEditor extends RasterizerState { + @serializable + @editable + public isDiscard = false; + + @serializable + @editable + @type(PolygonMode) + public polygonMode = PolygonMode.FILL; + + @type(ShadeModel) + @serializable + @editable + public shadeModel = ShadeModel.GOURAND; + + @type(CullMode) + @serializable + @editable + public cullMode = CullMode.BACK; + + @serializable + @editable + public isFrontFaceCCW = true; + + @serializable + @editable + public depthBias = 0; + + @serializable + @editable + public depthBiasClamp = 0.0; + + @serializable + @editable + public depthBiasSlop = 0.0; + + @serializable + @editable + public isDepthClip = true; + + @serializable + @editable + public isMultisample = false; + + @serializable + @editable + public lineWidth = 1.0; +} + +@ccclass('DepthStencilState') +export class DepthStencilStateEditor extends DepthStencilState { + @serializable + @editable + public depthTest = true; + + @serializable + @editable + public depthWrite = true; + + @type(ComparisonFunc) + @serializable + @editable + public depthFunc = ComparisonFunc.LESS; + + @serializable + @editable + public stencilTestFront = false; + + @type(ComparisonFunc) + @serializable + @editable + public stencilFuncFront = ComparisonFunc.ALWAYS; + + @serializable + @editable + public stencilReadMaskFront = 0xffffffff; + + @serializable + @editable + public stencilWriteMaskFront = 0xffffffff; + + @type(StencilOp) + @serializable + @editable + public stencilFailOpFront = StencilOp.KEEP; + + @type(StencilOp) + @serializable + @editable + public stencilZFailOpFront = StencilOp.KEEP; + + @type(StencilOp) + @serializable + @editable + public stencilPassOpFront = StencilOp.KEEP; + + @serializable + @editable + public stencilRefFront = 1; + + @serializable + @editable + public stencilTestBack = false; + + @type(ComparisonFunc) + @serializable + @editable + public stencilFuncBack = ComparisonFunc.ALWAYS; + + @serializable + @editable + public stencilReadMaskBack = 0xffffffff; + + @serializable + @editable + public stencilWriteMaskBack = 0xffffffff; + + @type(StencilOp) + @serializable + @editable + public stencilFailOpBack = StencilOp.KEEP; + + @type(StencilOp) + @serializable + @editable + public stencilZFailOpBack = StencilOp.KEEP; + + @type(StencilOp) + @serializable + @editable + public stencilPassOpBack = StencilOp.KEEP; + + @serializable + @editable + public stencilRefBack = 1; +} + +// description of pipeline-state.ts class BlendTarget +@ccclass('BlendTarget') +export class BlendTargetEditor extends BlendTarget { + @serializable + @editable + public blend = false; + + @type(BlendFactor) + @serializable + @editable + public blendSrc = BlendFactor.ONE; + + @type({ type: BlendFactor }) + @serializable + @editable + public blendDst = BlendFactor.ZERO; + + @type(BlendOp) + @serializable + @editable + public blendEq = BlendOp.ADD; + + @type(BlendFactor) + @serializable + @editable + public blendSrcAlpha = BlendFactor.ONE; + + @type(BlendFactor) + @serializable + @editable + public blendDstAlpha = BlendFactor.ZERO; + + @type(BlendOp) + @serializable + @editable + public blendAlphaEq = BlendOp.ADD; + + @type(ColorMask) + @serializable + @editable + public blendColorMask = ColorMask.ALL; +} + +@ccclass('BlendState') +export class BlendStateEditor extends BlendState { + @serializable + @editable + public isA2C = false; + + @serializable + @editable + public isIndepend = false; + + @type(Color) + @serializable + @editable + public blendColor: Color = new Color(); + + @type([BlendTargetEditor]) + @serializable + @editable + public targets: BlendTargetEditor[] = []; + + public init (blendState: any) { + let length = 1; + if (blendState && blendState.targets) { + length = blendState.targets.length; + } + + for (let i = 0; i < length; i++) { + this.targets.push(new BlendTargetEditor()); + } + } +} + +@ccclass('PassStates') +export class PassStatesEditor implements EffectAsset.IPassStates { + @serializable + @editable + public priority = 128; + + @type(PrimitiveMode) + @serializable + @editable + public primitive = PrimitiveMode.TRIANGLE_LIST; + + @type(RenderPassStage) + @serializable + @editable + public stage = RenderPassStage.DEFAULT; + + @type(RasterizerStateEditor) + @serializable + @editable + public rasterizerState: RasterizerStateEditor = new RasterizerStateEditor(); + + @type(DepthStencilStateEditor) + @serializable + @editable + public depthStencilState: DepthStencilStateEditor = new DepthStencilStateEditor(); + + @type(BlendStateEditor) + @serializable + @editable + public blendState: BlendStateEditor = new BlendStateEditor(); + + @type([DynamicStateFlagBit]) + @serializable + @editable + public dynamics = []; + + @type([CCString]) + @serializable + @editable + public customizations = []; + + @serializable + @editable + public phase = ''; +} diff --git a/cocos/gfx/base/pipeline-state.jsb.ts b/cocos/gfx/base/pipeline-state.jsb.ts index 30adc71ece1..f404c7cfeec 100644 --- a/cocos/gfx/base/pipeline-state.jsb.ts +++ b/cocos/gfx/base/pipeline-state.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ declare const gfx: any; @@ -586,14 +585,14 @@ export class BlendState { this._nativeObj = new gfx.BlendState(); this._setTargets(targets); this.blendColor = blendColor; - this.isA2c = isA2C; + this.isA2C = isA2C; this.isIndepend = isIndepend; } - get isA2c (): boolean { + get isA2C (): boolean { return this._isA2C; } - set isA2c (val: boolean) { + set isA2C (val: boolean) { this._isA2C = val; this._nativeObj.isA2C = val; } @@ -629,7 +628,7 @@ export class BlendState { } public reset () { - this.isA2c = false; + this.isA2C = false; this.isIndepend = false; this.blendColor = new Color(0, 0, 0, 0); diff --git a/cocos/gfx/base/pipeline-state.ts b/cocos/gfx/base/pipeline-state.ts index 983d0a0e905..5943d8c57d7 100644 --- a/cocos/gfx/base/pipeline-state.ts +++ b/cocos/gfx/base/pipeline-state.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineLayout } from './pipeline-layout'; import { RenderPass } from './render-pass'; diff --git a/cocos/gfx/base/queue.ts b/cocos/gfx/base/queue.ts index c1e1256d8b4..d80c02ed35a 100644 --- a/cocos/gfx/base/queue.ts +++ b/cocos/gfx/base/queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { CommandBuffer } from './command-buffer'; import { GFXObject, ObjectType, QueueType, QueueInfo } from './define'; diff --git a/cocos/gfx/base/render-pass.ts b/cocos/gfx/base/render-pass.ts index 466a96576cf..c40f303d707 100644 --- a/cocos/gfx/base/render-pass.ts +++ b/cocos/gfx/base/render-pass.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; +import { murmurhash2_32_gc } from '../../core'; import { GFXObject, ObjectType, diff --git a/cocos/gfx/base/shader.ts b/cocos/gfx/base/shader.ts index 0367cf74a13..e66622196a4 100644 --- a/cocos/gfx/base/shader.ts +++ b/cocos/gfx/base/shader.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { GFXObject, ObjectType, ShaderInfo, ShaderStage, UniformBlock, UniformSampler, Attribute } from './define'; diff --git a/cocos/gfx/base/states/buffer-barrier.ts b/cocos/gfx/base/states/buffer-barrier.ts index ae2a6730cb4..c3fd997c6f1 100644 --- a/cocos/gfx/base/states/buffer-barrier.ts +++ b/cocos/gfx/base/states/buffer-barrier.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { murmurhash2_32_gc } from '../../../core/algorithm/murmurhash2_gc'; +import { murmurhash2_32_gc } from '../../../core'; import { GFXObject, ObjectType, BufferBarrierInfo } from '../define'; /** diff --git a/cocos/gfx/base/states/general-barrier.ts b/cocos/gfx/base/states/general-barrier.ts index 6f452138cbe..78e77860339 100644 --- a/cocos/gfx/base/states/general-barrier.ts +++ b/cocos/gfx/base/states/general-barrier.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { murmurhash2_32_gc } from '../../../core/algorithm/murmurhash2_gc'; +import { murmurhash2_32_gc } from '../../../core'; import { GFXObject, ObjectType, GeneralBarrierInfo } from '../define'; /** diff --git a/cocos/gfx/base/states/sampler.ts b/cocos/gfx/base/states/sampler.ts index c1611704092..3ac8865af95 100644 --- a/cocos/gfx/base/states/sampler.ts +++ b/cocos/gfx/base/states/sampler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { GFXObject, ObjectType, SamplerInfo } from '../define'; diff --git a/cocos/gfx/base/states/texture-barrier.ts b/cocos/gfx/base/states/texture-barrier.ts index 9ae5c795387..a00765d1743 100644 --- a/cocos/gfx/base/states/texture-barrier.ts +++ b/cocos/gfx/base/states/texture-barrier.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { murmurhash2_32_gc } from '../../../core/algorithm/murmurhash2_gc'; +import { murmurhash2_32_gc } from '../../../core'; import { GFXObject, ObjectType, TextureBarrierInfo } from '../define'; /** diff --git a/cocos/gfx/base/swapchain.ts b/cocos/gfx/base/swapchain.ts index f44f4f46d6b..829c8009044 100644 --- a/cocos/gfx/base/swapchain.ts +++ b/cocos/gfx/base/swapchain.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { GFXObject, ObjectType, SurfaceTransform, SwapchainInfo } from './define'; import { Texture } from './texture'; diff --git a/cocos/gfx/base/texture.ts b/cocos/gfx/base/texture.ts index aa405017f68..de1fec1e484 100644 --- a/cocos/gfx/base/texture.ts +++ b/cocos/gfx/base/texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Format, @@ -168,6 +167,8 @@ export abstract class Texture extends GFXObject { public abstract destroy (): void; + public abstract getGLTextureHandle (): number; + /** * @en Resize texture. * @zh 重置纹理大小。 diff --git a/cocos/gfx/deprecated-3.0.0.ts b/cocos/gfx/deprecated-3.0.0.ts index d78b88ba8b6..c617631fb42 100644 --- a/cocos/gfx/deprecated-3.0.0.ts +++ b/cocos/gfx/deprecated-3.0.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { replaceProperty, removeProperty } from '../core/utils/x-deprecated'; -import { legacyCC } from '../core/global-exports'; +import { replaceProperty, removeProperty, cclegacy } from '../core'; // Deprecated CC polyfill const polyfills = { @@ -98,17 +96,17 @@ for (const name in polyfills) { newName = name; } // Deprecation - replaceProperty(legacyCC, 'cc', [ + replaceProperty(cclegacy, 'cc', [ { name, newName, - target: legacyCC.gfx, + target: cclegacy.gfx, targetName: 'cc.gfx', }, ]); } -removeProperty(legacyCC, 'cc', [ +removeProperty(cclegacy, 'cc', [ { name: 'GFX_MAX_VERTEX_ATTRIBUTES' }, { name: 'GFX_MAX_TEXTURE_UNITS' }, { name: 'GFX_MAX_ATTACHMENTS' }, diff --git a/cocos/gfx/deprecated-3.5.0.ts b/cocos/gfx/deprecated-3.5.0.ts index 09cf9da63a2..8ad0214e4e4 100644 --- a/cocos/gfx/deprecated-3.5.0.ts +++ b/cocos/gfx/deprecated-3.5.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { removeProperty, replaceProperty } from '../core/utils/x-deprecated'; +import { removeProperty, replaceProperty } from '../core'; import { Device } from './base/device'; import { Feature, ColorAttachment, DepthStencilAttachment } from './base/define'; diff --git a/cocos/gfx/device-manager.ts b/cocos/gfx/device-manager.ts index 2d66aaf237d..c9a0a45150f 100644 --- a/cocos/gfx/device-manager.ts +++ b/cocos/gfx/device-manager.ts @@ -1,19 +1,18 @@ /* eslint-disable max-len */ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,17 +21,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { JSB, WEBGPU } from 'internal:constants'; -import { legacyCC } from '../core/global-exports'; -import { error, getError } from '../core/platform/debug'; -import { sys } from '../core/platform/sys'; +import { cclegacy, error, getError, sys, screen, Settings, settings } from '../core'; import { BindingMappingInfo, DeviceInfo, SwapchainInfo } from './base/define'; import { Device } from './base/device'; import { Swapchain } from './base/swapchain'; -import { screen } from '../core/platform/screen'; -import { Settings, settings } from '../core/settings'; import { BrowserType } from '../../pal/system-info/enum-type'; /** @@ -117,11 +112,11 @@ export class DeviceManager { if (this._renderType === RenderType.WEBGL) { const deviceInfo = new DeviceInfo(bindingMappingInfo); - if (JSB && window.gfx) { + if (JSB && (globalThis as any).gfx) { this._gfxDevice = gfx.DeviceManager.create(deviceInfo); } else { - let useWebGL2 = (!!window.WebGL2RenderingContext); - const userAgent = window.navigator.userAgent.toLowerCase(); + let useWebGL2 = (!!globalThis.WebGL2RenderingContext); + const userAgent = globalThis.navigator.userAgent.toLowerCase(); if (userAgent.indexOf('safari') !== -1 && userAgent.indexOf('chrome') === -1 || sys.browserType === BrowserType.UC // UC browser implementation doesn't conform to WebGL2 standard ) { @@ -130,16 +125,16 @@ export class DeviceManager { const deviceCtors: Constructor[] = []; if (WEBGPU) { - deviceCtors.push(legacyCC.WebGPUDevice); + deviceCtors.push(cclegacy.WebGPUDevice); } - if (useWebGL2 && legacyCC.WebGL2Device) { - deviceCtors.push(legacyCC.WebGL2Device); + if (useWebGL2 && cclegacy.WebGL2Device) { + deviceCtors.push(cclegacy.WebGL2Device); } - if (legacyCC.WebGLDevice) { - deviceCtors.push(legacyCC.WebGLDevice); + if (cclegacy.WebGLDevice) { + deviceCtors.push(cclegacy.WebGLDevice); } - if (legacyCC.EmptyDevice) { - deviceCtors.push(legacyCC.EmptyDevice); + if (cclegacy.EmptyDevice) { + deviceCtors.push(cclegacy.EmptyDevice); } Device.canvas = canvas!; @@ -149,8 +144,8 @@ export class DeviceManager { } this._initSwapchain(); } - } else if (this._renderType === RenderType.HEADLESS && legacyCC.EmptyDevice) { - this._gfxDevice = new legacyCC.EmptyDevice(); + } else if (this._renderType === RenderType.HEADLESS && cclegacy.EmptyDevice) { + this._gfxDevice = new cclegacy.EmptyDevice(); this._gfxDevice.initialize(new DeviceInfo(bindingMappingInfo)); this._initSwapchain(); } diff --git a/cocos/gfx/empty/empty-buffer.ts b/cocos/gfx/empty/empty-buffer.ts index 93ec343e55c..009c3c0d08f 100644 --- a/cocos/gfx/empty/empty-buffer.ts +++ b/cocos/gfx/empty/empty-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BufferSource, BufferInfo, BufferViewInfo } from '../base/define'; import { Buffer } from '../base/buffer'; diff --git a/cocos/gfx/empty/empty-command-buffer.ts b/cocos/gfx/empty/empty-command-buffer.ts index 32397ccf223..770544f5943 100644 --- a/cocos/gfx/empty/empty-command-buffer.ts +++ b/cocos/gfx/empty/empty-command-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { Buffer } from '../base/buffer'; @@ -34,7 +33,9 @@ import { RenderPass } from '../base/render-pass'; import { GeneralBarrier } from '../base/states/general-barrier'; import { TextureBarrier } from '../base/states/texture-barrier'; import { BufferBarrier } from '../base/states/buffer-barrier'; -import { StencilFace, BufferSource, CommandBufferInfo, BufferTextureCopy, Color, Rect, Viewport, DrawInfo } from '../base/define'; +import { StencilFace, BufferSource, CommandBufferInfo, BufferTextureCopy, Color, + Rect, Viewport, DrawInfo, TextureBlit, Filter, +} from '../base/define'; export class EmptyCommandBuffer extends CommandBuffer { public initialize (info: Readonly) { @@ -66,4 +67,5 @@ export class EmptyCommandBuffer extends CommandBuffer { buffers?: Readonly, textureBarriers?: Readonly, textures?: Readonly) {} + public blitTexture (srcTexture: Readonly, dstTexture: Texture, regions: Readonly, filter: Filter): void {} } diff --git a/cocos/gfx/empty/empty-descriptor-set-layout.ts b/cocos/gfx/empty/empty-descriptor-set-layout.ts index 842280664aa..7e59e095c93 100644 --- a/cocos/gfx/empty/empty-descriptor-set-layout.ts +++ b/cocos/gfx/empty/empty-descriptor-set-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSetLayoutInfo } from '../base/define'; import { DescriptorSetLayout } from '../base/descriptor-set-layout'; diff --git a/cocos/gfx/empty/empty-descriptor-set.ts b/cocos/gfx/empty/empty-descriptor-set.ts index 2e543a74f4f..b75a15f31c8 100644 --- a/cocos/gfx/empty/empty-descriptor-set.ts +++ b/cocos/gfx/empty/empty-descriptor-set.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { DescriptorSetInfo } from '../base/define'; diff --git a/cocos/gfx/empty/empty-device.ts b/cocos/gfx/empty/empty-device.ts index 0b53ba4552a..8958073ebda 100644 --- a/cocos/gfx/empty/empty-device.ts +++ b/cocos/gfx/empty/empty-device.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { DescriptorSetLayout } from '../base/descriptor-set-layout'; @@ -60,8 +59,7 @@ import { EmptyRenderPass } from './empty-render-pass'; import { EmptyShader } from './empty-shader'; import { EmptySwapchain } from './empty-swapchain'; import { EmptyTexture } from './empty-texture'; -import { debug } from '../../core'; -import { legacyCC } from '../../core/global-exports'; +import { debug, cclegacy } from '../../core'; export class EmptyDevice extends Device { private _swapchain: EmptySwapchain | null = null; @@ -217,4 +215,4 @@ export class EmptyDevice extends Device { public copyTexImagesToTexture (texImages: Readonly, texture: Texture, regions: Readonly) {} } -legacyCC.EmptyDevice = EmptyDevice; +cclegacy.EmptyDevice = EmptyDevice; diff --git a/cocos/gfx/empty/empty-framebuffer.ts b/cocos/gfx/empty/empty-framebuffer.ts index 1ab75b59f76..bc9d01ec872 100644 --- a/cocos/gfx/empty/empty-framebuffer.ts +++ b/cocos/gfx/empty/empty-framebuffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { FramebufferInfo } from '../base/define'; import { Framebuffer } from '../base/framebuffer'; diff --git a/cocos/gfx/empty/empty-input-assembler.ts b/cocos/gfx/empty/empty-input-assembler.ts index e09f3646920..b266c176ffe 100644 --- a/cocos/gfx/empty/empty-input-assembler.ts +++ b/cocos/gfx/empty/empty-input-assembler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { InputAssemblerInfo } from '../base/define'; import { InputAssembler } from '../base/input-assembler'; diff --git a/cocos/gfx/empty/empty-pipeline-layout.ts b/cocos/gfx/empty/empty-pipeline-layout.ts index daa885df506..709d509a72a 100644 --- a/cocos/gfx/empty/empty-pipeline-layout.ts +++ b/cocos/gfx/empty/empty-pipeline-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineLayout } from '../base/pipeline-layout'; import { PipelineLayoutInfo } from '../base/define'; diff --git a/cocos/gfx/empty/empty-pipeline-state.ts b/cocos/gfx/empty/empty-pipeline-state.ts index 3354bb3c8e5..43329304023 100644 --- a/cocos/gfx/empty/empty-pipeline-state.ts +++ b/cocos/gfx/empty/empty-pipeline-state.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineState, PipelineStateInfo } from '../base/pipeline-state'; diff --git a/cocos/gfx/empty/empty-queue.ts b/cocos/gfx/empty/empty-queue.ts index 35b73206503..bcf8fee8c3f 100644 --- a/cocos/gfx/empty/empty-queue.ts +++ b/cocos/gfx/empty/empty-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { QueueInfo } from '../base/define'; import { CommandBuffer } from '../base/command-buffer'; diff --git a/cocos/gfx/empty/empty-render-pass.ts b/cocos/gfx/empty/empty-render-pass.ts index 4a564ebb267..fb0bfd341fe 100644 --- a/cocos/gfx/empty/empty-render-pass.ts +++ b/cocos/gfx/empty/empty-render-pass.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { RenderPassInfo } from '../base/define'; import { RenderPass } from '../base/render-pass'; diff --git a/cocos/gfx/empty/empty-shader.ts b/cocos/gfx/empty/empty-shader.ts index c90955115f4..4c626f96087 100644 --- a/cocos/gfx/empty/empty-shader.ts +++ b/cocos/gfx/empty/empty-shader.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { debug } from '../../core'; import { ShaderInfo } from '../base/define'; diff --git a/cocos/gfx/empty/empty-swapchain.ts b/cocos/gfx/empty/empty-swapchain.ts index af1271fb7bf..651fed9edba 100644 --- a/cocos/gfx/empty/empty-swapchain.ts +++ b/cocos/gfx/empty/empty-swapchain.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Format, SwapchainInfo, SurfaceTransform } from '../base/define'; import { Swapchain } from '../base/swapchain'; diff --git a/cocos/gfx/empty/empty-texture.ts b/cocos/gfx/empty/empty-texture.ts index 326f50e5ab5..3256020e53a 100644 --- a/cocos/gfx/empty/empty-texture.ts +++ b/cocos/gfx/empty/empty-texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { TextureInfo, TextureViewInfo, ISwapchainTextureInfo, FormatSurfaceSize, IsPowerOf2 } from '../base/define'; import { Texture } from '../base/texture'; @@ -51,6 +50,11 @@ export class EmptyTexture extends Texture { this.depth, this._info.levelCount) * this._info.layerCount; } public destroy () {} + + public getGLTextureHandle (): number { + return 0; + } + public resize (width: number, height: number) { this._info.width = width; this._info.height = height; diff --git a/cocos/core/gfx/index.ems.ts b/cocos/gfx/index.ems.ts similarity index 68% rename from cocos/core/gfx/index.ems.ts rename to cocos/gfx/index.ems.ts index 099d9db83ac..4ef3ed9d731 100644 --- a/cocos/core/gfx/index.ems.ts +++ b/cocos/gfx/index.ems.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @packageDocumentation * @module gfx */ -import { legacyCC } from '../global-exports'; -import { gfx, webgpuAdapter } from '../../webgpu/instantiated'; +import { cclegacy } from '../core'; +import { gfx, webgpuAdapter } from '../webgpu/instantiated'; import './deprecated-3.0.0'; @@ -54,7 +53,7 @@ polyfillCC.PipelineLayout = gfx.CCWGPUPipelineLayout; polyfillCC.PipelineState = gfx.CCWGPUPipelineState; polyfillCC.CommandBuffer = gfx.CCWGPUCommandBuffer; polyfillCC.Queue = gfx.CCWGPUQueue; -legacyCC.gfx = polyfillCC; +cclegacy.gfx = polyfillCC; export * from './webgpu/override'; export * from './webgpu/webgpu-define' diff --git a/cocos/gfx/index.jsb.ts b/cocos/gfx/index.jsb.ts index 050ddbd9323..ecff904f0da 100644 --- a/cocos/gfx/index.jsb.ts +++ b/cocos/gfx/index.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ declare const gfx: any; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import * as defines from './base/define'; import * as pso from './base/pipeline-state'; @@ -65,7 +64,7 @@ polyfillCC.PipelineLayout = gfx.PipelineLayout; polyfillCC.PipelineState = gfx.PipelineState; polyfillCC.CommandBuffer = gfx.CommandBuffer; polyfillCC.Queue = gfx.Queue; -legacyCC.gfx = polyfillCC; +cclegacy.gfx = polyfillCC; polyfillCC.BlendTarget = pso.BlendTarget; polyfillCC.BlendState = pso.BlendState; diff --git a/cocos/gfx/index.ts b/cocos/gfx/index.ts index c84acd727d6..fbe590e88b2 100644 --- a/cocos/gfx/index.ts +++ b/cocos/gfx/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './polyfill-legacy-cc'; import './deprecated-3.0.0'; diff --git a/cocos/gfx/polyfill-legacy-cc.ts b/cocos/gfx/polyfill-legacy-cc.ts index 57a3216d404..3bcfa4c3266 100644 --- a/cocos/gfx/polyfill-legacy-cc.ts +++ b/cocos/gfx/polyfill-legacy-cc.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Buffer } from './base/buffer'; import { CommandBuffer } from './base/command-buffer'; @@ -41,7 +40,7 @@ import { Texture } from './base/texture'; import { GeneralBarrier } from './base/states/general-barrier'; import { TextureBarrier } from './base/states/texture-barrier'; import { BufferBarrier } from './base/states/buffer-barrier'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import * as defines from './base/define'; const polyfills: Record = { @@ -72,4 +71,4 @@ const polyfills: Record = { }; Object.assign(polyfills, defines); -legacyCC.gfx = polyfills; +cclegacy.gfx = polyfills; diff --git a/cocos/gfx/webgl/states/webgl-sampler.ts b/cocos/gfx/webgl/states/webgl-sampler.ts index 2e6324f5c14..1ffb6ef140b 100644 --- a/cocos/gfx/webgl/states/webgl-sampler.ts +++ b/cocos/gfx/webgl/states/webgl-sampler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Filter, SamplerInfo } from '../../base/define'; import { Sampler } from '../../base/states/sampler'; diff --git a/cocos/gfx/webgl/webgl-buffer.ts b/cocos/gfx/webgl/webgl-buffer.ts index 086f89b39c9..8a9f598b5ae 100644 --- a/cocos/gfx/webgl/webgl-buffer.ts +++ b/cocos/gfx/webgl/webgl-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BufferSource, BufferInfo, BufferViewInfo, BufferUsageBit } from '../base/define'; import { Buffer } from '../base/buffer'; diff --git a/cocos/gfx/webgl/webgl-command-allocator.ts b/cocos/gfx/webgl/webgl-command-allocator.ts index c12d5abadf7..97ad1bf0ba2 100644 --- a/cocos/gfx/webgl/webgl-command-allocator.ts +++ b/cocos/gfx/webgl/webgl-command-allocator.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { CachedArray } from '../../core'; import { WebGLCmdBeginRenderPass, WebGLCmdBindStates, + WebGLCmdBlitTexture, WebGLCmdCopyBufferToTexture, WebGLCmdDraw, WebGLCmdObject, @@ -109,6 +109,7 @@ export class WebGLCommandAllocator { public drawCmdPool: WebGLCommandPool; public updateBufferCmdPool: WebGLCommandPool; public copyBufferToTextureCmdPool: WebGLCommandPool; + public blitTextureCmdPool: WebGLCommandPool; constructor () { this.beginRenderPassCmdPool = new WebGLCommandPool(WebGLCmdBeginRenderPass, 1); @@ -116,6 +117,7 @@ export class WebGLCommandAllocator { this.drawCmdPool = new WebGLCommandPool(WebGLCmdDraw, 1); this.updateBufferCmdPool = new WebGLCommandPool(WebGLCmdUpdateBuffer, 1); this.copyBufferToTextureCmdPool = new WebGLCommandPool(WebGLCmdCopyBufferToTexture, 1); + this.blitTextureCmdPool = new WebGLCommandPool(WebGLCmdBlitTexture, 1); } public clearCmds (cmdPackage: WebGLCmdPackage) { @@ -144,6 +146,11 @@ export class WebGLCommandAllocator { cmdPackage.copyBufferToTextureCmds.clear(); } + if (cmdPackage.blitTextureCmds.length) { + this.blitTextureCmdPool.freeCmds(cmdPackage.blitTextureCmds); + cmdPackage.blitTextureCmds.clear(); + } + cmdPackage.cmds.clear(); } @@ -153,5 +160,6 @@ export class WebGLCommandAllocator { this.drawCmdPool.release(); this.updateBufferCmdPool.release(); this.copyBufferToTextureCmdPool.release(); + this.blitTextureCmdPool.release(); } } diff --git a/cocos/gfx/webgl/webgl-command-buffer.ts b/cocos/gfx/webgl/webgl-command-buffer.ts index a8b87f6fa69..7cb4a1d8383 100644 --- a/cocos/gfx/webgl/webgl-command-buffer.ts +++ b/cocos/gfx/webgl/webgl-command-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { Buffer } from '../base/buffer'; @@ -41,8 +40,8 @@ import { WebGLTexture } from './webgl-texture'; import { RenderPass } from '../base/render-pass'; import { WebGLRenderPass } from './webgl-render-pass'; import { BufferUsageBit, CommandBufferType, StencilFace, BufferSource, - CommandBufferInfo, BufferTextureCopy, Color, Rect, Viewport, DrawInfo, DynamicStates } from '../base/define'; -import { WebGLCmd, WebGLCmdBeginRenderPass, WebGLCmdBindStates, WebGLCmdCopyBufferToTexture, + CommandBufferInfo, BufferTextureCopy, Color, Rect, Viewport, DrawInfo, DynamicStates, TextureBlit, Filter } from '../base/define'; +import { WebGLCmd, WebGLCmdBeginRenderPass, WebGLCmdBindStates, WebGLCmdBlitTexture, WebGLCmdCopyBufferToTexture, WebGLCmdDraw, WebGLCmdPackage, WebGLCmdUpdateBuffer } from './webgl-commands'; import { GeneralBarrier } from '../base/states/general-barrier'; import { TextureBarrier } from '../base/states/texture-barrier'; @@ -392,6 +391,12 @@ export class WebGLCommandBuffer extends CommandBuffer { this.cmdPackage.copyBufferToTextureCmds.push(cmd); } + for (let c = 0; c < webGLCmdBuff.cmdPackage.blitTextureCmds.length; ++c) { + const cmd = webGLCmdBuff.cmdPackage.blitTextureCmds.array[c]; + ++cmd.refCount; + this.cmdPackage.blitTextureCmds.push(cmd); + } + this.cmdPackage.cmds.concat(webGLCmdBuff.cmdPackage.cmds.array); this._numDrawCalls += webGLCmdBuff._numDrawCalls; @@ -421,4 +426,17 @@ export class WebGLCommandBuffer extends CommandBuffer { this._isStateInvalied = false; } } + + public blitTexture (srcTexture: Readonly, dstTexture: Texture, regions: Readonly, filter: Filter): void { + const blitTextureCmd = this._cmdAllocator.blitTextureCmdPool.alloc(WebGLCmdBlitTexture); + blitTextureCmd.srcTexture = (srcTexture as WebGLTexture).gpuTexture; + blitTextureCmd.dstTexture = (dstTexture as WebGLTexture).gpuTexture; + blitTextureCmd.regions = regions as TextureBlit[]; + blitTextureCmd.filter = filter; + + ++this._numDrawCalls; // blit is also seen as draw call in webgl1 + + this.cmdPackage.blitTextureCmds.push(blitTextureCmd); + this.cmdPackage.cmds.push(WebGLCmd.BLIT_TEXTURE); + } } diff --git a/cocos/gfx/webgl/webgl-commands.ts b/cocos/gfx/webgl/webgl-commands.ts index f28c87ed44d..54fbe5943e2 100644 --- a/cocos/gfx/webgl/webgl-commands.ts +++ b/cocos/gfx/webgl/webgl-commands.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { debug, error, errorID, CachedArray } from '../../core'; +import { debug, error, errorID, CachedArray, cclegacy } from '../../core'; import { WebGLCommandAllocator } from './webgl-command-allocator'; import { WebGLEXT } from './webgl-define'; import { WebGLDevice } from './webgl-device'; @@ -34,8 +33,11 @@ import { import { BufferUsageBit, ClearFlagBit, ClearFlags, ColorMask, CullMode, Format, BufferTextureCopy, Color, Rect, FormatInfos, FormatSize, LoadOp, MemoryUsageBit, ShaderStageFlagBit, UniformSamplerTexture, - TextureFlagBit, TextureType, Type, FormatInfo, DynamicStateFlagBit, BufferSource, DrawInfo, IndirectBuffer, DynamicStates, Extent, getTypedArrayConstructor, formatAlignment, Offset, alignTo, + TextureFlagBit, TextureType, Type, FormatInfo, DynamicStateFlagBit, BufferSource, DrawInfo, + IndirectBuffer, DynamicStates, Extent, getTypedArrayConstructor, formatAlignment, Offset, alignTo, + TextureBlit, Filter, } from '../base/define'; +import { WebGLStateCache } from './webgl-state-cache'; export function GFXFormatToWebGLType (format: Format, gl: WebGLRenderingContext): GLenum { switch (format) { @@ -439,6 +441,7 @@ export enum WebGLCmd { DRAW, UPDATE_BUFFER, COPY_BUFFER_TO_TEXTURE, + BLIT_TEXTURE, COUNT, } @@ -534,6 +537,23 @@ export class WebGLCmdCopyBufferToTexture extends WebGLCmdObject { } } +export class WebGLCmdBlitTexture extends WebGLCmdObject { + public srcTexture: IWebGLGPUTexture | null = null; + public dstTexture: IWebGLGPUTexture | null = null; + public regions: TextureBlit[] = []; + public filter: Filter = Filter.LINEAR; + + constructor () { + super(WebGLCmd.BLIT_TEXTURE); + } + + public clear () { + this.srcTexture = null; + this.dstTexture = null; + this.regions.length = 0; + } +} + export class WebGLCmdPackage { public cmds: CachedArray = new CachedArray(1); public beginRenderPassCmds: CachedArray = new CachedArray(1); @@ -541,6 +561,7 @@ export class WebGLCmdPackage { public drawCmds: CachedArray = new CachedArray(1); public updateBufferCmds: CachedArray = new CachedArray(1); public copyBufferToTextureCmds: CachedArray = new CachedArray(1); + public blitTextureCmds: CachedArray = new CachedArray(1); public clearCmds (allocator: WebGLCommandAllocator) { if (this.beginRenderPassCmds.length) { @@ -568,6 +589,11 @@ export class WebGLCmdPackage { this.copyBufferToTextureCmds.clear(); } + if (this.blitTextureCmds.length) { + allocator.blitTextureCmdPool.freeCmds(this.blitTextureCmds); + this.blitTextureCmds.clear(); + } + this.cmds.clear(); } } @@ -819,7 +845,6 @@ export function WebGLCmdFuncCreateTexture (device: WebGLDevice, gpuTexture: IWeb switch (gpuTexture.type) { case TextureType.TEX2D: { gpuTexture.glTarget = gl.TEXTURE_2D; - if (gpuTexture.isSwapchainTexture) break; const maxSize = Math.max(w, h); if (maxSize > device.capabilities.maxTextureSize) { @@ -1435,26 +1460,40 @@ export function WebGLCmdFuncCreateShader (device: WebGLDevice, gpuShader: IWebGL const { bindingMappings } = device; const { texUnitCacheMap } = device.stateCache; - let flexibleSetBaseOffset = 0; - for (let i = 0; i < gpuShader.blocks.length; ++i) { - if (gpuShader.blocks[i].set === bindingMappings.flexibleSet) { - flexibleSetBaseOffset++; + if (!(cclegacy.rendering && cclegacy.rendering.enableEffectImport)) { + let flexibleSetBaseOffset = 0; + for (let i = 0; i < gpuShader.blocks.length; ++i) { + if (gpuShader.blocks[i].set === bindingMappings.flexibleSet) { + flexibleSetBaseOffset++; + } } - } - let arrayOffset = 0; - for (let i = 0; i < gpuShader.samplerTextures.length; ++i) { - const sampler = gpuShader.samplerTextures[i]; - const glLoc = gl.getUniformLocation(gpuShader.glProgram, sampler.name); - if (device.extensions.isLocationActive(glLoc)) { - glActiveSamplers.push(gpuShader.glSamplerTextures[i]); - glActiveSamplerLocations.push(glLoc); + let arrayOffset = 0; + for (let i = 0; i < gpuShader.samplerTextures.length; ++i) { + const sampler = gpuShader.samplerTextures[i]; + const glLoc = gl.getUniformLocation(gpuShader.glProgram, sampler.name); + if (device.extensions.isLocationActive(glLoc)) { + glActiveSamplers.push(gpuShader.glSamplerTextures[i]); + glActiveSamplerLocations.push(glLoc); + } + if (texUnitCacheMap[sampler.name] === undefined) { + let binding = sampler.binding + bindingMappings.samplerTextureOffsets[sampler.set] + arrayOffset; + if (sampler.set === bindingMappings.flexibleSet) { binding -= flexibleSetBaseOffset; } + texUnitCacheMap[sampler.name] = binding % device.capabilities.maxTextureUnits; + arrayOffset += sampler.count - 1; + } } - if (texUnitCacheMap[sampler.name] === undefined) { - let binding = sampler.binding + bindingMappings.samplerTextureOffsets[sampler.set] + arrayOffset; - if (sampler.set === bindingMappings.flexibleSet) { binding -= flexibleSetBaseOffset; } - texUnitCacheMap[sampler.name] = binding % device.capabilities.maxTextureUnits; - arrayOffset += sampler.count - 1; + } else { + for (let i = 0; i < gpuShader.samplerTextures.length; ++i) { + const sampler = gpuShader.samplerTextures[i]; + const glLoc = gl.getUniformLocation(gpuShader.glProgram, sampler.name); + if (device.extensions.isLocationActive(glLoc)) { + glActiveSamplers.push(gpuShader.glSamplerTextures[i]); + glActiveSamplerLocations.push(glLoc); + } + if (texUnitCacheMap[sampler.name] === undefined) { + texUnitCacheMap[sampler.name] = sampler.flattened; + } } } @@ -2645,6 +2684,11 @@ export function WebGLCmdFuncExecuteCmds (device: WebGLDevice, cmdPackage: WebGLC WebGLCmdFuncCopyBuffersToTexture(device, cmd5.buffers, cmd5.gpuTexture as IWebGLGPUTexture, cmd5.regions); break; } + case WebGLCmd.BLIT_TEXTURE: { + const cmd6 = cmdPackage.blitTextureCmds.array[cmdId]; + WebGLCmdFuncBlitTexture(device, cmd6.srcTexture as IWebGLGPUTexture, cmd6.dstTexture as IWebGLGPUTexture, cmd6.regions, cmd6.filter); + break; + } default: } // switch } // for @@ -2752,7 +2796,7 @@ export function WebGLCmdFuncCopyBuffersToTexture ( let n = 0; let f = 0; const fmtInfo: FormatInfo = FormatInfos[gpuTexture.format]; - const ArrayBufferCtor : TypedArrayConstructor = getTypedArrayConstructor(fmtInfo); + const ArrayBufferCtor: TypedArrayConstructor = getTypedArrayConstructor(fmtInfo); const { isCompressed } = fmtInfo; const blockSize = formatAlignment(gpuTexture.format); @@ -2778,7 +2822,7 @@ export function WebGLCmdFuncCopyBuffersToTexture ( const destWidth = (region.texExtent.width + offset.x === (gpuTexture.width >> mipLevel)) ? region.texExtent.width : extent.width; const destHeight = (region.texExtent.height + offset.y === (gpuTexture.height >> mipLevel)) ? region.texExtent.height : extent.height; - let pixels : ArrayBufferView; + let pixels: ArrayBufferView; const buffer = buffers[n++]; if (stride.width === extent.width && stride.height === extent.height) { pixels = new ArrayBufferCtor(buffer.buffer, buffer.byteOffset + region.buffOffset); @@ -2902,3 +2946,9 @@ export function WebGLCmdFuncCopyTextureToBuffers ( cache.glFramebuffer = null; gl.deleteFramebuffer(framebuffer); } + +export function WebGLCmdFuncBlitTexture (device: WebGLDevice, + srcTexture: Readonly, dstTexture: IWebGLGPUTexture, regions: Readonly, filter: Filter) { + // logic different from native, because framebuffer map is not implemented in webgl + device.blitManager.draw(srcTexture, dstTexture, regions as TextureBlit[], filter); +} diff --git a/cocos/gfx/webgl/webgl-define.ts b/cocos/gfx/webgl/webgl-define.ts index 35dd732690e..1e7caf0f129 100644 --- a/cocos/gfx/webgl/webgl-define.ts +++ b/cocos/gfx/webgl/webgl-define.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { WebGLDevice } from './webgl-device'; diff --git a/cocos/gfx/webgl/webgl-descriptor-set-layout.ts b/cocos/gfx/webgl/webgl-descriptor-set-layout.ts index be86f25ca5c..8ec72b9118a 100644 --- a/cocos/gfx/webgl/webgl-descriptor-set-layout.ts +++ b/cocos/gfx/webgl/webgl-descriptor-set-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSetLayoutInfo, DESCRIPTOR_DYNAMIC_TYPE } from '../base/define'; import { DescriptorSetLayout } from '../base/descriptor-set-layout'; diff --git a/cocos/gfx/webgl/webgl-descriptor-set.ts b/cocos/gfx/webgl/webgl-descriptor-set.ts index 7d30d4d5e19..38d6679a3cf 100644 --- a/cocos/gfx/webgl/webgl-descriptor-set.ts +++ b/cocos/gfx/webgl/webgl-descriptor-set.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { WebGLBuffer } from './webgl-buffer'; diff --git a/cocos/gfx/webgl/webgl-device.ts b/cocos/gfx/webgl/webgl-device.ts index 30441222472..440d08a16b5 100644 --- a/cocos/gfx/webgl/webgl-device.ts +++ b/cocos/gfx/webgl/webgl-device.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { DescriptorSetLayout } from '../base/descriptor-set-layout'; @@ -96,6 +95,10 @@ export class WebGLDevice extends Device { return this._bindingMappings!; } + get blitManager () { + return this._swapchain!.blitManager; + } + private _swapchain: WebGLSwapchain | null = null; private _context: WebGLRenderingContext | null = null; private _bindingMappings: IWebGLBindingMapping | null = null; @@ -148,7 +151,8 @@ export class WebGLDevice extends Device { this._caps.maxVertexTextureUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); this._caps.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); this._caps.maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); - + this._caps.maxArrayTextureLayers = 0; + this._caps.max3DTextureSize = 0; // WebGL doesn't support UBOs at all, so here we return // the guaranteed minimum number of available bindings in WebGL2 this._caps.maxUniformBufferBindings = 16; diff --git a/cocos/gfx/webgl/webgl-framebuffer.ts b/cocos/gfx/webgl/webgl-framebuffer.ts index 073a5ebd328..287fd3ca0d3 100644 --- a/cocos/gfx/webgl/webgl-framebuffer.ts +++ b/cocos/gfx/webgl/webgl-framebuffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { FramebufferInfo } from '../base/define'; import { Framebuffer } from '../base/framebuffer'; diff --git a/cocos/gfx/webgl/webgl-gpu-objects.ts b/cocos/gfx/webgl/webgl-gpu-objects.ts index 85a981f20ce..e8d6e563b18 100644 --- a/cocos/gfx/webgl/webgl-gpu-objects.ts +++ b/cocos/gfx/webgl/webgl-gpu-objects.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,23 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { nextPow2 } from '../../core'; import { DescriptorType, BufferUsage, Format, MemoryUsage, SampleCount, DynamicStateFlagBit, ShaderStageFlagBit, TextureFlags, TextureType, TextureUsage, Type, Attribute, ColorAttachment, DepthStencilAttachment, - UniformBlock, UniformSamplerTexture, DescriptorSetLayoutBinding, DrawInfo, UniformInputAttachment, + UniformBlock, UniformSamplerTexture, DescriptorSetLayoutBinding, + DrawInfo, UniformInputAttachment, Uniform, BufferUsageBit, MemoryUsageBit, + TextureBlit, Filter, FormatInfos, } from '../base/define'; import { BlendState, DepthStencilState, RasterizerState } from '../base/pipeline-state'; +import { WebGLCmdFuncBindStates, WebGLCmdFuncCreateBuffer, WebGLCmdFuncCreateInputAssember, + WebGLCmdFuncCreateShader, WebGLCmdFuncDestroyBuffer, WebGLCmdFuncDestroyInputAssembler, + WebGLCmdFuncDestroyShader, WebGLCmdFuncDraw, WebGLCmdFuncUpdateBuffer, +} from './webgl-commands'; +import { WebGLDeviceManager } from './webgl-define'; export class WebGLIndirectDrawInfos { public counts: Int32Array; @@ -309,3 +315,289 @@ export interface IWebGLGPUInputAssembler { glIndexType: GLenum; glVAOs: Map; } + +export class IWebGLBlitManager { + private _gpuShader: IWebGLGPUShader | null = null; + private _gpuDescriptorSetLayout: IWebGLGPUDescriptorSetLayout | null = null; + private _gpuPipelineLayout: IWebGLGPUPipelineLayout | null = null; + private _gpuPipelineState: IWebGLGPUPipelineState | null = null; + + private _gpuVertexBuffer: IWebGLGPUBuffer | null = null; + private _gpuInputAssembler: IWebGLGPUInputAssembler | null = null; + private _gpuPointSampler: IWebGLGPUSampler | null = null; + private _gpuLinearSampler: IWebGLGPUSampler | null = null; + private _gpuDescriptorSet: IWebGLGPUDescriptorSet | null = null; + private _gpuUniformBuffer: IWebGLGPUBuffer | null = null; + private _drawInfo: DrawInfo | null = null; + private _glFramebuffer: WebGLFramebuffer | null = null; + + private _uniformBuffer: Float32Array | null = null; + + constructor () { + const { gl } = WebGLDeviceManager.instance; + const device = WebGLDeviceManager.instance; + const samplerOffset = device.bindingMappingInfo.maxBlockCounts[0]; + + this._gpuShader = { + name: 'Blit Pass', + blocks: [ + new UniformBlock(0, 0, `BlitParams`, + [ + new Uniform(`tilingOffsetSrc`, Type.FLOAT4, 1), + new Uniform(`tilingOffsetDst`, Type.FLOAT4, 1), + ], + 1), + ], + samplerTextures: [new UniformSamplerTexture(0, samplerOffset, 'textureSrc', Type.SAMPLER2D, 1)], + subpassInputs: [], + gpuStages: [ + { + type: ShaderStageFlagBit.VERTEX, + source: ` + precision mediump float; + + attribute vec2 a_position; + attribute vec2 a_texCoord; + + uniform vec4 tilingOffsetSrc; + uniform vec4 tilingOffsetDst; + + varying vec2 v_texCoord; + + void main() { + v_texCoord = a_texCoord * tilingOffsetSrc.xy + tilingOffsetSrc.zw; + gl_Position = vec4((a_position + 1.0) * tilingOffsetDst.xy - 1.0 + tilingOffsetDst.zw * 2.0, 0, 1); + }`, + glShader: null }, + { + type: ShaderStageFlagBit.FRAGMENT, + source: ` + precision mediump float; + uniform sampler2D textureSrc; + + varying vec2 v_texCoord; + + void main() { + gl_FragColor = texture2D(textureSrc, v_texCoord); + }`, + glShader: null }, + + ], + glProgram: null, + glInputs: [], + glUniforms: [], + glBlocks: [], + glSamplerTextures: [], + }; + WebGLCmdFuncCreateShader(WebGLDeviceManager.instance, this._gpuShader); + + this._gpuDescriptorSetLayout = { + bindings: [ + new DescriptorSetLayoutBinding(0, DescriptorType.UNIFORM_BUFFER, 1, ShaderStageFlagBit.VERTEX), + new DescriptorSetLayoutBinding(samplerOffset, DescriptorType.SAMPLER_TEXTURE, 1, ShaderStageFlagBit.FRAGMENT), + ], + dynamicBindings: [], + descriptorIndices: [], + descriptorCount: samplerOffset + 1, + }; + for (let i = 0; i < samplerOffset; i++) { + this._gpuDescriptorSetLayout.descriptorIndices[i] = 0; + } + this._gpuDescriptorSetLayout.descriptorIndices.push(1); + + this._gpuPipelineLayout = { + gpuSetLayouts: [this._gpuDescriptorSetLayout], + dynamicOffsetCount: 0, + dynamicOffsetOffsets: [0], + dynamicOffsetIndices: [[]], + }; + + this._gpuPipelineState = { + glPrimitive: gl.TRIANGLE_STRIP, + gpuShader: this._gpuShader, + gpuPipelineLayout: this._gpuPipelineLayout, + rs: null!, + dss: new DepthStencilState(false, false), + bs: null!, + dynamicStates: [], + gpuRenderPass: null, + }; + + this._gpuVertexBuffer = { + usage: BufferUsageBit.VERTEX, + memUsage: MemoryUsageBit.DEVICE, + size: 16 * Float32Array.BYTES_PER_ELEMENT, + stride: 4 * Float32Array.BYTES_PER_ELEMENT, + buffer: null, + vf32: null, + indirects: new WebGLIndirectDrawInfos(), + glTarget: 0, + glBuffer: null, + }; + WebGLCmdFuncCreateBuffer(WebGLDeviceManager.instance, this._gpuVertexBuffer); + WebGLDeviceManager.instance.memoryStatus.bufferSize += this._gpuVertexBuffer.size; + const data = new Float32Array( + [-1.0, -1.0, 0.0, 0.0, + 1.0, -1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, 1.0, + 1.0, 1.0, 1.0, 1.0], + ); + WebGLCmdFuncUpdateBuffer(WebGLDeviceManager.instance, this._gpuVertexBuffer, data, 0, data.length); + + this._gpuInputAssembler = { + attributes: [new Attribute(`a_position`, Format.RG32F), new Attribute(`a_texCoord`, Format.RG32F)], + gpuVertexBuffers: [this._gpuVertexBuffer], + gpuIndexBuffer: null, + gpuIndirectBuffer: null, + + glAttribs: [], + glIndexType: 0, + glVAOs: new Map(), + }; + WebGLCmdFuncCreateInputAssember(WebGLDeviceManager.instance, this._gpuInputAssembler); + + this._gpuPointSampler = { + glMinFilter: 0x2600, // WebGLRenderingContext.NEAREST + glMagFilter: 0x2600, // WebGLRenderingContext.NEAREST + glWrapS: 0x2901, // WebGLRenderingContext.REPEAT, + glWrapT: 0x2901, // WebGLRenderingContext.REPEAT, + glWrapR: 0x2901, // WebGLRenderingContext.REPEAT, + }; + + this._gpuLinearSampler = { + glMinFilter: 0x2601, // WebGLRenderingContext.LINEAR; + glMagFilter: 0x2601, // WebGLRenderingContext.LINEAR; + glWrapS: 0x2901, // WebGLRenderingContext.REPEAT, + glWrapT: 0x2901, // WebGLRenderingContext.REPEAT, + glWrapR: 0x2901, // WebGLRenderingContext.REPEAT, + }; + + this._uniformBuffer = new Float32Array(8); + this._gpuUniformBuffer = { + usage: BufferUsageBit.UNIFORM, + memUsage: MemoryUsageBit.DEVICE, + size: 8 * Float32Array.BYTES_PER_ELEMENT, + stride: 8 * Float32Array.BYTES_PER_ELEMENT, + buffer: this._uniformBuffer, + vf32: null, + indirects: new WebGLIndirectDrawInfos(), + glTarget: 0, + glBuffer: null, + }; + WebGLCmdFuncCreateBuffer(WebGLDeviceManager.instance, this._gpuUniformBuffer); + WebGLDeviceManager.instance.memoryStatus.bufferSize += this._gpuUniformBuffer.size; + + this._gpuDescriptorSet = { + gpuDescriptors: [ + { type: DescriptorType.UNIFORM_BUFFER, gpuBuffer: this._gpuUniformBuffer, gpuTexture: null, gpuSampler: null }, + { type: DescriptorType.SAMPLER_TEXTURE, gpuBuffer: null, gpuTexture: null, gpuSampler: null }], + descriptorIndices: this._gpuDescriptorSetLayout.descriptorIndices, + }; + + this._drawInfo = new DrawInfo(4, 0, 0, 0, 0, 0, 0); + this._glFramebuffer = WebGLDeviceManager.instance.gl.createFramebuffer(); + } + + public destroy () { + if (this._glFramebuffer) { + WebGLDeviceManager.instance.gl.deleteFramebuffer(this._glFramebuffer); + this._glFramebuffer = null; + } + if (this._gpuVertexBuffer) { + WebGLDeviceManager.instance.memoryStatus.bufferSize -= this._gpuVertexBuffer.size; + WebGLCmdFuncDestroyBuffer(WebGLDeviceManager.instance, this._gpuVertexBuffer); + } + if (this._gpuUniformBuffer) { + WebGLDeviceManager.instance.memoryStatus.bufferSize -= this._gpuUniformBuffer.size; + WebGLCmdFuncDestroyBuffer(WebGLDeviceManager.instance, this._gpuUniformBuffer); + } + if (this._gpuShader) { + WebGLCmdFuncDestroyShader(WebGLDeviceManager.instance, this._gpuShader); + } + if (this._gpuInputAssembler) { + WebGLCmdFuncDestroyInputAssembler(WebGLDeviceManager.instance, this._gpuInputAssembler); + } + } + + public draw (gpuTextureSrc: IWebGLGPUTexture, gpuTextureDst: IWebGLGPUTexture, regions: TextureBlit[], filter: Filter) { + const device = WebGLDeviceManager.instance; + const { gl } = device; + const stateCache = device.stateCache; + const origFramebuffer = stateCache.glFramebuffer; + + gl.viewport(0, 0, gpuTextureDst.width, gpuTextureDst.height); + gl.scissor(0, 0, gpuTextureDst.width, gpuTextureDst.height); + + if (!this._uniformBuffer || !this._gpuUniformBuffer || !this._gpuPipelineState + || !this._gpuInputAssembler || !this._gpuDescriptorSet || !this._drawInfo) { + return; + } + + const descriptor = this._gpuDescriptorSet.gpuDescriptors[1]; + descriptor.gpuTexture = gpuTextureSrc; + descriptor.gpuSampler = filter === Filter.POINT ? this._gpuPointSampler : this._gpuLinearSampler; + + const formatInfo = FormatInfos[gpuTextureDst.format]; + let attachment = gl.COLOR_ATTACHMENT0; + if (formatInfo.hasStencil) { + attachment = gl.DEPTH_STENCIL_ATTACHMENT; + } else if (formatInfo.hasDepth) { + attachment = gl.DEPTH_ATTACHMENT; + } + + const regionIndices = regions.map((_, i) => i); + regionIndices.sort((a, b) => regions[a].srcSubres.mipLevel - regions[b].srcSubres.mipLevel); + + if (stateCache.glFramebuffer !== this._glFramebuffer) { + device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._glFramebuffer); + stateCache.glFramebuffer = this._glFramebuffer; + } + + let mipLevel = regions[0].dstSubres.mipLevel; + if (gpuTextureDst.glTexture) { + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gpuTextureDst.glTarget, gpuTextureDst.glTexture, mipLevel); + } else { + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, gpuTextureDst.glRenderbuffer); + } + + for (let i = 0; i < regionIndices.length; ++i) { + const region = regions[regionIndices[i]]; + + if (gpuTextureSrc.glTexture && mipLevel !== region.srcSubres.mipLevel) { + mipLevel = region.srcSubres.mipLevel; + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gpuTextureDst.glTarget, gpuTextureDst.glTexture, mipLevel); + } + + const srcWidth = gpuTextureSrc.width; + const srcHeight = gpuTextureSrc.height; + const dstWidth = gpuTextureDst.width; + const dstHeight = gpuTextureDst.height; + + this._uniformBuffer[0] = region.srcExtent.width / srcWidth; + this._uniformBuffer[1] = region.srcExtent.height / srcHeight; + this._uniformBuffer[2] = region.srcOffset.x / srcWidth; + this._uniformBuffer[3] = region.srcOffset.y / srcHeight; + this._uniformBuffer[4] = region.dstExtent.width / dstWidth; + this._uniformBuffer[5] = region.dstExtent.height / dstHeight; + this._uniformBuffer[6] = region.dstOffset.x / dstWidth; + this._uniformBuffer[7] = region.dstOffset.y / dstHeight; + + WebGLCmdFuncUpdateBuffer(device, this._gpuUniformBuffer, this._uniformBuffer, 0, + this._uniformBuffer.length * Float32Array.BYTES_PER_ELEMENT); + WebGLCmdFuncBindStates(device, this._gpuPipelineState, this._gpuInputAssembler, [this._gpuDescriptorSet], [], null!); + WebGLCmdFuncDraw(device, this._drawInfo); + } + + // restore fbo + if (stateCache.glFramebuffer !== origFramebuffer) { + device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, origFramebuffer); + stateCache.glFramebuffer = origFramebuffer; + } + // restore viewport + const origViewport = stateCache.viewport; + gl.viewport(origViewport.left, origViewport.top, origViewport.width, origViewport.height); + // restore scissor + const origScissor = stateCache.scissorRect; + gl.scissor(origScissor.x, origScissor.y, origScissor.width, origScissor.height); + } +} diff --git a/cocos/gfx/webgl/webgl-input-assembler.ts b/cocos/gfx/webgl/webgl-input-assembler.ts index cde9930071b..61f41e570f5 100644 --- a/cocos/gfx/webgl/webgl-input-assembler.ts +++ b/cocos/gfx/webgl/webgl-input-assembler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { InputAssemblerInfo } from '../base/define'; import { InputAssembler } from '../base/input-assembler'; diff --git a/cocos/gfx/webgl/webgl-pipeline-layout.ts b/cocos/gfx/webgl/webgl-pipeline-layout.ts index ae2082e3f78..56f904a9fda 100644 --- a/cocos/gfx/webgl/webgl-pipeline-layout.ts +++ b/cocos/gfx/webgl/webgl-pipeline-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineLayout } from '../base/pipeline-layout'; import { IWebGLGPUPipelineLayout, IWebGLGPUDescriptorSetLayout } from './webgl-gpu-objects'; diff --git a/cocos/gfx/webgl/webgl-pipeline-state.ts b/cocos/gfx/webgl/webgl-pipeline-state.ts index 7768c276323..63701a9b104 100644 --- a/cocos/gfx/webgl/webgl-pipeline-state.ts +++ b/cocos/gfx/webgl/webgl-pipeline-state.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineState, PipelineStateInfo } from '../base/pipeline-state'; import { IWebGLGPUPipelineState } from './webgl-gpu-objects'; diff --git a/cocos/gfx/webgl/webgl-primary-command-buffer.ts b/cocos/gfx/webgl/webgl-primary-command-buffer.ts index 79d13a6808a..e6f34ad3c91 100644 --- a/cocos/gfx/webgl/webgl-primary-command-buffer.ts +++ b/cocos/gfx/webgl/webgl-primary-command-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Buffer } from '../base/buffer'; import { CommandBuffer } from '../base/command-buffer'; -import { BufferSource, DrawInfo, BufferTextureCopy, Color, Rect, BufferUsageBit, Viewport } from '../base/define'; +import { BufferSource, DrawInfo, BufferTextureCopy, Color, Rect, BufferUsageBit, Viewport, TextureBlit, Filter } from '../base/define'; import { Framebuffer } from '../base/framebuffer'; import { InputAssembler } from '../base/input-assembler'; import { Texture } from '../base/texture'; import { WebGLBuffer } from './webgl-buffer'; import { WebGLCommandBuffer } from './webgl-command-buffer'; import { - WebGLCmdFuncBeginRenderPass, WebGLCmdFuncBindStates, WebGLCmdFuncCopyBuffersToTexture, + WebGLCmdFuncBeginRenderPass, WebGLCmdFuncBindStates, WebGLCmdFuncBlitTexture, WebGLCmdFuncCopyBuffersToTexture, WebGLCmdFuncDraw, WebGLCmdFuncExecuteCmds, WebGLCmdFuncUpdateBuffer } from './webgl-commands'; import { WebGLFramebuffer } from './webgl-framebuffer'; import { WebGLTexture } from './webgl-texture'; @@ -66,7 +65,7 @@ export class WebGLPrimaryCommandBuffer extends WebGLCommandBuffer { const info = 'drawInfo' in infoOrAssembler ? infoOrAssembler.drawInfo : infoOrAssembler; - WebGLCmdFuncDraw(WebGLDeviceManager.instance, info as DrawInfo); + WebGLCmdFuncDraw(WebGLDeviceManager.instance, info); ++this._numDrawCalls; this._numInstances += info.instanceCount; @@ -170,4 +169,10 @@ export class WebGLPrimaryCommandBuffer extends WebGLCommandBuffer { this._curGPUDescriptorSets, this._curDynamicOffsets, this._curDynamicStates); this._isStateInvalied = false; } + + public blitTexture (srcTexture: Readonly, dstTexture: Texture, regions: Readonly, filter: Filter): void { + const gpuTextureSrc = (srcTexture as WebGLTexture).gpuTexture; + const gpuTextureDst = (dstTexture as WebGLTexture).gpuTexture; + WebGLCmdFuncBlitTexture(WebGLDeviceManager.instance, gpuTextureSrc, gpuTextureDst, regions, filter); + } } diff --git a/cocos/gfx/webgl/webgl-queue.ts b/cocos/gfx/webgl/webgl-queue.ts index 23214ec7d68..1cbccb4aa4e 100644 --- a/cocos/gfx/webgl/webgl-queue.ts +++ b/cocos/gfx/webgl/webgl-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { QueueInfo } from '../base/define'; import { CommandBuffer } from '../base/command-buffer'; diff --git a/cocos/gfx/webgl/webgl-render-pass.ts b/cocos/gfx/webgl/webgl-render-pass.ts index c8fffd9fdb3..328d5cf97ca 100644 --- a/cocos/gfx/webgl/webgl-render-pass.ts +++ b/cocos/gfx/webgl/webgl-render-pass.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { RenderPassInfo } from '../base/define'; import { RenderPass } from '../base/render-pass'; diff --git a/cocos/gfx/webgl/webgl-shader.ts b/cocos/gfx/webgl/webgl-shader.ts index 4c965514d21..e7d5ed07798 100644 --- a/cocos/gfx/webgl/webgl-shader.ts +++ b/cocos/gfx/webgl/webgl-shader.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ShaderInfo } from '../base/define'; import { Shader } from '../base/shader'; diff --git a/cocos/gfx/webgl/webgl-state-cache.ts b/cocos/gfx/webgl/webgl-state-cache.ts index 7b0f228f170..c5a52cd6474 100644 --- a/cocos/gfx/webgl/webgl-state-cache.ts +++ b/cocos/gfx/webgl/webgl-state-cache.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Rect, Viewport } from '../base/define'; import { BlendState, DepthStencilState, RasterizerState } from '../base/pipeline-state'; diff --git a/cocos/gfx/webgl/webgl-swapchain.ts b/cocos/gfx/webgl/webgl-swapchain.ts index 805722f1a7c..408d3e7dc50 100644 --- a/cocos/gfx/webgl/webgl-swapchain.ts +++ b/cocos/gfx/webgl/webgl-swapchain.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { ALIPAY, RUNTIME_BASED, BYTEDANCE, WECHAT, LINKSURE, QTT, COCOSPLAY, HUAWEI, EDITOR, VIVO } from 'internal:constants'; +import { ALIPAY, RUNTIME_BASED, BYTEDANCE, WECHAT, LINKSURE, QTT, COCOSPLAY, HUAWEI, EDITOR, VIVO, TAOBAO } from 'internal:constants'; import { systemInfo } from 'pal/system-info'; import { WebGLCommandAllocator } from './webgl-command-allocator'; import { WebGLStateCache } from './webgl-state-cache'; @@ -34,6 +33,7 @@ import { Swapchain } from '../base/swapchain'; import { IWebGLExtensions, WebGLDeviceManager } from './webgl-define'; import { macro, warnID, warn, debug } from '../../core'; import { BrowserType, OS } from '../../../pal/system-info/enum-type'; +import { IWebGLBlitManager } from './webgl-gpu-objects'; const eventWebGLContextLost = 'webglcontextlost'; @@ -174,6 +174,15 @@ export function getExtensions (gl: WebGLRenderingContext) { if (WECHAT) { res.noCompressedTexSubImage2D = true; } + + // HACK: on Taobao Android, some devices can't query texture float extension correctly, especially Huawei devices + // the query interface returns null. + if (TAOBAO && systemInfo.os === OS.ANDROID) { + res.OES_texture_half_float = { HALF_FLOAT_OES: 36193 }; + res.OES_texture_half_float_linear = {}; + res.OES_texture_float = {}; + res.OES_texture_float_linear = {}; + } } if (res.OES_vertex_array_object) { @@ -210,6 +219,10 @@ export class WebGLSwapchain extends Swapchain { return this._extensions as IWebGLExtensions; } + get blitManager () { + return this._blitManager!; + } + public stateCache: WebGLStateCache = new WebGLStateCache(); public cmdAllocator: WebGLCommandAllocator = new WebGLCommandAllocator(); public nullTex2D: WebGLTexture = null!; @@ -218,6 +231,7 @@ export class WebGLSwapchain extends Swapchain { private _canvas: HTMLCanvasElement | null = null; private _webGLContextLostHandler: ((event: Event) => void) | null = null; private _extensions: IWebGLExtensions | null = null; + private _blitManager: IWebGLBlitManager | null = null; public initialize (info: Readonly) { this._canvas = info.windowHandle; @@ -301,6 +315,7 @@ export class WebGLSwapchain extends Swapchain { [nullTexBuff, nullTexBuff, nullTexBuff, nullTexBuff, nullTexBuff, nullTexBuff], this.nullTexCube, [nullTexRegion], ); + this._blitManager = new IWebGLBlitManager(); } public destroy (): void { @@ -319,6 +334,11 @@ export class WebGLSwapchain extends Swapchain { this.nullTexCube = null!; } + if (this._blitManager) { + this._blitManager.destroy(); + this._blitManager = null!; + } + this._extensions = null; this._canvas = null; } diff --git a/cocos/gfx/webgl/webgl-texture.ts b/cocos/gfx/webgl/webgl-texture.ts index db07e3e722f..bcb7370953f 100644 --- a/cocos/gfx/webgl/webgl-texture.ts +++ b/cocos/gfx/webgl/webgl-texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { FormatSurfaceSize, TextureInfo, TextureViewInfo, IsPowerOf2, ISwapchainTextureInfo, TextureUsageBit, FormatInfos } from '../base/define'; import { Texture } from '../base/texture'; @@ -31,10 +30,10 @@ import { IWebGLGPUTexture } from './webgl-gpu-objects'; export class WebGLTexture extends Texture { get gpuTexture (): IWebGLGPUTexture { - return this._gpuTexture!; + return this._gpuTexture!; } - get lodLevel () :number { + get lodLevel (): number { return this._lodLevel; } @@ -86,9 +85,10 @@ export class WebGLTexture extends Texture { isSwapchainTexture: isSwapchainTexture || false, }; - WebGLCmdFuncCreateTexture(WebGLDeviceManager.instance, this._gpuTexture); - - WebGLDeviceManager.instance.memoryStatus.textureSize += this._size; + if (!this._gpuTexture.isSwapchainTexture) { + WebGLCmdFuncCreateTexture(WebGLDeviceManager.instance, this._gpuTexture); + WebGLDeviceManager.instance.memoryStatus.textureSize += this._size; + } this._viewInfo.texture = this; this._viewInfo.type = info.type; @@ -112,6 +112,21 @@ export class WebGLTexture extends Texture { } } + public getGLTextureHandle () : number { + const gpuTexture = this._gpuTexture; + if (!gpuTexture) { + return 0; + } + + if (gpuTexture.glTexture) { + return gpuTexture.glTexture as number; + } else if (gpuTexture.glRenderbuffer) { + return gpuTexture.glRenderbuffer as number; + } + + return 0; + } + public resize (width: number, height: number) { if (this._info.width === width && this._info.height === height) { return; @@ -134,9 +149,11 @@ export class WebGLTexture extends Texture { this._gpuTexture.width = width; this._gpuTexture.height = height; this._gpuTexture.size = this._size; - WebGLCmdFuncResizeTexture(WebGLDeviceManager.instance, this._gpuTexture); - WebGLDeviceManager.instance.memoryStatus.textureSize -= oldSize; - WebGLDeviceManager.instance.memoryStatus.textureSize += this._size; + if (!this._gpuTexture.isSwapchainTexture) { + WebGLCmdFuncResizeTexture(WebGLDeviceManager.instance, this._gpuTexture); + WebGLDeviceManager.instance.memoryStatus.textureSize -= oldSize; + WebGLDeviceManager.instance.memoryStatus.textureSize += this._size; + } } } diff --git a/cocos/gfx/webgl2/states/webgl2-sampler.ts b/cocos/gfx/webgl2/states/webgl2-sampler.ts index 6aa359d81f0..4c75f7960af 100644 --- a/cocos/gfx/webgl2/states/webgl2-sampler.ts +++ b/cocos/gfx/webgl2/states/webgl2-sampler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { SamplerInfo } from '../../base/define'; import { Sampler } from '../../base/states/sampler'; diff --git a/cocos/gfx/webgl2/webgl2-buffer.ts b/cocos/gfx/webgl2/webgl2-buffer.ts index b9e533947da..6353ed5d42f 100644 --- a/cocos/gfx/webgl2/webgl2-buffer.ts +++ b/cocos/gfx/webgl2/webgl2-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Buffer } from '../base/buffer'; import { BufferUsageBit, BufferSource, BufferInfo, BufferViewInfo } from '../base/define'; diff --git a/cocos/gfx/webgl2/webgl2-command-allocator.ts b/cocos/gfx/webgl2/webgl2-command-allocator.ts index c88569bce83..2a977eefd4a 100644 --- a/cocos/gfx/webgl2/webgl2-command-allocator.ts +++ b/cocos/gfx/webgl2/webgl2-command-allocator.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { CachedArray } from '../../core'; import { WebGL2CmdBeginRenderPass, WebGL2CmdBindStates, + WebGL2CmdBlitTexture, WebGL2CmdCopyBufferToTexture, WebGL2CmdDraw, WebGL2CmdObject, @@ -109,6 +109,7 @@ export class WebGL2CommandAllocator { public drawCmdPool: WebGL2CommandPool; public updateBufferCmdPool: WebGL2CommandPool; public copyBufferToTextureCmdPool: WebGL2CommandPool; + public blitTextureCmdPool: WebGL2CommandPool; constructor () { this.beginRenderPassCmdPool = new WebGL2CommandPool(WebGL2CmdBeginRenderPass, 1); @@ -116,6 +117,7 @@ export class WebGL2CommandAllocator { this.drawCmdPool = new WebGL2CommandPool(WebGL2CmdDraw, 1); this.updateBufferCmdPool = new WebGL2CommandPool(WebGL2CmdUpdateBuffer, 1); this.copyBufferToTextureCmdPool = new WebGL2CommandPool(WebGL2CmdCopyBufferToTexture, 1); + this.blitTextureCmdPool = new WebGL2CommandPool(WebGL2CmdBlitTexture, 1); } public clearCmds (cmdPackage: WebGL2CmdPackage) { @@ -144,6 +146,11 @@ export class WebGL2CommandAllocator { cmdPackage.copyBufferToTextureCmds.clear(); } + if (cmdPackage.blitTextureCmds.length) { + this.blitTextureCmdPool.freeCmds(cmdPackage.blitTextureCmds); + cmdPackage.blitTextureCmds.clear(); + } + cmdPackage.cmds.clear(); } @@ -153,5 +160,6 @@ export class WebGL2CommandAllocator { this.drawCmdPool.release(); this.updateBufferCmdPool.release(); this.copyBufferToTextureCmdPool.release(); + this.blitTextureCmdPool.release(); } } diff --git a/cocos/gfx/webgl2/webgl2-command-buffer.ts b/cocos/gfx/webgl2/webgl2-command-buffer.ts index 33656f5182e..39698b185fa 100644 --- a/cocos/gfx/webgl2/webgl2-command-buffer.ts +++ b/cocos/gfx/webgl2/webgl2-command-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { Buffer } from '../base/buffer'; @@ -31,7 +30,7 @@ import { CommandBufferType, StencilFace, BufferSource, CommandBufferInfo, - BufferTextureCopy, Color, Rect, Viewport, DrawInfo, DynamicStates, + BufferTextureCopy, Color, Rect, Viewport, DrawInfo, DynamicStates, TextureBlit, Filter, } from '../base/define'; import { Framebuffer } from '../base/framebuffer'; import { InputAssembler } from '../base/input-assembler'; @@ -44,6 +43,7 @@ import { WebGL2Cmd, WebGL2CmdBeginRenderPass, WebGL2CmdBindStates, + WebGL2CmdBlitTexture, WebGL2CmdCopyBufferToTexture, WebGL2CmdDraw, WebGL2CmdPackage, @@ -400,6 +400,12 @@ export class WebGL2CommandBuffer extends CommandBuffer { this.cmdPackage.copyBufferToTextureCmds.push(cmd); } + for (let c = 0; c < webGL2CmdBuff.cmdPackage.blitTextureCmds.length; ++c) { + const cmd = webGL2CmdBuff.cmdPackage.blitTextureCmds.array[c]; + ++cmd.refCount; + this.cmdPackage.blitTextureCmds.push(cmd); + } + this.cmdPackage.cmds.concat(webGL2CmdBuff.cmdPackage.cmds.array); this._numDrawCalls += webGL2CmdBuff._numDrawCalls; @@ -426,4 +432,17 @@ export class WebGL2CommandBuffer extends CommandBuffer { this._isStateInvalied = false; } + + public blitTexture (srcTexture: Readonly, dstTexture: Texture, regions: Readonly, filter: Filter): void { + const blitTextureCmd = this._cmdAllocator.blitTextureCmdPool.alloc(WebGL2CmdBlitTexture); + blitTextureCmd.srcTexture = (srcTexture as WebGL2Texture).gpuTexture; + blitTextureCmd.dstTexture = (dstTexture as WebGL2Texture).gpuTexture; + blitTextureCmd.regions = regions as TextureBlit[]; + blitTextureCmd.filter = filter; + + ++this._numDrawCalls; + + this.cmdPackage.blitTextureCmds.push(blitTextureCmd); + this.cmdPackage.cmds.push(WebGL2Cmd.BLIT_TEXTURE); + } } diff --git a/cocos/gfx/webgl2/webgl2-commands.ts b/cocos/gfx/webgl2/webgl2-commands.ts index fd674ee236d..c2a1dab4894 100644 --- a/cocos/gfx/webgl2/webgl2-commands.ts +++ b/cocos/gfx/webgl2/webgl2-commands.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BufferUsageBit, ColorMask, CullMode, DynamicStateFlagBit, Filter, Format, TextureType, Type, FormatInfo, FormatInfos, FormatSize, LoadOp, MemoryUsageBit, SampleCount, ShaderStageFlagBit, TextureFlagBit, Color, Rect, BufferTextureCopy, BufferSource, DrawInfo, IndirectBuffer, UniformBlock, DynamicStates, - UniformSamplerTexture, - alignTo, - Extent, - formatAlignment, - getTypedArrayConstructor, - Offset, + UniformSamplerTexture, alignTo, Extent, formatAlignment, getTypedArrayConstructor, Offset, TextureBlit, } from '../base/define'; import { WebGL2EXT } from './webgl2-define'; import { WebGL2CommandAllocator } from './webgl2-command-allocator'; @@ -52,7 +46,7 @@ import { IWebGL2GPUUniformSamplerTexture, IWebGL2GPURenderPass, } from './webgl2-gpu-objects'; -import { CachedArray, error, errorID, debug } from '../../core'; +import { CachedArray, error, errorID, debug, cclegacy } from '../../core'; const WebGLWraps: GLenum[] = [ 0x2901, // WebGLRenderingContext.REPEAT @@ -627,6 +621,7 @@ export enum WebGL2Cmd { DRAW, UPDATE_BUFFER, COPY_BUFFER_TO_TEXTURE, + BLIT_TEXTURE, COUNT, } @@ -721,6 +716,23 @@ export class WebGL2CmdCopyBufferToTexture extends WebGL2CmdObject { } } +export class WebGL2CmdBlitTexture extends WebGL2CmdObject { + public srcTexture: IWebGL2GPUTexture | null = null; + public dstTexture: IWebGL2GPUTexture | null = null; + public regions: TextureBlit[] = []; + public filter: Filter = Filter.LINEAR; + + constructor () { + super(WebGL2Cmd.BLIT_TEXTURE); + } + + public clear () { + this.srcTexture = null; + this.dstTexture = null; + this.regions.length = 0; + } +} + export class WebGL2CmdPackage { public cmds: CachedArray = new CachedArray(1); public beginRenderPassCmds: CachedArray = new CachedArray(1); @@ -728,6 +740,7 @@ export class WebGL2CmdPackage { public drawCmds: CachedArray = new CachedArray(1); public updateBufferCmds: CachedArray = new CachedArray(1); public copyBufferToTextureCmds: CachedArray = new CachedArray(1); + public blitTextureCmds: CachedArray = new CachedArray(1); public clearCmds (allocator: WebGL2CommandAllocator) { if (this.beginRenderPassCmds.length) { @@ -755,6 +768,11 @@ export class WebGL2CmdPackage { this.copyBufferToTextureCmds.clear(); } + if (this.blitTextureCmds.length) { + allocator.blitTextureCmdPool.freeCmds(this.blitTextureCmds); + this.blitTextureCmds.clear(); + } + this.cmds.clear(); } } @@ -1034,11 +1052,12 @@ export function WebGL2CmdFuncCreateTexture (device: WebGL2Device, gpuTexture: IW let w = gpuTexture.width; let h = gpuTexture.height; + const d = gpuTexture.depth; + const l = gpuTexture.arrayLayer; switch (gpuTexture.type) { case TextureType.TEX2D: { gpuTexture.glTarget = gl.TEXTURE_2D; - if (gpuTexture.isSwapchainTexture) break; const maxSize = Math.max(w, h); if (maxSize > device.capabilities.maxTextureSize) { @@ -1081,6 +1100,71 @@ export function WebGL2CmdFuncCreateTexture (device: WebGL2Device, gpuTexture: IW } break; } + case TextureType.TEX2D_ARRAY: { + gpuTexture.glTarget = gl.TEXTURE_2D_ARRAY; + + const maxSize = Math.max(w, h); + if (maxSize > device.capabilities.maxTextureSize) { + errorID(9100, maxSize, device.capabilities.maxTextureSize); + } + if (l > device.capabilities.maxArrayTextureLayers) { + errorID(9100, l, device.capabilities.maxArrayTextureLayers); + } + + gpuTexture.glTexture = gl.createTexture(); + if (gpuTexture.size > 0) { + const glTexUnit = device.stateCache.glTexUnits[device.stateCache.texUnit]; + + if (glTexUnit.glTexture !== gpuTexture.glTexture) { + gl.bindTexture(gl.TEXTURE_2D_ARRAY, gpuTexture.glTexture); + glTexUnit.glTexture = gpuTexture.glTexture; + } + + if (FormatInfos[gpuTexture.format].isCompressed) { + for (let i = 0; i < gpuTexture.mipLevel; ++i) { + const imgSize = FormatSize(gpuTexture.format, w, h, l); + const view: Uint8Array = new Uint8Array(imgSize); + gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, i, gpuTexture.glInternalFmt, w, h, l, 0, view); + w = Math.max(1, w >> 1); + h = Math.max(1, h >> 1); + } + } else { + gl.texStorage3D(gl.TEXTURE_2D_ARRAY, gpuTexture.mipLevel, gpuTexture.glInternalFmt, w, h, l); + } + } + break; + } + case TextureType.TEX3D: { + gpuTexture.glTarget = gl.TEXTURE_3D; + + const maxSize = Math.max(Math.max(w, h), d); + if (maxSize > device.capabilities.max3DTextureSize) { + errorID(9100, maxSize, device.capabilities.max3DTextureSize); + } + + gpuTexture.glTexture = gl.createTexture(); + if (gpuTexture.size > 0) { + const glTexUnit = device.stateCache.glTexUnits[device.stateCache.texUnit]; + + if (glTexUnit.glTexture !== gpuTexture.glTexture) { + gl.bindTexture(gl.TEXTURE_3D, gpuTexture.glTexture); + glTexUnit.glTexture = gpuTexture.glTexture; + } + + if (FormatInfos[gpuTexture.format].isCompressed) { + for (let i = 0; i < gpuTexture.mipLevel; ++i) { + const imgSize = FormatSize(gpuTexture.format, w, h, d); + const view: Uint8Array = new Uint8Array(imgSize); + gl.compressedTexImage3D(gl.TEXTURE_3D, i, gpuTexture.glInternalFmt, w, h, d, 0, view); + w = Math.max(1, w >> 1); + h = Math.max(1, h >> 1); + } + } else { + gl.texStorage3D(gl.TEXTURE_3D, gpuTexture.mipLevel, gpuTexture.glInternalFmt, w, h, d); + } + } + break; + } case TextureType.CUBE: { gpuTexture.glTarget = gl.TEXTURE_CUBE_MAP; @@ -1158,6 +1242,8 @@ export function WebGL2CmdFuncResizeTexture (device: WebGL2Device, gpuTexture: IW let w = gpuTexture.width; let h = gpuTexture.height; + const d = gpuTexture.depth; + const l = gpuTexture.arrayLayer; switch (gpuTexture.type) { case TextureType.TEX2D: { @@ -1200,6 +1286,71 @@ export function WebGL2CmdFuncResizeTexture (device: WebGL2Device, gpuTexture: IW } break; } + case TextureType.TEX2D_ARRAY: { + gpuTexture.glTarget = gl.TEXTURE_2D_ARRAY; + + const maxSize = Math.max(w, h); + if (maxSize > device.capabilities.maxTextureSize) { + errorID(9100, maxSize, device.capabilities.maxTextureSize); + } + if (l > device.capabilities.maxArrayTextureLayers) { + errorID(9100, l, device.capabilities.maxArrayTextureLayers); + } + + gpuTexture.glTexture = gl.createTexture(); + if (gpuTexture.size > 0) { + const glTexUnit = device.stateCache.glTexUnits[device.stateCache.texUnit]; + + if (glTexUnit.glTexture !== gpuTexture.glTexture) { + gl.bindTexture(gl.TEXTURE_2D_ARRAY, gpuTexture.glTexture); + glTexUnit.glTexture = gpuTexture.glTexture; + } + + if (FormatInfos[gpuTexture.format].isCompressed) { + for (let i = 0; i < gpuTexture.mipLevel; ++i) { + const imgSize = FormatSize(gpuTexture.format, w, h, l); + const view: Uint8Array = new Uint8Array(imgSize); + gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, i, gpuTexture.glInternalFmt, w, h, l, 0, view); + w = Math.max(1, w >> 1); + h = Math.max(1, h >> 1); + } + } else { + gl.texStorage3D(gl.TEXTURE_2D_ARRAY, gpuTexture.mipLevel, gpuTexture.glInternalFmt, w, h, l); + } + } + break; + } + case TextureType.TEX3D: { + gpuTexture.glTarget = gl.TEXTURE_3D; + + const maxSize = Math.max(Math.max(w, h), d); + if (maxSize > device.capabilities.max3DTextureSize) { + errorID(9100, maxSize, device.capabilities.max3DTextureSize); + } + + gpuTexture.glTexture = gl.createTexture(); + if (gpuTexture.size > 0) { + const glTexUnit = device.stateCache.glTexUnits[device.stateCache.texUnit]; + + if (glTexUnit.glTexture !== gpuTexture.glTexture) { + gl.bindTexture(gl.TEXTURE_3D, gpuTexture.glTexture); + glTexUnit.glTexture = gpuTexture.glTexture; + } + + if (FormatInfos[gpuTexture.format].isCompressed) { + for (let i = 0; i < gpuTexture.mipLevel; ++i) { + const imgSize = FormatSize(gpuTexture.format, w, h, d); + const view: Uint8Array = new Uint8Array(imgSize); + gl.compressedTexImage3D(gl.TEXTURE_3D, i, gpuTexture.glInternalFmt, w, h, d, 0, view); + w = Math.max(1, w >> 1); + h = Math.max(1, h >> 1); + } + } else { + gl.texStorage3D(gl.TEXTURE_3D, gpuTexture.mipLevel, gpuTexture.glInternalFmt, w, h, d); + } + } + break; + } case TextureType.CUBE: { gpuTexture.type = TextureType.CUBE; gpuTexture.glTarget = gl.TEXTURE_CUBE_MAP; @@ -1463,6 +1614,8 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb gpuShader.glProgram = glProgram; + const enableEffectImport = !!(cclegacy.rendering && cclegacy.rendering.enableEffectImport); + // link program for (let k = 0; k < gpuShader.gpuStages.length; k++) { const gpuStage = gpuShader.gpuStages[k]; @@ -1553,7 +1706,10 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb // blockIdx = gl.getUniformBlockIndex(gpuShader.glProgram, blockName); blockIdx = b; blockSize = gl.getActiveUniformBlockParameter(gpuShader.glProgram, blockIdx, gl.UNIFORM_BLOCK_DATA_SIZE); - const glBinding = block.binding + (device.bindingMappings.blockOffsets[block.set] || 0); + + const glBinding = enableEffectImport + ? block.flattened + : block.binding + (device.bindingMappings.blockOffsets[block.set] || 0); gl.uniformBlockBinding(gpuShader.glProgram, blockIdx, glBinding); @@ -1602,27 +1758,42 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb const glActiveSamplerLocations: WebGLUniformLocation[] = []; const texUnitCacheMap = device.stateCache.texUnitCacheMap; - let flexibleSetBaseOffset = 0; - for (let i = 0; i < gpuShader.blocks.length; ++i) { - if (gpuShader.blocks[i].set === device.bindingMappings.flexibleSet) { - flexibleSetBaseOffset++; + if (!enableEffectImport) { + let flexibleSetBaseOffset = 0; + for (let i = 0; i < gpuShader.blocks.length; ++i) { + if (gpuShader.blocks[i].set === device.bindingMappings.flexibleSet) { + flexibleSetBaseOffset++; + } } - } - let arrayOffset = 0; - for (let i = 0; i < gpuShader.samplerTextures.length; ++i) { - const sampler = gpuShader.samplerTextures[i]; - const glLoc = gl.getUniformLocation(gpuShader.glProgram, sampler.name); - // wEcHAT just returns { id: -1 } for non-existing names /eyerolling - if (glLoc && (glLoc as any).id !== -1) { - glActiveSamplers.push(gpuShader.glSamplerTextures[i]); - glActiveSamplerLocations.push(glLoc); + let arrayOffset = 0; + for (let i = 0; i < gpuShader.samplerTextures.length; ++i) { + const sampler = gpuShader.samplerTextures[i]; + const glLoc = gl.getUniformLocation(gpuShader.glProgram, sampler.name); + // wEcHAT just returns { id: -1 } for non-existing names /eyerolling + if (glLoc && (glLoc as any).id !== -1) { + glActiveSamplers.push(gpuShader.glSamplerTextures[i]); + glActiveSamplerLocations.push(glLoc); + } + if (texUnitCacheMap[sampler.name] === undefined) { + let binding = sampler.binding + device.bindingMappings.samplerTextureOffsets[sampler.set] + arrayOffset; + if (sampler.set === device.bindingMappings.flexibleSet) { binding -= flexibleSetBaseOffset; } + texUnitCacheMap[sampler.name] = binding % device.capabilities.maxTextureUnits; + arrayOffset += sampler.count - 1; + } } - if (texUnitCacheMap[sampler.name] === undefined) { - let binding = sampler.binding + device.bindingMappings.samplerTextureOffsets[sampler.set] + arrayOffset; - if (sampler.set === device.bindingMappings.flexibleSet) { binding -= flexibleSetBaseOffset; } - texUnitCacheMap[sampler.name] = binding % device.capabilities.maxTextureUnits; - arrayOffset += sampler.count - 1; + } else { + for (let i = 0; i < gpuShader.samplerTextures.length; ++i) { + const sampler = gpuShader.samplerTextures[i]; + const glLoc = gl.getUniformLocation(gpuShader.glProgram, sampler.name); + // wEcHAT just returns { id: -1 } for non-existing names /eyerolling + if (glLoc && (glLoc as any).id !== -1) { + glActiveSamplers.push(gpuShader.glSamplerTextures[i]); + glActiveSamplerLocations.push(glLoc); + } + if (texUnitCacheMap[sampler.name] === undefined) { + texUnitCacheMap[sampler.name] = sampler.flattened % device.capabilities.maxTextureUnits; + } } } @@ -2574,6 +2745,11 @@ export function WebGL2CmdFuncExecuteCmds (device: WebGL2Device, cmdPackage: WebG WebGL2CmdFuncCopyBuffersToTexture(device, cmd5.buffers, cmd5.gpuTexture as IWebGL2GPUTexture, cmd5.regions); break; } + case WebGL2Cmd.BLIT_TEXTURE: { + const cmd6 = cmdPackage.blitTextureCmds.array[cmdId]; + WebGL2CmdFuncBlitTexture(device, cmd6.srcTexture as IWebGL2GPUTexture, cmd6.dstTexture as IWebGL2GPUTexture, cmd6.regions, cmd6.filter); + break; + } default: } // switch } // for @@ -2971,3 +3147,111 @@ export function WebGL2CmdFuncBlitFramebuffer ( gl.bindFramebuffer(gl.FRAMEBUFFER, device.stateCache.glFramebuffer); } } + +export function WebGL2CmdFuncBlitTexture ( + device: WebGL2Device, + src: Readonly, + dst: IWebGL2GPUTexture, + regions: Readonly, + filter: Filter, +) { + const { gl } = device; + const cache = device.stateCache; + const blitManager = device.blitManager; + if (!blitManager) { + return; + } + + // logic different from native, because framebuffer-map is not implemented in webgl2 + const glFilter = (filter === Filter.LINEAR || filter === Filter.ANISOTROPIC) ? gl.LINEAR : gl.NEAREST; + + const srcFramebuffer = blitManager.srcFramebuffer; + const dstFramebuffer = blitManager.dstFramebuffer; + const origReadFBO = cache.glReadFramebuffer; + const origDrawFBO = cache.glFramebuffer; + + let srcMip = regions[0].srcSubres.mipLevel; + let dstMip = regions[0].dstSubres.mipLevel; + + const blitInfo = (formatInfo: FormatInfo) => { + let mask = 0; + let attachment = gl.COLOR_ATTACHMENT0; + + if (formatInfo.hasStencil) { + attachment = gl.DEPTH_STENCIL_ATTACHMENT; + } else if (formatInfo.hasDepth) { + attachment = gl.DEPTH_ATTACHMENT; + } + + if (formatInfo.hasDepth || formatInfo.hasStencil) { + if (formatInfo.hasDepth) { + mask |= gl.DEPTH_BUFFER_BIT; + } + if (formatInfo.hasStencil) { + mask |= gl.STENCIL_BUFFER_BIT; + } + } else { + mask |= gl.COLOR_BUFFER_BIT; + } + + return { mask, attachment }; + }; + + const regionIndices = regions.map((_, i) => i); + regionIndices.sort((a, b) => regions[a].srcSubres.mipLevel - regions[b].srcSubres.mipLevel); + + const { mask: srcMask, attachment: srcAttachment } = blitInfo(FormatInfos[src.format]); + const { mask: dstMask, attachment: dstAttachment } = blitInfo(FormatInfos[dst.format]); + + if (cache.glReadFramebuffer !== srcFramebuffer) { + gl.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFramebuffer); + cache.glReadFramebuffer = srcFramebuffer; + } + + if (cache.glFramebuffer !== dstFramebuffer) { + gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFramebuffer); + cache.glFramebuffer = dstFramebuffer; + } + + if (src.glTexture) { + gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, srcAttachment, src.glTarget, src.glTexture, srcMip); + } else { + gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, srcAttachment, gl.RENDERBUFFER, src.glRenderbuffer); + } + + if (dst.glTexture) { + gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, dstAttachment, dst.glTarget, dst.glTexture, dstMip); + } else { + gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, dstAttachment, gl.RENDERBUFFER, dst.glRenderbuffer); + } + + for (let i = 0; i < regionIndices.length; i++) { + const region = regions[regionIndices[i]]; + + if (src.glTexture && srcMip !== region.srcSubres.mipLevel) { + srcMip = region.srcSubres.mipLevel; + gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, srcAttachment, src.glTarget, src.glTexture, srcMip); + } + + if (dst.glTexture && dstMip !== region.dstSubres.mipLevel) { + dstMip = region.dstSubres.mipLevel; + gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, dstAttachment, dst.glTarget, dst.glTexture, dstMip); + } + + gl.blitFramebuffer( + region.srcOffset.x, region.srcOffset.y, region.srcOffset.x + region.srcExtent.width, region.srcOffset.y + region.srcExtent.height, + region.dstOffset.x, region.dstOffset.y, region.dstOffset.x + region.dstExtent.width, region.dstOffset.y + region.dstExtent.height, + srcMask, glFilter, + ); + } + + // restore fbo state + if (cache.glReadFramebuffer !== origReadFBO) { + gl.bindFramebuffer(gl.READ_FRAMEBUFFER, origReadFBO); + cache.glReadFramebuffer = origReadFBO; + } + if (cache.glFramebuffer !== origDrawFBO) { + gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, origDrawFBO); + cache.glFramebuffer = origDrawFBO; + } +} diff --git a/cocos/gfx/webgl2/webgl2-define.ts b/cocos/gfx/webgl2/webgl2-define.ts index 92553146d5c..6bfe1593457 100644 --- a/cocos/gfx/webgl2/webgl2-define.ts +++ b/cocos/gfx/webgl2/webgl2-define.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { WebGL2Device } from './webgl2-device'; diff --git a/cocos/gfx/webgl2/webgl2-descriptor-set-layout.ts b/cocos/gfx/webgl2/webgl2-descriptor-set-layout.ts index 2899f183768..66af8f60504 100644 --- a/cocos/gfx/webgl2/webgl2-descriptor-set-layout.ts +++ b/cocos/gfx/webgl2/webgl2-descriptor-set-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSetLayoutInfo, DESCRIPTOR_DYNAMIC_TYPE } from '../base/define'; import { DescriptorSetLayout } from '../base/descriptor-set-layout'; diff --git a/cocos/gfx/webgl2/webgl2-descriptor-set.ts b/cocos/gfx/webgl2/webgl2-descriptor-set.ts index fc3cedff48f..65cd99a2341 100644 --- a/cocos/gfx/webgl2/webgl2-descriptor-set.ts +++ b/cocos/gfx/webgl2/webgl2-descriptor-set.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DescriptorSet } from '../base/descriptor-set'; import { WebGL2Buffer } from './webgl2-buffer'; diff --git a/cocos/gfx/webgl2/webgl2-device.ts b/cocos/gfx/webgl2/webgl2-device.ts index b0ec975a70c..cb2e5ee8140 100644 --- a/cocos/gfx/webgl2/webgl2-device.ts +++ b/cocos/gfx/webgl2/webgl2-device.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,8 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ +import { systemInfo } from 'pal/system-info'; import { DescriptorSet } from '../base/descriptor-set'; import { DescriptorSetLayout } from '../base/descriptor-set-layout'; import { PipelineLayout } from '../base/pipeline-layout'; @@ -62,10 +62,11 @@ import { WebGL2CmdFuncCopyTextureToBuffers, WebGL2CmdFuncCopyBuffersToTexture, W import { GeneralBarrier } from '../base/states/general-barrier'; import { TextureBarrier } from '../base/states/texture-barrier'; import { BufferBarrier } from '../base/states/buffer-barrier'; -import { debug } from '../../core'; +import { debug, sys } from '../../core'; import { Swapchain } from '../base/swapchain'; import { IWebGL2Extensions, WebGL2DeviceManager } from './webgl2-define'; import { IWebGL2BindingMapping } from './webgl2-gpu-objects'; +import { BrowserType, OS } from '../../../pal/system-info/enum-type'; export class WebGL2Device extends Device { get gl () { @@ -96,6 +97,10 @@ export class WebGL2Device extends Device { return this._bindingMappings!; } + get blitManager () { + return this._swapchain!.blitManager; + } + private _swapchain: WebGL2Swapchain | null = null; private _context: WebGL2RenderingContext | null = null; private _bindingMappings: IWebGL2BindingMapping | null = null; @@ -143,6 +148,13 @@ export class WebGL2Device extends Device { this._caps.maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); this._caps.maxVertexUniformVectors = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); + // WECHAT browser in IOS implementation of WebGL2 exist bugs. + // iOS15.5 or higher 15.x version the max valid vertex uniform vectors is 256. + // iOS16.0 or higher 16.x version the max valid vertex uniform vectors is 520? + // So limit wechat browser in IOS using vertex uniform vectors no more than 256. + if (systemInfo.os === OS.IOS && sys.browserType === BrowserType.WECHAT) { + this._caps.maxVertexUniformVectors = 256; + } this._caps.maxFragmentUniformVectors = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); this._caps.maxTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); this._caps.maxVertexTextureUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); @@ -150,6 +162,8 @@ export class WebGL2Device extends Device { this._caps.maxUniformBlockSize = gl.getParameter(gl.MAX_UNIFORM_BLOCK_SIZE); this._caps.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); this._caps.maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); + this._caps.maxArrayTextureLayers = gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS); + this._caps.max3DTextureSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE); this._caps.uboOffsetAlignment = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT); const extensions = gl.getSupportedExtensions(); diff --git a/cocos/gfx/webgl2/webgl2-framebuffer.ts b/cocos/gfx/webgl2/webgl2-framebuffer.ts index 1b7694bf15f..596a3295bbf 100644 --- a/cocos/gfx/webgl2/webgl2-framebuffer.ts +++ b/cocos/gfx/webgl2/webgl2-framebuffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { FramebufferInfo } from '../base/define'; import { Framebuffer } from '../base/framebuffer'; diff --git a/cocos/gfx/webgl2/webgl2-gpu-objects.ts b/cocos/gfx/webgl2/webgl2-gpu-objects.ts index 9b1f2b380ea..2bd64282424 100644 --- a/cocos/gfx/webgl2/webgl2-gpu-objects.ts +++ b/cocos/gfx/webgl2/webgl2-gpu-objects.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { nextPow2 } from '../../core'; import { @@ -30,6 +29,7 @@ import { ColorAttachment, DepthStencilAttachment, UniformBlock, UniformSamplerTexture, DescriptorSetLayoutBinding, } from '../base/define'; import { BlendState, DepthStencilState, RasterizerState } from '../base/pipeline-state'; +import { WebGL2DeviceManager } from './webgl2-define'; import { WebGL2Device } from './webgl2-device'; export class WebGL2IndirectDrawInfos { @@ -190,7 +190,7 @@ export interface IWebGL2GPUSampler { glWrapT: GLenum; glWrapR: GLenum; - getGLSampler (device: WebGL2Device, minLod: number, maxLod: number) : WebGLSampler; + getGLSampler (device: WebGL2Device, minLod: number, maxLod: number): WebGLSampler; } export interface IWebGL2GPUInput { @@ -321,3 +321,28 @@ export interface IWebGL2GPUInputAssembler { glIndexType: GLenum; glVAOs: Map; } + +export class IWebGL2BlitManager { + private _srcFramebuffer: WebGLFramebuffer | null; + private _dstFramebuffer: WebGLFramebuffer | null; + + get srcFramebuffer () { + return this._srcFramebuffer; + } + + get dstFramebuffer () { + return this._dstFramebuffer; + } + + constructor () { + const { gl } = WebGL2DeviceManager.instance; + this._srcFramebuffer = gl.createFramebuffer(); + this._dstFramebuffer = gl.createFramebuffer(); + } + + destroy () { + const { gl } = WebGL2DeviceManager.instance; + gl.deleteFramebuffer(this._srcFramebuffer); + gl.deleteFramebuffer(this._dstFramebuffer); + } +} diff --git a/cocos/gfx/webgl2/webgl2-input-assembler.ts b/cocos/gfx/webgl2/webgl2-input-assembler.ts index 9e7584b7ec2..bb066d39365 100644 --- a/cocos/gfx/webgl2/webgl2-input-assembler.ts +++ b/cocos/gfx/webgl2/webgl2-input-assembler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { InputAssemblerInfo } from '../base/define'; import { InputAssembler } from '../base/input-assembler'; diff --git a/cocos/gfx/webgl2/webgl2-pipeline-layout.ts b/cocos/gfx/webgl2/webgl2-pipeline-layout.ts index ca87272824b..4e21412ba02 100644 --- a/cocos/gfx/webgl2/webgl2-pipeline-layout.ts +++ b/cocos/gfx/webgl2/webgl2-pipeline-layout.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineLayout } from '../base/pipeline-layout'; import { IWebGL2GPUPipelineLayout, IWebGL2GPUDescriptorSetLayout } from './webgl2-gpu-objects'; diff --git a/cocos/gfx/webgl2/webgl2-pipeline-state.ts b/cocos/gfx/webgl2/webgl2-pipeline-state.ts index 4286cf2ac0e..d4175e81136 100644 --- a/cocos/gfx/webgl2/webgl2-pipeline-state.ts +++ b/cocos/gfx/webgl2/webgl2-pipeline-state.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PipelineState, PipelineStateInfo } from '../base/pipeline-state'; import { IWebGL2GPUPipelineState } from './webgl2-gpu-objects'; diff --git a/cocos/gfx/webgl2/webgl2-primary-command-buffer.ts b/cocos/gfx/webgl2/webgl2-primary-command-buffer.ts index 12ce356652b..d6b5db5e443 100644 --- a/cocos/gfx/webgl2/webgl2-primary-command-buffer.ts +++ b/cocos/gfx/webgl2/webgl2-primary-command-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Buffer } from '../base/buffer'; import { CommandBuffer } from '../base/command-buffer'; -import { BufferUsageBit, BufferTextureCopy, Color, Rect, BufferSource, DrawInfo, Viewport } from '../base/define'; +import { BufferUsageBit, BufferTextureCopy, Color, Rect, BufferSource, DrawInfo, Viewport, TextureBlit, Filter } from '../base/define'; import { Framebuffer } from '../base/framebuffer'; import { InputAssembler } from '../base/input-assembler'; import { Texture } from '../base/texture'; import { WebGL2Buffer } from './webgl2-buffer'; import { WebGL2CommandBuffer } from './webgl2-command-buffer'; import { - WebGL2CmdFuncBeginRenderPass, WebGL2CmdFuncBindStates, WebGL2CmdFuncCopyBuffersToTexture, + WebGL2CmdFuncBeginRenderPass, WebGL2CmdFuncBindStates, WebGL2CmdFuncBlitTexture, WebGL2CmdFuncCopyBuffersToTexture, WebGL2CmdFuncDraw, WebGL2CmdFuncExecuteCmds, WebGL2CmdFuncUpdateBuffer } from './webgl2-commands'; import { WebGL2Framebuffer } from './webgl2-framebuffer'; import { WebGL2Texture } from './webgl2-texture'; @@ -170,4 +169,10 @@ export class WebGL2PrimaryCommandBuffer extends WebGL2CommandBuffer { this._curGPUDescriptorSets, this._curDynamicOffsets, this._curDynamicStates); this._isStateInvalied = false; } + + public blitTexture (srcTexture: Readonly, dstTexture: Texture, regions: Readonly, filter: Filter): void { + const gpuTextureSrc = (srcTexture as WebGL2Texture).gpuTexture; + const gpuTextureDst = (dstTexture as WebGL2Texture).gpuTexture; + WebGL2CmdFuncBlitTexture(WebGL2DeviceManager.instance, gpuTextureSrc, gpuTextureDst, regions, filter); + } } diff --git a/cocos/gfx/webgl2/webgl2-queue.ts b/cocos/gfx/webgl2/webgl2-queue.ts index 700ec83b5a1..117d8cc8af7 100644 --- a/cocos/gfx/webgl2/webgl2-queue.ts +++ b/cocos/gfx/webgl2/webgl2-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { QueueInfo } from '../base/define'; import { CommandBuffer } from '../base/command-buffer'; diff --git a/cocos/gfx/webgl2/webgl2-render-pass.ts b/cocos/gfx/webgl2/webgl2-render-pass.ts index 7f91011c457..c307a5fab12 100644 --- a/cocos/gfx/webgl2/webgl2-render-pass.ts +++ b/cocos/gfx/webgl2/webgl2-render-pass.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { RenderPassInfo } from '../base/define'; import { RenderPass } from '../base/render-pass'; diff --git a/cocos/gfx/webgl2/webgl2-shader.ts b/cocos/gfx/webgl2/webgl2-shader.ts index 767261b0554..94f92ccb1a3 100644 --- a/cocos/gfx/webgl2/webgl2-shader.ts +++ b/cocos/gfx/webgl2/webgl2-shader.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ShaderInfo } from '../base/define'; import { Shader } from '../base/shader'; diff --git a/cocos/gfx/webgl2/webgl2-state-cache.ts b/cocos/gfx/webgl2/webgl2-state-cache.ts index ac1fa5af424..37ee443dcc1 100644 --- a/cocos/gfx/webgl2/webgl2-state-cache.ts +++ b/cocos/gfx/webgl2/webgl2-state-cache.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Rect, Viewport } from '../base/define'; import { BlendState, DepthStencilState, RasterizerState } from '../base/pipeline-state'; diff --git a/cocos/gfx/webgl2/webgl2-swapchain.ts b/cocos/gfx/webgl2/webgl2-swapchain.ts index be52645e027..8165f847e57 100644 --- a/cocos/gfx/webgl2/webgl2-swapchain.ts +++ b/cocos/gfx/webgl2/webgl2-swapchain.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { systemInfo } from 'pal/system-info'; @@ -33,6 +32,7 @@ import { Format, TextureInfo, TextureFlagBit, TextureType, import { Swapchain } from '../base/swapchain'; import { IWebGL2Extensions, WebGL2DeviceManager } from './webgl2-define'; import { OS } from '../../../pal/system-info/enum-type'; +import { IWebGL2BlitManager } from './webgl2-gpu-objects'; const eventWebGLContextLost = 'webglcontextlost'; @@ -120,6 +120,22 @@ export function getExtensions (gl: WebGL2RenderingContext) { export function getContext (canvas: HTMLCanvasElement): WebGL2RenderingContext | null { let context: WebGL2RenderingContext | null = null; try { + if (globalThis.__globalXR.webxrCompatible) { + const glAttribs = { + alpha: macro.ENABLE_TRANSPARENT_CANVAS, + antialias: EDITOR || macro.ENABLE_WEBGL_ANTIALIAS, + depth: true, + stencil: true, + premultipliedAlpha: false, + preserveDrawingBuffer: false, + powerPreference: 'default', + failIfMajorPerformanceCaveat: false, + xrCompatible: true, + }; + context = canvas.getContext('webgl2', glAttribs) as WebGL2RenderingContext; + return context; + } + const webGLCtxAttribs: WebGLContextAttributes = { alpha: macro.ENABLE_TRANSPARENT_CANVAS, antialias: EDITOR || macro.ENABLE_WEBGL_ANTIALIAS, @@ -144,6 +160,10 @@ export class WebGL2Swapchain extends Swapchain { return this._extensions as IWebGL2Extensions; } + get blitManager () { + return this._blitManager; + } + public stateCache: WebGL2StateCache = new WebGL2StateCache(); public nullTex2D: WebGL2Texture = null!; public nullTexCube: WebGL2Texture = null!; @@ -151,6 +171,7 @@ export class WebGL2Swapchain extends Swapchain { private _canvas: HTMLCanvasElement | null = null; private _webGL2ContextLostHandler: ((event: Event) => void) | null = null; private _extensions: IWebGL2Extensions | null = null; + private _blitManager: IWebGL2BlitManager | null = null; public initialize (info: Readonly) { this._canvas = info.windowHandle; @@ -231,6 +252,8 @@ export class WebGL2Swapchain extends Swapchain { [nullTexBuff, nullTexBuff, nullTexBuff, nullTexBuff, nullTexBuff, nullTexBuff], this.nullTexCube, [nullTexRegion], ); + + this._blitManager = new IWebGL2BlitManager(); } public destroy (): void { @@ -249,6 +272,11 @@ export class WebGL2Swapchain extends Swapchain { this.nullTexCube = null!; } + if (this._blitManager) { + this._blitManager.destroy(); + this._blitManager = null; + } + this._extensions = null; this._canvas = null; } diff --git a/cocos/gfx/webgl2/webgl2-texture.ts b/cocos/gfx/webgl2/webgl2-texture.ts index a643d5e8b38..eef170be1d3 100644 --- a/cocos/gfx/webgl2/webgl2-texture.ts +++ b/cocos/gfx/webgl2/webgl2-texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { FormatSurfaceSize, TextureInfo, IsPowerOf2, TextureViewInfo, ISwapchainTextureInfo, @@ -89,9 +88,10 @@ export class WebGL2Texture extends Texture { isSwapchainTexture: isSwapchainTexture || false, }; - WebGL2CmdFuncCreateTexture(WebGL2DeviceManager.instance, this._gpuTexture); - - WebGL2DeviceManager.instance.memoryStatus.textureSize += this._size; + if (!this._gpuTexture.isSwapchainTexture && this._gpuTexture) { + WebGL2CmdFuncCreateTexture(WebGL2DeviceManager.instance, this._gpuTexture); + WebGL2DeviceManager.instance.memoryStatus.textureSize += this._size; + } this._viewInfo.texture = this; this._viewInfo.type = info.type; @@ -135,6 +135,21 @@ export class WebGL2Texture extends Texture { } } + public getGLTextureHandle () : number { + const gpuTexture = this._gpuTexture; + if (!gpuTexture) { + return 0; + } + + if (gpuTexture.glTexture) { + return gpuTexture.glTexture as number; + } else if (gpuTexture.glRenderbuffer) { + return gpuTexture.glRenderbuffer as number; + } + + return 0; + } + public resize (width: number, height: number) { if (this._info.width === width && this._info.height === height) { return; @@ -156,9 +171,11 @@ export class WebGL2Texture extends Texture { this._gpuTexture.width = width; this._gpuTexture.height = height; this._gpuTexture.size = this._size; - WebGL2CmdFuncResizeTexture(WebGL2DeviceManager.instance, this._gpuTexture); - WebGL2DeviceManager.instance.memoryStatus.textureSize -= oldSize; - WebGL2DeviceManager.instance.memoryStatus.textureSize += this._size; + if (!this._gpuTexture.isSwapchainTexture) { + WebGL2CmdFuncResizeTexture(WebGL2DeviceManager.instance, this._gpuTexture); + WebGL2DeviceManager.instance.memoryStatus.textureSize -= oldSize; + WebGL2DeviceManager.instance.memoryStatus.textureSize += this._size; + } } } diff --git a/cocos/core/gfx/webgpu/override.ts b/cocos/gfx/webgpu/override.ts similarity index 61% rename from cocos/core/gfx/webgpu/override.ts rename to cocos/gfx/webgpu/override.ts index c5a7cd92ede..f0190ac39d8 100644 --- a/cocos/core/gfx/webgpu/override.ts +++ b/cocos/gfx/webgpu/override.ts @@ -1,7 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable import/no-mutable-exports */ import { WEBGPU } from 'internal:constants'; -import { gfx, promiseForWebGPUInstantiation } from '../../../webgpu/instantiated'; +import { gfx, promiseForWebGPUInstantiation } from '../../webgpu/instantiated'; export let Device: any; export let WebGPUDevice: any; diff --git a/cocos/core/gfx/webgpu/webgpu-define.ts b/cocos/gfx/webgpu/webgpu-define.ts similarity index 89% rename from cocos/core/gfx/webgpu/webgpu-define.ts rename to cocos/gfx/webgpu/webgpu-define.ts index 1924b9caf9a..73283fd0868 100644 --- a/cocos/core/gfx/webgpu/webgpu-define.ts +++ b/cocos/gfx/webgpu/webgpu-define.ts @@ -3,20 +3,19 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable func-names */ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,17 +24,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { WEBGPU } from 'internal:constants'; -import { gfx, webgpuAdapter, glslalgWasmModule, promiseForWebGPUInstantiation } from '../../../webgpu/instantiated'; +import { gfx, webgpuAdapter, glslalgWasmModule, promiseForWebGPUInstantiation } from '../../webgpu/instantiated'; import { Texture, CommandBuffer, DescriptorSet, Device, InputAssembler, Buffer, Shader } from './override'; import { - DeviceInfo, BufferTextureCopy, ShaderInfo, ShaderStageFlagBit, TextureViewInfo, TextureInfo, DrawInfo, BufferViewInfo, BufferInfo, + DeviceInfo, BufferTextureCopy, ShaderInfo, ShaderStageFlagBit, TextureViewInfo, TextureInfo, DrawInfo, BufferViewInfo, BufferInfo, BufferUsageBit, IndirectBuffer, } from '../base/define'; +import { ccwindow } from '../../core/global-exports'; + + WEBGPU && promiseForWebGPUInstantiation.then(() => { const originDeviceInitializeFunc = Device.prototype.initialize; Device.prototype.initialize = function (info: DeviceInfo) { @@ -85,22 +87,30 @@ WEBGPU && promiseForWebGPUInstantiation.then(() => { const oldUpdateBuffer = Buffer.prototype.update; Buffer.prototype.update = function (data: BufferSource, size?: number) { - const updateSize = size === undefined ? data.byteLength : size; - if ('buffer' in data) { - oldUpdateBuffer.call(this, new Uint8Array(data.buffer, data.byteOffset, data.byteLength), updateSize); + if (this.usage & BufferUsageBit.INDIRECT) { + this.updateIndirect(((data as unknown) as IndirectBuffer).drawInfos); } else { - oldUpdateBuffer.call(this, new Uint8Array(data), updateSize); + const updateSize = size === undefined ? data.byteLength : size; + if ('buffer' in data) { + oldUpdateBuffer.call(this, new Uint8Array(data.buffer, data.byteOffset, data.byteLength), updateSize); + } else { + oldUpdateBuffer.call(this, new Uint8Array(data), updateSize); + } } + }; const oldCmdUpdateBuffer = CommandBuffer.prototype.updateBuffer; CommandBuffer.prototype.updateBuffer = function (buffer: typeof Buffer, data: BufferSource, size?: number) { - const updateSize = size === undefined ? data.byteLength : size; - - if ('buffer' in data) { - oldCmdUpdateBuffer.call(this, buffer, new Uint8Array(data.buffer, data.byteOffset, data.byteLength), updateSize); + if (this.usage & BufferUsageBit.INDIRECT) { + this.updateIndirect(buffer, ((data as unknown) as IndirectBuffer).drawInfos); } else { - oldCmdUpdateBuffer.call(this, buffer, new Uint8Array(data), updateSize); + const updateSize = size === undefined ? data.byteLength : size; + if ('buffer' in data) { + oldCmdUpdateBuffer.call(this, buffer, new Uint8Array(data.buffer, data.byteOffset, data.byteLength), updateSize); + } else { + oldCmdUpdateBuffer.call(this, buffer, new Uint8Array(data), updateSize); + } } }; @@ -160,13 +170,13 @@ WEBGPU && promiseForWebGPUInstantiation.then(() => { data = new Uint8Array(rawBuffer); } buffers[i] = data; - } else if (texImages[i] instanceof HTMLImageElement) { - const img = texImages[i] as HTMLImageElement; - const canvas = document.createElement('canvas'); + } else if (texImages[i] instanceof HTMLImageElement || texImages[i] instanceof ImageBitmap) { + const img = texImages[i]; + const canvas = ccwindow.document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); - ctx?.drawImage(img, 0, 0); + ctx?.drawImage(img as any, 0, 0); const imageData = ctx?.getImageData(0, 0, img.width, img.height); const buff = imageData!.data.buffer; let data; @@ -196,25 +206,34 @@ WEBGPU && promiseForWebGPUInstantiation.then(() => { const referredFuncMap = new Map(); const samplerSet = new Set(); samplerTexturArr?.every((str) => { - let textureName = str.match(/(?<=uniform(.*?)sampler\w* )(\w+)(?=;)/g)!.toString(); + // `(?<=)` not compatible with str.match on safari. + // let textureName = str.match(/(?<=uniform(.*?)sampler\w* )(\w+)(?=;)/g)!.toString(); + const textureNameRegExpStr = '(?<=uniform(.*?)sampler\\w* )(\\w+)(?=;)'; + let textureName = (new RegExp(textureNameRegExpStr, 'g')).exec(str)![0]; + let samplerStr = str.replace(textureName, `${textureName}Sampler`); - let samplerFunc = samplerStr.match(/(?<=uniform(.*?))sampler(\w*)/g)!.toString(); + + // let samplerFunc = samplerStr.match(/(?<=uniform(.*?))sampler(\w*)/g)!.toString(); + const samplerRegExpStr = '(?<=uniform(.*?))sampler(\\w*)'; + let samplerFunc = (new RegExp(samplerRegExpStr, 'g')).exec(str)![0]; samplerFunc = samplerFunc.replace('sampler', ''); if (samplerFunc === '') { textureName = textureName.replace('Sampler', ''); } else { - samplerStr = samplerStr.replace(/(?<=uniform(.*?))(sampler\w*)/g, 'sampler'); + const samplerReplaceReg = new RegExp('(?<=uniform(.*?))(sampler\\w*)', 'g'); + samplerStr = samplerStr.replace(samplerReplaceReg, 'sampler'); // layout (set = a, binding = b) uniform sampler2D cctex; // to: // layout (set = a, binding = b) uniform sampler cctexSampler; // layout (set = a, binding = b + maxTextureNum) uniform texture2D cctex; - const samplerReg = /(?<=binding = )(\d+)(?=\))/g; - const samplerBindingStr = str.match(samplerReg)!.toString(); + const samplerReg = new RegExp('(?<=binding = )(\\d+)(?=\\))', 'g'); + const samplerBindingStr = samplerReg.exec(str)![0]; const samplerBinding = Number(samplerBindingStr) + 16; samplerStr = samplerStr.replace(samplerReg, samplerBinding.toString()); - const textureStr = str.replace(/(?<=uniform(.*?))(sampler)(?=\w*)/g, 'texture'); + const textureReg = new RegExp('(?<=uniform(.*?))(sampler)(?=\\w*)', 'g'); + const textureStr = str.replace(textureReg, 'texture'); code = code.replace(str, `${textureStr}\n${samplerStr}`); } @@ -515,10 +534,10 @@ WEBGPU && promiseForWebGPUInstantiation.then(() => { if (isNanIndex !== -1) { // getPrecision(isNanIndex); functionDefs += `\n - bool isNan(${precisionKeyWord} float val) { - return (val < 0.0 || 0.0 < val || val == 0.0) ? false : true; - } - \n`; + bool isNan(${precisionKeyWord} float val) { + return (val < 0.0 || 0.0 < val || val == 0.0) ? false : true; + } + \n`; code = code.replace(/isnan\(/gi, 'isNan('); } @@ -526,10 +545,10 @@ WEBGPU && promiseForWebGPUInstantiation.then(() => { if (isInfIndex !== -1) { // getPrecision(isInfIndex); functionDefs += `\n - bool isInf(${precisionKeyWord} float x) { - return x == x * 2.0 && x != 0.0; - } - \n`; + bool isInf(${precisionKeyWord} float x) { + return x == x * 2.0 && x != 0.0; + } + \n`; code = code.replace(/isinf\(/gi, 'isInf('); } diff --git a/cocos/gi/light-probe/auto-placement.ts b/cocos/gi/light-probe/auto-placement.ts new file mode 100644 index 00000000000..c728c0d39e8 --- /dev/null +++ b/cocos/gi/light-probe/auto-placement.ts @@ -0,0 +1,86 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Vec3, Enum } from '../../core'; + +export const PlaceMethod = Enum({ + UNIFORM: 0, + ADAPTIVE: 1, +}); + +export interface PlacementInfo { + method: number; + nProbesX: number; + nProbesY: number; + nProbesZ: number; + minPos: Vec3; + maxPos: Vec3; +} + +export class AutoPlacement { + public static generate (info: PlacementInfo) { + switch (info.method) { + case PlaceMethod.UNIFORM: + return this.doGenerateUniform(info); + case PlaceMethod.ADAPTIVE: + return this.doGenerateAdaptive(info); + default: + return []; + } + } + + private static doGenerateUniform (info: PlacementInfo) { + if (info.nProbesX < 2 || info.nProbesY < 2 || info.nProbesZ < 2) { + return []; + } + + const probes: Vec3[] = []; + const position = new Vec3(0.0, 0.0, 0.0); + const gridSize = new Vec3( + (info.maxPos.x - info.minPos.x) / (info.nProbesX - 1), + (info.maxPos.y - info.minPos.y) / (info.nProbesY - 1), + (info.maxPos.z - info.minPos.z) / (info.nProbesZ - 1), + ); + + for (let x = 0; x < info.nProbesX; x++) { + position.x = x * gridSize.x + info.minPos.x; + + for (let y = 0; y < info.nProbesY; y++) { + position.y = y * gridSize.y + info.minPos.y; + + for (let z = 0; z < info.nProbesZ; z++) { + position.z = z * gridSize.z + info.minPos.z; + probes.push(new Vec3(position)); + } + } + } + + return probes; + } + + private static doGenerateAdaptive (info: PlacementInfo) { + // TODO + return this.doGenerateUniform(info); + } +} diff --git a/cocos/gi/light-probe/delaunay.jsb.ts b/cocos/gi/light-probe/delaunay.jsb.ts new file mode 100644 index 00000000000..6dab49911cf --- /dev/null +++ b/cocos/gi/light-probe/delaunay.jsb.ts @@ -0,0 +1,52 @@ +/* + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { Mat3, Vec3, _decorator } from "../../core"; + +const { ccclass, serializable } = _decorator; + +export const Vertex = jsb.Vertex; +const VertexProto = Vertex.prototype; +serializable(VertexProto, 'position', () => new Vec3(0, 0, 0)); +serializable(VertexProto, 'normal', () => new Vec3(0, 0, 0)); +serializable(VertexProto, 'coefficients', () => []); +ccclass('cc.Vertex')(Vertex); + +export const CircumSphere = jsb.CircumSphere; +const CircumSphereProto = CircumSphere.prototype; +serializable(CircumSphereProto, 'center', () => new Vec3(0, 0, 0)); +serializable(CircumSphereProto, 'radiusSquared', () => 0.0); +ccclass('cc.CircumSphere')(CircumSphere); + +export const Tetrahedron = jsb.Tetrahedron; +const TetrahedronProto = Tetrahedron.prototype; +serializable(TetrahedronProto, 'invalid', () => false); +serializable(TetrahedronProto, 'vertex0', () => -1); +serializable(TetrahedronProto, 'vertex1', () => -1); +serializable(TetrahedronProto, 'vertex2', () => -1); +serializable(TetrahedronProto, 'vertex3', () => -1); +serializable(TetrahedronProto, 'neighbours', () => [-1, -1, -1, -1]); +serializable(TetrahedronProto, 'matrix', () => new Mat3()); +serializable(TetrahedronProto, 'offset', () => new Vec3(0.0, 0.0, 0.0)); +serializable(TetrahedronProto, 'sphere', () => new CircumSphere()); +ccclass('cc.Tetrahedron')(Tetrahedron); diff --git a/cocos/gi/light-probe/delaunay.ts b/cocos/gi/light-probe/delaunay.ts new file mode 100644 index 00000000000..e82235e195f --- /dev/null +++ b/cocos/gi/light-probe/delaunay.ts @@ -0,0 +1,644 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { Mat3, EPSILON, Vec3, _decorator } from '../../core'; + +const { ccclass, serializable } = _decorator; + +const _mat = new Mat3(); +const _n = new Vec3(0.0, 0.0, 0.0); + +const _a = new Vec3(0.0, 0.0, 0.0); +const _ap = new Vec3(0.0, 0.0, 0.0); +const _b = new Vec3(0.0, 0.0, 0.0); +const _bp = new Vec3(0.0, 0.0, 0.0); +const _p2 = new Vec3(0.0, 0.0, 0.0); +const _cp = new Vec3(0.0, 0.0, 0.0); + +@ccclass('cc.Vertex') +export class Vertex { + @serializable + public position = new Vec3(0, 0, 0); + @serializable + public normal = new Vec3(0, 0, 0); + @serializable + public coefficients: Vec3[] = []; + + public constructor (pos: Vec3) { + this.position.set(pos); + } +} + +class Edge { + @serializable + public tetrahedron = -1; // tetrahedron index this edge belongs to + @serializable + public index = -1; // index in triangle's three edges of an outer cell + @serializable + public vertex0 = -1; + @serializable + public vertex1 = -1; + + public constructor (tet: number, i: number, v0: number, v1: number) { + this.tetrahedron = tet; + this.index = i; + + if (v0 < v1) { + this.vertex0 = v0; + this.vertex1 = v1; + } else { + this.vertex0 = v1; + this.vertex1 = v0; + } + } + + public set (tet: number, i: number, v0: number, v1: number) { + this.tetrahedron = tet; + this.index = i; + + if (v0 < v1) { + this.vertex0 = v0; + this.vertex1 = v1; + } else { + this.vertex0 = v1; + this.vertex1 = v0; + } + } + + public isSame (other: Edge) { + return (this.vertex0 === other.vertex0 && this.vertex1 === other.vertex1); + } +} + +class Triangle { + @serializable + public invalid = false; + @serializable + public isOuterFace = true; + @serializable + public tetrahedron = -1; // tetrahedron index this triangle belongs to + @serializable + public index = -1; // index in tetrahedron's four triangles + @serializable + public vertex0 = -1; + @serializable + public vertex1 = -1; + @serializable + public vertex2 = -1; + @serializable + public vertex3 = -1; // tetrahedron's last vertex index used to compute normal direction + + public constructor (tet: number, i: number, v0: number, v1: number, v2: number, v3: number) { + this.tetrahedron = tet; + this.index = i; + this.vertex3 = v3; + + if (v0 < v1 && v0 < v2) { + this.vertex0 = v0; + if (v1 < v2) { + this.vertex1 = v1; + this.vertex2 = v2; + } else { + this.vertex1 = v2; + this.vertex2 = v1; + } + } else if (v1 < v0 && v1 < v2) { + this.vertex0 = v1; + if (v0 < v2) { + this.vertex1 = v0; + this.vertex2 = v2; + } else { + this.vertex1 = v2; + this.vertex2 = v0; + } + } else { + this.vertex0 = v2; + if (v0 < v1) { + this.vertex1 = v0; + this.vertex2 = v1; + } else { + this.vertex1 = v1; + this.vertex2 = v0; + } + } + } + + public set (tet: number, i: number, v0: number, v1: number, v2: number, v3: number) { + this.invalid = false; + this.isOuterFace = true; + + this.tetrahedron = tet; + this.index = i; + this.vertex3 = v3; + + if (v0 < v1 && v0 < v2) { + this.vertex0 = v0; + if (v1 < v2) { + this.vertex1 = v1; + this.vertex2 = v2; + } else { + this.vertex1 = v2; + this.vertex2 = v1; + } + } else if (v1 < v0 && v1 < v2) { + this.vertex0 = v1; + if (v0 < v2) { + this.vertex1 = v0; + this.vertex2 = v2; + } else { + this.vertex1 = v2; + this.vertex2 = v0; + } + } else { + this.vertex0 = v2; + if (v0 < v1) { + this.vertex1 = v0; + this.vertex2 = v1; + } else { + this.vertex1 = v1; + this.vertex2 = v0; + } + } + } + + public isSame (other: Triangle) { + return (this.vertex0 === other.vertex0 && this.vertex1 === other.vertex1 && this.vertex2 === other.vertex2); + } +} + +@ccclass('cc.CircumSphere') +export class CircumSphere { + @serializable + public center = new Vec3(0, 0, 0); + @serializable + public radiusSquared = 0.0; + + public init (p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3) { + // calculate circumsphere of 4 points in R^3 space. + _mat.set( + p1.x - p0.x, p1.y - p0.y, p1.z - p0.z, + p2.x - p0.x, p2.y - p0.y, p2.z - p0.z, + p3.x - p0.x, p3.y - p0.y, p3.z - p0.z, + ); + _mat.invert(); + _mat.transpose(); + + _n.set( + ((p1.x + p0.x) * (p1.x - p0.x) + (p1.y + p0.y) * (p1.y - p0.y) + (p1.z + p0.z) * (p1.z - p0.z)) * 0.5, + ((p2.x + p0.x) * (p2.x - p0.x) + (p2.y + p0.y) * (p2.y - p0.y) + (p2.z + p0.z) * (p2.z - p0.z)) * 0.5, + ((p3.x + p0.x) * (p3.x - p0.x) + (p3.y + p0.y) * (p3.y - p0.y) + (p3.z + p0.z) * (p3.z - p0.z)) * 0.5, + ); + + Vec3.transformMat3(this.center, _n, _mat); + this.radiusSquared = Vec3.squaredDistance(p0, this.center); + } +} + +/** + * inner tetrahedron or outer cell structure + */ + +@ccclass('cc.Tetrahedron') +export class Tetrahedron { + @serializable + public invalid = false; + @serializable + public vertex0 = -1; + @serializable + public vertex1 = -1; + @serializable + public vertex2 = -1; + @serializable + public vertex3 = -1; // -1 means outer cell, otherwise inner tetrahedron + @serializable + public neighbours: number[] = [-1, -1, -1, -1]; + + @serializable + public matrix = new Mat3(); + @serializable + public offset = new Vec3(0.0, 0.0, 0.0); // only valid in outer cell + @serializable + public sphere = new CircumSphere(); // only valid in inner tetrahedron + + // inner tetrahedron or outer cell constructor + public constructor (delaunay: Delaunay, v0: number, v1: number, v2: number, v3 = -1) { + this.vertex0 = v0; + this.vertex1 = v1; + this.vertex2 = v2; + this.vertex3 = v3; + + // inner tetrahedron + if (v3 >= 0) { + const probes = delaunay._probes; + const p0 = probes[this.vertex0].position; + const p1 = probes[this.vertex1].position; + const p2 = probes[this.vertex2].position; + const p3 = probes[this.vertex3].position; + this.sphere.init(p0, p1, p2, p3); + } + } + + public isInCircumSphere (point: Vec3) { + return Vec3.squaredDistance(point, this.sphere.center) < this.sphere.radiusSquared - EPSILON; + } + + public contain (vertexIndex: number) { + return (this.vertex0 === vertexIndex || this.vertex1 === vertexIndex + || this.vertex2 === vertexIndex || this.vertex3 === vertexIndex); + } + + public isInnerTetrahedron () { + return this.vertex3 >= 0; + } + + public isOuterCell () { + return this.vertex3 < 0; // -1 or -2 + } +} + +export class Delaunay { + public _probes: Vertex[] = []; + private _tetrahedrons: Tetrahedron[] = []; + + private _triangles: Triangle[] = []; + private _edges: Edge[] = []; + + public constructor (probes: Vertex[]) { + this._probes = probes; + } + + public build () { + this.reset(); + this.tetrahedralize(); + this.computeAdjacency(); + this.computeMatrices(); + + return this._tetrahedrons; + } + + private reset () { + this._tetrahedrons.length = 0; + this._triangles.length = 0; + this._edges.length = 0; + } + + /** + * Bowyer-Watson algorithm + */ + private tetrahedralize () { + // get probe count first + const probeCount = this._probes.length; + + // init a super tetrahedron containing all probes + const center = this.initTetrahedron(); + + for (let i = 0; i < probeCount; i++) { + this.addProbe(i); + } + + // remove all tetrahedrons which contain the super tetrahedron's vertices + this._tetrahedrons = this._tetrahedrons.filter((tetrahedron) => { + const vertexIndex = probeCount; + const isSuperTetrahedron = ( + tetrahedron.contain(vertexIndex) + || tetrahedron.contain(vertexIndex + 1) + || tetrahedron.contain(vertexIndex + 2) + || tetrahedron.contain(vertexIndex + 3)); + + return !isSuperTetrahedron; + }); + + // remove all additional points in the super tetrahedron + this._probes.length = probeCount; + + this.reorder(center); + } + + private initTetrahedron () { + const minPos = new Vec3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + const maxPos = new Vec3(Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE); + + for (let i = 0; i < this._probes.length; i++) { + const position = this._probes[i].position; + minPos.x = Math.min(minPos.x, position.x); + maxPos.x = Math.max(maxPos.x, position.x); + + minPos.y = Math.min(minPos.y, position.y); + maxPos.y = Math.max(maxPos.y, position.y); + + minPos.z = Math.min(minPos.z, position.z); + maxPos.z = Math.max(maxPos.z, position.z); + } + + const center = new Vec3(0.0, 0.0, 0.0); + Vec3.add(center, minPos, maxPos); + Vec3.multiplyScalar(center, center, 0.5); + + const extent = new Vec3(0.0, 0.0, 0.0); + Vec3.subtract(extent, maxPos, minPos); + const offset = Math.max(extent.x, extent.y, extent.z) * 10.0; + + const p0 = new Vec3(center.x, center.y + offset, center.z); + const p1 = new Vec3(center.x - offset, center.y - offset, center.z - offset); + const p2 = new Vec3(center.x - offset, center.y - offset, center.z + offset); + const p3 = new Vec3(center.x + offset, center.y - offset, center.z); + + const index = this._probes.length; + this._probes.push(new Vertex(p0)); + this._probes.push(new Vertex(p1)); + this._probes.push(new Vertex(p2)); + this._probes.push(new Vertex(p3)); + + this._tetrahedrons.push(new Tetrahedron(this, index, index + 1, index + 2, index + 3)); + + return center; + } + + private addTriangle (index: number, tet: number, i: number, v0: number, v1: number, v2: number, v3: number) { + if (index < this._triangles.length) { + this._triangles[index].set(tet, i, v0, v1, v2, v3); + } else { + this._triangles.push(new Triangle(tet, i, v0, v1, v2, v3)); + } + } + + private addEdge (index: number, tet: number, i: number, v0: number, v1: number) { + if (index < this._edges.length) { + this._edges[index].set(tet, i, v0, v1); + } else { + this._edges.push(new Edge(tet, i, v0, v1)); + } + } + + private addProbe (vertexIndex: number) { + const probe = this._probes[vertexIndex]; + const position = probe.position; + + let triangleIndex = 0; + for (let i = 0; i < this._tetrahedrons.length; i++) { + const tetrahedron = this._tetrahedrons[i]; + if (tetrahedron.isInCircumSphere(position)) { + tetrahedron.invalid = true; + + this.addTriangle(triangleIndex, i, 0, tetrahedron.vertex1, tetrahedron.vertex3, tetrahedron.vertex2, tetrahedron.vertex0); + this.addTriangle(triangleIndex + 1, i, 1, tetrahedron.vertex0, tetrahedron.vertex2, tetrahedron.vertex3, tetrahedron.vertex1); + this.addTriangle(triangleIndex + 2, i, 2, tetrahedron.vertex0, tetrahedron.vertex3, tetrahedron.vertex1, tetrahedron.vertex2); + this.addTriangle(triangleIndex + 3, i, 3, tetrahedron.vertex0, tetrahedron.vertex1, tetrahedron.vertex2, tetrahedron.vertex3); + triangleIndex += 4; + } + } + + for (let i = 0; i < triangleIndex; i++) { + if (this._triangles[i].invalid) { + continue; + } + + for (let k = i + 1; k < triangleIndex; k++) { + if (this._triangles[i].isSame(this._triangles[k])) { + this._triangles[i].invalid = true; + this._triangles[k].invalid = true; + break; + } + } + } + + // remove containing tetrahedron + this._tetrahedrons = this._tetrahedrons.filter((tetrahedron) => !tetrahedron.invalid); + + for (let i = 0; i < triangleIndex; i++) { + const triangle = this._triangles[i]; + if (!triangle.invalid) { + this._tetrahedrons.push(new Tetrahedron(this, triangle.vertex0, triangle.vertex1, triangle.vertex2, vertexIndex)); + } + } + } + + private reorder (center: Vec3) { + // The tetrahedron in the middle is placed at the front of the vector + this._tetrahedrons.sort((a, b) => Vec3.squaredDistance(a.sphere.center, center) - Vec3.squaredDistance(b.sphere.center, center)); + } + + private computeAdjacency () { + const normal = new Vec3(0.0, 0.0, 0.0); + const edge1 = new Vec3(0.0, 0.0, 0.0); + const edge2 = new Vec3(0.0, 0.0, 0.0); + const edge3 = new Vec3(0.0, 0.0, 0.0); + + const tetrahedronCount = this._tetrahedrons.length; + + let triangleIndex = 0; + for (let i = 0; i < this._tetrahedrons.length; i++) { + const tetrahedron = this._tetrahedrons[i]; + + this.addTriangle(triangleIndex, i, 0, tetrahedron.vertex1, tetrahedron.vertex3, tetrahedron.vertex2, tetrahedron.vertex0); + this.addTriangle(triangleIndex + 1, i, 1, tetrahedron.vertex0, tetrahedron.vertex2, tetrahedron.vertex3, tetrahedron.vertex1); + this.addTriangle(triangleIndex + 2, i, 2, tetrahedron.vertex0, tetrahedron.vertex3, tetrahedron.vertex1, tetrahedron.vertex2); + this.addTriangle(triangleIndex + 3, i, 3, tetrahedron.vertex0, tetrahedron.vertex1, tetrahedron.vertex2, tetrahedron.vertex3); + triangleIndex += 4; + } + + for (let i = 0; i < triangleIndex; i++) { + if (!this._triangles[i].isOuterFace) { + continue; + } + + for (let k = i + 1; k < triangleIndex; k++) { + if (this._triangles[i].isSame(this._triangles[k])) { + // update adjacency between tetrahedrons + this._tetrahedrons[this._triangles[i].tetrahedron].neighbours[this._triangles[i].index] = this._triangles[k].tetrahedron; + this._tetrahedrons[this._triangles[k].tetrahedron].neighbours[this._triangles[k].index] = this._triangles[i].tetrahedron; + this._triangles[i].isOuterFace = false; + this._triangles[k].isOuterFace = false; + break; + } + } + + if (this._triangles[i].isOuterFace) { + const probe0 = this._probes[this._triangles[i].vertex0]; + const probe1 = this._probes[this._triangles[i].vertex1]; + const probe2 = this._probes[this._triangles[i].vertex2]; + const probe3 = this._probes[this._triangles[i].vertex3]; + + Vec3.subtract(edge1, probe1.position, probe0.position); + Vec3.subtract(edge2, probe2.position, probe0.position); + Vec3.cross(normal, edge1, edge2); + + Vec3.subtract(edge3, probe3.position, probe0.position); + const negative = Vec3.dot(normal, edge3); + if (negative > 0.0) { + Vec3.negate(normal, normal); + } + + // accumulate weighted normal + Vec3.add(probe0.normal, probe0.normal, normal); + Vec3.add(probe1.normal, probe1.normal, normal); + Vec3.add(probe2.normal, probe2.normal, normal); + + // create an outer cell with normal facing out + const v0 = this._triangles[i].vertex0; + const v1 = negative > 0.0 ? this._triangles[i].vertex2 : this._triangles[i].vertex1; + const v2 = negative > 0.0 ? this._triangles[i].vertex1 : this._triangles[i].vertex2; + const tetrahedron = new Tetrahedron(this, v0, v1, v2); + + // update adjacency between tetrahedron and outer cell + tetrahedron.neighbours[3] = this._triangles[i].tetrahedron; + this._tetrahedrons[this._triangles[i].tetrahedron].neighbours[this._triangles[i].index] = this._tetrahedrons.length; + this._tetrahedrons.push(tetrahedron); + } + } + + // start from outer cell index + let edgeIndex = 0; + for (let i = tetrahedronCount; i < this._tetrahedrons.length; i++) { + const tetrahedron = this._tetrahedrons[i]; + + this.addEdge(edgeIndex, i, 0, tetrahedron.vertex1, tetrahedron.vertex2); + this.addEdge(edgeIndex + 1, i, 1, tetrahedron.vertex2, tetrahedron.vertex0); + this.addEdge(edgeIndex + 2, i, 2, tetrahedron.vertex0, tetrahedron.vertex1); + edgeIndex += 3; + } + + for (let i = 0; i < edgeIndex; i++) { + for (let k = i + 1; k < edgeIndex; k++) { + if (this._edges[i].isSame(this._edges[k])) { + // update adjacency between outer cells + this._tetrahedrons[this._edges[i].tetrahedron].neighbours[this._edges[i].index] = this._edges[k].tetrahedron; + this._tetrahedrons[this._edges[k].tetrahedron].neighbours[this._edges[k].index] = this._edges[i].tetrahedron; + } + } + } + + // normalize all convex hull probes' normal + for (let i = 0; i < this._probes.length; i++) { + this._probes[i].normal.normalize(); + } + } + + private computeMatrices () { + for (let i = 0; i < this._tetrahedrons.length; i++) { + const tetrahedron = this._tetrahedrons[i]; + + if (tetrahedron.vertex3 >= 0) { + this.computeTetrahedronMatrix(tetrahedron); + } else { + this.computeOuterCellMatrix(tetrahedron); + } + } + } + + private computeTetrahedronMatrix (tetrahedron: Tetrahedron) { + const p0 = this._probes[tetrahedron.vertex0].position; + const p1 = this._probes[tetrahedron.vertex1].position; + const p2 = this._probes[tetrahedron.vertex2].position; + const p3 = this._probes[tetrahedron.vertex3].position; + + tetrahedron.matrix.set( + p0.x - p3.x, p1.x - p3.x, p2.x - p3.x, + p0.y - p3.y, p1.y - p3.y, p2.y - p3.y, + p0.z - p3.z, p1.z - p3.z, p2.z - p3.z, + ); + tetrahedron.matrix.invert(); + tetrahedron.matrix.transpose(); + } + + private computeOuterCellMatrix (tetrahedron: Tetrahedron) { + const v: Vec3[] = []; + const p: Vec3[] = []; + + v[0] = this._probes[tetrahedron.vertex0].normal; + v[1] = this._probes[tetrahedron.vertex1].normal; + v[2] = this._probes[tetrahedron.vertex2].normal; + + p[0] = this._probes[tetrahedron.vertex0].position; + p[1] = this._probes[tetrahedron.vertex1].position; + p[2] = this._probes[tetrahedron.vertex2].position; + + Vec3.subtract(_a, p[0], p[2]); + Vec3.subtract(_ap, v[0], v[2]); + Vec3.subtract(_b, p[1], p[2]); + Vec3.subtract(_bp, v[1], v[2]); + _p2.set(p[2]); + Vec3.negate(_cp, v[2]); + + const m: number[] = []; + + m[0] = _ap.y * _bp.z - _ap.z * _bp.y; + m[3] = -_ap.x * _bp.z + _ap.z * _bp.x; + m[6] = _ap.x * _bp.y - _ap.y * _bp.x; + m[9] = _a.x * _bp.y * _cp.z + - _a.y * _bp.x * _cp.z + + _ap.x * _b.y * _cp.z + - _ap.y * _b.x * _cp.z + + _a.z * _bp.x * _cp.y + - _a.z * _bp.y * _cp.x + + _ap.z * _b.x * _cp.y + - _ap.z * _b.y * _cp.x + - _a.x * _bp.z * _cp.y + + _a.y * _bp.z * _cp.x + - _ap.x * _b.z * _cp.y + + _ap.y * _b.z * _cp.x; + m[9] -= _p2.x * m[0] + _p2.y * m[3] + _p2.z * m[6]; + + m[1] = _ap.y * _b.z + _a.y * _bp.z - _ap.z * _b.y - _a.z * _bp.y; + m[4] = -_a.x * _bp.z - _ap.x * _b.z + _a.z * _bp.x + _ap.z * _b.x; + m[7] = _a.x * _bp.y - _a.y * _bp.x + _ap.x * _b.y - _ap.y * _b.x; + m[10] = _a.x * _b.y * _cp.z + - _a.y * _b.x * _cp.z + - _a.x * _b.z * _cp.y + + _a.y * _b.z * _cp.x + + _a.z * _b.x * _cp.y + - _a.z * _b.y * _cp.x; + m[10] -= _p2.x * m[1] + _p2.y * m[4] + _p2.z * m[7]; + + m[2] = -_a.z * _b.y + _a.y * _b.z; + m[5] = -_a.x * _b.z + _a.z * _b.x; + m[8] = _a.x * _b.y - _a.y * _b.x; + m[11] = 0.0; + m[11] -= _p2.x * m[2] + _p2.y * m[5] + _p2.z * m[8]; + + // coefficient of t^3 + const c = _ap.x * _bp.y * _cp.z + - _ap.y * _bp.x * _cp.z + + _ap.z * _bp.x * _cp.y + - _ap.z * _bp.y * _cp.x + + _ap.y * _bp.z * _cp.x + - _ap.x * _bp.z * _cp.y; + + if (Math.abs(c) > EPSILON) { + // t^3 + p * t^2 + q * t + r = 0 + for (let k = 0; k < 12; k++) { + m[k] /= c; + } + } else { + // set last vertex index of outer cell to -2 + // p * t^2 + q * t + r = 0 + tetrahedron.vertex3 = -2; + } + + // transpose the matrix + tetrahedron.matrix.set(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); + + // last column of mat3x4 + tetrahedron.offset.set(m[9], m[10], m[11]); + } +} diff --git a/cocos/gi/light-probe/index.ts b/cocos/gi/light-probe/index.ts new file mode 100644 index 00000000000..ba9de19d792 --- /dev/null +++ b/cocos/gi/light-probe/index.ts @@ -0,0 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +export * from './auto-placement'; +export * from './delaunay'; +export * from './sh'; +export * from './light-probe'; +export * from './light-probe-group'; diff --git a/cocos/gi/light-probe/light-probe-group.ts b/cocos/gi/light-probe/light-probe-group.ts new file mode 100644 index 00000000000..adc5adfd6f3 --- /dev/null +++ b/cocos/gi/light-probe/light-probe-group.ts @@ -0,0 +1,230 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { + ccclass, + disallowMultiple, + displayName, + editable, + executeInEditMode, + menu, + range, + serializable, + tooltip, + type, + visible, +} from 'cc.decorator'; +import { EDITOR } from 'internal:constants'; +import { NodeEventType } from '../../scene-graph/node-event'; +import { Component } from '../../scene-graph/component'; +import { Vec3, CCInteger } from '../../core'; +import { AutoPlacement, PlaceMethod } from './auto-placement'; + +/** + * @en The light probe group component. + * @zh 光照探针组组件。 + */ +@ccclass('cc.LightProbeGroup') +@menu('Rendering/LightProbeGroup') +@disallowMultiple +@executeInEditMode +export class LightProbeGroup extends Component { + @serializable + protected _probes: Vec3[] = []; + + @serializable + protected _method = PlaceMethod.UNIFORM; + + @serializable + protected _minPos = new Vec3(-5, -5, -5); + + @serializable + protected _maxPos = new Vec3(5, 5, 5); + + @serializable + protected _nProbesX = 3; + + @serializable + protected _nProbesY = 3; + + @serializable + protected _nProbesZ = 3; + + @editable + @type([Vec3]) + @visible(false) + get probes (): Vec3[] { + return this._probes; + } + set probes (val: Vec3[]) { + this._probes = val; + } + + @editable + @type(PlaceMethod) + @tooltip('i18n:light_probe_group.method') + @displayName('Generating Method') + get method () { + return this._method; + } + // Support this feature later. + // set method (val) { + // this._method = val; + // } + + /** + * @en Minimum position of the light probe group + * @zh 光照探针组包围盒最小值 + */ + @editable + @tooltip('i18n:light_probe_group.minPos') + @displayName('Generating Min Pos') + get minPos (): Vec3 { + return this._minPos; + } + set minPos (val: Vec3) { + this._minPos = val; + } + + /** + * @en Maximum position of the light probe group + * @zh 光照探针组包围盒最大值 + */ + @editable + @tooltip('i18n:light_probe_group.maxPos') + @displayName('Generating Max Pos') + get maxPos (): Vec3 { + return this._maxPos; + } + set maxPos (val: Vec3) { + this._maxPos = val; + } + + @editable + @range([2, 65535, 1]) + @type(CCInteger) + @tooltip('i18n:light_probe_group.nProbesX') + @displayName('Number Of Probes X') + get nProbesX (): number { + return this._nProbesX; + } + set nProbesX (val: number) { + this._nProbesX = val; + } + + @editable + @range([2, 65535, 1]) + @type(CCInteger) + @tooltip('i18n:light_probe_group.nProbesY') + @displayName('Number Of Probes Y') + get nProbesY (): number { + return this._nProbesY; + } + set nProbesY (val: number) { + this._nProbesY = val; + } + + @editable + @range([2, 65535, 1]) + @type(CCInteger) + @tooltip('i18n:light_probe_group.nProbesZ') + @displayName('Number Of Probes Z') + get nProbesZ (): number { + return this._nProbesZ; + } + set nProbesZ (val: number) { + this._nProbesZ = val; + } + + public onLoad () { + if (!EDITOR) { + return; + } + + if (!this.node) { + return; + } + + const changed = this.node.scene.globals.lightProbeInfo.addNode(this.node); + if (changed) { + this.node.scene.globals.lightProbeInfo.syncData(this.node, this.probes); + } + } + + public onEnable () { + if (!EDITOR) { + return; + } + + if (!this.node) { + return; + } + + const changed = this.node.scene.globals.lightProbeInfo.addNode(this.node); + if (changed) { + this.onProbeChanged(); + } + } + + public onDisable () { + if (!EDITOR) { + return; + } + + if (!this.node) { + return; + } + + const changed = this.node.scene.globals.lightProbeInfo.removeNode(this.node); + if (changed) { + this.onProbeChanged(); + } + } + + public generateLightProbes () { + if (!this.node) { + return; + } + + this._probes = AutoPlacement.generate({ + method: this._method, + nProbesX: this._nProbesX, + nProbesY: this._nProbesY, + nProbesZ: this._nProbesZ, + minPos: this._minPos, + maxPos: this._maxPos, + }); + + this.onProbeChanged(); + } + + public onProbeChanged (updateTet = true, emitEvent = true) { + this.node.scene.globals.lightProbeInfo.syncData(this.node, this.probes); + this.node.scene.globals.lightProbeInfo.update(updateTet); + + if (emitEvent) { + this.node.emit(NodeEventType.LIGHT_PROBE_CHANGED); + } + } +} diff --git a/cocos/gi/light-probe/light-probe.jsb.ts b/cocos/gi/light-probe/light-probe.jsb.ts new file mode 100644 index 00000000000..7f784795458 --- /dev/null +++ b/cocos/gi/light-probe/light-probe.jsb.ts @@ -0,0 +1,42 @@ +/* + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { _decorator } from '../../core'; +import { Tetrahedron, Vertex } from './delaunay'; + +const { ccclass, serializable, type } = _decorator; + +export const LightProbes = jsb.LightProbes; +ccclass('cc.LightProbes')(LightProbes); + +export const LightProbesData = jsb.LightProbesData; +const LightProbesDataProto = LightProbesData.prototype; + +// @ts-expect-error +type([Vertex])(LightProbesDataProto, '_probes', () => []); +serializable(LightProbesDataProto, '_probes', () => []); + +// @ts-expect-error +type([Tetrahedron])(LightProbesDataProto, '_tetrahedrons', () => []); +serializable(LightProbesDataProto, '_tetrahedrons', () => []); +ccclass('cc.LightProbesData')(LightProbesData); diff --git a/cocos/gi/light-probe/light-probe.ts b/cocos/gi/light-probe/light-probe.ts new file mode 100644 index 00000000000..9ea470a210e --- /dev/null +++ b/cocos/gi/light-probe/light-probe.ts @@ -0,0 +1,366 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ccclass, serializable, type } from 'cc.decorator'; +import { Vertex, Tetrahedron, Delaunay } from './delaunay'; +import { PolynomialSolver } from './polynomial-solver'; +import { LightProbeInfo } from '../../scene-graph/scene-globals'; +import { Vec3, Vec4, cclegacy, EPSILON } from '../../core'; +import { SH } from './sh'; + +const _v1 = new Vec3(0.0, 0.0, 0.0); +const _v2 = new Vec3(0.0, 0.0, 0.0); +const _normal = new Vec3(0.0, 0.0, 0.0); +const _edgeP0 = new Vec3(0.0, 0.0, 0.0); +const _edgeP1 = new Vec3(0.0, 0.0, 0.0); +const _edgeP2 = new Vec3(0.0, 0.0, 0.0); +const _crossP12 = new Vec3(0.0, 0.0, 0.0); +const _crossP20 = new Vec3(0.0, 0.0, 0.0); + +const _normal2 = new Vec3(0.0, 0.0, 0.0); +const _edge1 = new Vec3(0.0, 0.0, 0.0); +const _edge2 = new Vec3(0.0, 0.0, 0.0); +const _v = new Vec3(0.0, 0.0, 0.0); +const _vp0 = new Vec3(0.0, 0.0, 0.0); +const _vp1 = new Vec3(0.0, 0.0, 0.0); +const _vp2 = new Vec3(0.0, 0.0, 0.0); + +@ccclass('cc.LightProbesData') +export class LightProbesData { + public get probes () { + return this._probes; + } + + public get tetrahedrons () { + return this._tetrahedrons; + } + + public empty () { + return this._probes.length === 0 || this._tetrahedrons.length === 0; + } + + public reset () { + this._probes.length = 0; + this._tetrahedrons.length = 0; + } + + public updateProbes (points: Vec3[]) { + this._probes.length = 0; + + const pointCount = points.length; + for (let i = 0; i < pointCount; i++) { + this._probes.push(new Vertex(points[i])); + } + } + + public updateTetrahedrons () { + const delaunay = new Delaunay(this._probes); + this._tetrahedrons = delaunay.build(); + } + + public getInterpolationSHCoefficients (tetIndex: number, weights: Vec4, coefficients: Vec3[]) { + if (!this.hasCoefficients()) { + return false; + } + + const length = SH.getBasisCount(); + const tetrahedron = this._tetrahedrons[tetIndex]; + const c0 = this._probes[tetrahedron.vertex0].coefficients; + const c1 = this._probes[tetrahedron.vertex1].coefficients; + const c2 = this._probes[tetrahedron.vertex2].coefficients; + + if (tetrahedron.vertex3 >= 0) { + const c3 = this._probes[tetrahedron.vertex3].coefficients; + + for (let i = 0; i < length; i++) { + coefficients[i] = new Vec3(0.0, 0.0, 0.0); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c0[i], weights.x); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c1[i], weights.y); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c2[i], weights.z); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c3[i], weights.w); + } + } else { + for (let i = 0; i < length; i++) { + coefficients[i] = new Vec3(0.0, 0.0, 0.0); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c0[i], weights.x); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c1[i], weights.y); + Vec3.scaleAndAdd(coefficients[i], coefficients[i], c2[i], weights.z); + } + } + + return true; + } + + public getInterpolationWeights (position: Vec3, tetIndex: number, weights: Vec4) { + const tetrahedronCount = this._tetrahedrons.length; + if (tetIndex < 0 || tetIndex >= tetrahedronCount) { + tetIndex = 0; + } + + let lastIndex = -1; + let nextIndex = -1; + + for (let i = 0; i < tetrahedronCount; i++) { + const tetrahedron = this._tetrahedrons[tetIndex]; + this.getBarycentricCoord(position, tetrahedron, weights); + if (weights.x >= 0.0 && weights.y >= 0.0 && weights.z >= 0.0 && weights.w >= 0.0) { + break; + } + + if (weights.x < weights.y && weights.x < weights.z && weights.x < weights.w) { + nextIndex = tetrahedron.neighbours[0]; + } else if (weights.y < weights.z && weights.y < weights.w) { + nextIndex = tetrahedron.neighbours[1]; + } else if (weights.z < weights.w) { + nextIndex = tetrahedron.neighbours[2]; + } else { + nextIndex = tetrahedron.neighbours[3]; + } + + // return directly due to numerical precision error + if (lastIndex === nextIndex) { + break; + } + + lastIndex = tetIndex; + tetIndex = nextIndex; + } + + return tetIndex; + } + + public hasCoefficients () { + return !this.empty() && this._probes[0].coefficients.length !== 0; + } + + private static getTriangleBarycentricCoord (p0: Vec3, p1: Vec3, p2: Vec3, position: Vec3) { + Vec3.subtract(_v1, p1, p0); + Vec3.subtract(_v2, p2, p0); + Vec3.cross(_normal, _v1, _v2); + + if (_normal.lengthSqr() <= EPSILON) { + return new Vec3(0.0, 0.0, 0.0); + } + + const n = _normal.clone(); + n.normalize(); + const area012Inv = 1.0 / n.dot(_normal); + + Vec3.subtract(_edgeP0, p0, position); + Vec3.subtract(_edgeP1, p1, position); + Vec3.subtract(_edgeP2, p2, position); + + Vec3.cross(_crossP12, _edgeP1, _edgeP2); + const areaP12 = n.dot(_crossP12); + const alpha = areaP12 * area012Inv; + + Vec3.cross(_crossP20, _edgeP2, _edgeP0); + const areaP20 = n.dot(_crossP20); + const beta = areaP20 * area012Inv; + + return new Vec3(alpha, beta, 1.0 - alpha - beta); + } + + private getBarycentricCoord (position: Vec3, tetrahedron: Tetrahedron, weights: Vec4) { + if (tetrahedron.vertex3 >= 0) { + this.getTetrahedronBarycentricCoord(position, tetrahedron, weights); + } else { + this.getOuterCellBarycentricCoord(position, tetrahedron, weights); + } + } + + private getTetrahedronBarycentricCoord (position: Vec3, tetrahedron: Tetrahedron, weights: Vec4) { + const result = new Vec3(0.0, 0.0, 0.0); + Vec3.subtract(result, position, this._probes[tetrahedron.vertex3].position); + Vec3.transformMat3(result, result, tetrahedron.matrix); + + weights.set(result.x, result.y, result.z, 1.0 - result.x - result.y - result.z); + } + + private getOuterCellBarycentricCoord (position: Vec3, tetrahedron: Tetrahedron, weights: Vec4) { + const p0 = this._probes[tetrahedron.vertex0].position; + const p1 = this._probes[tetrahedron.vertex1].position; + const p2 = this._probes[tetrahedron.vertex2].position; + + Vec3.subtract(_edge1, p1, p0); + Vec3.subtract(_edge2, p2, p0); + Vec3.cross(_normal2, _edge1, _edge2); + Vec3.subtract(_v, position, p0); + + let t = Vec3.dot(_v, _normal2); + if (t < 0.0) { + // test tetrahedron in next iterator + weights.set(0.0, 0.0, 0.0, -1.0); + return; + } + + const coefficients = new Vec3(0.0, 0.0, 0.0); + Vec3.transformMat3(coefficients, position, tetrahedron.matrix); + Vec3.add(coefficients, coefficients, tetrahedron.offset); + + if (tetrahedron.vertex3 === -1) { + t = PolynomialSolver.getCubicUniqueRoot(coefficients.x, coefficients.y, coefficients.z); + } else { + t = PolynomialSolver.getQuadraticUniqueRoot(coefficients.x, coefficients.y, coefficients.z); + } + + Vec3.scaleAndAdd(_vp0, p0, this._probes[tetrahedron.vertex0].normal, t); + Vec3.scaleAndAdd(_vp1, p1, this._probes[tetrahedron.vertex1].normal, t); + Vec3.scaleAndAdd(_vp2, p2, this._probes[tetrahedron.vertex2].normal, t); + const result = LightProbesData.getTriangleBarycentricCoord(_vp0, _vp1, _vp2, position); + + weights.set(result.x, result.y, result.z, 0.0); + } + + @serializable + @type([Vertex]) + private _probes: Vertex[] = []; + @serializable + @type([Tetrahedron]) + private _tetrahedrons: Tetrahedron[] = []; +} +cclegacy.internal.LightProbesData = LightProbesData; + +/** + * @en light probe data + * @zh 光照探针数据 + */ +export class LightProbes { + /** + * @en GI multiplier + * @zh GI乘数 + */ + set giScale (val: number) { + this._giScale = val; + } + get giScale (): number { + return this._giScale; + } + + /** + * @en GI sample counts + * @zh GI 采样数量 + */ + set giSamples (val: number) { + this._giSamples = val; + } + get giSamples (): number { + return this._giSamples; + } + + /** + * @en light bounces + * @zh 光照反弹次数 + */ + set bounces (val: number) { + this._bounces = val; + } + get bounces (): number { + return this._bounces; + } + + /** + * @en Reduce ringing of light probe + * @zh 减少光照探针的振铃效果 + */ + set reduceRinging (val: number) { + this._reduceRinging = val; + } + get reduceRinging () { + return this._reduceRinging; + } + + /** + * @en Whether to show light probe + * @zh 是否显示光照探针 + */ + set showProbe (val: boolean) { + this._showProbe = val; + } + get showProbe () { + return this._showProbe; + } + + /** + * @en Whether to show light probe's connection + * @zh 是否显示光照探针连线 + */ + set showWireframe (val: boolean) { + this._showWireframe = val; + } + get showWireframe () { + return this._showWireframe; + } + + /** + * @en Whether to show light probe's convex + * @zh 是否显示光照探针凸包 + */ + set showConvex (val: boolean) { + this._showConvex = val; + } + get showConvex () { + return this._showConvex; + } + + /** + * @en light probe's vertex and tetrahedron data + * @zh 光照探针顶点及四面体数据 + */ + set data (val: LightProbesData | null) { + this._data = val; + } + get data (): LightProbesData | null { + return this._data; + } + + protected _giScale = 1.0; + protected _giSamples = 1024; + protected _bounces = 2; + protected _reduceRinging = 0.0; + protected _showProbe = true; + protected _showWireframe = true; + protected _showConvex = false; + protected _data: LightProbesData | null = null; + + public initialize (info: LightProbeInfo) { + this._giScale = info.giScale; + this._giSamples = info.giSamples; + this._bounces = info.bounces; + this._reduceRinging = info.reduceRinging; + this._showProbe = info.showProbe; + this._showWireframe = info.showWireframe; + this._showConvex = info.showConvex; + this._data = info.data; + } + + public empty () { + if (!this._data) { + return true; + } + + return this._data.empty(); + } +} +cclegacy.internal.LightProbes = LightProbes; diff --git a/cocos/gi/light-probe/polynomial-solver.ts b/cocos/gi/light-probe/polynomial-solver.ts new file mode 100644 index 00000000000..0882de614c9 --- /dev/null +++ b/cocos/gi/light-probe/polynomial-solver.ts @@ -0,0 +1,90 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +export class PolynomialSolver { + /** + * solve quadratic equation: b * t^2 + c * t + d = 0 + * return the unique real positive root + */ + public static getQuadraticUniqueRoot (b: number, c: number, d: number) { + // quadratic case + if (b !== 0.0) { + // the discriminant should be 0 + return -c / (2.0 * b); + } + + // linear case + if (c !== 0.0) { + return -d / c; + } + + // never reach here + return 0.0; + } + + /** + * solve cubic equation: t^3 + b * t^2 + c * t + d = 0 + * return the unique real positive root + */ + public static getCubicUniqueRoot (b: number, c: number, d: number) { + const roots: number[] = []; + + // let x = y - b / 3, convert equation to: y^3 + 3 * p * y + 2 * q = 0 + // where p = c / 3 - b^2 / 9, q = d / 2 + b^3 / 27 - b * c / 6 + const offset = -b / 3.0; + const p = c / 3.0 - (b * b) / 9.0; + const q = d / 2.0 + (b * b * b) / 27.0 - (b * c) / 6.0; + const delta = p * p * p + q * q; // discriminant + + if (delta > 0.0) { + // only one real root + const sqrtDelta = Math.sqrt(delta); + roots.push(Math.cbrt(-q + sqrtDelta) + Math.cbrt(-q - sqrtDelta)); + } else if (delta < 0.0) { + // three different real roots + const angle = Math.acos(-q * Math.sqrt(-p) / (p * p)) / 3.0; + roots.push(2.0 * Math.sqrt(-p) * Math.cos(angle)); + roots.push(2.0 * Math.sqrt(-p) * Math.cos(angle + 2.0 * Math.PI / 3.0)); + roots.push(2.0 * Math.sqrt(-p) * Math.cos(angle + 4.0 * Math.PI / 3.0)); + } else if (q === 0.0) { + // three real roots, at least two equal roots + roots.push(0.0); + } else { + // three real roots, at least two equal roots + const root = Math.cbrt(q); + roots.push(root); + roots.push(-2.0 * root); + } + + // return the unique positive root + for (let i = 0; i < roots.length; i++) { + if (roots[i] + offset >= 0.0) { + return roots[i] + offset; + } + } + + // never reach here + return 0.0; + } +} diff --git a/cocos/gi/light-probe/sh.ts b/cocos/gi/light-probe/sh.ts new file mode 100644 index 00000000000..28e90d9d1af --- /dev/null +++ b/cocos/gi/light-probe/sh.ts @@ -0,0 +1,328 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Vec4, Vec3, cclegacy, assertIsTrue } from '../../core'; + +const SH_BASIS_COUNT = 9; + +export class LightProbeSampler { + /** + * generate one sample from sphere uniformly + */ + public static uniformSampleSphere (u1: number, u2: number) { + const z = 1.0 - 2.0 * u1; + const r = Math.sqrt(Math.max(0.0, 1.0 - z * z)); + const phi = 2.0 * Math.PI * u2; + + const x = r * Math.cos(phi); + const y = r * Math.sin(phi); + + return new Vec3(x, y, z); + } + + /** + * generate ucount1 * ucount2 samples from sphere uniformly + */ + public static uniformSampleSphereAll (sampleCount: number) { + assertIsTrue(sampleCount > 0); + + const uCount1 = Math.floor(Math.sqrt(sampleCount)); + const uCount2 = uCount1; + + const samples: Vec3[] = []; + const uDelta1 = 1.0 / uCount1; + const uDelta2 = 1.0 / uCount2; + + for (let i = 0; i < uCount1; i++) { + const u1 = (i + 0.5) * uDelta1; + + for (let j = 0; j < uCount2; j++) { + const u2 = (j + 0.5) * uDelta2; + const sample = this.uniformSampleSphere(u1, u2); + samples.push(sample); + } + } + + return samples; + } + + /** + * probability density function of uniform distribution on spherical surface + */ + public static uniformSpherePdf () { return 1.0 / (4.0 * Math.PI); } +} + +/** + * Spherical Harmonics utility class + */ +export class SH { + private static LMAX = 2; + + private static basisFunctions: { (v: Vec3): number }[] = + [ + (v: Vec3): number => 0.282095, // 0.5 * Math.sqrt(1.0 / Math.PI) + (v: Vec3): number => 0.488603 * v.y, // 0.5 * Math.sqrt(3.0 / Math.PI) * v.y + (v: Vec3): number => 0.488603 * v.z, // 0.5 * Math.sqrt(3.0 / Math.PI) * v.z + (v: Vec3): number => 0.488603 * v.x, // 0.5 * Math.sqrt(3.0 / Math.PI) * v.x + (v: Vec3): number => 1.09255 * v.y * v.x, // 0.5 * Math.sqrt(15.0 / Math.PI) * v.y * v.x + (v: Vec3): number => 1.09255 * v.y * v.z, // 0.5 * Math.sqrt(15.0 / Math.PI) * v.y * v.z + (v: Vec3): number => 0.946175 * (v.z * v.z - 1.0 / 3.0), // 0.75 * Math.sqrt(5.0 / Math.PI) * (v.z * v.z - 1.0 / 3.0) + (v: Vec3): number => 1.09255 * v.z * v.x, // 0.5 * Math.sqrt(15.0 / Math.PI) * v.z * v.x + (v: Vec3): number => 0.546274 * (v.x * v.x - v.y * v.y), // 0.25 * Math.sqrt(15.0 / Math.PI) * (v.x * v.x - v.y * v.y) + ]; + + private static basisOverPI: number[] = + [ + 0.0897936, // 0.282095 / Math.PI + 0.155527, // 0.488603 / Math.PI + 0.155527, // 0.488603 / Math.PI + 0.155527, // 0.488603 / Math.PI + 0.347769, // 1.09255 / Math.PI + 0.347769, // 1.09255 / Math.PI + 0.301177, // 0.946175 / Math.PI + 0.347769, // 1.09255 / Math.PI + 0.173884, // 0.546274 / Math.PI + ]; + + /** + * update ubo data by coefficients + */ + public static updateUBOData (data: Float32Array, offset: number, coefficients: Vec3[]) { + // cc_sh_linear_const_r + data[offset++] = coefficients[3].x * this.basisOverPI[3]; + data[offset++] = coefficients[1].x * this.basisOverPI[1]; + data[offset++] = coefficients[2].x * this.basisOverPI[2]; + data[offset++] = coefficients[0].x * this.basisOverPI[0] - coefficients[6].x * this.basisOverPI[6] / 3.0; + + // cc_sh_linear_const_g + data[offset++] = coefficients[3].y * this.basisOverPI[3]; + data[offset++] = coefficients[1].y * this.basisOverPI[1]; + data[offset++] = coefficients[2].y * this.basisOverPI[2]; + data[offset++] = coefficients[0].y * this.basisOverPI[0] - coefficients[6].y * this.basisOverPI[6] / 3.0; + + // cc_sh_linear_const_b + data[offset++] = coefficients[3].z * this.basisOverPI[3]; + data[offset++] = coefficients[1].z * this.basisOverPI[1]; + data[offset++] = coefficients[2].z * this.basisOverPI[2]; + data[offset++] = coefficients[0].z * this.basisOverPI[0] - coefficients[6].z * this.basisOverPI[6] / 3.0; + + // cc_sh_quadratic_r + data[offset++] = coefficients[4].x * this.basisOverPI[4]; + data[offset++] = coefficients[5].x * this.basisOverPI[5]; + data[offset++] = coefficients[6].x * this.basisOverPI[6]; + data[offset++] = coefficients[7].x * this.basisOverPI[7]; + + // cc_sh_quadratic_g + data[offset++] = coefficients[4].y * this.basisOverPI[4]; + data[offset++] = coefficients[5].y * this.basisOverPI[5]; + data[offset++] = coefficients[6].y * this.basisOverPI[6]; + data[offset++] = coefficients[7].y * this.basisOverPI[7]; + + // cc_sh_quadratic_b + data[offset++] = coefficients[4].z * this.basisOverPI[4]; + data[offset++] = coefficients[5].z * this.basisOverPI[5]; + data[offset++] = coefficients[6].z * this.basisOverPI[6]; + data[offset++] = coefficients[7].z * this.basisOverPI[7]; + + // cc_sh_quadratic_a + data[offset++] = coefficients[8].x * this.basisOverPI[8]; + data[offset++] = coefficients[8].y * this.basisOverPI[8]; + data[offset++] = coefficients[8].z * this.basisOverPI[8]; + data[offset++] = 0.0; + } + + /** + * recreate a function from sh coefficients, which is same as SHEvaluate in shader + */ + public static shaderEvaluate (normal: Vec3, coefficients: Vec3[]) { + const linearConstR = new Vec4( + coefficients[3].x * this.basisOverPI[3], + coefficients[1].x * this.basisOverPI[1], + coefficients[2].x * this.basisOverPI[2], + coefficients[0].x * this.basisOverPI[0] - coefficients[6].x * this.basisOverPI[6] / 3.0, + ); + + const linearConstG = new Vec4( + coefficients[3].y * this.basisOverPI[3], + coefficients[1].y * this.basisOverPI[1], + coefficients[2].y * this.basisOverPI[2], + coefficients[0].y * this.basisOverPI[0] - coefficients[6].y * this.basisOverPI[6] / 3.0, + ); + + const linearConstB = new Vec4( + coefficients[3].z * this.basisOverPI[3], + coefficients[1].z * this.basisOverPI[1], + coefficients[2].z * this.basisOverPI[2], + coefficients[0].z * this.basisOverPI[0] - coefficients[6].z * this.basisOverPI[6] / 3.0, + ); + + const quadraticR = new Vec4( + coefficients[4].x * this.basisOverPI[4], + coefficients[5].x * this.basisOverPI[5], + coefficients[6].x * this.basisOverPI[6], + coefficients[7].x * this.basisOverPI[7], + ); + + const quadraticG = new Vec4( + coefficients[4].y * this.basisOverPI[4], + coefficients[5].y * this.basisOverPI[5], + coefficients[6].y * this.basisOverPI[6], + coefficients[7].y * this.basisOverPI[7], + ); + + const quadraticB = new Vec4( + coefficients[4].z * this.basisOverPI[4], + coefficients[5].z * this.basisOverPI[5], + coefficients[6].z * this.basisOverPI[6], + coefficients[7].z * this.basisOverPI[7], + ); + + const quadraticA = new Vec3( + coefficients[8].x * this.basisOverPI[8], + coefficients[8].y * this.basisOverPI[8], + coefficients[8].z * this.basisOverPI[8], + ); + + const result = new Vec3(0.0, 0.0, 0.0); + const normal4 = new Vec4(normal.x, normal.y, normal.z, 1.0); + + // calculate linear and const terms + result.x = Vec4.dot(linearConstR, normal4); + result.y = Vec4.dot(linearConstG, normal4); + result.z = Vec4.dot(linearConstB, normal4); + + // calculate quadratic terms + const n14 = new Vec4(normal.x * normal.y, normal.y * normal.z, normal.z * normal.z, normal.z * normal.x); + const n5 = normal.x * normal.x - normal.y * normal.y; + + result.x += Vec4.dot(quadraticR, n14); + result.y += Vec4.dot(quadraticG, n14); + result.z += Vec4.dot(quadraticB, n14); + Vec3.scaleAndAdd(result, result, quadraticA, n5); + + return result; + } + + /** + * recreate a function from sh coefficients + */ + public static evaluate (sample: Vec3, coefficients: Vec3[]) { + const result = new Vec3(0.0, 0.0, 0.0); + + const size = coefficients.length; + for (let i = 0; i < size; i++) { + const c = coefficients[i]; + Vec3.scaleAndAdd(result, result, c, this.evaluateBasis(i, sample)); + } + + return result; + } + + /** + * project a function to sh coefficients + */ + public static project (samples: Vec3[], values: Vec3[]) { + assertIsTrue(samples.length > 0 && samples.length === values.length); + + // integral using Monte Carlo method + const basisCount = this.getBasisCount(); + const sampleCount = samples.length; + const scale = 1.0 / (LightProbeSampler.uniformSpherePdf() * sampleCount); + + const coefficients: Vec3[] = []; + + for (let i = 0; i < basisCount; i++) { + const coefficient = new Vec3(0.0, 0.0, 0.0); + + for (let k = 0; k < sampleCount; k++) { + Vec3.scaleAndAdd(coefficient, coefficient, values[k], this.evaluateBasis(i, samples[k])); + } + + Vec3.multiplyScalar(coefficient, coefficient, scale); + coefficients.push(coefficient); + } + + return coefficients; + } + + /** + * calculate irradiance's sh coefficients from radiance's sh coefficients directly + */ + public static convolveCosine (radianceCoefficients: Vec3[]) { + const cosTheta: number[] = [0.8862268925, 1.0233267546, 0.4954159260]; + const irradianceCoefficients: Vec3[] = []; + + for (let l = 0; l <= this.LMAX; l++) { + for (let m = -l; m <= l; m++) { + const i = this.toIndex(l, m); + + const coefficient = new Vec3(0.0, 0.0, 0.0); + Vec3.multiplyScalar(coefficient, radianceCoefficients[i], this.lambda(l) * cosTheta[l]); + irradianceCoefficients.push(coefficient); + } + } + + return irradianceCoefficients; + } + + /** + * return basis function count + */ + public static getBasisCount () { + return SH_BASIS_COUNT; + } + + /** + * evaluate from a basis function + */ + public static evaluateBasis (index: number, sample: Vec3) { + assertIsTrue(index < this.getBasisCount()); + const func = this.basisFunctions[index]; + + return func(sample); + } + + public static reduceRinging (coefficients: Vec3[], lambda: number) { + if (lambda === 0.0) { + return; + } + + for (let l = 0; l <= this.LMAX; ++l) { + const scale = 1.0 / (1.0 + lambda * l * l * (l + 1) * (l + 1)); + for (let m = -l; m <= l; ++m) { + const i = this.toIndex(l, m); + Vec3.multiplyScalar(coefficients[i], coefficients[i], scale); + } + } + } + + private static lambda (l: number) { + return Math.sqrt((4.0 * Math.PI) / (2.0 * l + 1.0)); + } + + private static toIndex (l: number, m: number) { + return l * l + l + m; + } +} +cclegacy.internal.SH = SH; diff --git a/cocos/input/deprecated-3.3.0.ts b/cocos/input/deprecated-3.3.0.ts index 7173e4f69d3..f7f128c4509 100644 --- a/cocos/input/deprecated-3.3.0.ts +++ b/cocos/input/deprecated-3.3.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { deprecateModuleExportedName } from '../core/utils/x-deprecated'; +import { deprecateModuleExportedName } from '../core'; deprecateModuleExportedName({ SystemEventType: { diff --git a/cocos/input/deprecated-3.4.0.ts b/cocos/input/deprecated-3.4.0.ts index 8bd09af4e5f..d0d325a5422 100644 --- a/cocos/input/deprecated-3.4.0.ts +++ b/cocos/input/deprecated-3.4.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { deprecateModuleExportedName } from '../core/utils/x-deprecated'; +import { deprecateModuleExportedName } from '../core'; deprecateModuleExportedName({ SystemEvent: { diff --git a/cocos/input/deprecated.ts b/cocos/input/deprecated.ts index 922682b3141..a3e0dc8b75b 100644 --- a/cocos/input/deprecated.ts +++ b/cocos/input/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './deprecated-3.3.0'; import './deprecated-3.4.0'; -import { markAsWarning, replaceProperty } from '../core/utils/x-deprecated'; -import { Event, EventKeyboard, EventMouse, EventTouch, SystemEventType } from './types'; +import { markAsWarning, replaceProperty, macro } from '../core'; +import { Event, EventMouse, EventTouch, SystemEventType } from './types'; import { SystemEvent } from './system-event'; -import { macro } from '../core/platform/macro'; replaceProperty(SystemEventType, 'Node.EventType', [ { diff --git a/cocos/input/index.ts b/cocos/input/index.ts index 2e155401233..c361ae957e3 100644 --- a/cocos/input/index.ts +++ b/cocos/input/index.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import './deprecated'; export { input, Input } from './input'; diff --git a/cocos/input/input.ts b/cocos/input/input.ts index a18ca9c06bb..151d4070c59 100644 --- a/cocos/input/input.ts +++ b/cocos/input/input.ts @@ -1,16 +1,16 @@ /* Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -25,13 +25,11 @@ */ import { EDITOR, NATIVE } from 'internal:constants'; -import { TouchInputSource, MouseInputSource, KeyboardInputSource, AccelerometerInputSource, GamepadInputDevice, HandleInputDevice, HMDInputDevice } from 'pal/input'; +import { TouchInputSource, MouseInputSource, KeyboardInputSource, AccelerometerInputSource, GamepadInputDevice, HandleInputDevice, HMDInputDevice, HandheldInputDevice } from 'pal/input'; import { touchManager } from '../../pal/input/touch-manager'; -import { sys } from '../core/platform/sys'; -import { EventTarget } from '../core/event/event-target'; -import { Event, EventAcceleration, EventGamepad, EventHandle, EventHMD, EventKeyboard, EventMouse, EventTouch, Touch } from './types'; +import { sys, EventTarget, cclegacy } from '../core'; +import { Event, EventAcceleration, EventGamepad, EventHandle, EventHandheld, EventHMD, EventKeyboard, EventMouse, EventTouch, Touch } from './types'; import { InputEventType } from './types/event-enum'; -import { legacyCC } from '../core/global-exports'; export enum EventDispatcherPriority { GLOBAL = 0, @@ -47,7 +45,7 @@ export interface IEventDispatcher { * @param event * @returns Whether dispatch to next event dispatcher */ - dispatchEvent (event: Event): boolean; + dispatchEvent(event: Event): boolean; } class InputEventDispatcher implements IEventDispatcher { @@ -92,6 +90,7 @@ interface InputEventMap { [Input.EventType.HANDLE_INPUT]: (event: EventHandle) => void, [Input.EventType.HANDLE_POSE_INPUT]: (event: EventHandle) => void, [Input.EventType.HMD_POSE_INPUT]: (event: EventHMD) => void, + [Input.EventType.HANDHELD_POSE_INPUT]: (event: EventHandheld) => void, } /** @@ -135,6 +134,7 @@ export class Input { private _accelerometerInput = new AccelerometerInputSource(); private _handleInput = new HandleInputDevice(); private _hmdInput = new HMDInputDevice(); + private _handheldInput = new HandheldInputDevice(); private _eventTouchList: EventTouch[] = []; private _eventMouseList: EventMouse[] = []; @@ -143,6 +143,7 @@ export class Input { private _eventGamepadList: EventGamepad[] = []; private _eventHandleList: EventHandle[] = []; private _eventHMDList: EventHMD[] = []; + private _eventHandheldList: EventHandheld[] = []; private _needSimulateTouchMoveEvent = false; @@ -223,7 +224,7 @@ export class Input { * @param target - The event listener's target and callee */ public off (eventType: K, callback?: InputEventMap[K], target?: any) { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { return; } this._eventTarget.off(eventType, callback, target); @@ -236,7 +237,7 @@ export class Input { * 是否启用加速度计事件。 */ public setAccelerometerEnabled (isEnable: boolean) { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { return; } if (isEnable) { @@ -254,7 +255,7 @@ export class Input { * 设置加速度计间隔值。 */ public setAccelerometerInterval (intervalInMileSeconds: number): void { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { return; } this._accelerometerInput.setInterval(intervalInMileSeconds); @@ -270,7 +271,7 @@ export class Input { const changedTouches = [touch]; const eventTouch = new EventTouch(changedTouches, false, eventType, (eventType === InputEventType.TOUCH_END ? [] : changedTouches)); eventTouch.windowId = eventMouse.windowId; - + if (eventType === InputEventType.TOUCH_END) { touchManager.releaseTouch(touchID); } @@ -287,8 +288,13 @@ export class Input { const length = this._eventDispatcherList.length; for (let i = 0; i < length; ++i) { const dispatcher = this._eventDispatcherList[i]; - if (!dispatcher.dispatchEvent(event)) { - break; + try { + if (!dispatcher.dispatchEvent(event)) { + break; + } + } catch (e) { + console.error(`Error occurs in an event listener: ${event.type}`); + console.error(e); } } } @@ -351,6 +357,11 @@ export class Input { const eventHMDList = this._eventHMDList; this._hmdInput._on(InputEventType.HMD_POSE_INPUT, (event) => { this._dispatchOrPushEvent(event, eventHMDList); }); } + + if (sys.hasFeature(sys.Feature.EVENT_HANDHELD)) { + const eventHandheldList = this._eventHandheldList; + this._handheldInput._on(InputEventType.HANDHELD_POSE_INPUT, (event) => { this._dispatchOrPushEvent(event, eventHandheldList); }); + } } private _clearEvents () { @@ -386,6 +397,20 @@ export class Input { } private _frameDispatchEvents () { + const eventHMDList = this._eventHMDList; + // TODO: culling event queue + for (let i = 0, length = eventHMDList.length; i < length; ++i) { + const eventHMD = eventHMDList[i]; + this._emitEvent(eventHMD); + } + + const eventHandheldList = this._eventHandheldList; + // TODO: culling event queue + for (let i = 0, length = eventHandheldList.length; i < length; ++i) { + const eventHandheld = eventHandheldList[i]; + this._emitEvent(eventHandheld); + } + const eventMouseList = this._eventMouseList; // TODO: culling event queue for (let i = 0, length = eventMouseList.length; i < length; ++i) { @@ -434,13 +459,6 @@ export class Input { this._emitEvent(eventHandle); } - const eventHMDList = this._eventHMDList; - // TODO: culling event queue - for (let i = 0, length = eventHMDList.length; i < length; ++i) { - const eventHMD = eventHMDList[i]; - this._emitEvent(eventHMD); - } - this._clearEvents(); } } diff --git a/cocos/input/system-event.ts b/cocos/input/system-event.ts index 710d0a43378..bab303b25cb 100644 --- a/cocos/input/system-event.ts +++ b/cocos/input/system-event.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,10 +23,9 @@ THE SOFTWARE. */ -import { EventTarget } from '../core/event'; +import { EventTarget, cclegacy } from '../core'; import { EventAcceleration, EventKeyboard, EventMouse, EventTouch, SystemEventType, Touch } from './types'; -import { input, Input } from './input'; -import { legacyCC } from '../core/global-exports'; +import { input } from './input'; import { InputEventType } from './types/event-enum'; export declare namespace SystemEvent { @@ -147,7 +145,7 @@ export class SystemEvent extends EventTarget { } } -legacyCC.SystemEvent = SystemEvent; +cclegacy.SystemEvent = SystemEvent; /** * @module cc */ @@ -159,4 +157,4 @@ legacyCC.SystemEvent = SystemEvent; * @deprecated since v3.4.0, please use input instead. */ export const systemEvent = new SystemEvent(); -legacyCC.systemEvent = systemEvent; +cclegacy.systemEvent = systemEvent; diff --git a/cocos/input/types/acceleration.ts b/cocos/input/types/acceleration.ts index 073b8255667..0dead54501b 100644 --- a/cocos/input/types/acceleration.ts +++ b/cocos/input/types/acceleration.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /** * @en the device accelerometer reports values for each axis in units of g-force. * @zh 设备重力传感器传递的各个轴的数据。 diff --git a/cocos/input/types/event-enum.ts b/cocos/input/types/event-enum.ts index ca36e5f29d6..c8c2a8d4e82 100644 --- a/cocos/input/types/event-enum.ts +++ b/cocos/input/types/event-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { NodeEventType } from '../../scene-graph/node-event'; /** @@ -401,9 +400,15 @@ export enum InputEventType { * @en The event type for hmd pose input * @zh 头戴显示器姿态输入事件 */ - HMD_POSE_INPUT = 'hmd-pose-input' + HMD_POSE_INPUT = 'hmd-pose-input', + + /** + * @en The event type for handheld pose input + * @zh 手持设备相机姿态输入事件 + */ + HANDHELD_POSE_INPUT = 'handheld-pose-input' } export type SystemEventTypeUnion = SystemEventType | NodeEventType | InputEventType | string; -legacyCC.SystemEventType = SystemEventType; +cclegacy.SystemEventType = SystemEventType; diff --git a/cocos/input/types/event/event-acceleration.ts b/cocos/input/types/event/event-acceleration.ts index 60e4bd7d465..f91c716d655 100644 --- a/cocos/input/types/event/event-acceleration.ts +++ b/cocos/input/types/event/event-acceleration.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/input/types/event/event-gamepad.ts b/cocos/input/types/event/event-gamepad.ts index fb87002d778..b0c03b71a9f 100644 --- a/cocos/input/types/event/event-gamepad.ts +++ b/cocos/input/types/event/event-gamepad.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2022 Chukong Technologies Inc. - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/input/types/event/event-handheld.ts b/cocos/input/types/event/event-handheld.ts new file mode 100644 index 00000000000..131b3cbde34 --- /dev/null +++ b/cocos/input/types/event/event-handheld.ts @@ -0,0 +1,51 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { HandheldInputDevice } from 'pal/input'; +import { Event } from './event'; +import { SystemEventTypeUnion } from '../event-enum'; + +/** + * @en + * The Handheld event. + * + * @zh + * 手持设备事件。 + */ +export class EventHandheld extends Event { + /** + * @en The handheld device which trigger the current handheld event + * @zh 触发当前手持设备事件的手持设备 + */ + public handheldInputDevice: HandheldInputDevice; + + /** + * @param eventType - The type of the event + * @param handheldInputDevice - The handheld device which trigger the current handheld event + */ + constructor (eventType: SystemEventTypeUnion, handheldInputDevice: HandheldInputDevice) { + super(eventType, false); + this.handheldInputDevice = handheldInputDevice; + } +} diff --git a/cocos/input/types/event/event-handle.ts b/cocos/input/types/event/event-handle.ts index 689a6122b10..5074ac90452 100644 --- a/cocos/input/types/event/event-handle.ts +++ b/cocos/input/types/event/event-handle.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/input/types/event/event-hmd.ts b/cocos/input/types/event/event-hmd.ts index b31852e342f..9806dee9a7d 100644 --- a/cocos/input/types/event/event-hmd.ts +++ b/cocos/input/types/event/event-hmd.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/input/types/event/event-keyboard.ts b/cocos/input/types/event/event-keyboard.ts index 8f38f056b06..2cfab5486e8 100644 --- a/cocos/input/types/event/event-keyboard.ts +++ b/cocos/input/types/event/event-keyboard.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/input/types/event/event-mouse.ts b/cocos/input/types/event/event-mouse.ts index 00a2c70bbfe..34d4de39bda 100644 --- a/cocos/input/types/event/event-mouse.ts +++ b/cocos/input/types/event/event-mouse.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,8 +24,7 @@ */ import { Event } from './event'; -import { Vec2 } from '../../../core/math/vec2'; -import { legacyCC } from '../../../core/global-exports'; +import { Vec2, cclegacy } from '../../../core'; import { SystemEventTypeUnion } from '../event-enum'; /** @@ -148,13 +146,14 @@ export class EventMouse extends Event { * @param eventType - The type of the event * @param bubbles - Indicate whether the event bubbles up through the hierarchy or not. */ - constructor (eventType: SystemEventTypeUnion, bubbles?: boolean, prevLoc?: Vec2) { + constructor (eventType: SystemEventTypeUnion, bubbles?: boolean, prevLoc?: Vec2, windowId?: number) { super(eventType, bubbles); this._eventType = eventType; if (prevLoc) { this._prevX = prevLoc.x; this._prevY = prevLoc.y; } + this.windowId = windowId ?? this.windowId; } /** @@ -219,7 +218,7 @@ export class EventMouse extends Event { out = new Vec2(); } - Vec2.set(out, this._x, legacyCC.view._designResolutionSize.height - this._y); + Vec2.set(out, this._x, cclegacy.view._designResolutionSize.height - this._y); return out; } @@ -234,7 +233,7 @@ export class EventMouse extends Event { } Vec2.set(out, this._x, this._y); - legacyCC.view._convertToUISpace(out); + cclegacy.view._convertToUISpace(out); return out; } @@ -263,7 +262,7 @@ export class EventMouse extends Event { } Vec2.set(out, this._prevX, this._prevY); - legacyCC.view._convertToUISpace(out); + cclegacy.view._convertToUISpace(out); return out; } @@ -307,7 +306,7 @@ export class EventMouse extends Event { out = new Vec2(); } - Vec2.set(out, (this._x - this._prevX) / legacyCC.view.getScaleX(), (this._y - this._prevY) / legacyCC.view.getScaleY()); + Vec2.set(out, (this._x - this._prevX) / cclegacy.view.getScaleX(), (this._y - this._prevY) / cclegacy.view.getScaleY()); return out; } @@ -316,7 +315,7 @@ export class EventMouse extends Event { * @zh 获取鼠标距离上一次事件移动在 UI 坐标系下的 X 轴距离。 */ public getUIDeltaX () { - return (this._x - this._prevX) / legacyCC.view.getScaleX(); + return (this._x - this._prevX) / cclegacy.view.getScaleX(); } /** @@ -324,7 +323,7 @@ export class EventMouse extends Event { * @zh 获取鼠标距离上一次事件移动在 UI 坐标系下的 Y 轴距离。 */ public getUIDeltaY () { - return (this._y - this._prevY) / legacyCC.view.getScaleY(); + return (this._y - this._prevY) / cclegacy.view.getScaleY(); } /** @@ -365,8 +364,8 @@ export class EventMouse extends Event { * @zh 获取鼠标当前 X 轴位置。 */ public getUILocationX () { - const viewport = legacyCC.view.getViewportRect(); - return (this._x - viewport.x) / legacyCC.view.getScaleX(); + const viewport = cclegacy.view.getViewportRect(); + return (this._x - viewport.x) / cclegacy.view.getScaleX(); } /** @@ -374,8 +373,8 @@ export class EventMouse extends Event { * @zh 获取鼠标当前 Y 轴位置。 */ public getUILocationY () { - const viewport = legacyCC.view.getViewportRect(); - return (this._y - viewport.y) / legacyCC.view.getScaleY(); + const viewport = cclegacy.view.getViewportRect(); + return (this._y - viewport.y) / cclegacy.view.getScaleY(); } } diff --git a/cocos/input/types/event/event-touch.ts b/cocos/input/types/event/event-touch.ts index 462387fbbc9..9a27ee688f5 100644 --- a/cocos/input/types/event/event-touch.ts +++ b/cocos/input/types/event/event-touch.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,7 +24,7 @@ */ import { Event } from './event'; -import { Vec2 } from '../../../core/math/vec2'; +import { Vec2 } from '../../../core'; import { Touch } from '../touch'; import { SystemEventTypeUnion } from '../event-enum'; diff --git a/cocos/input/types/event/event.ts b/cocos/input/types/event/event.ts index 83612183632..6fc215ebda2 100644 --- a/cocos/input/types/event/event.ts +++ b/cocos/input/types/event/event.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,7 +23,7 @@ THE SOFTWARE. */ -import { legacyCC } from '../../../core/global-exports'; +import { cclegacy } from '../../../core'; import { SystemEventTypeUnion } from '../event-enum'; /** @@ -291,4 +290,4 @@ export class Event { } /* tslint:disable:no-string-literal */ -legacyCC.Event = Event; +cclegacy.Event = Event; diff --git a/cocos/input/types/event/index.ts b/cocos/input/types/event/index.ts index b09e8b1f6c2..cfd5cc0aa2f 100644 --- a/cocos/input/types/event/index.ts +++ b/cocos/input/types/event/index.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export * from './event'; export * from './event-acceleration'; export * from './event-keyboard'; @@ -6,3 +30,4 @@ export * from './event-touch'; export * from './event-gamepad'; export * from './event-handle'; export * from './event-hmd'; +export * from './event-handheld'; diff --git a/cocos/input/types/index.ts b/cocos/input/types/index.ts index dba72c1a0ba..87a171aea31 100644 --- a/cocos/input/types/index.ts +++ b/cocos/input/types/index.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export * from './event/index'; export * from './acceleration'; export { SystemEventType } from './event-enum'; diff --git a/cocos/input/types/key-code.ts b/cocos/input/types/key-code.ts index e7edf595ae2..a68557cf02d 100644 --- a/cocos/input/types/key-code.ts +++ b/cocos/input/types/key-code.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /** * @en Enum type of keyCode for key event * @zh 按键事件的按键码 diff --git a/cocos/input/types/touch.ts b/cocos/input/types/touch.ts index ad9c3b89448..e79daaaf351 100644 --- a/cocos/input/types/touch.ts +++ b/cocos/input/types/touch.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,8 +23,7 @@ THE SOFTWARE. */ -import { Vec2 } from '../../core/math'; -import { legacyCC } from '../../core/global-exports'; +import { Vec2, cclegacy } from '../../core'; const _vec2 = new Vec2(); /** @@ -94,7 +92,7 @@ export class Touch { } out.set(this._point.x, this._point.y); - legacyCC.view._convertToUISpace(out); + cclegacy.view._convertToUISpace(out); return out; } @@ -103,8 +101,8 @@ export class Touch { * @zh 获取当前触点在 UI 坐标系中 X 轴位置。 */ public getUILocationX () { - const viewport = legacyCC.view.getViewportRect(); - return (this._point.x - viewport.x) / legacyCC.view.getScaleX(); + const viewport = cclegacy.view.getViewportRect(); + return (this._point.x - viewport.x) / cclegacy.view.getScaleX(); } /** @@ -112,8 +110,8 @@ export class Touch { * @zh 获取当前触点在 UI 坐标系中 Y 轴位置。 */ public getUILocationY () { - const viewport = legacyCC.view.getViewportRect(); - return (this._point.y - viewport.y) / legacyCC.view.getScaleY(); + const viewport = cclegacy.view.getViewportRect(); + return (this._point.y - viewport.y) / cclegacy.view.getScaleY(); } /** @@ -141,7 +139,7 @@ export class Touch { } out.set(this._prevPoint.x, this._prevPoint.y); - legacyCC.view._convertToUISpace(out); + cclegacy.view._convertToUISpace(out); return out; } @@ -170,7 +168,7 @@ export class Touch { } out.set(this._startPoint.x, this._startPoint.y); - legacyCC.view._convertToUISpace(out); + cclegacy.view._convertToUISpace(out); return out; } @@ -201,7 +199,7 @@ export class Touch { _vec2.set(this._point); _vec2.subtract(this._prevPoint); - out.set(legacyCC.view.getScaleX(), legacyCC.view.getScaleY()); + out.set(cclegacy.view.getScaleX(), cclegacy.view.getScaleY()); Vec2.divide(out, _vec2, out); return out; } @@ -216,7 +214,7 @@ export class Touch { out = new Vec2(); } - out.set(this._point.x, legacyCC.view._designResolutionSize.height - this._point.y); + out.set(this._point.x, cclegacy.view._designResolutionSize.height - this._point.y); return out; } @@ -230,7 +228,7 @@ export class Touch { out = new Vec2(); } - out.set(this._prevPoint.x, legacyCC.view._designResolutionSize.height - this._prevPoint.y); + out.set(this._prevPoint.x, cclegacy.view._designResolutionSize.height - this._prevPoint.y); return out; } @@ -244,7 +242,7 @@ export class Touch { out = new Vec2(); } - out.set(this._startPoint.x, legacyCC.view._designResolutionSize.height - this._startPoint.y); + out.set(this._startPoint.x, cclegacy.view._designResolutionSize.height - this._startPoint.y); return out; } @@ -297,7 +295,7 @@ export class Touch { this._point.x = x || 0; this._point.y = y || 0; } - this._lastModified = legacyCC.game.frameStartTime; + this._lastModified = cclegacy.game.frameStartTime; } /** @@ -321,8 +319,8 @@ export class Touch { } else { this._prevPoint = new Vec2(x || 0, y || 0); } - this._lastModified = legacyCC.game.frameStartTime; + this._lastModified = cclegacy.game.frameStartTime; } } -legacyCC.Touch = Touch; +cclegacy.Touch = Touch; diff --git a/cocos/misc/camera-component.ts b/cocos/misc/camera-component.ts index e5738c82f2a..98071e802fe 100644 --- a/cocos/misc/camera-component.ts +++ b/cocos/misc/camera-component.ts @@ -1,15 +1,15 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -24,43 +24,59 @@ */ import { EDITOR } from 'internal:constants'; -import { ccclass, help, executeInEditMode, menu, tooltip, displayOrder, type, serializable, visible } from 'cc.decorator'; +import { ccclass, help, executeInEditMode, menu, tooltip, displayOrder, type, serializable, visible, range, rangeMin } from 'cc.decorator'; import { RenderTexture } from '../asset/assets/render-texture'; import { UITransform } from '../2d/framework'; import { Component } from '../scene-graph'; -import { Ray } from '../core/geometry'; -import { Color, Rect, toRadian, Vec3 } from '../core/math'; +import { Color, Rect, toRadian, Vec3, cclegacy, geometry, Enum } from '../core'; import { CAMERA_DEFAULT_MASK } from '../rendering/define'; import { scene } from '../render-scene'; import { SKYBOX_FLAG, CameraProjection, CameraFOVAxis, CameraAperture, CameraISO, CameraShutter, CameraType, TrackingType } from '../render-scene/scene/camera'; import { Node } from '../scene-graph/node'; import { Layers } from '../scene-graph/layers'; -import { Enum } from '../core/value-types'; import { TransformBit } from '../scene-graph/node-enum'; -import { legacyCC } from '../core/global-exports'; import { RenderWindow } from '../render-scene/core/render-window'; import { ClearFlagBit } from '../gfx'; const _temp_vec3_1 = new Vec3(); -/** - * @en The projection type. - * @zh 投影类型。 - */ const ProjectionType = Enum(CameraProjection); const FOVAxis = Enum(CameraFOVAxis); const Aperture = Enum(CameraAperture); const Shutter = Enum(CameraShutter); const ISO = Enum(CameraISO); +/** + * @en Clear screen flag enumeration of the camera. + * @zh 相机的清屏标记枚举。 + */ export const ClearFlag = Enum({ + /** + * @en Clear the screen with [[SceneGlobals.skybox]], will clear the depth and stencil buffer at the same time. + * @zh 使用指定天空盒 [[SceneGlobals.skybox]] 清屏,会同时清理深度和蒙版缓冲。 + */ SKYBOX: SKYBOX_FLAG | ClearFlagBit.DEPTH_STENCIL, + /** + * @en Clear the screen with the given [[Camera.clearColor]], will clear the depth and stencil buffer at the same time. + * @zh 使用指定的相机清屏颜色 [[Camera.clearColor]] 来清屏,会同时清理将深度和蒙版缓冲。 + */ SOLID_COLOR: ClearFlagBit.ALL, + /** + * @en Only clear the depth and stencil buffer while keeping the color buffer intact. Often used in UI camera. + * @zh 只清理深度和蒙版缓冲,同时保留颜色缓冲不变。常用于 UI 相机。 + */ DEPTH_ONLY: ClearFlagBit.DEPTH_STENCIL, + /** + * @en Don't clear anything and continue rendering. + * @zh 不清理任何内容就开始渲染,适合多 Camera 叠加渲染。 + */ DONT_CLEAR: ClearFlagBit.NONE, }); +/** + * @internal + */ export declare namespace Camera { export type ProjectionType = EnumAlias; export type FOVAxis = EnumAlias; @@ -173,6 +189,7 @@ export class Camera extends Component { * @zh 相机的渲染优先级,值越小越优先渲染。 */ @displayOrder(0) + @range([0, 65535, 1]) @tooltip('i18n:camera.priority') get priority () { return this._priority; @@ -314,6 +331,7 @@ export class Camera extends Component { @visible(function (this: Camera) { return this._projection === ProjectionType.PERSPECTIVE; }) + @range([1, 180, 1]) @tooltip('i18n:camera.fov') get fov () { return this._fov; @@ -332,6 +350,7 @@ export class Camera extends Component { @visible(function (this: Camera) { return this._projection === ProjectionType.ORTHO; }) + @rangeMin(1) @tooltip('i18n:camera.ortho_height') get orthoHeight () { return this._orthoHeight; @@ -347,6 +366,7 @@ export class Camera extends Component { * @zh 相机的近裁剪距离,应在可接受范围内尽量取最大。 */ @displayOrder(10) + @rangeMin(0) @tooltip('i18n:camera.near') get near () { return this._near; @@ -362,6 +382,7 @@ export class Camera extends Component { * @zh 相机的远裁剪距离,应在可接受范围内尽量取最小。 */ @displayOrder(11) + @rangeMin(0) @tooltip('i18n:camera.far') get far () { return this._far; @@ -457,7 +478,7 @@ export class Camera extends Component { this._updateTargetTexture(); if (!value && this._camera) { - this._camera.changeTargetWindow(EDITOR ? legacyCC.director.root.tempWindow : null); + this._camera.changeTargetWindow(EDITOR ? cclegacy.director.root.tempWindow : null); this._camera.isWindowSize = true; } this.node.emit(Camera.TARGET_TEXTURE_CHANGE, this); @@ -487,11 +508,14 @@ export class Camera extends Component { set inEditorMode (value) { this._inEditorMode = value; if (this._camera) { - this._camera.changeTargetWindow(value ? legacyCC.director.root && legacyCC.director.root.mainWindow - : legacyCC.director.root && legacyCC.director.root.tempWindow); + this._camera.changeTargetWindow(value ? cclegacy.director.root && cclegacy.director.root.mainWindow + : cclegacy.director.root && cclegacy.director.root.tempWindow); } } + /** + * @internal + */ get cameraType () { return this._cameraType; } @@ -506,6 +530,9 @@ export class Camera extends Component { } } + /** + * @internal + */ get trackingType () { return this._trackingType; } @@ -556,8 +583,8 @@ export class Camera extends Component { * @param out The output ray object. * @returns Return the output ray object. */ - public screenPointToRay (x: number, y: number, out?: Ray) { - if (!out) { out = Ray.create(); } + public screenPointToRay (x: number, y: number, out?: geometry.Ray) { + if (!out) { out = geometry.Ray.create(); } if (this._camera) { this._camera.screenPointToRay(out, x, y); } return out; } @@ -610,11 +637,11 @@ export class Camera extends Component { this.worldToScreen(wpos, _temp_vec3_1); const cmp = uiNode.getComponent('cc.UITransform') as UITransform; - const designSize = legacyCC.view.getVisibleSize(); + const designSize = cclegacy.view.getVisibleSize(); const xoffset = _temp_vec3_1.x - this._camera.width * 0.5; const yoffset = _temp_vec3_1.y - this._camera.height * 0.5; - _temp_vec3_1.x = xoffset / legacyCC.view.getScaleX() + designSize.width * 0.5; - _temp_vec3_1.y = yoffset / legacyCC.view.getScaleY() + designSize.height * 0.5; + _temp_vec3_1.x = xoffset / cclegacy.view.getScaleX() + designSize.width * 0.5; + _temp_vec3_1.y = yoffset / cclegacy.view.getScaleY() + designSize.height * 0.5; if (cmp) { cmp.convertToNodeSpaceAR(_temp_vec3_1, out); @@ -628,13 +655,13 @@ export class Camera extends Component { */ public _createCamera () { if (!this._camera) { - this._camera = (legacyCC.director.root).createCamera(); + this._camera = (cclegacy.director.root).createCamera(); this._camera!.initialize({ name: this.node.name, node: this.node, projection: this._projection, - window: this._inEditorMode ? legacyCC.director.root && legacyCC.director.root.mainWindow - : legacyCC.director.root && legacyCC.director.root.tempWindow, + window: this._inEditorMode ? cclegacy.director.root && cclegacy.director.root.mainWindow + : cclegacy.director.root && cclegacy.director.root.tempWindow, priority: this._priority, cameraType: this.cameraType, trackingType: this.trackingType, @@ -703,4 +730,4 @@ export class Camera extends Component { } } -legacyCC.Camera = Camera; +cclegacy.Camera = Camera; diff --git a/cocos/misc/deprecated.ts b/cocos/misc/deprecated.ts index 6d298e20130..9d7f7c3b5cd 100644 --- a/cocos/misc/deprecated.ts +++ b/cocos/misc/deprecated.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,9 +26,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { Camera } from './camera-component'; -import { replaceProperty } from '../core/utils/x-deprecated'; -import { legacyCC } from '../core/global-exports'; -import { js } from '../core/utils/js'; +import { replaceProperty, cclegacy, js } from '../core'; import { ModelRenderer } from './model-renderer'; replaceProperty(Camera, 'Camera', [ @@ -59,7 +56,7 @@ replaceProperty(Camera.prototype, 'Camera.prototype', [ * @deprecated Since v1.2 */ export { Camera as CameraComponent }; -legacyCC.CameraComponent = Camera; +cclegacy.CameraComponent = Camera; js.setClassAlias(Camera, 'cc.CameraComponent'); /** @@ -67,5 +64,5 @@ js.setClassAlias(Camera, 'cc.CameraComponent'); * @deprecated Since v3.6 */ export { ModelRenderer as RenderableComponent }; -legacyCC.RenderableComponent = ModelRenderer; +cclegacy.RenderableComponent = ModelRenderer; js.setClassAlias(ModelRenderer, 'cc.RenderableComponent'); diff --git a/cocos/misc/index.ts b/cocos/misc/index.ts index de07f74a901..566c0cffcb9 100644 --- a/cocos/misc/index.ts +++ b/cocos/misc/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/misc/intersect.ts b/cocos/misc/intersect.ts index 94e5d86e304..c5c72da77c7 100644 --- a/cocos/misc/intersect.ts +++ b/cocos/misc/intersect.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3, Mat4, IVec3Like } from '../core/math'; -import { intersect, Ray, Triangle } from '../core/geometry'; +import { Vec3, Mat4, IVec3Like, geometry } from '../core'; import { PrimitiveMode } from '../gfx'; import { Mesh } from '../3d/assets/mesh'; import { IBArray, RenderingSubMesh } from '../asset/assets/rendering-sub-mesh'; -import { IRaySubMeshOptions, ERaycastMode, IRaySubMeshResult, IRayMeshOptions, IRayModelOptions } from '../core/geometry/spec'; import { scene } from '../render-scene'; // Implement some intersects functions here. As these functions depends on upper modules, so they are not @@ -38,7 +35,7 @@ import { scene } from '../render-scene'; // FIXME(minggo): rayAABB2 is also implemented in core/geometry/intersects.ts, but it is not exported. // And i don't think should export this function, so copy the implementation here. -function rayAABB2 (ray: Ray, min: IVec3Like, max: IVec3Like) { +function rayAABB2 (ray: geometry.Ray, min: IVec3Like, max: IVec3Like) { const o = ray.o; const d = ray.d; const ix = 1 / d.x; const iy = 1 / d.y; const iz = 1 / d.z; const t1 = (min.x - o.x) * ix; @@ -64,12 +61,12 @@ function rayAABB2 (ray: Ray, min: IVec3Like, max: IVec3Like) { * @return @zh 0 或非 0 @en 0 or not 0, 0 indicates there is no intersection */ const raySubMesh = (function () { - const tri = Triangle.create(); - const deOpt: IRaySubMeshOptions = { distance: Infinity, doubleSided: false, mode: ERaycastMode.ANY }; + const tri = geometry.Triangle.create(); + const deOpt: geometry.IRaySubMeshOptions = { distance: Infinity, doubleSided: false, mode: geometry.ERaycastMode.ANY }; let minDis = 0; - const fillResult = (m: ERaycastMode, d: number, i0: number, i1: number, i2: number, r?: IRaySubMeshResult[]) => { - if (m === ERaycastMode.CLOSEST) { + const fillResult = (m: geometry.ERaycastMode, d: number, i0: number, i1: number, i2: number, r?: geometry.IRaySubMeshResult[]) => { + if (m === geometry.ERaycastMode.CLOSEST) { if (minDis > d || minDis === 0) { minDis = d; if (r) { @@ -86,7 +83,7 @@ const raySubMesh = (function () { } }; - const narrowphase = (vb: Float32Array, ib: IBArray, pm: PrimitiveMode, ray: Ray, opt: IRaySubMeshOptions) => { + const narrowphase = (vb: Float32Array, ib: IBArray, pm: PrimitiveMode, ray: geometry.Ray, opt: geometry.IRaySubMeshOptions) => { if (pm === PrimitiveMode.TRIANGLE_LIST) { const cnt = ib.length; for (let j = 0; j < cnt; j += 3) { @@ -96,10 +93,10 @@ const raySubMesh = (function () { Vec3.set(tri.a, vb[i0], vb[i0 + 1], vb[i0 + 2]); Vec3.set(tri.b, vb[i1], vb[i1 + 1], vb[i1 + 2]); Vec3.set(tri.c, vb[i2], vb[i2 + 1], vb[i2 + 2]); - const dist = intersect.rayTriangle(ray, tri, opt.doubleSided); + const dist = geometry.intersect.rayTriangle(ray, tri, opt.doubleSided); if (dist === 0 || dist > opt.distance) continue; fillResult(opt.mode, dist, i0, i1, i2, opt.result); - if (opt.mode === ERaycastMode.ANY) return dist; + if (opt.mode === geometry.ERaycastMode.ANY) return dist; } } else if (pm === PrimitiveMode.TRIANGLE_STRIP) { const cnt = ib.length - 2; @@ -112,10 +109,10 @@ const raySubMesh = (function () { Vec3.set(tri.b, vb[i1], vb[i1 + 1], vb[i1 + 2]); Vec3.set(tri.c, vb[i2], vb[i2 + 1], vb[i2 + 2]); rev = ~rev; - const dist = intersect.rayTriangle(ray, tri, opt.doubleSided); + const dist = geometry.intersect.rayTriangle(ray, tri, opt.doubleSided); if (dist === 0 || dist > opt.distance) continue; fillResult(opt.mode, dist, i0, i1, i2, opt.result); - if (opt.mode === ERaycastMode.ANY) return dist; + if (opt.mode === geometry.ERaycastMode.ANY) return dist; } } else if (pm === PrimitiveMode.TRIANGLE_FAN) { const cnt = ib.length - 1; @@ -126,15 +123,15 @@ const raySubMesh = (function () { const i2 = ib[j + 1] * 3; Vec3.set(tri.b, vb[i1], vb[i1 + 1], vb[i1 + 2]); Vec3.set(tri.c, vb[i2], vb[i2 + 1], vb[i2 + 2]); - const dist = intersect.rayTriangle(ray, tri, opt.doubleSided); + const dist = geometry.intersect.rayTriangle(ray, tri, opt.doubleSided); if (dist === 0 || dist > opt.distance) continue; fillResult(opt.mode, dist, i0, i1, i2, opt.result); - if (opt.mode === ERaycastMode.ANY) return dist; + if (opt.mode === geometry.ERaycastMode.ANY) return dist; } } return minDis; }; - return function (ray: Ray, submesh: RenderingSubMesh, options?: IRaySubMeshOptions) { + return function (ray: geometry.Ray, submesh: RenderingSubMesh, options?: geometry.IRaySubMeshOptions) { minDis = 0; if (submesh.geometricInfo.positions.length === 0) return minDis; const opt = options === undefined ? deOpt : options; @@ -161,8 +158,8 @@ const raySubMesh = (function () { */ const rayMesh = (function () { let minDis = 0; - const deOpt: IRayMeshOptions = { distance: Infinity, doubleSided: false, mode: ERaycastMode.ANY }; - return function (ray: Ray, mesh: Mesh, options?: IRayMeshOptions) { + const deOpt: geometry.IRayMeshOptions = { distance: Infinity, doubleSided: false, mode: geometry.ERaycastMode.ANY }; + return function (ray: geometry.Ray, mesh: Mesh, options?: geometry.IRayMeshOptions) { minDis = 0; const opt = options === undefined ? deOpt : options; const length = mesh.renderingSubMeshes.length; @@ -173,7 +170,7 @@ const rayMesh = (function () { const sm = mesh.renderingSubMeshes[i]; const dis = raySubMesh(ray, sm, opt); if (dis) { - if (opt.mode === ERaycastMode.CLOSEST) { + if (opt.mode === geometry.ERaycastMode.CLOSEST) { if (minDis === 0 || minDis > dis) { minDis = dis; if (opt.subIndices) opt.subIndices[0] = i; @@ -181,13 +178,13 @@ const rayMesh = (function () { } else { minDis = dis; if (opt.subIndices) opt.subIndices.push(i); - if (opt.mode === ERaycastMode.ANY) { + if (opt.mode === geometry.ERaycastMode.ANY) { return dis; } } } } - if (minDis && opt.mode === ERaycastMode.CLOSEST) { + if (minDis && opt.mode === geometry.ERaycastMode.CLOSEST) { if (opt.result) { opt.result[0].distance = minDis; opt.result.length = 1; @@ -210,15 +207,15 @@ const rayMesh = (function () { */ const rayModel = (function () { let minDis = 0; - const deOpt: IRayModelOptions = { distance: Infinity, doubleSided: false, mode: ERaycastMode.ANY }; - const modelRay = new Ray(); + const deOpt: geometry.IRayModelOptions = { distance: Infinity, doubleSided: false, mode: geometry.ERaycastMode.ANY }; + const modelRay = new geometry.Ray(); const m4 = new Mat4(); - return function (r: Ray, model: scene.Model, options?: IRayModelOptions) { + return function (r: geometry.Ray, model: scene.Model, options?: geometry.IRayModelOptions) { minDis = 0; const opt = options === undefined ? deOpt : options; const wb = model.worldBounds; - if (wb && !intersect.rayAABB(r, wb)) return minDis; - Ray.copy(modelRay, r); + if (wb && !geometry.intersect.rayAABB(r, wb)) return minDis; + geometry.Ray.copy(modelRay, r); if (model.node) { Mat4.invert(m4, model.node.getWorldMatrix(m4)); Vec3.transformMat4(modelRay.o, r.o, m4); @@ -229,7 +226,7 @@ const rayModel = (function () { const subMesh = subModels[i].subMesh; const dis = raySubMesh(modelRay, subMesh, opt); if (dis) { - if (opt.mode === ERaycastMode.CLOSEST) { + if (opt.mode === geometry.ERaycastMode.CLOSEST) { if (minDis === 0 || minDis > dis) { minDis = dis; if (opt.subIndices) opt.subIndices[0] = i; @@ -237,13 +234,13 @@ const rayModel = (function () { } else { minDis = dis; if (opt.subIndices) opt.subIndices.push(i); - if (opt.mode === ERaycastMode.ANY) { + if (opt.mode === geometry.ERaycastMode.ANY) { return dis; } } } } - if (minDis && opt.mode === ERaycastMode.CLOSEST) { + if (minDis && opt.mode === geometry.ERaycastMode.CLOSEST) { if (opt.result) { opt.result[0].distance = minDis; opt.result.length = 1; @@ -254,6 +251,6 @@ const rayModel = (function () { }; }()); -intersect.rayModel = rayModel; -intersect.raySubMesh = raySubMesh; -intersect.rayMesh = rayMesh; +geometry.intersect.rayModel = rayModel; +geometry.intersect.raySubMesh = raySubMesh; +geometry.intersect.rayMesh = rayMesh; diff --git a/cocos/misc/missing-script.ts b/cocos/misc/missing-script.ts index bd64dcae8b7..7f83263f208 100644 --- a/cocos/misc/missing-script.ts +++ b/cocos/misc/missing-script.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,10 +24,8 @@ */ import { ccclass, inspector, editorOnly, serializable } from 'cc.decorator'; -import { getClassById } from '../core/utils/js'; import { Component } from '../scene-graph/component'; -import { legacyCC } from '../core/global-exports'; -import { warnID, error } from '../core/platform/debug'; +import { warnID, error, js, cclegacy } from '../core'; /** * @en @@ -54,11 +51,11 @@ export class MissingScript extends Component { * @return {function} constructor */ public static safeFindClass (id: string) { - const cls = getClassById(id); + const cls = js.getClassById(id); if (cls) { return cls; } - legacyCC.deserialize.reportMissingClass(id); + cclegacy.deserialize.reportMissingClass(id); return undefined; } @@ -80,7 +77,7 @@ export class MissingScript extends Component { } } -legacyCC._MissingScript = MissingScript; +cclegacy._MissingScript = MissingScript; // DEBUG: Check MissingScript class for issue 9878 // import { error } from '../platform/debug'; diff --git a/cocos/misc/model-renderer.ts b/cocos/misc/model-renderer.ts index b543b4e558a..4aa82d2c4cf 100644 --- a/cocos/misc/model-renderer.ts +++ b/cocos/misc/model-renderer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable, diff --git a/cocos/misc/prefab-link.ts b/cocos/misc/prefab-link.ts index fd5793fca72..98e2b99f484 100644 --- a/cocos/misc/prefab-link.ts +++ b/cocos/misc/prefab-link.ts @@ -1,6 +1,32 @@ -import { ccclass, serializable, type, visible } from '../core/data/decorators'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { _decorator } from '../core'; import { Component } from '../scene-graph/component'; -import { Prefab } from '../asset/assets/prefab'; +import { Prefab } from '../scene-graph/prefab'; + +const { ccclass, serializable, type, visible } = _decorator; /** * @en diff --git a/cocos/misc/renderer.ts b/cocos/misc/renderer.ts index b9d785d101f..f6135324638 100644 --- a/cocos/misc/renderer.ts +++ b/cocos/misc/renderer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; -import { - ccclass, type, displayOrder, displayName, disallowMultiple, -} from 'cc.decorator'; import { Material } from '../asset/assets/material'; import { Component } from '../scene-graph'; import { IMaterialInstanceInfo, MaterialInstance } from '../render-scene/core/material-instance'; -import { warnID } from '../core/platform/debug'; +import { warnID, _decorator } from '../core'; const _matInsInfo: IMaterialInstanceInfo = { parent: null!, @@ -38,6 +34,8 @@ const _matInsInfo: IMaterialInstanceInfo = { subModelIdx: 0, }; +const { ccclass, serializable, disallowMultiple, type, displayOrder, displayName } = _decorator; + /** * @en Base class for all components which can submit contents for the rendering process. * It manages a series of [[renderer.Model]]s and the visibility, the materials and the material instances of the models. diff --git a/cocos/native-binding/impl.ts b/cocos/native-binding/impl.ts index 290976ec130..8513c0a1f60 100644 --- a/cocos/native-binding/impl.ts +++ b/cocos/native-binding/impl.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,33 +20,33 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -import { sys } from "../core/platform/sys"; +*/ +import { sys } from "../core"; import { NATIVE } from 'internal:constants'; const globalJsb = globalThis.jsb ?? {}; -if( NATIVE ){ +if (NATIVE) { Object.defineProperty(globalJsb, 'reflection', { - get () { + get() { if (globalJsb.__bridge !== undefined) return globalJsb.__bridge; if (globalThis.JavascriptJavaBridge && (sys.os === sys.OS.ANDROID || sys.os === sys.OS.OHOS)) { globalJsb.__bridge = new globalThis.JavascriptJavaBridge(); } else if (globalThis.JavaScriptObjCBridge && (sys.os === sys.OS.IOS || sys.os === sys.OS.OSX)) { globalJsb.__bridge = new globalThis.JavaScriptObjCBridge(); - } else { + } else { globalJsb.__bridge = null; } return globalJsb.__bridge; }, enumerable: true, configurable: true, - set (value) { + set(value) { globalJsb.__bridge = value; }, }); Object.defineProperty(globalJsb, 'bridge', { - get () { + get() { if (globalJsb.__ccbridge !== undefined) return globalJsb.__ccbridge; - if (window.ScriptNativeBridge && sys.os === sys.OS.ANDROID || sys.os === sys.OS.IOS || sys.os === sys.OS.OSX || sys.os === sys.OS.OHOS) { + if (globalThis.ScriptNativeBridge && sys.os === sys.OS.ANDROID || sys.os === sys.OS.IOS || sys.os === sys.OS.OSX || sys.os === sys.OS.OHOS) { globalJsb.__ccbridge = new ScriptNativeBridge(); } else { globalJsb.__ccbridge = null; @@ -56,13 +55,13 @@ if( NATIVE ){ }, enumerable: true, configurable: true, - set (value) { + set(value) { globalJsb.__ccbridge = value; }, }); const JsbBridgeWrapper = { eventMap: new Map(), - addNativeEventListener (eventName, listener) { + addNativeEventListener(eventName, listener) { if (!this.eventMap.get(eventName)) { this.eventMap.set(eventName, []); } @@ -71,13 +70,13 @@ if( NATIVE ){ arr.push(listener); } }, - dispatchEventToNative (eventName, arg) { + dispatchEventToNative(eventName, arg) { globalJsb.bridge.sendToNative(eventName, arg); }, - removeAllListenersForEvent (eventName) { + removeAllListenersForEvent(eventName) { return this.eventMap.delete(eventName); }, - removeNativeEventListener (eventName, listener) { + removeNativeEventListener(eventName, listener) { const arr = this.eventMap.get(eventName); if (!arr) { return false; @@ -90,10 +89,10 @@ if( NATIVE ){ } return true; }, - removeAllListeners () { + removeAllListeners() { this.eventMap.clear(); }, - triggerEvent (eventName, arg) { + triggerEvent(eventName, arg) { const arr = this.eventMap.get(eventName); if (!arr) { console.error(`${eventName} does not exist`); @@ -102,15 +101,15 @@ if( NATIVE ){ arr.map((listener) => listener.call(null, arg)); }, }; - + Object.defineProperty(globalJsb, 'jsbBridgeWrapper', { - get () { + get() { if (globalJsb.__JsbBridgeWrapper !== undefined) return globalJsb.__JsbBridgeWrapper; - - if (window.ScriptNativeBridge && sys.os === sys.OS.ANDROID || sys.os === sys.OS.IOS || sys.os === sys.OS.OSX || sys.os === sys.OS.OHOS) { + + if (globalThis.ScriptNativeBridge && sys.os === sys.OS.ANDROID || sys.os === sys.OS.IOS || sys.os === sys.OS.OSX || sys.os === sys.OS.OHOS) { globalJsb.__JsbBridgeWrapper = JsbBridgeWrapper; globalJsb.bridge.onNative = (methodName, arg1) => { - console.log(`Trigger event: ${methodName} with argeter: ${arg1}`); + // console.log(`Trigger event: ${methodName} with argeter: ${arg1}`); globalJsb.__JsbBridgeWrapper.triggerEvent(methodName, arg1); }; } else { @@ -120,21 +119,21 @@ if( NATIVE ){ }, enumerable: true, configurable: true, - set (value) { + set(value) { globalJsb.__JsbBridgeWrapper = value; }, }); const originSaveImageData = globalJsb.saveImageData; globalJsb.saveImageData = (data: Uint8Array, width: number, height: number, filePath: string) => { - return new Promise((resolve, reject) => { - originSaveImageData(data, width, height, filePath, (isSuccess) => { - if (isSuccess) { - resolve(); - } else { - reject(); - } - }) - }); + return new Promise((resolve, reject) => { + originSaveImageData(data, width, height, filePath, (isSuccess) => { + if (isSuccess) { + resolve(); + } else { + reject(); + } + }) + }); } } @@ -153,4 +152,5 @@ export const native = { EventAssetsManager: globalJsb.EventAssetsManager, Manifest: globalJsb.Manifest, saveImageData: globalJsb.saveImageData, + process: globalJsb.process, }; diff --git a/cocos/native-binding/index.ts b/cocos/native-binding/index.ts index 162f0aa3d82..b790a343709 100644 --- a/cocos/native-binding/index.ts +++ b/cocos/native-binding/index.ts @@ -1,7 +1,30 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /* eslint-disable @typescript-eslint/no-namespace */ -import type { Color } from '../core/math/color'; -import type { Vec2 } from '../core/math/vec2'; +import type { Color, Vec2 } from '../core'; // @ts-expect-error this is a virtual module export * from 'internal:native'; @@ -1367,4 +1390,16 @@ export declare namespace native { }); */ export function saveImageData(data: Uint8Array, width: number, height: number, filePath: string): Promise; + + /** + * @en Current process information + * @zh 当前进程信息 + */ + export namespace process { + /** + * @en Get argument list passed to execution file + * @zh 获取当前传递给执行文件的参数列表 + */ + export const argv: Readonly; + } } diff --git a/cocos/particle-2d/define.ts b/cocos/particle-2d/define.ts index fd2b508e24f..a57244e52ee 100644 --- a/cocos/particle-2d/define.ts +++ b/cocos/particle-2d/define.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Enum } from '../core/value-types'; +import { Enum } from '../core'; /** * @en The Particle emitter lives forever. diff --git a/cocos/particle-2d/index.ts b/cocos/particle-2d/index.ts index 609a833f94e..8237c15d0d4 100644 --- a/cocos/particle-2d/index.ts +++ b/cocos/particle-2d/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ParticleSystem2D } from './particle-system-2d'; import { MotionStreak } from './motion-streak-2d'; diff --git a/cocos/particle-2d/motion-streak-2d-assembler.ts b/cocos/particle-2d/motion-streak-2d-assembler.ts index 024132786e1..1b6593ed717 100644 --- a/cocos/particle-2d/motion-streak-2d-assembler.ts +++ b/cocos/particle-2d/motion-streak-2d-assembler.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2017-2018 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Chukong Aipu reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,12 +21,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { JSB } from 'internal:constants'; import { IAssembler, IAssemblerManager } from '../2d/renderer/base'; import { MotionStreak } from './motion-streak-2d'; -import { Vec2, Color } from '../core/math'; +import { Vec2, Color } from '../core'; import { IBatcher } from '../2d/renderer/i-batcher'; import { RenderData } from '../2d/renderer/render-data'; diff --git a/cocos/particle-2d/motion-streak-2d.ts b/cocos/particle-2d/motion-streak-2d.ts index d89a2fb724c..c9830049793 100644 --- a/cocos/particle-2d/motion-streak-2d.ts +++ b/cocos/particle-2d/motion-streak-2d.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,15 +21,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, executeInEditMode, serializable, playOnFocus, menu, help, editable, type } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; import { UIRenderer } from '../2d/framework'; import { Texture2D } from '../asset/assets/texture-2d'; import { IBatcher } from '../2d/renderer/i-batcher'; -import { Vec2 } from '../core'; -import { legacyCC } from '../core/global-exports'; +import { Vec2, cclegacy } from '../core'; class Point { public point = new Vec2(); @@ -222,7 +220,7 @@ export class MotionStreak extends UIRenderer { } public lateUpdate (dt) { - if (EDITOR && !legacyCC.GAME_VIEW && !this._preview) return; + if (EDITOR && !cclegacy.GAME_VIEW && !this._preview) return; if (this._assembler) this._assembler.update(this, dt); } diff --git a/cocos/particle-2d/particle-asset.ts b/cocos/particle-2d/particle-asset.ts index 208745a0686..9b75d43b85d 100644 --- a/cocos/particle-2d/particle-asset.ts +++ b/cocos/particle-2d/particle-asset.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,10 +23,11 @@ THE SOFTWARE. */ -import { ccclass, serializable, editable } from '../core/data/decorators'; import { Asset } from '../asset/assets/asset'; import { SpriteFrame } from '../2d/assets/sprite-frame'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy, _decorator } from '../core'; + +const { ccclass, serializable, editable } = _decorator; /** * @en Class for 2D particle asset handling. @@ -42,4 +42,4 @@ export class ParticleAsset extends Asset { public spriteFrame: SpriteFrame | null= null; } -legacyCC.ParticleAsset = ParticleAsset; +cclegacy.ParticleAsset = ParticleAsset; diff --git a/cocos/particle-2d/particle-simulator-2d.ts b/cocos/particle-2d/particle-simulator-2d.ts index 5a75f5cde38..73d92f70f0c 100644 --- a/cocos/particle-2d/particle-simulator-2d.ts +++ b/cocos/particle-2d/particle-simulator-2d.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec2, Color } from '../core/math'; -import Pool from '../core/utils/pool'; -import { clampf, degreesToRadians, radiansToDegrees } from '../core/utils/misc'; +import { Vec2, Color, js, misc } from '../core'; import { vfmtPosUvColor, getComponentPerVertex } from '../2d/renderer/vertex-format'; import { PositionType, EmitterMode, START_SIZE_EQUAL_TO_END_SIZE, START_RADIUS_EQUAL_TO_END_RADIUS } from './define'; import { ParticleSystem2D } from './particle-system-2d'; @@ -73,7 +70,7 @@ class Particle { public deltaRadius = 0; } -class ParticlePool extends Pool { +class ParticlePool extends js.Pool { public get (): Particle { return this._get() || new Particle(); } @@ -170,14 +167,14 @@ export class Simulator { const endColor = psys.endColor; const endColorVar = psys.endColorVar; - particle.color.r = sr = clampf(startColor.r + startColorVar.r * (Math.random() - 0.5) * 2, 0, 255); - particle.color.g = sg = clampf(startColor.g + startColorVar.g * (Math.random() - 0.5) * 2, 0, 255); - particle.color.b = sb = clampf(startColor.b + startColorVar.b * (Math.random() - 0.5) * 2, 0, 255); - particle.color.a = sa = clampf(startColor.a + startColorVar.a * (Math.random() - 0.5) * 2, 0, 255); - particle.deltaColor.r = (clampf(endColor.r + endColorVar.r * (Math.random() - 0.5) * 2, 0, 255) - sr) / timeToLive; - particle.deltaColor.g = (clampf(endColor.g + endColorVar.g * (Math.random() - 0.5) * 2, 0, 255) - sg) / timeToLive; - particle.deltaColor.b = (clampf(endColor.b + endColorVar.b * (Math.random() - 0.5) * 2, 0, 255) - sb) / timeToLive; - particle.deltaColor.a = (clampf(endColor.a + endColorVar.a * (Math.random() - 0.5) * 2, 0, 255) - sa) / timeToLive; + particle.color.r = sr = misc.clampf(startColor.r + startColorVar.r * (Math.random() - 0.5) * 2, 0, 255); + particle.color.g = sg = misc.clampf(startColor.g + startColorVar.g * (Math.random() - 0.5) * 2, 0, 255); + particle.color.b = sb = misc.clampf(startColor.b + startColorVar.b * (Math.random() - 0.5) * 2, 0, 255); + particle.color.a = sa = misc.clampf(startColor.a + startColorVar.a * (Math.random() - 0.5) * 2, 0, 255); + particle.deltaColor.r = (misc.clampf(endColor.r + endColorVar.r * (Math.random() - 0.5) * 2, 0, 255) - sr) / timeToLive; + particle.deltaColor.g = (misc.clampf(endColor.g + endColorVar.g * (Math.random() - 0.5) * 2, 0, 255) - sg) / timeToLive; + particle.deltaColor.b = (misc.clampf(endColor.b + endColorVar.b * (Math.random() - 0.5) * 2, 0, 255) - sb) / timeToLive; + particle.deltaColor.a = (misc.clampf(endColor.a + endColorVar.a * (Math.random() - 0.5) * 2, 0, 255) - sa) / timeToLive; // size let startS = psys.startSize + psys.startSizeVar * (Math.random() - 0.5) * 2; @@ -205,7 +202,7 @@ export class Simulator { particle.aspectRatio = psys.aspectRatio || 1; // direction - const a = degreesToRadians(psys.angle + this._worldRotation + psys.angleVar * (Math.random() - 0.5) * 2); + const a = misc.degreesToRadians(psys.angle + this._worldRotation + psys.angleVar * (Math.random() - 0.5) * 2); // Mode Gravity: A if (psys.emitterMode === EmitterMode.GRAVITY) { const s = psys.speed + psys.speedVar * (Math.random() - 0.5) * 2; @@ -219,7 +216,7 @@ export class Simulator { particle.tangentialAccel = psys.tangentialAccel + psys.tangentialAccelVar * (Math.random() - 0.5) * 2; // rotation is dir if (psys.rotationIsDir) { - particle.rotation = -radiansToDegrees(Math.atan2(particle.dir.y, particle.dir.x)); + particle.rotation = -misc.radiansToDegrees(Math.atan2(particle.dir.y, particle.dir.x)); } } else { // Mode Radius: B @@ -229,7 +226,7 @@ export class Simulator { particle.radius = startRadius; particle.deltaRadius = (psys.endRadius === START_RADIUS_EQUAL_TO_END_RADIUS) ? 0 : (endRadius - startRadius) / timeToLive; particle.angle = a; - particle.degreesPerSecond = degreesToRadians(psys.rotatePerS + psys.rotatePerSVar * (Math.random() - 0.5) * 2); + particle.degreesPerSecond = misc.degreesToRadians(psys.rotatePerS + psys.rotatePerSVar * (Math.random() - 0.5) * 2); } } @@ -278,7 +275,7 @@ export class Simulator { const y1 = -halfHeight; const x2 = halfWidth; const y2 = halfHeight; - const rad = -degreesToRadians(particle.rotation); + const rad = -misc.degreesToRadians(particle.rotation); const cr = Math.cos(rad); const sr = Math.sin(rad); // bl diff --git a/cocos/particle-2d/particle-system-2d-assembler.ts b/cocos/particle-2d/particle-system-2d-assembler.ts index fc3f37f9a11..bb8032428d7 100644 --- a/cocos/particle-2d/particle-system-2d-assembler.ts +++ b/cocos/particle-2d/particle-system-2d-assembler.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2017-2018 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Chukong Aipu reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,13 +21,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IAssembler, IAssemblerManager } from '../2d/renderer/base'; import { ParticleSystem2D } from './particle-system-2d'; import { MeshRenderData } from '../2d/renderer/render-data'; import { IBatcher } from '../2d/renderer/i-batcher'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; export const ParticleAssembler: IAssembler = { maxParticleDeltaTime: 0, @@ -47,7 +46,7 @@ export const ParticleAssembler: IAssembler = { export const ParticleSystem2DAssembler: IAssemblerManager = { getAssembler (comp: ParticleSystem2D) { if (!ParticleAssembler.maxParticleDeltaTime) { - ParticleAssembler.maxParticleDeltaTime = legacyCC.game.frameTime / 1000 * 2; + ParticleAssembler.maxParticleDeltaTime = cclegacy.game.frameTime / 1000 * 2; } return ParticleAssembler; }, diff --git a/cocos/particle-2d/particle-system-2d.ts b/cocos/particle-2d/particle-system-2d.ts index ae8be06cdd7..87837d4d4f4 100644 --- a/cocos/particle-2d/particle-system-2d.ts +++ b/cocos/particle-2d/particle-system-2d.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,27 +21,27 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { ccclass, editable, type, displayOrder, menu, - executeInEditMode, serializable, playOnFocus, tooltip, visible, formerlySerializedAs } from 'cc.decorator'; +import { + ccclass, editable, type, displayOrder, menu, + executeInEditMode, serializable, playOnFocus, tooltip, visible, formerlySerializedAs, override, +} from 'cc.decorator'; import { EDITOR } from 'internal:constants'; import { UIRenderer } from '../2d/framework/ui-renderer'; -import { Color, Vec2 } from '../core/math'; -import { warnID, errorID, error } from '../core/platform/debug'; +import { Color, Vec2, warnID, errorID, error, path, cclegacy } from '../core'; import { Simulator } from './particle-simulator-2d'; import { SpriteFrame } from '../2d/assets/sprite-frame'; import { ImageAsset } from '../asset/assets/image-asset'; import { ParticleAsset } from './particle-asset'; import { BlendFactor } from '../gfx'; -import { path } from '../core/utils'; import { PNGReader } from './png-reader'; import { TiffReader } from './tiff-reader'; import codec from '../../external/compression/ZipUtils'; import { IBatcher } from '../2d/renderer/i-batcher'; import { assetManager, builtinResMgr } from '../asset/asset-manager'; import { PositionType, EmitterMode, DURATION_INFINITY, START_RADIUS_EQUAL_TO_END_RADIUS, START_SIZE_EQUAL_TO_END_SIZE } from './define'; -import { legacyCC } from '../core/global-exports'; +import { ccwindow } from '../core/global-exports'; /** * Image formats @@ -187,7 +186,7 @@ export class ParticleSystem2D extends UIRenderer { return this._custom; } public set custom (value) { - if (EDITOR && !legacyCC.GAME_VIEW && !value && !this._file) { + if (EDITOR && !cclegacy.GAME_VIEW && !value && !this._file) { warnID(6000); return; } @@ -340,6 +339,7 @@ export class ParticleSystem2D extends UIRenderer { this._startColorVar.a = val.a; } + @override @visible(() => false) set color (value) { } @@ -741,10 +741,12 @@ export class ParticleSystem2D extends UIRenderer { private declare _focused: boolean; private declare _plistFile; private declare _tiffReader; + private _useFile: boolean; constructor () { super(); this.initProperties(); + this._useFile = false; } public onEnable () { @@ -824,7 +826,7 @@ export class ParticleSystem2D extends UIRenderer { } // auto play - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this.playOnLoad) { this.resetSystem(); } @@ -980,7 +982,7 @@ export class ParticleSystem2D extends UIRenderer { return false; } - const canvasObj = document.createElement('canvas'); + const canvasObj = ccwindow.document.createElement('canvas'); if (imageFormat === ImageFormat.PNG) { const myPngObj = new PNGReader(buffer); myPngObj.render(canvasObj); @@ -1015,6 +1017,7 @@ export class ParticleSystem2D extends UIRenderer { * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _initWithDictionary (dict: any) { + this._useFile = true; this.totalParticles = parseInt(dict.maxParticles || 0); // life span @@ -1143,7 +1146,9 @@ export class ParticleSystem2D extends UIRenderer { this._renderSpriteFrame = this._renderSpriteFrame || this._spriteFrame; if (this._renderSpriteFrame) { if (this._renderSpriteFrame.texture) { - this._simulator.updateUVs(true); + if (this._simulator) { + this._simulator.updateUVs(true); + } this._syncAspect(); this._updateMaterial(); this._stopped = false; @@ -1165,6 +1170,14 @@ export class ParticleSystem2D extends UIRenderer { * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _updateMaterial () { + if (!this._useFile) { + if (this._customMaterial) { + this.setMaterial(this._customMaterial, 0); + const target = this.getRenderMaterial(0)!.passes[0].blendState.targets[0]; + this._dstBlendFactor = target.blendDst; + this._srcBlendFactor = target.blendSrc; + } + } const mat = this.getMaterialInstance(0); if (mat) mat.recompileShaders({ USE_LOCAL: this._positionType !== PositionType.FREE }); if (mat && mat.passes.length > 0) { @@ -1176,7 +1189,7 @@ export class ParticleSystem2D extends UIRenderer { * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _finishedSimulation () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (this._preview && this._focused && !this.active /* && !cc.engine.isPlaying */) { this.resetSystem(); } diff --git a/cocos/particle-2d/png-reader.ts b/cocos/particle-2d/png-reader.ts index 2e25d14e23d..6276ef42298 100644 --- a/cocos/particle-2d/png-reader.ts +++ b/cocos/particle-2d/png-reader.ts @@ -3,16 +3,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -24,9 +24,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { getError } from '../core/platform/debug'; +import { getError } from '../core'; import zlib from '../../external/compression/zlib.min'; /** diff --git a/cocos/particle-2d/tiff-reader.ts b/cocos/particle-2d/tiff-reader.ts index 1becc22e60e..bf4eec4127c 100644 --- a/cocos/particle-2d/tiff-reader.ts +++ b/cocos/particle-2d/tiff-reader.ts @@ -5,20 +5,19 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,9 +26,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { getError, logID } from '../core/platform/debug'; +import { getError, logID } from '../core'; +import { ccwindow } from '../core/global-exports'; interface IFile { type: string, @@ -252,7 +252,7 @@ export class TiffReader { * @returns {*} */ parseTIFF (tiffData, canvas) { - canvas = canvas || document.createElement('canvas'); + canvas = canvas || ccwindow.document.createElement('canvas'); this._tiffData = tiffData; this._canvas = canvas; diff --git a/cocos/particle/animator/color-overtime.ts b/cocos/particle/animator/color-overtime.ts index 1e26c461b0e..b14aa8b8d95 100644 --- a/cocos/particle/animator/color-overtime.ts +++ b/cocos/particle/animator/color-overtime.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,29 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, type, serializable } from 'cc.decorator'; -import { pseudoRandom } from '../../core/math'; +import { pseudoRandom } from '../../core'; import { Particle, PARTICLE_MODULE_NAME, ParticleModuleBase } from '../particle'; import GradientRange from './gradient-range'; import { ModuleRandSeed } from '../enum'; +import { isGradientTwoValues } from '../particle-general-function'; const COLOR_OVERTIME_RAND_OFFSET = ModuleRandSeed.COLOR; +/** + * @en + * This module will modify particle color over life time. You can set the color gradient to see how it changes. + * @zh + * 本模块用于在粒子生命周期内对颜色进行改变,可以修改模块下的颜色渐变条来查看粒子颜色渐变效果。 + */ @ccclass('cc.ColorOvertimeModule') export default class ColorOvertimeModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable or disable this module. * @zh 是否启用。 */ @displayOrder(0) @@ -51,7 +58,8 @@ export default class ColorOvertimeModule extends ParticleModuleBase { } /** - * @zh 颜色随时间变化的参数,各个 key 之间线性差值变化。 + * @en Change color over life time. Evaluate by key interpolation. + * @zh 颜色随时间变化的参数,各个 key 之间线性插值变化。 */ @type(GradientRange) @serializable @@ -59,8 +67,15 @@ export default class ColorOvertimeModule extends ParticleModuleBase { public color = new GradientRange(); public name = PARTICLE_MODULE_NAME.COLOR; + /** + * @en Apply color animation to particle. + * @zh 作用颜色变换到粒子上。 + * @param particle @en Particle to animate. @zh 模块需要更新的粒子。 + * @internal + */ public animate (particle: Particle) { particle.color.set(particle.startColor); - particle.color.multiply(this.color.evaluate(1.0 - particle.remainingLifetime / particle.startLifetime, pseudoRandom(particle.randomSeed + COLOR_OVERTIME_RAND_OFFSET))); + const rand = isGradientTwoValues(this.color) ? pseudoRandom(particle.randomSeed + COLOR_OVERTIME_RAND_OFFSET) : 0; + particle.color.multiply(this.color.evaluate(1.0 - particle.remainingLifetime / particle.startLifetime, rand)); } } diff --git a/cocos/particle/animator/curve-range.ts b/cocos/particle/animator/curve-range.ts index c40b48b5a00..59b4bce7409 100644 --- a/cocos/particle/animator/curve-range.ts +++ b/cocos/particle/animator/curve-range.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; -import { lerp } from '../../core/math'; -import { Enum } from '../../core/value-types'; -import { AnimationCurve, constructLegacyCurveAndConvert } from '../../core/geometry/curve'; -import { RealCurve, CCClass } from '../../core'; +import { EDITOR } from 'internal:constants'; +import { lerp, RealCurve, CCClass, geometry, Enum, approx, EPSILON } from '../../core'; import { PixelFormat, Filter, WrapMode } from '../../asset/assets/asset-enum'; import { Texture2D, ImageAsset } from '../../asset/assets'; @@ -40,6 +37,21 @@ const SerializableTable = [ ['mode', 'constantMin', 'constantMax', 'multiplier'], ] as const; +/** + * @en + * This curve has 4 modes: + * Constant means this curve only have the constant value all the time. + * Tow Constants means this curve value will generated by the interpolation of these 2 constant values. + * Curve means the curve value will generated by one RealCurve. + * A RealCurve has many key frames, so the value will be generated by interpolation of key frames. + * Two Curves has two RealCurve, so the value is generated by the interpolation of these 2 curves. + * @zh + * 曲线控件包含四种模式: + * 常值,表示曲线的值从头到尾都是一个常量。 + * 双常值,表示曲线的值是从两个常量进行插值。 + * 曲线,包含一个 RealCurve 曲线值,从 RealCurve 取得关键帧进行插值得到。 + * 双曲线,包含两个 RealCurve 曲线,首先对每个曲线进行关键帧插值计算,然后再对算出的两个曲线值进行插值得到最终的数值。 + */ export const Mode = Enum({ Constant: 0, Curve: 1, @@ -47,36 +59,75 @@ export const Mode = Enum({ TwoConstants: 3, }); // TODO: can not remove ccclass for now, we need ccclass specified deserialization to handle deserialization of RealCurve + +/** + * @en + * CurveRange is a data structure which contains some constants or curves. + * Calculate the value by its mode and particle system will use it to change particle attribute associated with it. + * Refer [[CurveRange.Mode]] to see the detail of calculation mode. + * @zh + * CurveRange 是一类数据结构,其包含了多个常数值或曲线值,计算时其将根据计算模式计算最终值,粒子系统使用此数据结构对所有的粒子的属性进行修改。 + * 详细的计算模式请参考 [[CurveRange.Mode]] 的解释。 + */ @ccclass('cc.CurveRange') export default class CurveRange { + /** + * @en The curve mode. See [[Mode]]. + * @zh 曲线类型 [[Mode]]。 + */ public static Mode = Mode; /** - * @zh 曲线类型[[Mode]]。 + * @en Spline will create a RealCurve when mode is curve. The mode of curve range, see [[Mode]]. + * A RealCurve will be created for each spline(SplineMin & SplineMax) when mode is TwoCurves. + * @zh 当mode为Curve时,spline创建1个RealCurve,当mode为TwoCurves时,splineMax创建1个RealCurve,splineMin创建一个RealCurve。 */ - public mode = Mode.Constant; - + set mode (mode: number) { + this._mode = mode; + switch (mode) { + case Mode.Constant: + break; + case Mode.TwoConstants: + break; + case Mode.Curve: + if (!this.spline) this.spline = geometry.constructLegacyCurveAndConvert(); + break; + case Mode.TwoCurves: + if (!this.splineMax) this.splineMax = geometry.constructLegacyCurveAndConvert(); + if (!this.splineMin) this.splineMin = geometry.constructLegacyCurveAndConvert(); + break; + default: + break; + } + } + get mode () { + return this._mode; + } /** - * @zh 当mode为Curve时,使用的曲线。 + * @en The spline used when mode is Mode.Curve. + * @zh 当 mode 为Curve时,使用的曲线。 */ - public spline = constructLegacyCurveAndConvert(); + public declare spline: RealCurve; /** - * @zh 当mode为TwoCurves时,使用的曲线下限。 + * @en The min spline when mode is Mode.TwoCurves. + * @zh 当 mode 为TwoCurves时,使用的曲线下限。 */ - public splineMin = constructLegacyCurveAndConvert(); + public declare splineMin: RealCurve; /** - * @zh 当mode为TwoCurves时,使用的曲线上限。 + * @en Max spline when mode is TwoCurves. + * @zh 当 mode 为TwoCurves时,使用的曲线上限。 */ - public splineMax = constructLegacyCurveAndConvert(); + public declare splineMax: RealCurve; /** - * @zh 当mode为Curve时,使用的曲线。 + * @en Gets/Sets the curve when use curve mode. + * @zh 当 mode 为 Curve 时,使用的曲线。 * @deprecated Since V3.3. Use `spline` instead. */ get curve () { - return this._curve ??= new AnimationCurve(this.spline); + return this._curve ??= new geometry.AnimationCurve(this.spline); } set curve (value) { @@ -85,11 +136,12 @@ export default class CurveRange { } /** - * @zh 当mode为TwoCurves时,使用的曲线下限。 + * @en Get/Set min curve when use TwoCurves mode. + * @zh 当 mode 为 TwoCurves 时,使用的曲线下限。 * @deprecated Since V3.3. Use `splineMin` instead. */ get curveMin () { - return this._curveMin ??= new AnimationCurve(this.splineMin); + return this._curveMin ??= new geometry.AnimationCurve(this.splineMin); } set curveMin (value) { @@ -98,11 +150,12 @@ export default class CurveRange { } /** - * @zh 当mode为TwoCurves时,使用的曲线上限。 + * @en Gets/Sets max curve when use TwoCurves mode. + * @zh 当 mode 为 TwoCurves 时,使用的曲线上限。 * @deprecated Since V3.3. Use `splineMax` instead. */ get curveMax () { - return this._curveMax ??= new AnimationCurve(this.splineMax); + return this._curveMax ??= new geometry.AnimationCurve(this.splineMax); } set curveMax (value) { @@ -111,31 +164,56 @@ export default class CurveRange { } /** - * @zh 当mode为Constant时,曲线的值。 + * @en Constant value when use constant mode. + * @zh 当 mode 为 Constant 时,曲线的值。 */ public constant = 0; /** - * @zh 当mode为TwoConstants时,曲线的上限。 + * @en Constant min value when use TwoConstants mode. + * @zh 当 mode 为 TwoConstants 时,曲线的下限。 */ public constantMin = 0; /** - * @zh 当mode为TwoConstants时,曲线的下限。 + * @en Constant max value when use TwoConstants mode. + * @zh 当 mode 为 TwoConstants 时,曲线的上限。 */ public constantMax = 0; /** + * @en Mulitplier used to evaluate spline. * @zh 应用于曲线插值的系数。 */ public multiplier = 1; - constructor () { + /** + * @en Curve mode to use. + * @zh 曲线类型 [[Mode]]。 + */ + private _mode = Mode.Constant; + constructor () { + /* Only create RealCurves in Editor, in order to show the Splines in Editor, + in RunTime the RealCurves will only be created when it is in Curve mode*/ + if (EDITOR) { + this.spline = geometry.constructLegacyCurveAndConvert(); + this.splineMin = geometry.constructLegacyCurveAndConvert(); + this.splineMax = geometry.constructLegacyCurveAndConvert(); + } } + /** + * @en Calculate curve value. + * @zh 计算曲线数值。 + * @param time @en Normalized time to interpolate. @zh 用于插值的归一化时间。 + * @param rndRatio @en Interpolation ratio when mode is TwoCurves or TwoConstants. + * Particle attribute will pass in a random number to get a random result. + * @zh 当模式为双曲线或双常数时,使用的插值比例,通常粒子系统会传入一个随机数以获得一个随机结果。 + * @returns @en Curve value. @zh 曲线的值。 + */ public evaluate (time: number, rndRatio: number) { - switch (this.mode) { + switch (this._mode) { default: case Mode.Constant: return this.constant; @@ -148,8 +226,13 @@ export default class CurveRange { } } + /** + * @en Gets the max value this curve can reach. + * @zh 获得曲线能达到的最大值。 + * @returns @en Max value of this curve @zh 曲线能达到的最大值 + */ public getMax (): number { - switch (this.mode) { + switch (this._mode) { default: case Mode.Constant: return this.constant; @@ -162,17 +245,31 @@ export default class CurveRange { } } + public isZero (): boolean { + switch (this._mode) { + default: + case Mode.Constant: + return approx(this.constant, 0.0, EPSILON); + case Mode.Curve: + return approx(this.multiplier, 0.0, EPSILON); + case Mode.TwoConstants: + return approx(Math.max(Math.abs(this.constantMax), Math.abs(this.constantMin)), 0.0, EPSILON); + case Mode.TwoCurves: + return approx(this.multiplier, 0.0, EPSILON); + } + } + /** * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. */ public _onBeforeSerialize (props) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return SerializableTable[this.mode]; + return SerializableTable[this._mode]; } - private declare _curve: AnimationCurve | undefined; - private declare _curveMin: AnimationCurve | undefined; - private declare _curveMax: AnimationCurve | undefined; + private declare _curve: geometry.AnimationCurve | undefined; + private declare _curveMin: geometry.AnimationCurve | undefined; + private declare _curveMax: geometry.AnimationCurve | undefined; } CCClass.fastDefine('cc.CurveRange', CurveRange, { @@ -181,9 +278,9 @@ CCClass.fastDefine('cc.CurveRange', CurveRange, { constantMin: 0, constant: 0, mode: Mode.Constant, - splineMax: Object.freeze(constructLegacyCurveAndConvert()), - splineMin: Object.freeze(constructLegacyCurveAndConvert()), - spline: Object.freeze(constructLegacyCurveAndConvert()), + splineMax: Object.freeze(geometry.constructLegacyCurveAndConvert()), + splineMin: Object.freeze(geometry.constructLegacyCurveAndConvert()), + spline: Object.freeze(geometry.constructLegacyCurveAndConvert()), }); setClassAttr(CurveRange, 'multiplier', 'visible', true); @@ -259,7 +356,7 @@ function updateTexture (tex: Texture2D | null, data, width, height): Texture2D { return tex; } -export function packCurveRangeZ (tex: Texture2D | null, data: Float32Array | null, samples:number, cr: CurveRange, discrete?: boolean) { +export function packCurveRangeZ (tex: Texture2D | null, data: Float32Array | null, samples: number, cr: CurveRange, discrete?: boolean) { const height = evaluateHeight(cr); const len = samples * height * 4; if (data === null || data.length !== len) { @@ -286,7 +383,7 @@ export function packCurveRangeZ (tex: Texture2D | null, data: Float32Array | nul } return { texture: updateTexture(tex, data, samples, height), texdata: data }; } -export function packCurveRangeN (tex: Texture2D | null, data: Float32Array | null, samples:number, cr: CurveRange, discrete?: boolean) { +export function packCurveRangeN (tex: Texture2D | null, data: Float32Array | null, samples: number, cr: CurveRange, discrete?: boolean) { const height = evaluateHeight(cr); const len = samples * height * 4; if (data === null || data.length !== len) { diff --git a/cocos/particle/animator/force-overtime.ts b/cocos/particle/animator/force-overtime.ts index 2b7d4fe05b0..91d5fd875fa 100644 --- a/cocos/particle/animator/force-overtime.ts +++ b/cocos/particle/animator/force-overtime.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,25 +20,34 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, range, type, serializable } from 'cc.decorator'; -import { pseudoRandom, Quat, Vec3 } from '../../core/math'; +import { pseudoRandom, Quat, Vec3 } from '../../core'; import { Space, ModuleRandSeed } from '../enum'; -import { calculateTransform } from '../particle-general-function'; +import { calculateTransform, isCurveTwoValues } from '../particle-general-function'; import CurveRange from './curve-range'; -import { ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; +import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; const FORCE_OVERTIME_RAND_OFFSET = ModuleRandSeed.FORCE; const _temp_v3 = new Vec3(); +/** + * @en + * This module will apply force to particle over life time. + * Force on every axis is curve so you can modify these curves to see how it animate. + * @zh + * 本模块用于在粒子生命周期内对粒子施加外力。 + * 每个轴上的受力大小都是可以用曲线来进行编辑,修改曲线就能够看到粒子受力变化的效果了。 + */ @ccclass('cc.ForceOvertimeModule') export default class ForceOvertimeModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -55,36 +63,37 @@ export default class ForceOvertimeModule extends ParticleModuleBase { } /** + * @en Force on the X axis. * @zh X 轴方向上的加速度分量。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(2) @tooltip('i18n:forceOvertimeModule.x') public x = new CurveRange(); /** + * @en Force on the Y axis. * @zh Y 轴方向上的加速度分量。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(3) @tooltip('i18n:forceOvertimeModule.y') public y = new CurveRange(); /** + * @en Force on the Z axis. * @zh Z 轴方向上的加速度分量。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(4) @tooltip('i18n:forceOvertimeModule.z') public z = new CurveRange(); /** + * @en Force calculation coordinate. See [[Space]]. * @zh 加速度计算时采用的坐标系 [[Space]]。 */ @type(Space) @@ -107,13 +116,34 @@ export default class ForceOvertimeModule extends ParticleModuleBase { this.needUpdate = true; } + /** + * @en Update force module calculate transform. + * @zh 更新模块,计算坐标变换。 + * @param space @en Force module update space. @zh 模块更新空间。 + * @param worldTransform @en Particle system world transform. @zh 粒子系统的世界变换矩阵。 + * @internal + */ public update (space, worldTransform) { this.needTransform = calculateTransform(space, this.space, worldTransform, this.rotation); } - public animate (p, dt) { + /** + * @en Apply force to particle. + * @zh 作用力到粒子上。 + * @param p @en Particle to animate. @zh 模块需要更新的粒子。 + * @param dt @en Update interval time. @zh 粒子系统更新的间隔时间。 + * @internal + */ + public animate (p: Particle, dt) { const normalizedTime = 1 - p.remainingLifetime / p.startLifetime; - const force = Vec3.set(_temp_v3, this.x.evaluate(normalizedTime, pseudoRandom(p.randomSeed + FORCE_OVERTIME_RAND_OFFSET))!, this.y.evaluate(normalizedTime, pseudoRandom(p.randomSeed + FORCE_OVERTIME_RAND_OFFSET))!, this.z.evaluate(normalizedTime, pseudoRandom(p.randomSeed + FORCE_OVERTIME_RAND_OFFSET))!); + const randX = isCurveTwoValues(this.x) ? pseudoRandom(p.randomSeed + FORCE_OVERTIME_RAND_OFFSET) : 0; + const randY = isCurveTwoValues(this.y) ? pseudoRandom(p.randomSeed + FORCE_OVERTIME_RAND_OFFSET) : 0; + const randZ = isCurveTwoValues(this.z) ? pseudoRandom(p.randomSeed + FORCE_OVERTIME_RAND_OFFSET) : 0; + + const force = Vec3.set(_temp_v3, + this.x.evaluate(normalizedTime, randX)!, + this.y.evaluate(normalizedTime, randY)!, + this.z.evaluate(normalizedTime, randZ)!); if (this.needTransform) { Vec3.transformQuat(force, force, this.rotation); } diff --git a/cocos/particle/animator/gradient-range.ts b/cocos/particle/animator/gradient-range.ts index f42a9074007..c4b3f5c2993 100644 --- a/cocos/particle/animator/gradient-range.ts +++ b/cocos/particle/animator/gradient-range.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, type, serializable, editable } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; -import { Color } from '../../core/math'; -import { Enum } from '../../core/value-types'; +import { Color, Enum, cclegacy } from '../../core'; import Gradient, { AlphaKey, ColorKey } from './gradient'; import { Texture2D } from '../../asset/assets'; import { PixelFormat, Filter, WrapMode } from '../../asset/assets/asset-enum'; -import { legacyCC } from '../../core/global-exports'; const SerializableTable = EDITOR && [ ['_mode', 'color'], @@ -40,6 +37,22 @@ const SerializableTable = EDITOR && [ ['_mode', 'gradient'], ]; +/** + * @en + * Gradinet is a component to calculate color value. It contains 5 modes: + * Color is just the color value all the time. + * Two Colors has 2 color values to interpolate the color value. + * Gradient value is generated by many color keys interpolation. + * Two Gradients has 2 gradients. The value is calculated by interpolation of the 2 gradients value. + * Random Color has one gradient. The value is get from color keys of the gradient randomly. + * @zh + * 渐变曲线是用来计算颜色值的控件,它包含五种模式: + * 单色从头到尾只返回一种颜色值。 + * 双色包含两个颜色值,返回两种颜色之间的插值。 + * 渐变曲线包含许多颜色帧,返回颜色帧之间的插值。 + * 双渐变曲线包含两个渐变曲线,对两个渐变曲线返回的颜色值再进行插值。 + * 随机颜色包含一个颜色曲线,从曲线中随机获取颜色值。 + */ const Mode = Enum({ Color: 0, Gradient: 1, @@ -48,10 +61,20 @@ const Mode = Enum({ RandomColor: 4, }); +/** + * @en + * GradientRange is a data structure which contains some constant colors or gradients. + * Calculate the color by its mode and particle system will use it to change particle attribute associated with it. + * Refer [[GradientRange.Mode]] to see the detail of calculation mode. + * @zh + * GradientRange 是一类数据结构,其包含了多个常数颜色或渐变色,计算时其将根据计算模式计算最终颜色,粒子系统使用此数据结构对所有的粒子的属性进行修改。 + * 详细的计算模式请参考 [[GradientRange.Mode]] 的解释。 + */ @ccclass('cc.GradientRange') export default class GradientRange { /** - * @zh 渐变色类型 [[Mode]]。 + * @en Gets/Sets color gradient mode to use. See [[Mode]]. + * @zh 使用的渐变色类型 参考 [[Mode]]。 */ @type(Mode) get mode () { @@ -59,7 +82,7 @@ export default class GradientRange { } set mode (m) { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (m === Mode.RandomColor) { if (this.gradient.colorKeys.length === 0) { this.gradient.colorKeys.push(new ColorKey()); @@ -72,43 +95,53 @@ export default class GradientRange { this._mode = m; } + /** + * @en The gradient mode. See [[Mode]]. + * @zh 渐变色类型 参考 [[Mode]]。 + */ public static Mode = Mode; /** - * @zh 当mode为Color时的颜色。 + * @en Color value when use color mode. + * @zh 当 mode 为 Color 时的颜色。 */ @serializable @editable public color = Color.WHITE.clone(); /** - * @zh 当mode为TwoColors时的颜色下限。 + * @en Min color value when use TwoColors mode. + * @zh 当 mode 为 TwoColors 时的颜色下限。 */ @serializable @editable public colorMin = Color.WHITE.clone(); /** - * @zh 当mode为TwoColors时的颜色上限。 + * @en Max color value when use TwoColors mode. + * @zh 当 mode 为 TwoColors 时的颜色上限。 */ @serializable @editable public colorMax = Color.WHITE.clone(); /** - * @zh 当mode为Gradient时的颜色渐变。 + * @en Gradient value when use gradient mode. + * @zh 当 mode 为 Gradient 时的颜色渐变。 */ @type(Gradient) public gradient = new Gradient(); /** + * @en Gradient min value when use TwoGradients. * @zh 当mode为TwoGradients时的颜色渐变下限。 */ @type(Gradient) public gradientMin = new Gradient(); /** - * @zh 当mode为TwoGradients时的颜色渐变上限。 + * @en Gradient max value when use TwoGradients. + * @zh 当 mode 为 TwoGradients 时的颜色渐变上限。 */ @type(Gradient) public gradientMax = new Gradient(); @@ -118,6 +151,15 @@ export default class GradientRange { private _color = Color.WHITE.clone(); + /** + * @en Calculate gradient value. + * @zh 计算颜色渐变曲线数值。 + * @param time @en Normalized time to interpolate. @zh 用于插值的归一化时间。 + * @param rndRatio @en Interpolation ratio when mode is TwoColors or TwoGradients. + * Particle attribute will pass in a random number to get a random result. + * @zh 当模式为双色或双渐变色时,使用的插值比例,通常粒子系统会传入一个随机数以获得一个随机结果。 + * @returns @en Gradient value. @zh 颜色渐变曲线的值。 + */ public evaluate (time: number, rndRatio: number) { switch (this._mode) { case Mode.Color: diff --git a/cocos/particle/animator/gradient.ts b/cocos/particle/animator/gradient.ts index 7fa987bc721..acb5d1468d6 100644 --- a/cocos/particle/animator/gradient.ts +++ b/cocos/particle/animator/gradient.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { ccclass, serializable, editable } from 'cc.decorator'; -import { CCClass } from '../../core/data/class'; -import { Color, lerp, repeat } from '../../core/math'; -import { Enum } from '../../core/value-types'; +import { CCClass, Color, lerp, repeat, Enum } from '../../core'; const Mode = Enum({ Blend: 0, @@ -76,7 +72,21 @@ CCClass.fastDefine('cc.AlphaKey', AlphaKey, { CCClass.Attr.setClassAttr(AlphaKey, 'alpha', 'visible', true); CCClass.Attr.setClassAttr(AlphaKey, 'time', 'visible', true); +/** + * @en Gradient is a component that has a lot of color keys and alpha keys to get the interpolated color value. + * @zh 渐变曲线控件包含了颜色关键帧和透明度关键帧,在关键帧中进行插值渐变返回最终的颜色值。 + */ export default class Gradient { + /** + * @en + * There are 2 kind of mode: + * Blend just interpolate the nearest 2 colors from keys. + * Fixed get the nearest color from keys without interpolate. + * @zh + * 这个控件包含了两种取色模式: + * 混合模式对取到的最近两个颜色帧进行插值计算。 + * 固定模式直接取最近的颜色帧返回,不进行插值。 + */ public static Mode = Mode; /** * @en Array of color key. @@ -100,11 +110,21 @@ export default class Gradient { this._color = Color.WHITE.clone(); } + /** + * @en Set color keys array and alpha keys array. + * @zh 设置颜色和透明度的关键帧列表。 + * @param colorKeys @en Array of color keys @zh 颜色关键帧列表 + * @param alphaKeys @en Array of alpha keys @zh 透明度关键帧列表 + */ public setKeys (colorKeys: ColorKey[], alphaKeys: AlphaKey[]) { this.colorKeys = colorKeys; this.alphaKeys = alphaKeys; } + /** + * @en Sort color keys and alpha keys. + * @zh 对颜色和透明度的关键帧进行排序。 + */ public sortKeys () { if (this.colorKeys.length > 1) { this.colorKeys.sort((a, b) => a.time - b.time); @@ -114,12 +134,23 @@ export default class Gradient { } } + /** + * @en Interpolate color and alpha from color and alpha keys. + * @zh 根据颜色列表插值计算颜色和透明度。 + * @param time @en Normalized time to interpolate. @zh 用于插值的归一化时间。 + * @returns @en Interpolated color value. @zh 插值过后的颜色值。 + */ public evaluate (time: number) { this.getRGB(time); this._color._set_a_unsafe(this.getAlpha(time)!); return this._color; } + /** + * @en Generates a random color and alpha. + * @zh 随机生成颜色和透明度。 + * @returns @en Randomized color. @zh 随机生成的颜色。 + */ public randomColor () { const c = this.colorKeys[Math.trunc(Math.random() * this.colorKeys.length)]; const a = this.alphaKeys[Math.trunc(Math.random() * this.alphaKeys.length)]; diff --git a/cocos/particle/animator/limit-velocity-overtime.ts b/cocos/particle/animator/limit-velocity-overtime.ts index 9e4f572a7d3..f7d7f6f0129 100644 --- a/cocos/particle/animator/limit-velocity-overtime.ts +++ b/cocos/particle/animator/limit-velocity-overtime.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,25 +20,36 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, range, type, serializable, visible } from 'cc.decorator'; -import { lerp, pseudoRandom, Vec3, Mat4, Quat } from '../../core/math'; +import { lerp, pseudoRandom, Vec3, Mat4, Quat } from '../../core'; import { Space, ModuleRandSeed } from '../enum'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; import CurveRange from './curve-range'; -import { calculateTransform } from '../particle-general-function'; +import { calculateTransform, isCurveTwoValues } from '../particle-general-function'; const LIMIT_VELOCITY_RAND_OFFSET = ModuleRandSeed.LIMIT; const _temp_v3 = new Vec3(); const _temp_v3_1 = new Vec3(); +/** + * @en + * This module will damping particle velocity to the limit value over life time. + * Open the separateAxes option you can damping the particle velocity on XYZ axis + * Limit value on every axis is curve so you can modify these curves to see how it animate. + * @zh + * 本模块用于在粒子生命周期内对速度进行衰减,速度每次衰减比例为 dampen 持续衰减到极限速度。 + * 打开 separateAxes 就能够修改粒子在三个轴方向的极限速度大小。 + * 每个轴上的粒子极限速度大小都是可以用曲线来进行编辑,修改曲线就能够看到粒子大小变化的效果了。 + */ @ccclass('cc.LimitVelocityOvertimeModule') export default class LimitVelocityOvertimeModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -55,11 +65,11 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { } /** + * @en Limit velocity on X axis. * @zh X 轴方向上的速度下限。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(4) @tooltip('i18n:limitVelocityOvertimeModule.limitX') @visible(function (this: LimitVelocityOvertimeModule): boolean { @@ -68,11 +78,11 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { public limitX = new CurveRange(); /** + * @en Limit velocity on Y axis. * @zh Y 轴方向上的速度下限。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(5) @tooltip('i18n:limitVelocityOvertimeModule.limitY') @visible(function (this: LimitVelocityOvertimeModule): boolean { @@ -81,11 +91,11 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { public limitY = new CurveRange(); /** + * @en Limit velocity on Z axis. * @zh Z 轴方向上的速度下限。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(6) @tooltip('i18n:limitVelocityOvertimeModule.limitZ') @visible(function (this: LimitVelocityOvertimeModule): boolean { @@ -94,11 +104,11 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { public limitZ = new CurveRange(); /** + * @en Velocity limit. * @zh 速度下限。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(3) @tooltip('i18n:limitVelocityOvertimeModule.limit') @visible(function (this: LimitVelocityOvertimeModule): boolean { @@ -107,7 +117,8 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { public limit = new CurveRange(); /** - * @zh 当前速度与速度下限的插值。 + * @en Dampen velocity percent every time. + * @zh 速度每次衰减的比例。 */ @serializable @displayOrder(7) @@ -115,6 +126,7 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { public dampen = 3; /** + * @en Limit velocity on separate axis. * @zh 是否三个轴分开限制。 */ @serializable @@ -123,6 +135,7 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { public separateAxes = false; /** + * @en Space used to calculate limit velocity. * @zh 计算速度下限时采用的坐标系 [[Space]]。 */ @type(Space) @@ -146,17 +159,35 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { this.needUpdate = true; } + /** + * @en Update limit velocity module calculate transform. + * @zh 更新模块,计算坐标变换。 + * @param space @en Limit velocity module update space @zh 模块更新空间 + * @param worldTransform @en Particle system world transform @zh 粒子系统的世界变换矩阵 + * @internal + */ public update (space: number, worldTransform: Mat4) { this.needTransform = calculateTransform(space, this.space, worldTransform, this.rotation); } + /** + * @en Apply limit velocity to particle. + * @zh 作用速度衰减到粒子上。 + * @param p @en Particle to animate @zh 模块需要更新的粒子 + * @param dt @en Update interval time @zh 粒子系统更新的间隔时间 + * @internal + */ public animate (p: Particle, dt: number) { const normalizedTime = 1 - p.remainingLifetime / p.startLifetime; const dampedVel = _temp_v3; if (this.separateAxes) { - Vec3.set(_temp_v3_1, this.limitX.evaluate(normalizedTime, pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET))!, - this.limitY.evaluate(normalizedTime, pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET))!, - this.limitZ.evaluate(normalizedTime, pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET))!); + const randX = isCurveTwoValues(this.limitX) ? pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET) : 0; + const randY = isCurveTwoValues(this.limitY) ? pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET) : 0; + const randZ = isCurveTwoValues(this.limitZ) ? pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET) : 0; + Vec3.set(_temp_v3_1, + this.limitX.evaluate(normalizedTime, randX)!, + this.limitY.evaluate(normalizedTime, randY)!, + this.limitZ.evaluate(normalizedTime, randZ)!); if (this.needTransform) { Vec3.transformQuat(_temp_v3_1, _temp_v3_1, this.rotation); } @@ -166,9 +197,12 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { dampenBeyondLimit(p.ultimateVelocity.z, _temp_v3_1.z, this.dampen)); } else { Vec3.normalize(dampedVel, p.ultimateVelocity); - Vec3.multiplyScalar(dampedVel, dampedVel, dampenBeyondLimit(p.ultimateVelocity.length(), this.limit.evaluate(normalizedTime, pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET))!, this.dampen)); + const rand = isCurveTwoValues(this.limit) ? pseudoRandom(p.randomSeed + LIMIT_VELOCITY_RAND_OFFSET) : 0; + Vec3.multiplyScalar(dampedVel, dampedVel, + dampenBeyondLimit(p.ultimateVelocity.length(), this.limit.evaluate(normalizedTime, rand)!, this.dampen)); } Vec3.copy(p.ultimateVelocity, dampedVel); + Vec3.copy(p.velocity, p.ultimateVelocity); } } @@ -176,7 +210,12 @@ function dampenBeyondLimit (vel: number, limit: number, dampen: number) { const sgn = Math.sign(vel); let abs = Math.abs(vel); if (abs > limit) { - abs = lerp(abs, limit, dampen); + const absToGive = abs - abs * dampen; + if (absToGive > limit) { + abs = absToGive; + } else { + abs = limit; + } } return abs * sgn; } diff --git a/cocos/particle/animator/noise-module.ts b/cocos/particle/animator/noise-module.ts index 9132a9573b5..cfce15415a2 100644 --- a/cocos/particle/animator/noise-module.ts +++ b/cocos/particle/animator/noise-module.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,20 +20,26 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { ccclass, displayOrder, type, serializable } from 'cc.decorator'; -import { CCFloat, CCInteger } from '../../core'; -import { range, rangeStep, slide, visible } from '../../core/data/decorators/editable'; -import { Vec3 } from '../../core/math'; +import { CCFloat, CCInteger, _decorator, Vec3 } from '../../core'; import { ParticleNoise } from '../noise'; import { Particle, PARTICLE_MODULE_NAME, ParticleModuleBase } from '../particle'; +const { ccclass, serializable, displayOrder, type, range, slide, visible } = _decorator; + +/** + * @en + * Adding noise to your particles is a simple and effective way to create interesting patterns and effects. + * @zh + * 为粒子添加噪声是创建有趣方案和效果的简单有效方法。 + */ @ccclass('cc.NoiseModule') export class NoiseModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -49,6 +54,10 @@ export class NoiseModule extends ParticleModuleBase { this.target.enableModule(this.name, val, this); } + /** + * @en Strength on X axis. + * @zh X 轴上的强度大小。 + */ @type(CCFloat) @range([0, 100]) @displayOrder(16) @@ -62,6 +71,10 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _strengthX = 10; + /** + * @en Strength on Y axis. + * @zh Y 轴上的强度大小。 + */ @type(CCFloat) @range([0, 100]) @displayOrder(16) @@ -75,6 +88,10 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _strengthY = 10; + /** + * @en Strength on Z axis. + * @zh Z 轴上的强度大小。 + */ @type(CCFloat) @range([0, 100]) @displayOrder(16) @@ -88,6 +105,10 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _strengthZ = 10; + /** + * @en Noise texture roll speed on X axis. + * @zh X 轴上的噪声图滚动速度。 + */ @type(CCFloat) @range([0, 100]) @slide @@ -101,6 +122,10 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _noiseSpeedX = 0; + /** + * @en Noise texture roll speed on Y axis. + * @zh Y 轴上的噪声图滚动速度。 + */ @type(CCFloat) @range([0, 100]) @displayOrder(16) @@ -114,6 +139,10 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _noiseSpeedY = 0; + /** + * @en Noise texture roll speed on Z axis. + * @zh Z 轴上的噪声图滚动速度。 + */ @type(CCFloat) @range([0, 100]) @displayOrder(16) @@ -127,9 +156,12 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _noiseSpeedZ = 0; + /** + * @en Noise frequency. + * @zh 噪声图频率。 + */ @type(CCFloat) - @range([0, 100]) - @rangeStep(0.1) + @range([0, 100, 0.1]) @displayOrder(16) @slide get noiseFrequency () { @@ -141,10 +173,13 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _noiseFrequency = 1; + /** + * @en Remap the final noise X axis values into a different range. + * @zh 噪声值映射到 X 轴的不同范围。 + */ @visible(false) @type(CCFloat) - @range([0, 1]) - @rangeStep(0.1) + @range([0, 1, 0.1]) @displayOrder(16) @slide get remapX () { @@ -156,10 +191,13 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _remapX = 0; + /** + * @en Remap the final noise Y axis values into a different range. + * @zh 噪声值映射到 Y 轴的不同范围。 + */ @visible(false) @type(CCFloat) - @range([0, 1]) - @rangeStep(0.1) + @range([0, 1, 0.1]) @displayOrder(16) @slide get remapY () { @@ -171,10 +209,13 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _remapY = 0; + /** + * @en Remap the final noise Z axis values into a different range. + * @zh 噪声值映射到 Z 轴的不同范围。 + */ @visible(false) @type(CCFloat) - @range([0, 1]) - @rangeStep(0.1) + @range([0, 1, 0.1]) @displayOrder(16) @slide get remapZ () { @@ -186,9 +227,12 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _remapZ = 0; + /** + * @en Specify how many layers of overlapping noise are combined to produce the final noise values. + * @zh 指定组合多少层重叠噪声来产生最终噪声值。 + */ @type(CCInteger) - @range([1, 4]) - @rangeStep(1) + @range([1, 4, 1]) @displayOrder(16) @slide get octaves () { @@ -200,11 +244,14 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _octaves = 1; + /** + * @en For each additional noise layer, reduce the strength by this proportion. + * @zh 对于每个附加的噪声层,按此比例降低强度。 + */ // eslint-disable-next-line func-names @visible(function (this: NoiseModule) { return this._octaves > 1; }) @type(CCFloat) - @range([0, 1]) - @rangeStep(0.1) + @range([0, 1, 0.1]) @displayOrder(16) get octaveMultiplier () { return this._octaveMultiplier; @@ -215,11 +262,14 @@ export class NoiseModule extends ParticleModuleBase { @serializable private _octaveMultiplier = 0.5; + /** + * @en For each additional noise layer, adjust the frequency by this multiplier. + * @zh 对于每个附加的噪声层,按此乘数调整频率。 + */ // eslint-disable-next-line func-names @visible(function (this: NoiseModule) { return this._octaves > 1; }) @type(CCFloat) - @range([1, 4]) - @rangeStep(0.1) + @range([1, 4, 0.1]) @displayOrder(16) get octaveScale () { return this._octaveScale; @@ -236,6 +286,13 @@ export class NoiseModule extends ParticleModuleBase { private samplePosition: Vec3 = new Vec3(); + /** + * @en Apply noise effect to particle. + * @zh 作用噪声效果到粒子上。 + * @param particle @en Particle to animate @zh 模块需要更新的粒子 + * @param dt @en Update interval time @zh 粒子系统更新的间隔时间 + * @internal + */ public animate (particle: Particle, dt: number) { this.noise.setTime(particle.particleSystem.time); this.noise.setSpeed(this.noiseSpeedX, this.noiseSpeedY, this.noiseSpeedZ); @@ -254,6 +311,14 @@ export class NoiseModule extends ParticleModuleBase { Vec3.add(particle.position, particle.position, noisePosition.multiplyScalar(dt)); } + /** + * @en Gets the preview of noise texture. + * @zh 获取噪声图预览。 + * @param out @en Noise texture pixels array @zh 噪声图像素数组 + * @param ps @en Particle system @zh 噪声图作用的粒子系统 + * @param width @en Texture width @zh 噪声图宽度 + * @param height @en Texture height @zh 噪声图高度 + */ public getNoisePreview (out: number[], ps, width: number, height: number) { this.noise.setTime(ps.time); this.noise.setSpeed(this.noiseSpeedX, this.noiseSpeedY, this.noiseSpeedZ); diff --git a/cocos/particle/animator/optimized-curve.ts b/cocos/particle/animator/optimized-curve.ts index 88f996350ce..19aa08a696f 100644 --- a/cocos/particle/animator/optimized-curve.ts +++ b/cocos/particle/animator/optimized-curve.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { repeat } from '../../core/math'; -import { AnimationCurve, evalOptCurve, OptimizedKey } from '../../core/geometry/curve'; +import { repeat, geometry } from '../../core'; const CURVE_MODE_CONSTANT = 0; const CURVE_MODE_RANDOM_CONSTANT = 1; @@ -52,7 +50,7 @@ function integrateKeyframeTwice (coef: Float32Array | number[]) { } export class OptimizedCurve { - private optimizedKeys: OptimizedKey[]; + private optimizedKeys: geometry.OptimizedKey[]; private integral: number[]; private constructUniform: boolean; public coefUniform: Float32Array | null; @@ -60,7 +58,7 @@ export class OptimizedCurve { public integralUniform: Float32Array | null; constructor (constructUniform = false) { - this.optimizedKeys = new Array(); // the i-th optimezed key stores coefficients of [i,i+1] segment in the original curve,so if the time of last key of the original key is 1,the last key won't be kept in the opt curve. + this.optimizedKeys = new Array(); // the i-th optimezed key stores coefficients of [i,i+1] segment in the original curve,so if the time of last key of the original key is 1,the last key won't be kept in the opt curve. this.integral = new Array(); // the integral of the curve between 0 and corresponding key,the i-th integral corresponds to the i+1-th key in optimizedKeys (because the integral of the first key is always zero,the first key won't be stored) this.constructUniform = constructUniform; this.coefUniform = null; @@ -68,13 +66,13 @@ export class OptimizedCurve { this.integralUniform = null; } - public buildCurve (animationCurve: AnimationCurve, multiplier: number = 1) { + public buildCurve (animationCurve: geometry.AnimationCurve, multiplier: number = 1) { const keyNum = animationCurve.keyFrames!.length - 1; let i = 0; if (this.optimizedKeys.length < keyNum) { const keyToAdd = keyNum - this.optimizedKeys.length; for (i = 0; i < keyToAdd; i++) { - const optKey = new OptimizedKey(); + const optKey = new geometry.OptimizedKey(); this.optimizedKeys.push(optKey); } } else { @@ -87,7 +85,7 @@ export class OptimizedCurve { } else { let keyOffset = 0; if (animationCurve.keyFrames![0].time !== 0) { - this.optimizedKeys.unshift(new OptimizedKey()); + this.optimizedKeys.unshift(new geometry.OptimizedKey()); this.optimizedKeys[0].time = 0; this.optimizedKeys[0].endTime = animationCurve.keyFrames![0].time; this.optimizedKeys[0].coefficient[3] = animationCurve.keyFrames![0].value; @@ -98,7 +96,7 @@ export class OptimizedCurve { this.optimizedKeys[i + keyOffset].index += keyOffset; } if (animationCurve.keyFrames![animationCurve.keyFrames!.length - 1].time !== 1) { - this.optimizedKeys.push(new OptimizedKey()); + this.optimizedKeys.push(new geometry.OptimizedKey()); this.optimizedKeys[this.optimizedKeys.length - 1].time = animationCurve.keyFrames![animationCurve.keyFrames!.length - 1].time; this.optimizedKeys[this.optimizedKeys.length - 1].endTime = 1; this.optimizedKeys[this.optimizedKeys.length - 1].coefficient[3] = animationCurve.keyFrames![animationCurve.keyFrames!.length - 1].value; @@ -141,7 +139,7 @@ export class OptimizedCurve { integrateKeyframe(this.optimizedKeys[i].coefficient); const deltaT = this.optimizedKeys[i + 1].time - this.optimizedKeys[i].time; const prevIntegral = i === 0 ? 0 : this.integral[i - 1]; - this.integral[i] = prevIntegral + (deltaT * evalOptCurve(deltaT, this.optimizedKeys[i].coefficient)); + this.integral[i] = prevIntegral + (deltaT * geometry.evalOptCurve(deltaT, this.optimizedKeys[i].coefficient)); } integrateKeyframe(this.optimizedKeys[this.optimizedKeys.length - 1].coefficient); if (this.constructUniform) { @@ -157,11 +155,11 @@ export class OptimizedCurve { if (t < this.optimizedKeys[i].time) { const prevInt = i === 1 ? 0 : this.integral[i - 2]; const dt = t - this.optimizedKeys[i - 1].time; - return ts * (prevInt + (dt * evalOptCurve(dt, this.optimizedKeys[i - 1].coefficient))); + return ts * (prevInt + (dt * geometry.evalOptCurve(dt, this.optimizedKeys[i - 1].coefficient))); } } const dt = t - this.optimizedKeys[this.optimizedKeys.length - 1].time; - return ts * (this.integral[this.integral.length - 1] + (dt * evalOptCurve(dt, this.optimizedKeys[this.optimizedKeys.length - 1].coefficient))); + return ts * (this.integral[this.integral.length - 1] + (dt * geometry.evalOptCurve(dt, this.optimizedKeys[this.optimizedKeys.length - 1].coefficient))); } // calculate second order integral coefficients of all keys @@ -178,7 +176,7 @@ export class OptimizedCurve { integrateKeyframeTwice(this.optimizedKeys[i].coefficient); const deltaT = this.optimizedKeys[i + 1].time - this.optimizedKeys[i].time; const prevIntegral = i === 0 ? 0 : this.integral[i - 1]; - this.integral[i] = prevIntegral + (deltaT * deltaT * evalOptCurve(deltaT, this.optimizedKeys[i].coefficient)); + this.integral[i] = prevIntegral + (deltaT * deltaT * geometry.evalOptCurve(deltaT, this.optimizedKeys[i].coefficient)); } integrateKeyframeTwice(this.optimizedKeys[this.optimizedKeys.length - 1].coefficient); if (this.constructUniform) { @@ -194,11 +192,11 @@ export class OptimizedCurve { if (t < this.optimizedKeys[i].time) { const prevInt = i === 1 ? 0 : this.integral[i - 2]; const dt = t - this.optimizedKeys[i - 1].time; - return ts * ts * (prevInt + (dt * dt * evalOptCurve(dt, this.optimizedKeys[i - 1].coefficient))); + return ts * ts * (prevInt + (dt * dt * geometry.evalOptCurve(dt, this.optimizedKeys[i - 1].coefficient))); } } const dt = t - this.optimizedKeys[this.optimizedKeys.length - 1].time; - return ts * ts * (this.integral[this.integral.length - 1] + (dt * dt * evalOptCurve(dt, this.optimizedKeys[this.optimizedKeys.length - 1].coefficient))); + return ts * ts * (this.integral[this.integral.length - 1] + (dt * dt * geometry.evalOptCurve(dt, this.optimizedKeys[this.optimizedKeys.length - 1].coefficient))); } public updateKeyUniform () { diff --git a/cocos/particle/animator/rotation-overtime.ts b/cocos/particle/animator/rotation-overtime.ts index 413135fa7b9..474b388d1d2 100644 --- a/cocos/particle/animator/rotation-overtime.ts +++ b/cocos/particle/animator/rotation-overtime.ts @@ -1,19 +1,18 @@ /* eslint-disable max-len */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,21 +21,33 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, range, type, radian, serializable, visible } from 'cc.decorator'; -import { Mat4, pseudoRandom, Quat, Vec4, Vec3 } from '../../core/math'; +import { Mat4, pseudoRandom, Quat, Vec3 } from '../../core'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; import CurveRange from './curve-range'; import { ModuleRandSeed, RenderMode } from '../enum'; +import { isCurveTwoValues } from '../particle-general-function'; const ROTATION_OVERTIME_RAND_OFFSET = ModuleRandSeed.ROTATION; +/** + * @en + * This module will apply rotation to particle over life time. + * Open the separateAxes option you can change the rotation on XYZ axis + * Rotation on every axis is curve so you can modify these curves to see how it animate. + * @zh + * 本模块用于在粒子生命周期内对粒子施加旋转角速度。 + * 打开 separateAxes 就能够修改粒子在三个轴方向的旋转角速度大小。 + * 每个轴上的旋转角速度都是可以用曲线来进行编辑,修改曲线就能够看到粒子受力变化的效果了。 + */ @ccclass('cc.RotationOvertimeModule') export default class RotationOvertimeModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -55,7 +66,8 @@ export default class RotationOvertimeModule extends ParticleModuleBase { private _separateAxes = false; /** - * @zh 是否三个轴分开设定旋转(暂不支持)。 + * @en Rotation around separate axis. + * @zh 是否三个轴分开设定旋转。 */ @displayOrder(1) @tooltip('i18n:rotationOvertimeModule.separateAxes') @@ -68,11 +80,11 @@ export default class RotationOvertimeModule extends ParticleModuleBase { } /** + * @en Angle around X axis. * @zh 绕 X 轴设定旋转。 */ @type(CurveRange) @serializable - @range([-1, 1]) @radian @displayOrder(2) @tooltip('i18n:rotationOvertimeModule.x') @@ -80,11 +92,11 @@ export default class RotationOvertimeModule extends ParticleModuleBase { public x = new CurveRange(); /** + * @en Angle around Y axis. * @zh 绕 Y 轴设定旋转。 */ @type(CurveRange) @serializable - @range([-1, 1]) @radian @displayOrder(3) @tooltip('i18n:rotationOvertimeModule.y') @@ -92,11 +104,11 @@ export default class RotationOvertimeModule extends ParticleModuleBase { public y = new CurveRange(); /** + * @en Angle around Z axis. * @zh 绕 Z 轴设定旋转。 */ @type(CurveRange) @serializable - @range([-1, 1]) @radian @displayOrder(4) @tooltip('i18n:rotationOvertimeModule.z') @@ -104,10 +116,10 @@ export default class RotationOvertimeModule extends ParticleModuleBase { public name = PARTICLE_MODULE_NAME.ROTATION; - private _startMat:Mat4 = new Mat4(); - private _matRot:Mat4 = new Mat4(); - private _quatRot:Quat = new Quat(); - private _otherEuler:Vec3 = new Vec3(); + private _startMat: Mat4 = new Mat4(); + private _matRot: Mat4 = new Mat4(); + private _quatRot: Quat = new Quat(); + private _otherEuler: Vec3 = new Vec3(); private _processRotation (p: Particle, r2d: number) { // Same as the particle-vs-legacy.chunk glsl statemants @@ -124,15 +136,24 @@ export default class RotationOvertimeModule extends ParticleModuleBase { } } + /** + * @en Apply rotation to particle. + * @zh 作用旋转到粒子上。 + * @param p @en Particle to animate @zh 模块需要更新的粒子 + * @param dt @en Update interval time @zh 粒子系统更新的间隔时间 + * @internal + */ public animate (p: Particle, dt: number) { const normalizedTime = 1 - p.remainingLifetime / p.startLifetime; - const rotationRand = pseudoRandom(p.randomSeed + ROTATION_OVERTIME_RAND_OFFSET); + const randZ = isCurveTwoValues(this.z) ? pseudoRandom(p.randomSeed + ROTATION_OVERTIME_RAND_OFFSET) : 0; const renderMode = p.particleSystem.processor.getInfo().renderMode; if ((!this._separateAxes) || (renderMode === RenderMode.VerticalBillboard || renderMode === RenderMode.HorizontalBillboard)) { - Quat.fromEuler(p.deltaQuat, 0, 0, this.z.evaluate(normalizedTime, rotationRand)! * dt * Particle.R2D); + Quat.fromEuler(p.deltaQuat, 0, 0, this.z.evaluate(normalizedTime, randZ)! * dt * Particle.R2D); } else { - Quat.fromEuler(p.deltaQuat, this.x.evaluate(normalizedTime, rotationRand)! * dt * Particle.R2D, this.y.evaluate(normalizedTime, rotationRand)! * dt * Particle.R2D, this.z.evaluate(normalizedTime, rotationRand)! * dt * Particle.R2D); + const randX = isCurveTwoValues(this.x) ? pseudoRandom(p.randomSeed + ROTATION_OVERTIME_RAND_OFFSET) : 0; + const randY = isCurveTwoValues(this.y) ? pseudoRandom(p.randomSeed + ROTATION_OVERTIME_RAND_OFFSET) : 0; + Quat.fromEuler(p.deltaQuat, this.x.evaluate(normalizedTime, randX)! * dt * Particle.R2D, this.y.evaluate(normalizedTime, randY)! * dt * Particle.R2D, this.z.evaluate(normalizedTime, randZ)! * dt * Particle.R2D); } // Rotation-overtime combine with start rotation, after that we get quat from the mat diff --git a/cocos/particle/animator/size-overtime.ts b/cocos/particle/animator/size-overtime.ts index 78cd3710294..ced2a24b73d 100644 --- a/cocos/particle/animator/size-overtime.ts +++ b/cocos/particle/animator/size-overtime.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,33 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, type, serializable, range, visible } from 'cc.decorator'; -import { pseudoRandom, Vec3 } from '../../core/math'; +import { pseudoRandom, Vec3 } from '../../core'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; import CurveRange from './curve-range'; import { ModuleRandSeed } from '../enum'; +import { isCurveTwoValues } from '../particle-general-function'; const SIZE_OVERTIME_RAND_OFFSET = ModuleRandSeed.SIZE; +/** + * @en + * This module will modify particle size over life time. + * Open the separateAxes option you can change the particle size on XYZ axis (Size on Z axis is invalid for billboard particle) + * Size on every axis is curve so you can modify these curves to see how it animate. + * @zh + * 本模块用于在粒子生命周期内对大小进行改变。 + * 打开 separateAxes 就能够修改粒子在三个轴方向的大小(z轴大小对公告板粒子无效) + * 每个轴上的粒子大小都是可以用曲线来进行编辑,修改曲线就能够看到粒子大小变化的效果了。 + */ @ccclass('cc.SizeOvertimeModule') export default class SizeOvertimeModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -51,6 +62,7 @@ export default class SizeOvertimeModule extends ParticleModuleBase { } /** + * @en Different size on separate axis. * @zh 决定是否在每个轴上独立控制粒子大小。 */ @serializable @@ -59,44 +71,48 @@ export default class SizeOvertimeModule extends ParticleModuleBase { public separateAxes = false; /** + * @en Curve to modify particle size. * @zh 定义一条曲线来决定粒子在其生命周期中的大小变化。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(2) @tooltip('i18n:sizeOvertimeModule.size') @visible(function (this: SizeOvertimeModule): boolean { return !this.separateAxes; }) public size = new CurveRange(); /** + * @en Curve to modify particle size on X axis. * @zh 定义一条曲线来决定粒子在其生命周期中 X 轴方向上的大小变化。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(3) @tooltip('i18n:sizeOvertimeModule.x') @visible(function (this: SizeOvertimeModule): boolean { return this.separateAxes; }) public x = new CurveRange(); /** + * @en Curve to modify particle size on Y axis. * @zh 定义一条曲线来决定粒子在其生命周期中 Y 轴方向上的大小变化。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(4) @tooltip('i18n:sizeOvertimeModule.y') @visible(function (this: SizeOvertimeModule): boolean { return this.separateAxes; }) public y = new CurveRange(); /** + * @en Curve to modify particle size on Z axis. * @zh 定义一条曲线来决定粒子在其生命周期中 Z 轴方向上的大小变化。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(5) @tooltip('i18n:sizeOvertimeModule.z') @visible(function (this: SizeOvertimeModule): boolean { return this.separateAxes; }) @@ -104,15 +120,26 @@ export default class SizeOvertimeModule extends ParticleModuleBase { public name = PARTICLE_MODULE_NAME.SIZE; + /** + * @en Apply size animation to particle. + * @zh 应用大小变换到粒子上。 + * @param particle @en Particle to animate @zh 模块需要更新的粒子 + * @param dt @en Update interval time @zh 粒子系统更新的间隔时间 + * @internal + */ public animate (particle: Particle, dt: number) { if (!this.separateAxes) { - Vec3.multiplyScalar(particle.size, particle.startSize, this.size.evaluate(1 - particle.remainingLifetime / particle.startLifetime, pseudoRandom(particle.randomSeed + SIZE_OVERTIME_RAND_OFFSET))!); + const rand = isCurveTwoValues(this.size) ? pseudoRandom(particle.randomSeed + SIZE_OVERTIME_RAND_OFFSET) : 0; + Vec3.multiplyScalar(particle.size, particle.startSize, + this.size.evaluate(1 - particle.remainingLifetime / particle.startLifetime, rand)!); } else { const currLifetime = 1 - particle.remainingLifetime / particle.startLifetime; - const sizeRand = pseudoRandom(particle.randomSeed + SIZE_OVERTIME_RAND_OFFSET); - particle.size.x = particle.startSize.x * this.x.evaluate(currLifetime, sizeRand)!; - particle.size.y = particle.startSize.y * this.y.evaluate(currLifetime, sizeRand)!; - particle.size.z = particle.startSize.z * this.z.evaluate(currLifetime, sizeRand)!; + const randX = isCurveTwoValues(this.x) ? pseudoRandom(particle.randomSeed + SIZE_OVERTIME_RAND_OFFSET) : 0; + const randY = isCurveTwoValues(this.y) ? pseudoRandom(particle.randomSeed + SIZE_OVERTIME_RAND_OFFSET) : 0; + const randZ = isCurveTwoValues(this.z) ? pseudoRandom(particle.randomSeed + SIZE_OVERTIME_RAND_OFFSET) : 0; + particle.size.x = particle.startSize.x * this.x.evaluate(currLifetime, randX)!; + particle.size.y = particle.startSize.y * this.y.evaluate(currLifetime, randY)!; + particle.size.z = particle.startSize.z * this.z.evaluate(currLifetime, randZ)!; } } } diff --git a/cocos/particle/animator/texture-animation.ts b/cocos/particle/animator/texture-animation.ts index c7402e0c1ae..aa5f1696d70 100644 --- a/cocos/particle/animator/texture-animation.ts +++ b/cocos/particle/animator/texture-animation.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, type, formerlySerializedAs, serializable, range } from 'cc.decorator'; -import { lerp, pseudoRandom, repeat } from '../../core/math'; -import { Enum } from '../../core/value-types'; +import { lerp, pseudoRandom, repeat, Enum } from '../../core'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; import CurveRange from './curve-range'; import { ModuleRandSeed } from '../enum'; +import { isCurveTwoValues } from '../particle-general-function'; const TEXTURE_ANIMATION_RAND_OFFSET = ModuleRandSeed.TEXTURE; /** - * 粒子贴图动画类型。 + * @en Texture animation type. + * @zh 粒子贴图动画类型。 * @enum textureAnimationModule.Mode */ const Mode = Enum({ @@ -49,21 +49,30 @@ const Mode = Enum({ }); /** - * 贴图动画的播放方式。 + * @en Mode to play texture animation. + * @zh 贴图动画的播放方式。 * @enum textureAnimationModule.Animation */ const Animation = Enum({ /** - * 播放贴图中的所有帧。 + * @en Play whole sheet of texture. + * @zh 播放贴图中的所有帧。 */ WholeSheet: 0, /** - * 播放贴图中的其中一行动画。 + * @en Play just one row of texture. + * @zh 播放贴图中的其中一行动画。 */ SingleRow: 1, }); +/** + * @en + * Use this module to play frame animation of the particle texture. + * @zh + * 这个模块用于播放粒子纹理带的纹理帧动画。 + */ @ccclass('cc.TextureAnimationModule') export default class TextureAnimationModule extends ParticleModuleBase { @serializable @@ -76,6 +85,7 @@ export default class TextureAnimationModule extends ParticleModuleBase { private _numTilesY = 0; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -95,6 +105,7 @@ export default class TextureAnimationModule extends ParticleModuleBase { private _mode = Mode.Grid; /** + * @en Set texture animation [[Mode]] (only support Grid mode). * @zh 设定粒子贴图动画的类型(暂只支持 Grid 模式)[[Mode]]。 */ @type(Mode) @@ -111,6 +122,7 @@ export default class TextureAnimationModule extends ParticleModuleBase { } /** + * @en Tile count on X axis. * @zh X 方向动画帧数。 */ @displayOrder(2) @@ -127,6 +139,7 @@ export default class TextureAnimationModule extends ParticleModuleBase { } /** + * @en Tile count on Y axis. * @zh Y 方向动画帧数。 */ @displayOrder(3) @@ -143,6 +156,7 @@ export default class TextureAnimationModule extends ParticleModuleBase { } /** + * @en Texture animation type. See [[Animation]]. * @zh 动画播放方式 [[Animation]]。 */ @type(Animation) @@ -152,26 +166,29 @@ export default class TextureAnimationModule extends ParticleModuleBase { public animation = Animation.WholeSheet; /** + * @en Curve to control texture animation speed. * @zh 一个周期内动画播放的帧与时间变化曲线。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(7) @tooltip('i18n:textureAnimationModule.frameOverTime') public frameOverTime = new CurveRange(); /** + * @en Texture animation frame start to play. * @zh 从第几帧开始播放,时间为整个粒子系统的生命周期。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(8) @tooltip('i18n:textureAnimationModule.startFrame') public startFrame = new CurveRange(); /** + * @en Animation cycle count per particle life. * @zh 一个生命周期内播放循环的次数。 */ @serializable @@ -216,6 +233,8 @@ export default class TextureAnimationModule extends ParticleModuleBase { } /** + * @en Get random row from texture to generate animation.
+ * This option is available when [[Animation]] type is SingleRow. * @zh 随机从动画贴图中选择一行以生成动画。
* 此选项仅在动画播放方式为 SingleRow 时生效。 */ @@ -225,6 +244,8 @@ export default class TextureAnimationModule extends ParticleModuleBase { public randomRow = false; /** + * @en Generate animation from specific row in texture.
+ * This option is available when [[Animation]] type is SingleRow and randomRow option is disabled. * @zh 从动画贴图中选择特定行以生成动画。
* 此选项仅在动画播放方式为 SingleRow 时且禁用 randomRow 时可用。 */ @@ -235,26 +256,41 @@ export default class TextureAnimationModule extends ParticleModuleBase { public name = PARTICLE_MODULE_NAME.TEXTURE; + /** + * @en Init start row to particle. + * @zh 给粒子创建初始行属性。 + * @param p @en Particle to set start row. @zh 设置初始行属性的粒子。 + * @internal + */ public init (p: Particle) { p.startRow = Math.floor(Math.random() * this.numTilesY); } + /** + * @en Apply texture animation to particle. + * @zh 应用贴图动画到粒子。 + * @param p @en Particle to animate. @zh 模块需要更新的粒子。 + * @param dt @en Update interval time. @zh 粒子系统更新的间隔时间。 + * @internal + */ public animate (p: Particle, dt: number) { const normalizedTime = 1 - p.remainingLifetime / p.startLifetime; - const startFrame = this.startFrame.evaluate(normalizedTime, pseudoRandom(p.randomSeed + TEXTURE_ANIMATION_RAND_OFFSET))! / (this.numTilesX * this.numTilesY); + const randStart = isCurveTwoValues(this.startFrame) ? pseudoRandom(p.randomSeed + TEXTURE_ANIMATION_RAND_OFFSET) : 0; + const randFrame = isCurveTwoValues(this.frameOverTime) ? pseudoRandom(p.randomSeed + TEXTURE_ANIMATION_RAND_OFFSET) : 0; + const startFrame = this.startFrame.evaluate(normalizedTime, randStart)! / (this.numTilesX * this.numTilesY); if (this.animation === Animation.WholeSheet) { - p.frameIndex = repeat(this.cycleCount * (this.frameOverTime.evaluate(normalizedTime, pseudoRandom(p.randomSeed + TEXTURE_ANIMATION_RAND_OFFSET))! + startFrame), 1); + p.frameIndex = repeat(this.cycleCount * (this.frameOverTime.evaluate(normalizedTime, randFrame)! + startFrame), 1); } else if (this.animation === Animation.SingleRow) { const rowLength = 1 / this.numTilesY; if (this.randomRow) { - const f = repeat(this.cycleCount * (this.frameOverTime.evaluate(normalizedTime, pseudoRandom(p.randomSeed + TEXTURE_ANIMATION_RAND_OFFSET))! + startFrame), 1); + const f = repeat(this.cycleCount * (this.frameOverTime.evaluate(normalizedTime, randFrame)! + startFrame), 1); const from = p.startRow * rowLength; const to = from + rowLength; p.frameIndex = lerp(from, to, f); } else { const from = this.rowIndex * rowLength; const to = from + rowLength; - p.frameIndex = lerp(from, to, repeat(this.cycleCount * (this.frameOverTime.evaluate(normalizedTime, pseudoRandom(p.randomSeed + TEXTURE_ANIMATION_RAND_OFFSET))! + startFrame), 1)); + p.frameIndex = lerp(from, to, repeat(this.cycleCount * (this.frameOverTime.evaluate(normalizedTime, randFrame)! + startFrame), 1)); } } } diff --git a/cocos/particle/animator/velocity-overtime.ts b/cocos/particle/animator/velocity-overtime.ts index d3dad9a7014..9d3103a970f 100644 --- a/cocos/particle/animator/velocity-overtime.ts +++ b/cocos/particle/animator/velocity-overtime.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, range, type, serializable } from 'cc.decorator'; -import { Mat4, pseudoRandom, Quat, Vec3 } from '../../core/math'; +import { Mat4, pseudoRandom, Quat, Vec3 } from '../../core'; import { Space, ModuleRandSeed } from '../enum'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; -import { calculateTransform } from '../particle-general-function'; +import { calculateTransform, isCurveTwoValues } from '../particle-general-function'; import CurveRange from './curve-range'; const VELOCITY_X_OVERTIME_RAND_OFFSET = ModuleRandSeed.VELOCITY_X; @@ -36,11 +35,22 @@ const VELOCITY_Z_OVERTIME_RAND_OFFSET = ModuleRandSeed.VELOCITY_Z; const _temp_v3 = new Vec3(); +/** + * @en + * This module will modify particle velocity over life time. + * Open the separateAxes option you can change the velocity on XYZ axis. + * Velocity on every axis is curve so you can modify these curves to see how it animate. + * @zh + * 本模块用于在粒子生命周期内改变粒子的速度。 + * 打开 separateAxes 就能够修改粒子在三个轴方向的速度大小。 + * 每个轴上的速度大小都是可以用曲线来进行编辑,修改曲线就能够看到粒子速度变化的效果了。 + */ @ccclass('cc.VelocityOvertimeModule') export default class VelocityOvertimeModule extends ParticleModuleBase { @serializable _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -56,46 +66,47 @@ export default class VelocityOvertimeModule extends ParticleModuleBase { } /** + * @en Velocity on X axis. * @zh X 轴方向上的速度分量。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(2) @tooltip('i18n:velocityOvertimeModule.x') public x = new CurveRange(); /** + * @en Velocity on Y axis. * @zh Y 轴方向上的速度分量。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(3) @tooltip('i18n:velocityOvertimeModule.y') public y = new CurveRange(); /** + * @en Velocity on Z axis. * @zh Z 轴方向上的速度分量。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(4) @tooltip('i18n:velocityOvertimeModule.z') public z = new CurveRange(); /** + * @en Speed modifier (available for CPU particle). * @zh 速度修正系数(只支持 CPU 粒子)。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(5) @tooltip('i18n:velocityOvertimeModule.speedModifier') public speedModifier = new CurveRange(); /** + * @en Velocity [[Space]] used to calculate particle velocity. * @zh 速度计算时采用的坐标系[[Space]]。 */ @type(Space) @@ -116,18 +127,41 @@ export default class VelocityOvertimeModule extends ParticleModuleBase { this.needUpdate = true; } + /** + * @en Update velocity overtime module calculate transform. + * @zh 更新模块,计算坐标变换。 + * @param space @en Velocity overtime module update space @zh 模块更新空间 + * @param worldTransform @en Particle system world transform @zh 粒子系统的世界变换矩阵 + * @internal + */ public update (space: number, worldTransform: Mat4) { this.needTransform = calculateTransform(space, this.space, worldTransform, this.rotation); } + /** + * @en Apply velocity animation to particle. + * @zh 作用速度变换到粒子上。 + * @param p @en Particle to animate @zh 模块需要更新的粒子 + * @param dt @en Update interval time @zh 粒子系统更新的间隔时间 + * @internal + */ public animate (p: Particle, dt: number) { const normalizedTime = 1 - p.remainingLifetime / p.startLifetime; - const vel = Vec3.set(_temp_v3, this.x.evaluate(normalizedTime, pseudoRandom(p.randomSeed ^ VELOCITY_X_OVERTIME_RAND_OFFSET))!, this.y.evaluate(normalizedTime, pseudoRandom(p.randomSeed ^ VELOCITY_Y_OVERTIME_RAND_OFFSET))!, this.z.evaluate(normalizedTime, pseudoRandom(p.randomSeed ^ VELOCITY_Z_OVERTIME_RAND_OFFSET))!); + const randX = isCurveTwoValues(this.x) ? pseudoRandom(p.randomSeed ^ VELOCITY_X_OVERTIME_RAND_OFFSET) : 0; + const randY = isCurveTwoValues(this.y) ? pseudoRandom(p.randomSeed ^ VELOCITY_Y_OVERTIME_RAND_OFFSET) : 0; + const randZ = isCurveTwoValues(this.z) ? pseudoRandom(p.randomSeed ^ VELOCITY_Z_OVERTIME_RAND_OFFSET) : 0; + const randSpeed = isCurveTwoValues(this.speedModifier) ? pseudoRandom(p.randomSeed + VELOCITY_X_OVERTIME_RAND_OFFSET) : 0; + + const vel = Vec3.set(_temp_v3, + this.x.evaluate(normalizedTime, randX)!, + this.y.evaluate(normalizedTime, randY)!, + this.z.evaluate(normalizedTime, randZ)!); if (this.needTransform) { Vec3.transformQuat(vel, vel, this.rotation); } Vec3.add(p.animatedVelocity, p.animatedVelocity, vel); Vec3.add(p.ultimateVelocity, p.velocity, p.animatedVelocity); - Vec3.multiplyScalar(p.ultimateVelocity, p.ultimateVelocity, this.speedModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, pseudoRandom(p.randomSeed + VELOCITY_X_OVERTIME_RAND_OFFSET))!); + Vec3.multiplyScalar(p.ultimateVelocity, p.ultimateVelocity, + this.speedModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, randSpeed)!); } } diff --git a/cocos/particle/billboard.ts b/cocos/particle/billboard.ts index 4bbaf24a4ac..46384bc78e0 100644 --- a/cocos/particle/billboard.ts +++ b/cocos/particle/billboard.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, help, executeInEditMode, menu, tooltip, type, serializable } from 'cc.decorator'; import { builtinResMgr } from '../asset/asset-manager'; @@ -30,9 +29,8 @@ import { Mesh } from '../3d/assets'; import { Material, Texture2D } from '../asset/assets'; import { Component } from '../scene-graph/component'; import { Attribute, AttributeName, Format, PrimitiveMode } from '../gfx'; -import { Color, toDegree, toRadian, Vec4 } from '../core/math'; +import { Color, toDegree, toRadian, Vec4, cclegacy } from '../core'; import { scene } from '../render-scene'; -import { legacyCC } from '../core/global-exports'; @ccclass('cc.Billboard') @help('i18n:cc.Billboard') @@ -182,7 +180,7 @@ export class Billboard extends Component { ], indices: [0, 1, 2, 1, 2, 3], }, undefined, { calculateBounds: false }); - const model = this._model = legacyCC.director.root.createModel(scene.Model, this.node); + const model = this._model = cclegacy.director.root.createModel(scene.Model, this.node); model.node = model.transform = this.node; if (this._material == null) { this._material = new Material(); diff --git a/cocos/particle/burst.ts b/cocos/particle/burst.ts index f95b32531e2..83fe0c666d2 100644 --- a/cocos/particle/burst.ts +++ b/cocos/particle/burst.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,26 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, type, serializable, editable, range } from 'cc.decorator'; import { repeat } from '../core/math'; import CurveRange from './animator/curve-range'; +/** + * @en + * A burst is a particle emission event, where a number of particles are all emitted at the same time + * @zh + * Burst 是粒子的一种发射事件,触发时很多粒子将会同时喷出 + */ @ccclass('cc.Burst') export default class Burst { @serializable private _time = 0; /** - * @zh 粒子系统开始运行到触发此次 Brust 的时间。 + * @en The time from particle system start until this burst triggered. + * @zh 粒子系统开始运行到触发此次 Brust 的时间。 */ @editable get time () { @@ -49,6 +55,7 @@ export default class Burst { private _repeatCount = 1; /** + * @en Burst trigger count. * @zh Burst 的触发次数。 */ @editable @@ -62,6 +69,7 @@ export default class Burst { } /** + * @en Trigger interval count. * @zh 每次触发的间隔时间。 */ @serializable @@ -69,11 +77,12 @@ export default class Burst { public repeatInterval = 1; /** + * @en Burst particle count. * @zh 发射的粒子的数量。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY, 1]) public count: CurveRange = new CurveRange(); private _remainingCount: number; @@ -84,6 +93,13 @@ export default class Burst { this._curTime = 0.0; } + /** + * @en Update burst trigger + * @zh 更新触发事件 + * @param psys @en Particle system to burst. @zh 要触发的粒子系统。 + * @param dt @en Update interval time. @zh 粒子系统更新的间隔时间。 + * @internal + */ public update (psys, dt: number) { if (this._remainingCount === 0) { this._remainingCount = this._repeatCount; @@ -101,11 +117,21 @@ export default class Burst { } } + /** + * @en Reset remaining burst count and burst time to zero. + * @zh 重置触发时间和留存的触发次数为零。 + */ public reset () { this._remainingCount = 0; this._curTime = 0.0; } + /** + * @en Get the max particle count this burst trigger. + * @zh 获取最大的触发粒子数量。 + * @param psys @en Particle system to burst. @zh 要触发的粒子系统。 + * @returns @en burst max particle count. @zh 一次最多触发的粒子个数。 + */ public getMaxCount (psys) { return this.count.getMax() * Math.min(Math.ceil(psys.duration / this.repeatInterval), this.repeatCount); } diff --git a/cocos/particle/deprecated.ts b/cocos/particle/deprecated.ts index d5f342d5df9..7acc7cacb91 100644 --- a/cocos/particle/deprecated.ts +++ b/cocos/particle/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { removeProperty, replaceProperty } from '../core/utils/x-deprecated'; +import { removeProperty, replaceProperty, js, cclegacy } from '../core'; import Burst from './burst'; import { ParticleSystem } from './particle-system'; import { Billboard } from './billboard'; import { Line } from './line'; -import { js } from '../core/utils/js'; -import { legacyCC } from '../core/global-exports'; removeProperty(Burst.prototype, 'Burst.prototype', [ { @@ -52,19 +49,19 @@ replaceProperty(ParticleSystem.prototype, 'ParticleSystem.prototype', [ * @deprecated Since v1.2 */ export { ParticleSystem as ParticleSystemComponent }; -legacyCC.ParticleSystemComponent = ParticleSystem; +cclegacy.ParticleSystemComponent = ParticleSystem; js.setClassAlias(ParticleSystem, 'cc.ParticleSystemComponent'); /** * Alias of [[Billboard]] * @deprecated Since v1.2 */ export { Billboard as BillboardComponent }; -legacyCC.BillboardComponent = Billboard; +cclegacy.BillboardComponent = Billboard; js.setClassAlias(Billboard, 'cc.BillboardComponent'); /** * Alias of [[Line]] * @deprecated Since v1.2 */ export { Line as LineComponent }; -legacyCC.LineComponent = Line; +cclegacy.LineComponent = Line; js.setClassAlias(Line, 'cc.LineComponent'); diff --git a/cocos/particle/emitter/shape-module.ts b/cocos/particle/emitter/shape-module.ts index 54c54f22c4c..26afbad8243 100644 --- a/cocos/particle/emitter/shape-module.ts +++ b/cocos/particle/emitter/shape-module.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, type, formerlySerializedAs, serializable, visible, range } from 'cc.decorator'; -import { Mat4, Quat, Vec2, Vec3, clamp, pingPong, random, randomRange, repeat, toDegree, toRadian } from '../../core/math'; +import { Mat4, Quat, Vec2, Vec3, clamp, pingPong, random, randomRange, repeat, toDegree, toRadian } from '../../core'; import CurveRange from '../animator/curve-range'; import { ArcMode, EmitLocation, ShapeType } from '../enum'; @@ -35,7 +34,7 @@ import { ParticleSystem } from '../particle-system'; const _intermediVec = new Vec3(0, 0, 0); const _intermediArr: number[] = []; const _unitBoxExtent = new Vec3(0.5, 0.5, 0.5); -function getShapeTypeEnumName(enumValue: number): keyof typeof ShapeType { +function getShapeTypeEnumName (enumValue: number): keyof typeof ShapeType { let enumName = ''; for (const key in ShapeType) { if (ShapeType[key] === enumValue) { @@ -46,9 +45,23 @@ function getShapeTypeEnumName(enumValue: number): keyof typeof ShapeType { return enumName as keyof typeof ShapeType; } +/** + * @en + * This module defines the the volume or surface from which particles can be emitted, and the direction of the start velocity. + * The Shape property defines the shape of the emission volume, and the rest of the module properties vary depending on the Shape you choose. + * All shapes have properties that define their dimensions, such as the Radius property. + * To edit these, drag the handles on the wireframe emitter shape in the Scene view. + * The choice of shape affects the region from which particles can be emitted, but also the initial direction of the particles. + * @zh + * 本模块定义一个发射体或发射面,粒子将会从它进行发射,并且定义了粒子发射的初始方向和初始速度。 + * 形状属性定义粒子系统的发射体,剩下的属性依赖于选择的形状。 + * 所有形状都具有定义其大小的属性,例如 Radius 属性。要编辑这些属性,请在视图中拖动线框发射器形状上的控制柄。 + * 形状的选择会影响可发射粒子的区域,但也会影响粒子的初始方向。 + */ @ccclass('cc.ShapeModule') export default class ShapeModule { /** + * @en Emitter position. * @zh 粒子发射器位置。 */ @displayOrder(13) @@ -62,6 +75,7 @@ export default class ShapeModule { } /** + * @en Emitter rotation. * @zh 粒子发射器旋转角度。 */ @displayOrder(14) @@ -75,6 +89,7 @@ export default class ShapeModule { } /** + * @en Emitter size scale. * @zh 粒子发射器缩放比例。 */ @displayOrder(15) @@ -88,6 +103,7 @@ export default class ShapeModule { } /** + * @en Particles will be emitted in an arc if shape is Cone or Circle. * @zh 粒子发射器在一个扇形范围内发射。 */ @displayOrder(6) @@ -97,7 +113,7 @@ export default class ShapeModule { const enumName = getShapeTypeEnumName(this.shapeType); return subset.includes(enumName); }) - get arc() { + get arc () { return toDegree(this._arc); } @@ -106,6 +122,8 @@ export default class ShapeModule { } /** + * @en The angle of the Cone. + * Define how the cone opening and closing. * @zh 圆锥的轴与母线的夹角。 * 决定圆锥发射器的开合程度。 */ @@ -116,7 +134,7 @@ export default class ShapeModule { const enumName = getShapeTypeEnumName(this.shapeType); return subset.includes(enumName); }) - get angle() { + get angle () { return Math.round(toDegree(this._angle) * 100) / 100; } @@ -127,6 +145,7 @@ export default class ShapeModule { @serializable private _enable = false; /** + * @en Enable this module or not. * @zh 是否启用。 */ @displayOrder(0) @@ -139,6 +158,7 @@ export default class ShapeModule { } /** + * @en Emitter [[ShapeType]]. * @zh 粒子发射器类型 [[ShapeType]]。 * * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. @@ -179,6 +199,7 @@ export default class ShapeModule { } /** + * @en Particles emitted from which part of the shape [[EmitLocation]] (Box Cone Sphere Hemisphere). * @zh 粒子从发射器哪个部位发射 [[EmitLocation]]。 */ @type(EmitLocation) @@ -193,6 +214,7 @@ export default class ShapeModule { public emitFrom = EmitLocation.Volume; /** + * @en Align particle with particle direction. * @zh 根据粒子的初始方向决定粒子的移动方向。 */ @serializable @@ -201,6 +223,7 @@ export default class ShapeModule { public alignToDirection = false; /** + * @en Particle direction random amount. * @zh 粒子生成方向随机设定。 */ @serializable @@ -209,6 +232,7 @@ export default class ShapeModule { public randomDirectionAmount = 0; /** + * @en Blend particle directions towards a spherical direction, where they travel outwards from the center of their transform. * @zh 表示当前发射方向与当前位置到结点中心连线方向的插值。 */ @serializable @@ -217,6 +241,7 @@ export default class ShapeModule { public sphericalDirectionAmount = 0; /** + * @en Particle position random amount. * @zh 粒子生成位置随机设定(设定此值为非 0 会使粒子生成位置超出生成器大小范围)。 */ @serializable @@ -225,6 +250,7 @@ export default class ShapeModule { public randomPositionAmount = 0; /** + * @en Emition radius (available for Circle Cone Sphere Hemisphere). * @zh 粒子发射器半径。 */ @serializable @@ -238,6 +264,10 @@ export default class ShapeModule { public radius = 1; /** + * @en Emit position in shape (available for Circle Cone Sphere Hemisphere): + * - 0 Emit from surface; + * - 1 Emit from volume center; + * - 0 to 1 Emit within surface and volume center. * @zh 粒子发射器发射位置(对 Box 类型的发射器无效): * - 0 表示从表面发射; * - 1 表示从中心发射; @@ -254,6 +284,7 @@ export default class ShapeModule { public radiusThickness = 1; /** + * @en Arc mode for Cone and Circle shape. * @zh 粒子在扇形范围内的发射方式 [[ArcMode]]。 */ @type(ArcMode) @@ -268,6 +299,7 @@ export default class ShapeModule { public arcMode = ArcMode.Random; /** + * @en Control arc spread for Cone and circle shape. * @zh 控制可能产生粒子的弧周围的离散间隔。 */ @visible(function noArc (this: ShapeModule) { return this.arcMode !== ArcMode.Random; }) // Bug fix: Hide this input when arcMode is random @@ -282,6 +314,7 @@ export default class ShapeModule { public arcSpread = 0; /** + * @en Emit speed around arc (available for Cone and Circle). * @zh 粒子沿圆周发射的速度。 */ @type(CurveRange) @@ -298,6 +331,7 @@ export default class ShapeModule { public arcSpeed = new CurveRange(); /** + * @en The length from Cone bottom to top. * @zh 圆锥顶部截面距离底部的轴长。 * 决定圆锥发射器的高度。 */ @@ -312,6 +346,7 @@ export default class ShapeModule { public length = 5; /** + * @en Shape thickness for box shape. * @zh 粒子发射器发射位置(针对 Box 类型的粒子发射器)。 */ @serializable @@ -353,12 +388,24 @@ export default class ShapeModule { this.totalAngle = 0; } + /** + * @en Apply particle system to this shape and create shape transform matrix. + * @zh 把发射形状应用到粒子系统,并且创建发射形状变换矩阵。 + * @param ps @en Emit shape applied to which Particle system. @zh 使用发射形状的粒子系统。 + * @internal + */ public onInit (ps: ParticleSystem) { this.particleSystem = ps; this.constructMat(); this.lastTime = this.particleSystem._time; } + /** + * @en Emit particle by this shape. + * @zh 通过这个形状发射粒子。 + * @param p @en Particle emitted. @zh 发射出来的粒子。 + * @internal + */ public emit (p) { switch (this.shapeType) { case ShapeType.Box: diff --git a/cocos/particle/enum.ts b/cocos/particle/enum.ts index b16a9d81293..d81dbc71168 100644 --- a/cocos/particle/enum.ts +++ b/cocos/particle/enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Enum } from '../core/value-types'; +import { Enum } from '../core'; export const Space = Enum({ World: 0, diff --git a/cocos/particle/index.ts b/cocos/particle/index.ts index d741bb31656..0f7c56cb293 100644 --- a/cocos/particle/index.ts +++ b/cocos/particle/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Billboard } from './billboard'; import { Line } from './line'; import { ParticleSystem } from './particle-system'; import { ParticleUtils } from './particle-utils'; import CurveRange from './animator/curve-range'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import GradientRange from './animator/gradient-range'; import Gradient, { AlphaKey, ColorKey } from './animator/gradient'; import Burst from './burst'; @@ -48,4 +47,4 @@ export { export * from './deprecated'; -legacyCC.ParticleUtils = ParticleUtils; +cclegacy.ParticleUtils = ParticleUtils; diff --git a/cocos/particle/line.ts b/cocos/particle/line.ts index 7e10032668d..23724398cbc 100644 --- a/cocos/particle/line.ts +++ b/cocos/particle/line.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, help, executeInEditMode, menu, tooltip, displayOrder, type, serializable, range } from 'cc.decorator'; import { Material, Texture2D } from '../asset/assets'; import { Component } from '../scene-graph'; -import { Vec3, Vec2, Vec4 } from '../core/math'; +import { Vec3, Vec2, Vec4, cclegacy } from '../core'; import { LineModel } from './models/line-model'; import { builtinResMgr } from '../asset/asset-manager'; import CurveRange from './animator/curve-range'; import GradientRange from './animator/gradient-range'; -import { legacyCC } from '../core/global-exports'; import { IMaterialInstanceInfo, MaterialInstance } from '../render-scene/core/material-instance'; const _matInsInfo: IMaterialInstanceInfo = { @@ -219,7 +217,7 @@ export class Line extends Component { } public onLoad () { - const model = this._model = legacyCC.director.root.createModel(LineModel); + const model = this._model = cclegacy.director.root.createModel(LineModel); model.node = model.transform = this.node; if (this._material === null) { this._material = new Material(); diff --git a/cocos/particle/models/line-model.ts b/cocos/particle/models/line-model.ts index d1368d97385..0102e0b6b7f 100644 --- a/cocos/particle/models/line-model.ts +++ b/cocos/particle/models/line-model.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { JSB } from 'internal:constants'; import { RenderingSubMesh } from '../../asset/assets/rendering-sub-mesh'; import { DRAW_INFO_SIZE, Buffer, IndirectBuffer, Attribute, BufferInfo, DrawInfo, AttributeName, BufferUsageBit, Format, FormatInfos, MemoryUsageBit, PrimitiveMode } from '../../gfx'; -import { Vec3 } from '../../core/math'; +import { Vec3 } from '../../core'; import { scene } from '../../render-scene'; import CurveRange from '../animator/curve-range'; import GradientRange from '../animator/gradient-range'; diff --git a/cocos/particle/models/particle-batch-model.ts b/cocos/particle/models/particle-batch-model.ts index 96aeb4196e9..8a7d5fae87f 100644 --- a/cocos/particle/models/particle-batch-model.ts +++ b/cocos/particle/models/particle-batch-model.ts @@ -1,19 +1,18 @@ /* eslint-disable max-len */ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,7 +27,7 @@ import { JSB } from 'internal:constants'; import { Mesh } from '../../3d/assets/mesh'; import { AttributeName, BufferUsageBit, FormatInfos, MemoryUsageBit, PrimitiveMode, Attribute, DRAW_INFO_SIZE, Buffer, IndirectBuffer, BufferInfo, DrawInfo, Feature, deviceManager } from '../../gfx'; -import { Color } from '../../core/math/color'; +import { Color } from '../../core'; import { scene } from '../../render-scene'; import { Particle } from '../particle'; import { Material, RenderingSubMesh } from '../../asset/assets'; @@ -245,6 +244,7 @@ export default class ParticleBatchModel extends scene.Model { } private createSubMeshDataInsDynamic (): ArrayBuffer { + this._insBuffers.length = 0; this.destroySubMeshData(); const vertexBuffer = this._device.createBuffer(new BufferInfo( @@ -490,7 +490,6 @@ export default class ParticleBatchModel extends scene.Model { this._vdataF32![idx++] = p.rotation.x; this._vdataF32![idx++] = p.rotation.y; this._vdataF32![idx++] = p.rotation.z; - this._vdataF32![idx++] = p.randomSeed; this._vdataF32![idx++] = p.startColor.r / 255.0; this._vdataF32![idx++] = p.startColor.g / 255.0; @@ -502,6 +501,8 @@ export default class ParticleBatchModel extends scene.Model { this._vdataF32![idx++] = p.velocity.z; this._vdataF32![idx++] = p.startLifetime; + this._vdataF32![idx++] = p.randomSeed; + offset += this._vertAttrsFloatCount; } diff --git a/cocos/particle/noise.ts b/cocos/particle/noise.ts index 905d1d5c691..fd42921d23c 100644 --- a/cocos/particle/noise.ts +++ b/cocos/particle/noise.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec2, Vec3 } from '../core/math'; +/** + * @en Noise generation class. + * @zh 此类生成噪声纹理。 + */ export class ParticleNoise { private permutation: number[] = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, @@ -41,12 +44,22 @@ export class ParticleNoise { 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, ]; - constructor (permutation ? : number[]) { + constructor (permutation?: number[]) { if (permutation) { this.permutation = permutation; } } + /** + * @en Noise generation function. + * @zh 噪声生成函数。 + * @param x @en Relative X coordinate. @zh 纹理坐标在 X 轴的偏移量。 + * @param y @en Relative Y coordinate. @zh 纹理坐标在 Y 轴的偏移量。 + * @param z @en Relative Z coordinate. @zh 纹理坐标在 Z 轴的偏移量。 + * @param min @en Min pixel value. @zh 像素最小值。 + * @param max @en Max pixel value. @zh 像素最大值。 + * @returns @en Texture pixel generated. @zh 返回生成的噪声纹理值。 + */ public noise (x: number, y: number, z: number, min = 0, max = 1): number { const p: number[] = new Array(512); for (let i = 0; i < 256; i++) { p[256 + i] = p[i] = this.permutation[i]; } @@ -106,34 +119,83 @@ export class ParticleNoise { private result: Vec3 = new Vec3(); private mixOut: Vec2 = new Vec2(); + /** + * @en Set texture rolling speed. + * @zh 设置纹理滚动速度。 + * @param x @en X axis roll speed. @zh X 轴滚动速度。 + * @param y @en Y axis roll speed. @zh Y 轴滚动速度。 + * @param z @en Z axis roll speed. @zh Z 轴滚动速度。 + */ public setSpeed (x, y, z) { this.noiseSpeed.set(x, y, z); } + /** + * @en Set noise frequency. + * @zh 设置生成的噪声频率。 + * @param f @en Noise texture frequency. @zh 噪声频率。 + */ public setFrequency (f) { this.noiseFrequency = f; } + /** + * @zh 将最终噪声值重新映射到不同的范围。 + * @en The curve that describes how the final noise values are transformed. + * @param x @en X value transformed. @zh X 轴上噪声值的偏移。 + * @param y @en Y value transformed. @zh Y 轴上噪声值的偏移。 + * @param z @en Z value transformed. @zh Z 轴上噪声值的偏移。 + * @deprecated since v3.6.0 + */ public setAbs (x, y, z) { this.noiseAbs.set(x, y, z); } + /** + * @en Set noise amplititude. + * @zh 设置噪声强度。 + * @param x @en Noise amplititude on X axis. @zh X 轴上的噪声强度。 + * @param y @en Noise amplititude on Y axis. @zh Y 轴上的噪声强度。 + * @param z @en Noise amplititude on Z axis. @zh Z 轴上的噪声强度。 + */ public setAmplititude (x, y, z) { this.noiseAmplitude.set(x, y, z); } + /** + * @en Specify how many layers of overlapping noise are combined to produce the final noise values. + * @zh 指定组合多少层重叠噪声来产生最终噪声值。 + * @param x @en Layer count. @zh 噪声层数。 + * @param y @en For each additional noise layer, reduce the strength by this proportion. @zh 每一层的噪声强度衰减比例。 + * @param z @en For each additional noise layer, adjust the frequency by this multiplier. @zh 对于每个附加的噪声层,按此乘数调整频率。 + */ public setOctaves (x, y, z) { this.octaves.set(x, y, z); } + /** + * @en Set update interval time. + * @zh 设置更新间隔时间。 + * @param t @en Update interval time. @zh 更新的间隔时间。 + */ public setTime (t) { this.dt = t; } + /** + * @en Set noise texture sample point. + * @zh 设置噪声纹理的采样点。 + * @param p @en Sample point of noise texture. @zh 噪声纹理采样点。 + */ public setSamplePoint (p: Vec3) { this.point.set(p); } + /** + * @en Get the sample pixel. + * @zh 获取采样的像素。 + * @returns @en The sample result. @zh 纹理采样结果。 + */ public getResult (): Vec3 { return this.result; } @@ -163,6 +225,10 @@ export class ParticleNoise { out.y = this.getNoise(point.y, point.z, point.x, time, offSpeed, noiseFrequency, octaves); } + /** + * @en Sample pixel from noise texture. + * @zh 从噪声纹理采样像素。 + */ public getNoiseParticle () { this.accSpeed.set(this.noiseSpeed.x * this.dt, this.noiseSpeed.y * this.dt, this.noiseSpeed.z * this.dt); @@ -177,6 +243,13 @@ export class ParticleNoise { this.result.set(sampX * this.noiseAmplitude.x, sampY * this.noiseAmplitude.y, sampZ * this.noiseAmplitude.z); } + /** + * @en Generate noise texture preview. + * @zh 生成噪声纹理的预览。 + * @param out @en Noise pixel array. @zh 噪声像素 RGB 数组。 + * @param width @en Texture width. @zh 纹理宽度。 + * @param height @en Texture height. @zh 纹理高度。 + */ public getPreview (out: number[], width: number, height: number) { for (let h = 0; h < height; ++h) { for (let w = 0; w < width; ++w) { diff --git a/cocos/particle/particle-culler.ts b/cocos/particle/particle-culler.ts index c5e385feda0..f3ce82d43fc 100644 --- a/cocos/particle/particle-culler.ts +++ b/cocos/particle/particle-culler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IParticleModule, Particle, PARTICLE_MODULE_ORDER } from './particle'; import { Node } from '../scene-graph/node'; import { TransformBit } from '../scene-graph/node-enum'; import { RenderMode, Space } from './enum'; -import { approx, EPSILON, Mat4, pseudoRandom, Quat, randomRangeInt, Vec3, Vec4 } from '../core'; -import { INT_MAX } from '../core/math/bits'; -import { particleEmitZAxis } from './particle-general-function'; +import { approx, EPSILON, Mat4, pseudoRandom, Quat, randomRangeInt, Vec3, Vec4, geometry, bits } from '../core'; +import { isCurveTwoValues, particleEmitZAxis } from './particle-general-function'; import { IParticleSystemRenderer } from './renderer/particle-system-renderer-base'; import { Mesh } from '../3d'; -import { AABB } from '../core/geometry'; import type { ParticleSystem } from './particle-system'; +import { Mode } from './animator/curve-range'; const _node_mat = new Mat4(); const _node_parent_inv = new Mat4(); @@ -140,7 +138,7 @@ export class ParticleCuller { particle.particleSystem = ps; particle.reset(); - const rand = pseudoRandom(randomRangeInt(0, INT_MAX)); + const rand = pseudoRandom(randomRangeInt(0, bits.INT_MAX)); if (ps._shapeModule && ps._shapeModule.enable) { ps._shapeModule.emit(particle); @@ -205,7 +203,7 @@ export class ParticleCuller { }); if (ps.simulationSpace === Space.Local) { - const r:Quat = ps.node.getRotation(); + const r: Quat = ps.node.getRotation(); Mat4.fromQuat(this._localMat, r); this._localMat.transpose(); // just consider rotation, use transpose as invert } @@ -220,25 +218,30 @@ export class ParticleCuller { p.remainingLifetime -= dt; Vec3.set(p.animatedVelocity, 0, 0, 0); - if (ps.simulationSpace === Space.Local) { - const gravityFactor = -ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, pseudoRandom(p.randomSeed))! * 9.8 * dt; - this._gravity.x = 0.0; - this._gravity.y = gravityFactor; - this._gravity.z = 0.0; - this._gravity.w = 1.0; - if (!approx(gravityFactor, 0.0, EPSILON)) { - if (ps.node.parent) { - this._gravity = this._gravity.transformMat4(_node_parent_inv); + // apply gravity when both the mode is not Constant and the value is not 0. + const useGravity = (ps.gravityModifier.mode !== Mode.Constant || ps.gravityModifier.constant !== 0); + if (useGravity) { + const rand = isCurveTwoValues(ps.gravityModifier) ? pseudoRandom(p.randomSeed) : 0; + if (ps.simulationSpace === Space.Local) { + const gravityFactor = -ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, rand)! * 9.8 * dt; + this._gravity.x = 0.0; + this._gravity.y = gravityFactor; + this._gravity.z = 0.0; + this._gravity.w = 1.0; + if (!approx(gravityFactor, 0.0, EPSILON)) { + if (ps.node.parent) { + this._gravity = this._gravity.transformMat4(_node_parent_inv); + } + this._gravity = this._gravity.transformMat4(this._localMat); + + p.velocity.x += this._gravity.x; + p.velocity.y += this._gravity.y; + p.velocity.z += this._gravity.z; } - this._gravity = this._gravity.transformMat4(this._localMat); - - p.velocity.x += this._gravity.x; - p.velocity.y += this._gravity.y; - p.velocity.z += this._gravity.z; - } - } else { + } else { // apply gravity. - p.velocity.y -= ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, pseudoRandom(p.randomSeed))! * 9.8 * dt; + p.velocity.y -= ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, rand)! * 9.8 * dt; + } } Vec3.copy(p.ultimateVelocity, p.velocity); @@ -261,8 +264,8 @@ export class ParticleCuller { if (this._processor.getInfo()!.renderMode === RenderMode.Mesh) { const mesh: Mesh | null = this._processor.getInfo().mesh; if (mesh && mesh.struct.minPosition && mesh.struct.maxPosition) { - const meshAABB: AABB = new AABB(); - AABB.fromPoints(meshAABB, mesh.struct.minPosition, mesh.struct.maxPosition); + const meshAABB: geometry.AABB = new geometry.AABB(); + geometry.AABB.fromPoints(meshAABB, mesh.struct.minPosition, mesh.struct.maxPosition); const meshMax = Math.max(meshAABB.halfExtents.x, meshAABB.halfExtents.y, meshAABB.halfExtents.z); meshSize.set(meshMax, meshMax, meshMax); } @@ -291,7 +294,7 @@ export class ParticleCuller { public calculatePositions () { this._emit(this._particleSystem.capacity, 0, this._particlesAll); - const rand = pseudoRandom(randomRangeInt(0, INT_MAX)); + const rand = isCurveTwoValues(this._particleSystem.startLifetime) ? pseudoRandom(randomRangeInt(0, bits.INT_MAX)) : 0; this._updateParticles(0, this._particlesAll); this._calculateBounding(true); this._updateParticles(this._particleSystem.startLifetime.evaluate(0, rand), this._particlesAll); diff --git a/cocos/particle/particle-general-function.ts b/cocos/particle/particle-general-function.ts index c82a86f3db4..d7c8004b5db 100644 --- a/cocos/particle/particle-general-function.ts +++ b/cocos/particle/particle-general-function.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Mat4, Quat, random, randomRange, randomRangeInt, Vec2, Vec3 } from '../core/math'; -import { sign } from '../core/math/bits'; +import { Mat4, Quat, random, randomRange, randomRangeInt, Vec2, Vec3, bits } from '../core/math'; +import CurveRange from './animator/curve-range'; +import GradientRange from './animator/gradient-range'; import { Space } from './enum'; export const particleEmitZAxis = new Vec3(0, 0, -1); @@ -131,5 +131,34 @@ export function randomSign () { if (sgn === 0) { sgn++; } - return sign(sgn); + return bits.sign(sgn); +} + +/** + * @en judge if the CurveRange use TwoCurves or TwoConstants + * @zh 判断粒子的CurveRange是否使用了 TwoCurves 或者 TwoConstants + */ +export function isCurveTwoValues (curve: CurveRange): boolean { + const Mode = CurveRange.Mode; + switch (curve.mode) { + case Mode.TwoCurves: + case Mode.TwoConstants: + return true; + default: + return false; + } +} +/** + * @en judge if the GradientRange TwoValues use TwoGradients or TwoColors + * @zh 判断粒子的 GradientRange 是否使用了 TwoGradients 或者 TwoColors + */ +export function isGradientTwoValues (color: GradientRange): boolean { + const Mode = GradientRange.Mode; + switch (color.mode) { + case Mode.TwoGradients: + case Mode.TwoColors: + return true; + default: + return false; + } } diff --git a/cocos/particle/particle-system.ts b/cocos/particle/particle-system.ts index 2eb8dfb7c34..7f65b61d312 100644 --- a/cocos/particle/particle-system.ts +++ b/cocos/particle/particle-system.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ // eslint-disable-next-line max-len import { ccclass, help, executeInEditMode, executionOrder, menu, tooltip, displayOrder, type, range, displayName, formerlySerializedAs, override, radian, serializable, visible } from 'cc.decorator'; @@ -29,8 +28,7 @@ import { EDITOR } from 'internal:constants'; import { Renderer } from '../misc/renderer'; import { ModelRenderer } from '../misc/model-renderer'; import { Material } from '../asset/assets/material'; -import { Mat4, pseudoRandom, Quat, randomRangeInt, Vec2, Vec3 } from '../core/math'; -import { INT_MAX } from '../core/math/bits'; +import { Mat4, pseudoRandom, Quat, randomRangeInt, Vec2, Vec3, CCBoolean, CCFloat, bits, geometry, cclegacy } from '../core'; import { scene } from '../render-scene'; import ColorOverLifetimeModule from './animator/color-overtime'; import CurveRange, { Mode } from './animator/curve-range'; @@ -49,19 +47,26 @@ import ParticleSystemRenderer from './renderer/particle-system-renderer-data'; import TrailModule from './renderer/trail'; import { IParticleSystemRenderer } from './renderer/particle-system-renderer-base'; import { PARTICLE_MODULE_PROPERTY } from './particle'; -import { legacyCC } from '../core/global-exports'; import { TransformBit } from '../scene-graph/node-enum'; -import { AABB, intersect } from '../core/geometry'; import { Camera } from '../render-scene/scene'; import { ParticleCuller } from './particle-culler'; import { NoiseModule } from './animator/noise-module'; -import { CCBoolean, CCFloat } from '../core'; const _world_mat = new Mat4(); const _world_rol = new Quat(); const superMaterials = Object.getOwnPropertyDescriptor(Renderer.prototype, 'sharedMaterials')!; +/** + * @en + * Particle system component, which can make many effects such as smoke and fire. + * Include some interesting modules and components such as Velocity Overtime, Force Overtime, Trail and Noise. + * You can open these modules to see how the particles animate. + * @zh + * 粒子系统能够用来制作许多特效,例如 烟雾和火焰。 + * 包含一些有趣的模块,例如 速度模块,受力模块,拖尾模块和噪声模块。 + * 打开这些模块可以看到粒子如何进行变化。 + */ @ccclass('cc.ParticleSystem') @help('i18n:cc.ParticleSystem') @menu('Effects/ParticleSystem') @@ -69,9 +74,10 @@ const superMaterials = Object.getOwnPropertyDescriptor(Renderer.prototype, 'shar @executeInEditMode export class ParticleSystem extends ModelRenderer { /** + * @en Maximum particle capacity to generate. * @zh 粒子系统能生成的最大粒子数量。 */ - @range([0, Number.POSITIVE_INFINITY]) + @range([0, Number.POSITIVE_INFINITY, 1]) @displayOrder(1) @tooltip('i18n:particle_system.capacity') public get capacity () { @@ -88,6 +94,7 @@ export class ParticleSystem extends ModelRenderer { } /** + * @en The initial color of the particle. * @zh 粒子初始颜色。 */ @type(GradientRange) @@ -96,70 +103,86 @@ export class ParticleSystem extends ModelRenderer { @tooltip('i18n:particle_system.startColor') public startColor = new GradientRange(); + /** + * @en The space of particle scaling. + * @zh 计算粒子缩放的空间。 + */ @type(Space) @serializable @displayOrder(9) @tooltip('i18n:particle_system.scaleSpace') public scaleSpace = Space.Local; + /** + * @en Whether to modify particle size on XYZ axis. + * @zh 是否需要修改粒子在三个轴上的大小。 + */ @serializable @displayOrder(10) @tooltip('i18n:particle_system.startSize3D') public startSize3D = false; /** - * @zh 粒子初始大小。 + * @en The initial X size of the particle. + * @zh 粒子初始x轴方向大小。 */ @formerlySerializedAs('startSize') - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @type(CurveRange) @displayOrder(10) @tooltip('i18n:particle_system.startSizeX') public startSizeX = new CurveRange(); /** - * @zh 粒子初始大小。 + * @en The initial Y size of the particle. + * @zh 粒子初始y轴方向大小。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(10) @tooltip('i18n:particle_system.startSizeY') @visible(function (this: ParticleSystem): boolean { return this.startSize3D; }) public startSizeY = new CurveRange(); /** - * @zh 粒子初始大小。 + * @en The initial Z size of the particle. + * @zh 粒子初始z轴方向大小。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(10) @tooltip('i18n:particle_system.startSizeZ') @visible(function (this: ParticleSystem): boolean { return this.startSize3D; }) public startSizeZ = new CurveRange(); /** + * @en The initial velocity of the particle. * @zh 粒子初始速度。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(11) @tooltip('i18n:particle_system.startSpeed') public startSpeed = new CurveRange(); + /** + * @en Whether to modify particle rotation on XYZ axis. + * @zh 是否需要修改粒子在三个轴上的旋转。 + */ @serializable @displayOrder(12) @tooltip('i18n:particle_system.startRotation3D') public startRotation3D = false; /** - * @zh 粒子初始旋转角度。 + * @en The initial rotation angle of the particle on X axis. + * @zh 粒子初始x轴旋转角度。 */ @type(CurveRange) @serializable - @range([-1, 1]) + @range([-2 * Math.PI, 2 * Math.PI]) @radian @displayOrder(12) @tooltip('i18n:particle_system.startRotationX') @@ -167,11 +190,12 @@ export class ParticleSystem extends ModelRenderer { public startRotationX = new CurveRange(); /** - * @zh 粒子初始旋转角度。 + * @en The initial rotation angle of the particle on Y axis. + * @zh 粒子初始y轴旋转角度。 */ @type(CurveRange) @serializable - @range([-1, 1]) + @range([-2 * Math.PI, 2 * Math.PI]) @radian @displayOrder(12) @tooltip('i18n:particle_system.startRotationY') @@ -179,38 +203,41 @@ export class ParticleSystem extends ModelRenderer { public startRotationY = new CurveRange(); /** - * @zh 粒子初始旋转角度。 + * @en The initial rotation angle of the particle on Z axis. + * @zh 粒子初始z轴旋转角度。 */ @type(CurveRange) @formerlySerializedAs('startRotation') - @range([-1, 1]) + @range([-2 * Math.PI, 2 * Math.PI]) @radian @displayOrder(12) @tooltip('i18n:particle_system.startRotationZ') - @visible(function (this: ParticleSystem): boolean { return this.startRotation3D; }) public startRotationZ = new CurveRange(); /** + * @en The time delay to start emission after the particle system starts running. * @zh 粒子系统开始运行后,延迟粒子发射的时间。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(6) @tooltip('i18n:particle_system.startDelay') public startDelay = new CurveRange(); /** + * @en Particle life time. * @zh 粒子生命周期。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(7) @tooltip('i18n:particle_system.startLifetime') public startLifetime = new CurveRange(); /** + * @en Particle system duration time. * @zh 粒子系统运行时间。 */ @serializable @@ -219,6 +246,7 @@ export class ParticleSystem extends ModelRenderer { public duration = 5.0; /** + * @en Whether the particle system is looping. * @zh 粒子系统是否循环播放。 */ @serializable @@ -227,6 +255,7 @@ export class ParticleSystem extends ModelRenderer { public loop = true; /** + * @en Play one round before start this particle system. * @zh 选中之后,粒子系统会以已播放完一轮之后的状态开始播放(仅当循环播放启用时有效)。 */ @displayOrder(3) @@ -243,6 +272,7 @@ export class ParticleSystem extends ModelRenderer { } /** + * @en The simulation space of the particle system, it could be world, local or custom. * @zh 选择粒子系统所在的坐标系[[Space]]。
*/ @type(Space) @@ -264,6 +294,7 @@ export class ParticleSystem extends ModelRenderer { } /** + * @en The simulation speed of the particle system. * @zh 控制整个粒子系统的更新速度。 */ @serializable @@ -272,6 +303,7 @@ export class ParticleSystem extends ModelRenderer { public simulationSpeed = 1.0; /** + * @en Automatically start playing after particle system initialized. * @zh 粒子系统加载后是否自动开始播放。 */ @serializable @@ -280,37 +312,40 @@ export class ParticleSystem extends ModelRenderer { public playOnAwake = true; /** + * @en The gravity of the particle system. * @zh 粒子受重力影响的重力系数。 */ @type(CurveRange) @serializable - @range([-1, 1]) @displayOrder(13) @tooltip('i18n:particle_system.gravityModifier') public gravityModifier = new CurveRange(); // emission module /** - * @zh 每秒发射的粒子数。 + * @en The value curve of emission rate over time. + * @zh 随时间推移发射的粒子数的变化曲线。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, 2147483647]) @displayOrder(14) @tooltip('i18n:particle_system.rateOverTime') public rateOverTime = new CurveRange(); /** - * @zh 每移动单位距离发射的粒子数。 + * @en The value curve of emission rate over distance. + * @zh 每移动单位距离发射的粒子数的变化曲线。 */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, 2147483647]) @displayOrder(15) @tooltip('i18n:particle_system.rateOverDistance') public rateOverDistance = new CurveRange(); /** + * @en Burst triggers of the particle system. * @zh 设定在指定时间发射指定数量的粒子的 burst 的数量。 */ @type([Burst]) @@ -320,7 +355,8 @@ export class ParticleSystem extends ModelRenderer { public bursts: Burst[] = []; /** - * @en Enable particle culling switch. Open it to enable particle culling. If enabled will generate emitter bounding box and emitters outside the frustum will be culled. + * @en Enable particle culling switch. Open it to enable particle culling. + * If enabled will generate emitter bounding box and emitters outside the frustum will be culled. * @zh 粒子剔除开关,如果打开将会生成一个发射器包围盒,包围盒在相机外发射器将被剔除。 */ @type(CCBoolean) @@ -330,7 +366,7 @@ export class ParticleSystem extends ModelRenderer { this._renderCulling = value; if (value) { if (!this._boundingBox) { - this._boundingBox = new AABB(); + this._boundingBox = new geometry.AABB(); this._calculateBounding(false); } } @@ -361,6 +397,10 @@ export class ParticleSystem extends ModelRenderer { @serializable _cullingMode = CullingMode.Pause; + /** + * @en Emitter culling mode. + * @zh 发射器的各种剔除模式。 + */ public static CullingMode = CullingMode; /** @@ -470,13 +510,14 @@ export class ParticleSystem extends ModelRenderer { @type(ColorOverLifetimeModule) _colorOverLifetimeModule: ColorOverLifetimeModule | null = null; /** + * @en The module controlling particle's color over life time. * @zh 颜色控制模块。 */ @type(ColorOverLifetimeModule) @displayOrder(23) @tooltip('i18n:particle_system.colorOverLifetimeModule') public get colorOverLifetimeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._colorOverLifetimeModule) { this._colorOverLifetimeModule = new ColorOverLifetimeModule(); this._colorOverLifetimeModule.bindTarget(this.processor); @@ -494,13 +535,14 @@ export class ParticleSystem extends ModelRenderer { @type(ShapeModule) _shapeModule: ShapeModule | null = null; /** + * @en The module controlling emitter's shape. * @zh 粒子发射器模块。 */ @type(ShapeModule) @displayOrder(17) @tooltip('i18n:particle_system.shapeModule') public get shapeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._shapeModule) { this._shapeModule = new ShapeModule(); this._shapeModule.onInit(this); @@ -518,13 +560,14 @@ export class ParticleSystem extends ModelRenderer { @type(SizeOvertimeModule) _sizeOvertimeModule: SizeOvertimeModule | null = null; /** + * @en The module controlling particle's size over time. * @zh 粒子大小模块。 */ @type(SizeOvertimeModule) @displayOrder(21) @tooltip('i18n:particle_system.sizeOvertimeModule') public get sizeOvertimeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._sizeOvertimeModule) { this._sizeOvertimeModule = new SizeOvertimeModule(); this._sizeOvertimeModule.bindTarget(this.processor); @@ -542,13 +585,14 @@ export class ParticleSystem extends ModelRenderer { @type(VelocityOvertimeModule) _velocityOvertimeModule: VelocityOvertimeModule | null = null; /** + * @en The module controlling particle's velocity over time. * @zh 粒子速度模块。 */ @type(VelocityOvertimeModule) @displayOrder(18) @tooltip('i18n:particle_system.velocityOvertimeModule') public get velocityOvertimeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._velocityOvertimeModule) { this._velocityOvertimeModule = new VelocityOvertimeModule(); this._velocityOvertimeModule.bindTarget(this.processor); @@ -566,13 +610,14 @@ export class ParticleSystem extends ModelRenderer { @type(ForceOvertimeModule) _forceOvertimeModule: ForceOvertimeModule | null = null; /** + * @en The module controlling the force applied to particles over time. * @zh 粒子加速度模块。 */ @type(ForceOvertimeModule) @displayOrder(19) @tooltip('i18n:particle_system.forceOvertimeModule') public get forceOvertimeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._forceOvertimeModule) { this._forceOvertimeModule = new ForceOvertimeModule(); this._forceOvertimeModule.bindTarget(this.processor); @@ -591,13 +636,14 @@ export class ParticleSystem extends ModelRenderer { _limitVelocityOvertimeModule: LimitVelocityOvertimeModule | null = null; /** + * @en The module which limits the velocity applied to particles over time, only supported in CPU particle system. * @zh 粒子限制速度模块(只支持 CPU 粒子)。 */ @type(LimitVelocityOvertimeModule) @displayOrder(20) @tooltip('i18n:particle_system.limitVelocityOvertimeModule') public get limitVelocityOvertimeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._limitVelocityOvertimeModule) { this._limitVelocityOvertimeModule = new LimitVelocityOvertimeModule(); this._limitVelocityOvertimeModule.bindTarget(this.processor); @@ -615,13 +661,14 @@ export class ParticleSystem extends ModelRenderer { @type(RotationOvertimeModule) _rotationOvertimeModule: RotationOvertimeModule | null = null; /** + * @en The module controlling the rotation of particles over time. * @zh 粒子旋转模块。 */ @type(RotationOvertimeModule) @displayOrder(22) @tooltip('i18n:particle_system.rotationOvertimeModule') public get rotationOvertimeModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._rotationOvertimeModule) { this._rotationOvertimeModule = new RotationOvertimeModule(); this._rotationOvertimeModule.bindTarget(this.processor); @@ -639,13 +686,14 @@ export class ParticleSystem extends ModelRenderer { @type(TextureAnimationModule) _textureAnimationModule: TextureAnimationModule | null = null; /** + * @en The module controlling the texture animation of particles. * @zh 贴图动画模块。 */ @type(TextureAnimationModule) @displayOrder(24) @tooltip('i18n:particle_system.textureAnimationModule') public get textureAnimationModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._textureAnimationModule) { this._textureAnimationModule = new TextureAnimationModule(); this._textureAnimationModule.bindTarget(this.processor); @@ -660,11 +708,19 @@ export class ParticleSystem extends ModelRenderer { } // noise module + /** + * @en Noise module which can add some interesting effects. + * @zh 噪声模块能够增加许多有趣的特效。 + */ @type(NoiseModule) private _noiseModule: NoiseModule | null = null; - + /** + * @en The module controlling noise map applied to the particles, only supported in CPU particle system. + * @zh 噪声动画模块,仅支持 CPU 粒子。 + */ @type(NoiseModule) @displayOrder(24) + @tooltip('i18n:particle_system.noiseModule') public get noiseModule () { if (EDITOR) { if (!this._noiseModule) { @@ -684,17 +740,16 @@ export class ParticleSystem extends ModelRenderer { @type(TrailModule) _trailModule: TrailModule | null = null; /** + * @en The module controlling the trail module. * @zh 粒子轨迹模块。 */ @type(TrailModule) @displayOrder(25) @tooltip('i18n:particle_system.trailModule') public get trailModule () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { if (!this._trailModule) { this._trailModule = new TrailModule(); - this._trailModule.onInit(this); - this._trailModule.onEnable(); } } return this._trailModule; @@ -706,6 +761,10 @@ export class ParticleSystem extends ModelRenderer { } // particle system renderer + /** + * @en Particle system renderer (CPU or GPU). + * @zh 粒子系统渲染器(CPU 还是 GPU)。 + */ @type(ParticleSystemRenderer) @serializable @displayOrder(26) @@ -727,7 +786,7 @@ export class ParticleSystem extends ModelRenderer { private _oldWPos: Vec3; private _curWPos: Vec3; - private _boundingBox: AABB | null; + private _boundingBox: geometry.AABB | null; private _culler: ParticleCuller | null; private _oldPos: Vec3 | null; private _curPos: Vec3 | null; @@ -750,6 +809,10 @@ export class ParticleSystem extends ModelRenderer { @serializable private _simulationSpace = Space.Local; + /** + * @en Particle update processor (update every particle). + * @zh 粒子更新器(负责更新每个粒子)。 + */ public processor: IParticleSystemRenderer = null!; constructor () { @@ -795,7 +858,7 @@ export class ParticleSystem extends ModelRenderer { // HACK, TODO this.renderer.onInit(this); if (this._shapeModule) this._shapeModule.onInit(this); - if (this._trailModule && !this.renderer.useGPU) { + if (this._trailModule && !this.renderer.useGPU && this._trailModule.enable) { this._trailModule.onInit(this); } this.bindModule(); @@ -854,6 +917,10 @@ export class ParticleSystem extends ModelRenderer { } } + /** + * @en Bind module to particle processor. + * @zh 把模块绑定到粒子更新函数上。 + */ public bindModule () { if (this._colorOverLifetimeModule) this._colorOverLifetimeModule.bindTarget(this.processor); if (this._sizeOvertimeModule) this._sizeOvertimeModule.bindTarget(this.processor); @@ -871,7 +938,7 @@ export class ParticleSystem extends ModelRenderer { // } /** - * @en play particle system + * @en Play particle system. * @zh 播放粒子效果。 */ public play () { @@ -905,7 +972,7 @@ export class ParticleSystem extends ModelRenderer { } /** - * @en pause particle system + * @en Pause particle system. * @zh 暂停播放粒子效果。 */ public pause () { @@ -929,7 +996,7 @@ export class ParticleSystem extends ModelRenderer { } /** - * @en stop particle system + * @en Stop particle system. * @zh 停止播放粒子。 */ public stop () { @@ -973,7 +1040,8 @@ export class ParticleSystem extends ModelRenderer { } /** - * @zh 获取当前粒子数量 + * @en Get current particle capacity. + * @zh 获取当前粒子数量。 */ public getParticleCount () { return this.processor.getParticleCount(); @@ -986,6 +1054,9 @@ export class ParticleSystem extends ModelRenderer { Vec2.set(this._customData1, x, y); } + /** + * @ignore + */ public setCustomData2 (x, y) { Vec2.set(this._customData2, x, y); } @@ -998,7 +1069,7 @@ export class ParticleSystem extends ModelRenderer { this._trailModule._detachFromScene(); } } - legacyCC.director.off(legacyCC.Director.EVENT_BEFORE_COMMIT, this.beforeRender, this); + cclegacy.director.off(cclegacy.Director.EVENT_BEFORE_COMMIT, this.beforeRender, this); // this._system.remove(this); this.processor.onDestroy(); if (this._trailModule) this._trailModule.destroy(); @@ -1011,15 +1082,15 @@ export class ParticleSystem extends ModelRenderer { protected onEnable () { super.onEnable(); - legacyCC.director.on(legacyCC.Director.EVENT_BEFORE_COMMIT, this.beforeRender, this); - if (this.playOnAwake && (!EDITOR || legacyCC.GAME_VIEW)) { + cclegacy.director.on(cclegacy.Director.EVENT_BEFORE_COMMIT, this.beforeRender, this); + if (this.playOnAwake && (!EDITOR || cclegacy.GAME_VIEW)) { this.play(); } this.processor.onEnable(); if (this._trailModule) this._trailModule.onEnable(); } protected onDisable () { - legacyCC.director.off(legacyCC.Director.EVENT_BEFORE_COMMIT, this.beforeRender, this); + cclegacy.director.off(cclegacy.Director.EVENT_BEFORE_COMMIT, this.beforeRender, this); this.processor.onDisable(); if (this._trailModule) this._trailModule.onDisable(); if (this._boundingBox) { @@ -1038,7 +1109,7 @@ export class ParticleSystem extends ModelRenderer { this._culler = new ParticleCuller(this); } this._culler.calculatePositions(); - AABB.fromPoints(this._boundingBox, this._culler.minPos, this._culler.maxPos); + geometry.AABB.fromPoints(this._boundingBox, this._culler.minPos, this._culler.maxPos); if (forceRefresh) { this.aabbHalfX = this._boundingBox.halfExtents.x; this.aabbHalfY = this._boundingBox.halfExtents.y; @@ -1081,7 +1152,7 @@ export class ParticleSystem extends ModelRenderer { this._isSimulating = true; } else { if (!this._boundingBox) { - this._boundingBox = new AABB(); + this._boundingBox = new geometry.AABB(); this._calculateBounding(false); } @@ -1109,15 +1180,15 @@ export class ParticleSystem extends ModelRenderer { let culled = true; if (cameraLst !== undefined && this._boundingBox) { for (let i = 0; i < cameraLst.length; ++i) { - const camera:Camera = cameraLst[i]; + const camera: Camera = cameraLst[i]; const visibility = camera.visibility; if ((visibility & this.node.layer) === this.node.layer) { - if (EDITOR && !legacyCC.GAME_VIEW) { - if (camera.name === 'Editor Camera' && intersect.aabbFrustum(this._boundingBox, camera.frustum)) { + if (EDITOR && !cclegacy.GAME_VIEW) { + if (camera.name === 'Editor Camera' && geometry.intersect.aabbFrustum(this._boundingBox, camera.frustum)) { culled = false; break; } - } else if (intersect.aabbFrustum(this._boundingBox, camera.frustum)) { + } else if (geometry.intersect.aabbFrustum(this._boundingBox, camera.frustum)) { culled = false; break; } @@ -1195,15 +1266,21 @@ export class ParticleSystem extends ModelRenderer { } } } - } - protected beforeRender () { - if (!this._isPlaying) return; - this.processor.beforeRender(); - if (this._trailModule && this._trailModule.enable) { - this._trailModule.beforeRender(); + if (!this.renderer.useGPU && this._trailModule && this._trailModule.enable) { + // @ts-expect-error private property access + if (!this._trailModule._inited) { + this._trailModule.clear(); + this._trailModule.destroy(); + this._trailModule.onInit(this); + // Rebuild trail buffer + this._trailModule.enable = false; + this._trailModule.enable = true; + } } + } + protected beforeRender () { if (this.getParticleCount() <= 0) { if (this.processor.getModel()?.scene) { this.processor.detachFromScene(); @@ -1215,6 +1292,13 @@ export class ParticleSystem extends ModelRenderer { } else if (!this.processor.getModel()?.scene) { this._needAttach = true; } + + if (!this._isPlaying) return; + + this.processor.beforeRender(); + if (this._trailModule && this._trailModule.enable) { + this._trailModule.beforeRender(); + } } protected _onVisibilityChange (val) { @@ -1249,7 +1333,7 @@ export class ParticleSystem extends ModelRenderer { particle.particleSystem = this; particle.reset(); - const rand = pseudoRandom(randomRangeInt(0, INT_MAX)); + const rand = pseudoRandom(randomRangeInt(0, bits.INT_MAX)); if (this._shapeModule && this._shapeModule.enable) { this._shapeModule.emit(particle); @@ -1345,10 +1429,13 @@ export class ParticleSystem extends ModelRenderer { } // emit by rateOverDistance - this.node.getWorldPosition(this._curWPos); - const distance = Vec3.distance(this._curWPos, this._oldWPos); - Vec3.copy(this._oldWPos, this._curWPos); - this._emitRateDistanceCounter += distance * this.rateOverDistance.evaluate(this._time / this.duration, 1)!; + const rateOverDistance = this.rateOverDistance.evaluate(this._time / this.duration, 1)!; + if (rateOverDistance > 0) { + Vec3.copy(this._oldWPos, this._curWPos); + this.node.getWorldPosition(this._curWPos); + const distance = Vec3.distance(this._curWPos, this._oldWPos); + this._emitRateDistanceCounter += distance * rateOverDistance; + } if (this._emitRateDistanceCounter > 1) { const emitNum = Math.floor(this._emitRateDistanceCounter); @@ -1427,18 +1514,34 @@ export class ParticleSystem extends ModelRenderer { return this._isPlaying; } + /** + * @en Query particle system is paused or not. + * @zh 获取粒子系统当前是否已经暂停运行。 + */ get isPaused () { return this._isPaused; } + /** + * @en Query particle system is stopped or not. + * @zh 获取粒子系统当前是否已经停止。 + */ get isStopped () { return this._isStopped; } + /** + * @en Query particle system is emitting or not. + * @zh 获取粒子系统当前是否还在发射。 + */ get isEmitting () { return this._isEmitting; } + /** + * @en Query particle system simulation time. + * @zh 获取粒子系统运行时间。 + */ get time () { return this._time; } @@ -1451,6 +1554,13 @@ export class ParticleSystem extends ModelRenderer { return this.dataCulling ? props.filter((p) => !PARTICLE_MODULE_PROPERTY.includes(p) || (this[p] && this[p].enable)) : props; } + /** + * @en Gets the preview of noise texture. + * @zh 获取噪声图预览。 + * @param width @en Noise texture width @zh 噪声图宽度 + * @param height @en Noise texture height @zh 噪声图高度 + * @returns @en Noise texture RGB pixel array @zh 噪声图 RGB 纹理数组 + */ public getNoisePreview (width: number, height: number): number[] { const out: number[] = []; if (this.processor) { diff --git a/cocos/particle/particle-utils.ts b/cocos/particle/particle-utils.ts index c5685309d0d..e2781a74b94 100644 --- a/cocos/particle/particle-utils.ts +++ b/cocos/particle/particle-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,24 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { instantiate } from '../core/data'; -import { CCObject } from '../core/data/object'; +import { instantiate } from '../serialization'; +import { CCObject, Pool } from '../core'; import { Director, director } from '../game/director'; -import { Pool } from '../core/memop'; import { Node } from '../scene-graph'; import { ParticleSystem } from './particle-system'; +import CurveRange from './animator/curve-range'; +import GradientRange from './animator/gradient-range'; +/** + * @en Contains some util functions for particle system. Such as create and destroy particle system. + * @zh 该类包含一些粒子系统的工具函数,例如创建和销毁粒子系统。 + */ export class ParticleUtils { /** - * @en instantiate particle system from prefab - * @zh 从 prefab 实例化粒子系统 + * @en Instantiate particle system from prefab. + * @zh 从 prefab 实例化粒子系统。 */ public static instantiate (prefab) { if (!this.registeredSceneEvent) { @@ -47,6 +51,11 @@ export class ParticleUtils { return this.particleSystemPool.get(prefab._uuid)!.alloc(); } + /** + * @en Destroy particle system prefab. + * @zh 销毁创建出来的粒子系统prefab。 + * @param prefab @en Particle system prefab to destroy. @zh 要销毁的粒子系统prefab。 + */ public static destroy (prefab) { if (this.particleSystemPool.has(prefab._prefab.asset._uuid)) { this.stop(prefab); @@ -54,17 +63,28 @@ export class ParticleUtils { } } + /** + * @en Play particle system. + * @zh 播放粒子系统。 + * @param rootNode @en Root node contains the particle system. @zh 包含粒子系统的根节点。 + */ public static play (rootNode: Node) { for (const ps of rootNode.getComponentsInChildren(ParticleSystem)) { (ps).play(); } } + /** + * @en Stop particle system. + * @zh 停止播放粒子系统。 + * @param rootNode @en Root node contains the particle system. @zh 包含粒子系统的根节点。 + */ public static stop (rootNode: Node) { for (const ps of rootNode.getComponentsInChildren(ParticleSystem)) { (ps).stop(); } } + private static particleSystemPool: Map> = new Map>(); private static registeredSceneEvent = false; diff --git a/cocos/particle/particle.ts b/cocos/particle/particle.ts index a7e2e9c09a7..cd72c2131a5 100644 --- a/cocos/particle/particle.ts +++ b/cocos/particle/particle.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Color, Vec3, Mat4, Quat } from '../core/math'; +import { Color, Vec3, Mat4, Quat } from '../core'; import { ParticleSystem } from './particle-system'; import { IParticleSystemRenderer } from './renderer/particle-system-renderer-base'; diff --git a/cocos/particle/renderer/particle-system-renderer-base.ts b/cocos/particle/renderer/particle-system-renderer-base.ts index 7cd2977aa84..5afa9a11240 100644 --- a/cocos/particle/renderer/particle-system-renderer-base.ts +++ b/cocos/particle/renderer/particle-system-renderer-base.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Component } from '../../scene-graph'; import { Attribute, deviceManager, Feature } from '../../gfx'; @@ -30,7 +29,7 @@ import ParticleSystemRenderer from './particle-system-renderer-data'; import { Material } from '../../asset/assets'; import { Particle, IParticleModule } from '../particle'; import { RenderMode } from '../enum'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { Pass } from '../../render-scene'; export interface IParticleSystemRenderer { @@ -111,7 +110,7 @@ export abstract class ParticleSystemRendererBase implements IParticleSystemRende public onDestroy () { if (this._model) { - legacyCC.director.root.destroyModel(this._model); + cclegacy.director.root.destroyModel(this._model); this._model = null; } } @@ -148,7 +147,7 @@ export abstract class ParticleSystemRendererBase implements IParticleSystemRende protected _initModel () { if (!this._model) { - this._model = legacyCC.director.root.createModel(ParticleBatchModel); + this._model = cclegacy.director.root.createModel(ParticleBatchModel); this._model!.setCapacity(this._particleSystem.capacity); this._model!.visFlags = this._particleSystem.visibility; } diff --git a/cocos/particle/renderer/particle-system-renderer-cpu.ts b/cocos/particle/renderer/particle-system-renderer-cpu.ts index 6bfa5994945..ee123ed1e1d 100644 --- a/cocos/particle/renderer/particle-system-renderer-cpu.ts +++ b/cocos/particle/renderer/particle-system-renderer-cpu.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { builtinResMgr } from '../../asset/asset-manager'; import { Material } from '../../asset/assets'; import { AttributeName, Format, Attribute, FormatInfos } from '../../gfx'; -import { Mat4, Vec2, Vec3, Vec4, pseudoRandom, Quat, EPSILON, approx } from '../../core/math'; -import { RecyclePool } from '../../core/memop'; +import { Mat4, Vec2, Vec3, Vec4, pseudoRandom, Quat, EPSILON, approx, RecyclePool, cclegacy } from '../../core'; import { MaterialInstance, IMaterialInstanceInfo } from '../../render-scene/core/material-instance'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { AlignmentSpace, RenderMode, Space } from '../enum'; @@ -39,7 +37,8 @@ import { Camera } from '../../render-scene/scene/camera'; import { Pass } from '../../render-scene'; import { ParticleNoise } from '../noise'; import { NoiseModule } from '../animator/noise-module'; -import { legacyCC } from '../../core/global-exports'; +import { isCurveTwoValues } from '../particle-general-function'; +import { Mode } from '../animator/curve-range'; const _tempAttribUV = new Vec3(); const _tempWorldTrans = new Mat4(); @@ -311,9 +310,9 @@ export default class ParticleSystemRendererCPU extends ParticleSystemRendererBas const cameraLst: Camera[]|undefined = this._particleSystem.node.scene.renderScene?.cameras; if (cameraLst !== undefined) { for (let i = 0; i < cameraLst?.length; ++i) { - const camera:Camera = cameraLst[i]; + const camera: Camera = cameraLst[i]; // eslint-disable-next-line max-len - const checkCamera: boolean = (!EDITOR || legacyCC.GAME_VIEW) ? (camera.visibility & this._particleSystem.node.layer) === this._particleSystem.node.layer : camera.name === 'Editor Camera'; + const checkCamera: boolean = (!EDITOR || cclegacy.GAME_VIEW) ? (camera.visibility & this._particleSystem.node.layer) === this._particleSystem.node.layer : camera.name === 'Editor Camera'; if (checkCamera) { Quat.fromViewUp(_node_rot, camera.forward); break; @@ -369,15 +368,19 @@ export default class ParticleSystemRendererCPU extends ParticleSystemRendererBas trailModule.update(); } - if (ps.simulationSpace === Space.Local) { - const r:Quat = ps.node.getRotation(); - Mat4.fromQuat(this._localMat, r); - this._localMat.transpose(); // just consider rotation, use transpose as invert - } + const useGravity = !ps.gravityModifier.isZero(); + if (useGravity) { + if (ps.simulationSpace === Space.Local) { + const r: Quat = ps.node.getRotation(); + Mat4.fromQuat(this._localMat, r); + this._localMat.transpose(); // just consider rotation, use transpose as invert + } - if (ps.node.parent) { - ps.node.parent.getWorldMatrix(_tempParentInverse); - _tempParentInverse.invert(); + if (ps.node.parent) { + const r: Quat = ps.node.parent.getWorldRotation(); + Mat4.fromQuat(_tempParentInverse, r); + _tempParentInverse.transpose(); + } } for (let i = 0; i < this._particles!.length; ++i) { @@ -394,27 +397,31 @@ export default class ParticleSystemRendererCPU extends ParticleSystemRendererBas continue; } - if (ps.simulationSpace === Space.Local) { - const gravityFactor = -ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, pseudoRandom(p.randomSeed))! * 9.8 * dt; - this._gravity.x = 0.0; - this._gravity.y = gravityFactor; - this._gravity.z = 0.0; - this._gravity.w = 1.0; - if (!approx(gravityFactor, 0.0, EPSILON)) { - if (ps.node.parent) { - this._gravity = this._gravity.transformMat4(_tempParentInverse); + // apply gravity when both the mode is not Constant and the value is not 0. + if (useGravity) { + const rand = isCurveTwoValues(ps.gravityModifier) ? pseudoRandom(p.randomSeed) : 0; + if (ps.simulationSpace === Space.Local) { + const time = 1 - p.remainingLifetime / p.startLifetime; + const gravityFactor = -ps.gravityModifier.evaluate(time, rand)! * 9.8 * dt; + this._gravity.x = 0.0; + this._gravity.y = gravityFactor; + this._gravity.z = 0.0; + this._gravity.w = 1.0; + if (!approx(gravityFactor, 0.0, EPSILON)) { + if (ps.node.parent) { + this._gravity = this._gravity.transformMat4(_tempParentInverse); + } + this._gravity = this._gravity.transformMat4(this._localMat); + + p.velocity.x += this._gravity.x; + p.velocity.y += this._gravity.y; + p.velocity.z += this._gravity.z; } - this._gravity = this._gravity.transformMat4(this._localMat); - - p.velocity.x += this._gravity.x; - p.velocity.y += this._gravity.y; - p.velocity.z += this._gravity.z; + } else { + // apply gravity. + p.velocity.y -= ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, rand)! * 9.8 * dt; } - } else { - // apply gravity. - p.velocity.y -= ps.gravityModifier.evaluate(1 - p.remainingLifetime / p.startLifetime, pseudoRandom(p.randomSeed))! * 9.8 * dt; } - Vec3.copy(p.ultimateVelocity, p.velocity); this._runAnimateList.forEach((value) => { @@ -687,7 +694,7 @@ export default class ParticleSystemRendererCPU extends ParticleSystemRendererBas let enable = false; const roationModule = this._particleSystem._rotationOvertimeModule; - enable = roationModule && roationModule.enable; + enable = roationModule ? roationModule.enable : false; this._defines[ROTATION_OVER_TIME_MODULE_ENABLE] = enable; this._defines[INSTANCE_PARTICLE] = this._useInstance; diff --git a/cocos/particle/renderer/particle-system-renderer-data.ts b/cocos/particle/renderer/particle-system-renderer-data.ts index 427b41365d4..dc038c5fe40 100644 --- a/cocos/particle/renderer/particle-system-renderer-data.ts +++ b/cocos/particle/renderer/particle-system-renderer-data.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, type, serializable, disallowAnimation, visible } from 'cc.decorator'; import { Mesh } from '../../3d'; @@ -31,8 +30,7 @@ import ParticleSystemRendererCPU from './particle-system-renderer-cpu'; import ParticleSystemRendererGPU from './particle-system-renderer-gpu'; import { director } from '../../game/director'; import { Device, Format, FormatFeatureBit } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; -import { errorID, warnID } from '../../core'; +import { errorID, warnID, cclegacy } from '../../core'; function isSupportGPUParticle () { const device: Device = director.root!.device; @@ -41,7 +39,7 @@ function isSupportGPUParticle () { return true; } - legacyCC.warn('Maybe the device has restrictions on vertex textures or does not support float textures.'); + cclegacy.warn('Maybe the device has restrictions on vertex textures or does not support float textures.'); return false; } diff --git a/cocos/particle/renderer/particle-system-renderer-gpu.ts b/cocos/particle/renderer/particle-system-renderer-gpu.ts index 45fb37426a1..9333d82902e 100644 --- a/cocos/particle/renderer/particle-system-renderer-gpu.ts +++ b/cocos/particle/renderer/particle-system-renderer-gpu.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { builtinResMgr } from '../../asset/asset-manager'; import { Material, Texture2D } from '../../asset/assets'; import { Component } from '../../scene-graph'; import { AttributeName, Format, Attribute, API, deviceManager, FormatInfos } from '../../gfx'; -import { Mat4, Vec2, Vec4, Quat, Vec3 } from '../../core/math'; +import { Mat4, Vec2, Vec4, Quat, Vec3, cclegacy } from '../../core'; import { MaterialInstance, IMaterialInstanceInfo } from '../../render-scene/core/material-instance'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { AlignmentSpace, RenderMode, Space } from '../enum'; @@ -38,7 +37,6 @@ import { Pass } from '../../render-scene/core/pass'; import { packCurveRangeXYZ, packCurveRangeZ, packCurveRangeXYZW, packCurveRangeN, packCurveRangeXY } from '../animator/curve-range'; import { ParticleSystemRendererBase } from './particle-system-renderer-base'; import { Camera } from '../../render-scene/scene/camera'; -import { legacyCC } from '../../core/global-exports'; const _tempWorldTrans = new Mat4(); const _tempVec4 = new Vec4(); @@ -75,7 +73,7 @@ const _vert_attr_name = { DIR_LIFE: 'a_dir_life', RANDOM_SEED: 'a_rndSeed', VERT_SIZE_FID: 'a_size_fid', - VERT_ROTATION_RND: 'a_rotation_rnd', + VERT_ROTATION: 'a_rotation', VERT_UV: 'a_uv', }; @@ -104,18 +102,20 @@ const _gpu_vert_attr_mesh = [ const _gpu_vert_attr_ins = [ new Attribute(_vert_attr_name.POSITION_STARTTIME, Format.RGBA32F, false, 0, true), new Attribute(_vert_attr_name.VERT_SIZE_FID, Format.RGBA32F, false, 0, true), - new Attribute(_vert_attr_name.VERT_ROTATION_RND, Format.RGBA32F, false, 0, true), + new Attribute(_vert_attr_name.VERT_ROTATION, Format.RGB32F, false, 0, true), new Attribute(_vert_attr_name.COLOR, Format.RGBA32F, false, 0, true), new Attribute(_vert_attr_name.DIR_LIFE, Format.RGBA32F, false, 0, true), + new Attribute(_vert_attr_name.RANDOM_SEED, Format.R32F, false, 0, true), new Attribute(_vert_attr_name.VERT_UV, Format.RGB32F, false, 1), ]; const _gpu_vert_attr_mesh_ins = [ new Attribute(_vert_attr_name.POSITION_STARTTIME, Format.RGBA32F, false, 0, true), new Attribute(_vert_attr_name.VERT_SIZE_FID, Format.RGBA32F, false, 0, true), - new Attribute(_vert_attr_name.VERT_ROTATION_RND, Format.RGBA32F, false, 0, true), + new Attribute(_vert_attr_name.VERT_ROTATION, Format.RGB32F, false, 0, true), new Attribute(_vert_attr_name.COLOR, Format.RGBA32F, false, 0, true), new Attribute(_vert_attr_name.DIR_LIFE, Format.RGBA32F, false, 0, true), + new Attribute(_vert_attr_name.RANDOM_SEED, Format.R32F, false, 0, true), new Attribute(AttributeName.ATTR_TEX_COORD, Format.RGB32F, false, 1), // mesh uv new Attribute(AttributeName.ATTR_TEX_COORD3, Format.RGB32F, false, 1), // mesh position new Attribute(AttributeName.ATTR_NORMAL, Format.RGB32F, false, 1), // mesh normal @@ -269,9 +269,9 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas const cameraLst: Camera[]|undefined = this._particleSystem.node.scene.renderScene?.cameras; if (cameraLst !== undefined) { for (let i = 0; i < cameraLst?.length; ++i) { - const camera:Camera = cameraLst[i]; + const camera: Camera = cameraLst[i]; // eslint-disable-next-line max-len - const checkCamera: boolean = (!EDITOR || legacyCC.GAME_VIEW) ? (camera.visibility & this._particleSystem.node.layer) === this._particleSystem.node.layer : camera.name === 'Editor Camera'; + const checkCamera: boolean = (!EDITOR || cclegacy.GAME_VIEW) ? (camera.visibility & this._particleSystem.node.layer) === this._particleSystem.node.layer : camera.name === 'Editor Camera'; if (checkCamera) { Quat.fromViewUp(_node_rot, camera.forward); break; @@ -305,7 +305,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas } public updateParticles (dt: number) { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { const mat: Material | null = this._particleSystem.getMaterialInstance(0) || this._defaultMat; this._particleSystem.node.getWorldMatrix(_tempWorldTrans); @@ -374,7 +374,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas let enable = false; // force const forceModule = this._particleSystem._forceOvertimeModule; - enable = forceModule && forceModule.enable; + enable = forceModule ? forceModule.enable : false; this._defines[FORCE_OVER_TIME_MODULE_ENABLE] = enable; if (enable) { const packed = packCurveRangeXYZ(this._forceTexture, this._forceData, _sample_num, forceModule.x, forceModule.y, forceModule.z); @@ -392,7 +392,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas // velocity const velocityModule = this._particleSystem._velocityOvertimeModule; - enable = velocityModule && velocityModule.enable; + enable = velocityModule ? velocityModule.enable : false; this._defines[VELOCITY_OVER_TIME_MODULE_ENABLE] = enable; if (enable) { const packed = packCurveRangeXYZW(this._velocityTexture, this._velocityData, _sample_num, velocityModule.x, velocityModule.y, @@ -411,7 +411,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas // color module const colorModule = this._particleSystem._colorOverLifetimeModule; - enable = colorModule && colorModule.enable; + enable = colorModule ? colorModule.enable : false; this._defines[COLOR_OVER_TIME_MODULE_ENABLE] = enable; if (enable) { const packed = packGradientRange(this._colorTexture, this._colorData, _sample_num, colorModule.color); @@ -427,7 +427,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas // rotation module const roationModule = this._particleSystem._rotationOvertimeModule; - enable = roationModule && roationModule.enable; + enable = roationModule ? roationModule.enable : false; this._defines[ROTATION_OVER_TIME_MODULE_ENABLE] = enable; if (enable) { let packed; @@ -451,7 +451,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas // size module const sizeModule = this._particleSystem._sizeOvertimeModule; - enable = sizeModule && sizeModule.enable; + enable = sizeModule ? sizeModule.enable : false; this._defines[SIZE_OVER_TIME_MODULE_ENABLE] = enable; if (enable) { let packed; @@ -474,7 +474,7 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas // texture module const textureModule = this._particleSystem._textureAnimationModule; - enable = textureModule && textureModule.enable; + enable = textureModule ? textureModule.enable : false; this._defines[TEXTURE_ANIMATION_MODULE_ENABLE] = enable; if (enable) { // eslint-disable-next-line max-len diff --git a/cocos/particle/renderer/trail.ts b/cocos/particle/renderer/trail.ts index 67636b7e1e4..e02c073045d 100644 --- a/cocos/particle/renderer/trail.ts +++ b/cocos/particle/renderer/trail.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, type, serializable, range } from 'cc.decorator'; import { Material } from '../../asset/assets/material'; @@ -29,16 +28,13 @@ import { RenderingSubMesh } from '../../asset/assets/rendering-sub-mesh'; import { director } from '../../game/director'; import { AttributeName, BufferUsageBit, Format, FormatInfos, MemoryUsageBit, PrimitiveMode, Device, Attribute, Buffer, IndirectBuffer, BufferInfo, DrawInfo, DRAW_INFO_SIZE } from '../../gfx'; -import { Color, Mat4, Quat, toRadian, Vec3 } from '../../core/math'; -import { Pool } from '../../core/memop'; +import { Color, Mat4, Quat, toRadian, Vec3, Pool, warnID, cclegacy } from '../../core'; import { scene } from '../../render-scene'; import CurveRange from '../animator/curve-range'; import GradientRange from '../animator/gradient-range'; import { Space, TextureMode, TrailMode } from '../enum'; import { Particle } from '../particle'; -import { legacyCC } from '../../core/global-exports'; import { TransformBit } from '../../scene-graph/node-enum'; -import { warnID } from '../../core'; const PRE_TRIANGLE_INDEX = 1; const NEXT_TRIANGLE_INDEX = 1 << 2; @@ -216,7 +212,7 @@ export default class TrailModule { */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(3) @tooltip('i18n:trailSegment.lifeTime') public lifeTime = new CurveRange(); @@ -281,7 +277,7 @@ export default class TrailModule { */ @type(CurveRange) @serializable - @range([0, 1]) + @range([0, Number.POSITIVE_INFINITY]) @displayOrder(10) @tooltip('i18n:trailSegment.widthRatio') public widthRatio = new CurveRange(); @@ -339,6 +335,7 @@ export default class TrailModule { private _iBuffer: Uint16Array | null = null; private _needTransform = false; private _material: Material | null = null; + private _inited: boolean; constructor () { this._iaInfo = new IndirectBuffer([new DrawInfo()]); @@ -356,6 +353,8 @@ export default class TrailModule { } this._particleTrail = new Map(); + + this._inited = false; } public onInit (ps) { @@ -377,6 +376,7 @@ export default class TrailModule { if (this._enable) { this.enable = this._enable; } + this._inited = true; } public onEnable () { @@ -643,7 +643,7 @@ export default class TrailModule { return; } - this._trailModel = legacyCC.director.root.createModel(scene.Model); + this._trailModel = cclegacy.director.root.createModel(scene.Model); } private rebuild () { diff --git a/cocos/physics-2d/box2d/instantiate.ts b/cocos/physics-2d/box2d/instantiate.ts index 44b1bee3546..7dba695a258 100644 --- a/cocos/physics-2d/box2d/instantiate.ts +++ b/cocos/physics-2d/box2d/instantiate.ts @@ -1,4 +1,28 @@ -import { select } from '../framework/physics-selector'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { selector } from '../framework/physics-selector'; import { b2PhysicsWorld } from './physics-world'; import { b2RigidBody2D } from './rigid-body'; import { b2BoxShape } from './shapes/box-shape-2d'; @@ -13,20 +37,24 @@ import { b2FixedJoint } from './joints/fixed-joint'; import { b2WheelJoint } from './joints/wheel-joint'; import { b2HingeJoint } from './joints/hinge-joint'; -select('box2d', { - PhysicsWorld: b2PhysicsWorld, - RigidBody: b2RigidBody2D, - - BoxShape: b2BoxShape, - CircleShape: b2CircleShape, - PolygonShape: b2PolygonShape, - - MouseJoint: b2MouseJoint, - DistanceJoint: b2DistanceJoint, - SpringJoint: b2SpringJoint, - RelativeJoint: b2RelativeJoint, - SliderJoint: b2SliderJoint, - FixedJoint: b2FixedJoint, - WheelJoint: b2WheelJoint, - HingeJoint: b2HingeJoint, +import { Game, game } from '../../game'; + +game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { + selector.register('box2d', { + PhysicsWorld: b2PhysicsWorld, + RigidBody: b2RigidBody2D, + + BoxShape: b2BoxShape, + CircleShape: b2CircleShape, + PolygonShape: b2PolygonShape, + + MouseJoint: b2MouseJoint, + DistanceJoint: b2DistanceJoint, + SpringJoint: b2SpringJoint, + RelativeJoint: b2RelativeJoint, + SliderJoint: b2SliderJoint, + FixedJoint: b2FixedJoint, + WheelJoint: b2WheelJoint, + HingeJoint: b2HingeJoint, + }); }); diff --git a/cocos/physics-2d/box2d/joints/distance-joint.ts b/cocos/physics-2d/box2d/joints/distance-joint.ts index 3b86cfb1236..92d4e36b913 100644 --- a/cocos/physics-2d/box2d/joints/distance-joint.ts +++ b/cocos/physics-2d/box2d/joints/distance-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IDistanceJoint } from '../../spec/i-physics-joint'; import { b2Joint } from './joint-2d'; diff --git a/cocos/physics-2d/box2d/joints/fixed-joint.ts b/cocos/physics-2d/box2d/joints/fixed-joint.ts index ffbed905ffb..155da9db813 100644 --- a/cocos/physics-2d/box2d/joints/fixed-joint.ts +++ b/cocos/physics-2d/box2d/joints/fixed-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IFixedJoint } from '../../spec/i-physics-joint'; import { b2Joint } from './joint-2d'; diff --git a/cocos/physics-2d/box2d/joints/hinge-joint.ts b/cocos/physics-2d/box2d/joints/hinge-joint.ts index d869f26999b..6b0f0a70ff2 100644 --- a/cocos/physics-2d/box2d/joints/hinge-joint.ts +++ b/cocos/physics-2d/box2d/joints/hinge-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IHingeJoint } from '../../spec/i-physics-joint'; import { HingeJoint2D } from '../../framework'; @@ -52,8 +76,8 @@ export class b2HingeJoint extends b2Joint implements IHingeJoint { def.motorSpeed = toRadian(comp.motorSpeed); def.enableLimit = comp.enableLimit; - def.lowerAngle = comp.lowerAngle; - def.upperAngle = comp.upperAngle; + def.lowerAngle = toRadian(comp.lowerAngle); + def.upperAngle = toRadian(comp.upperAngle); return def; } } diff --git a/cocos/physics-2d/box2d/joints/joint-2d.ts b/cocos/physics-2d/box2d/joints/joint-2d.ts index 0e0438db33b..f222947671b 100644 --- a/cocos/physics-2d/box2d/joints/joint-2d.ts +++ b/cocos/physics-2d/box2d/joints/joint-2d.ts @@ -1,7 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IJoint2D } from '../../spec/i-physics-joint'; import { Joint2D, PhysicsSystem2D, RigidBody2D } from '../../framework'; import { b2PhysicsWorld } from '../physics-world'; +import { Vec2 } from '../../../core'; export class b2Joint implements IJoint2D { get impl () { @@ -52,13 +77,20 @@ export class b2Joint implements IJoint2D { return; } + def.bodyA = this._body!.impl!.impl; const connectedBody = comp.connectedBody; - if (!connectedBody || !connectedBody.enabledInHierarchy) { + //if connected body is set but not active, return + if (connectedBody && !connectedBody.enabledInHierarchy) { return; } - def.bodyA = this._body!.impl!.impl; - def.bodyB = connectedBody.impl!.impl; + //if connected body is not set, use scene origin as connected body + if (!connectedBody) { + def.bodyB = (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).groundBodyImpl; + } else { + def.bodyB = connectedBody.impl!.impl; + } + def.collideConnected = comp.collideConnected; this._b2joint = (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).impl.CreateJoint(def); @@ -80,7 +112,6 @@ export class b2Joint implements IJoint2D { } isValid () { - return this._b2joint && this._body && this._body.impl - && this._jointComp && this._jointComp.connectedBody && this._jointComp.connectedBody.impl; + return this._b2joint && this._body && this._body.impl && this._jointComp; } } diff --git a/cocos/physics-2d/box2d/joints/mouse-joint.ts b/cocos/physics-2d/box2d/joints/mouse-joint.ts index d2a4881f5ac..2811aab97e0 100644 --- a/cocos/physics-2d/box2d/joints/mouse-joint.ts +++ b/cocos/physics-2d/box2d/joints/mouse-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IMouseJoint } from '../../spec/i-physics-joint'; import { b2Joint } from './joint-2d'; diff --git a/cocos/physics-2d/box2d/joints/relative-joint.ts b/cocos/physics-2d/box2d/joints/relative-joint.ts index 50c050b9018..4817e0f2496 100644 --- a/cocos/physics-2d/box2d/joints/relative-joint.ts +++ b/cocos/physics-2d/box2d/joints/relative-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2, { MotorJointDef, Vec2 } from '@cocos/box2d'; import { IRelativeJoint } from '../../spec/i-physics-joint'; import { b2Joint } from './joint-2d'; diff --git a/cocos/physics-2d/box2d/joints/slider-joint.ts b/cocos/physics-2d/box2d/joints/slider-joint.ts index 91a5c0b2f69..5b713e42825 100644 --- a/cocos/physics-2d/box2d/joints/slider-joint.ts +++ b/cocos/physics-2d/box2d/joints/slider-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { ISliderJoint } from '../../spec/i-physics-joint'; import { b2Joint } from './joint-2d'; diff --git a/cocos/physics-2d/box2d/joints/spring-joint.ts b/cocos/physics-2d/box2d/joints/spring-joint.ts index 764bbf40bbf..61ee071e8fb 100644 --- a/cocos/physics-2d/box2d/joints/spring-joint.ts +++ b/cocos/physics-2d/box2d/joints/spring-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { ISpringJoint } from '../../spec/i-physics-joint'; import { b2Joint } from './joint-2d'; diff --git a/cocos/physics-2d/box2d/joints/wheel-joint.ts b/cocos/physics-2d/box2d/joints/wheel-joint.ts index a7d1ab414c1..ea33ea50674 100644 --- a/cocos/physics-2d/box2d/joints/wheel-joint.ts +++ b/cocos/physics-2d/box2d/joints/wheel-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IWheelJoint } from '../../spec/i-physics-joint'; import { WheelJoint2D } from '../../framework'; diff --git a/cocos/physics-2d/box2d/physics-contact.ts b/cocos/physics-2d/box2d/physics-contact.ts index 04c75c391cc..9c145f7ec9f 100644 --- a/cocos/physics-2d/box2d/physics-contact.ts +++ b/cocos/physics-2d/box2d/physics-contact.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import b2 from '@cocos/box2d'; +import { b2Contact } from '@cocos/box2d/src/box2d'; import { Vec2 } from '../../core'; import { PHYSICS_2D_PTM_RATIO } from '../framework/physics-types'; import { Collider2D, Contact2DType, PhysicsSystem2D } from '../framework'; import { b2Shape2D } from './shapes/shape-2d'; import { IPhysics2DContact, IPhysics2DImpulse, IPhysics2DManifoldPoint, IPhysics2DWorldManifold } from '../spec/i-physics-contact'; -export type b2ContactExtends = b2.Contact & { - m_userData: any -} - const pools: PhysicsContact[] = []; // temp world manifold @@ -68,40 +64,29 @@ const impulse: IPhysics2DImpulse = { }; export class PhysicsContact implements IPhysics2DContact { - static get (b2contact: b2ContactExtends) { - let c = pools.pop(); - - if (!c) { - c = new PhysicsContact(); - } - - c.init(b2contact); - return c; + public constructor (b2contact: b2Contact) { + this.ref = 1; + this.init(b2contact); } - static put (b2contact: b2ContactExtends) { - const c: PhysicsContact = b2contact.m_userData as PhysicsContact; - if (!c) return; + public ref = 0; + public status = Contact2DType.None; - pools.push(c); - c.reset(); - } + public colliderA: Collider2D | null = null; + public colliderB: Collider2D | null = null; - colliderA: Collider2D | null = null; - colliderB: Collider2D | null = null; - - disabled = false; - disabledOnce = false; + public disabled = false; + public disabledOnce = false; private _impulse: b2.ContactImpulse | null = null; private _inverted = false; - private _b2contact: b2ContactExtends | null = null; + private _b2contact: b2Contact | null = null; _setImpulse (impulse: b2.ContactImpulse | null) { this._impulse = impulse; } - init (b2contact: b2ContactExtends) { + private init (b2contact) { this.colliderA = (b2contact.m_fixtureA.m_userData as b2Shape2D).collider; this.colliderB = (b2contact.m_fixtureB.m_userData as b2Shape2D).collider; this.disabled = false; @@ -111,7 +96,6 @@ export class PhysicsContact implements IPhysics2DContact { this._inverted = false; this._b2contact = b2contact; - b2contact.m_userData = this; } reset () { @@ -123,8 +107,6 @@ export class PhysicsContact implements IPhysics2DContact { this.colliderB = null; this.disabled = false; this._impulse = null; - - this._b2contact!.m_userData = null; this._b2contact = null; } @@ -211,47 +193,6 @@ export class PhysicsContact implements IPhysics2DContact { return impulse; } - emit (contactType) { - let func; - switch (contactType) { - case Contact2DType.BEGIN_CONTACT: - func = 'onBeginContact'; - break; - case Contact2DType.END_CONTACT: - func = 'onEndContact'; - break; - case Contact2DType.PRE_SOLVE: - func = 'onPreSolve'; - break; - case Contact2DType.POST_SOLVE: - func = 'onPostSolve'; - break; - } - - const colliderA = this.colliderA; - const colliderB = this.colliderB; - - const bodyA = colliderA!.body; - const bodyB = colliderB!.body; - - if (bodyA!.enabledContactListener) { - colliderA?.emit(contactType, colliderA, colliderB, this); - } - - if (bodyB!.enabledContactListener) { - colliderB?.emit(contactType, colliderB, colliderA, this); - } - - if (bodyA!.enabledContactListener || bodyB!.enabledContactListener) { - PhysicsSystem2D.instance.emit(contactType, colliderA, colliderB, this); - } - - if (this.disabled || this.disabledOnce) { - this.setEnabled(false); - this.disabledOnce = false; - } - } - setEnabled (value) { this._b2contact!.SetEnabled(value); } diff --git a/cocos/physics-2d/box2d/physics-world.ts b/cocos/physics-2d/box2d/physics-world.ts index 4953c5a516d..f07abd246ae 100644 --- a/cocos/physics-2d/box2d/physics-world.ts +++ b/cocos/physics-2d/box2d/physics-world.ts @@ -1,10 +1,33 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { EDITOR } from 'internal:constants'; import { IPhysicsWorld } from '../spec/i-physics-world'; -import { IVec2Like, Vec3, Quat, toRadian, Vec2, toDegree, Rect, CCObject } from '../../core'; +import { IVec2Like, Vec3, Quat, toRadian, Vec2, toDegree, Rect, CCObject, js, cclegacy } from '../../core'; import { PHYSICS_2D_PTM_RATIO, ERaycast2DType, ERigidBody2DType } from '../framework/physics-types'; -import { array } from '../../core/utils/js'; import { Canvas } from '../../2d/framework'; import { Graphics } from '../../2d/components'; @@ -12,11 +35,9 @@ import { b2RigidBody2D } from './rigid-body'; import { PhysicsContactListener } from './platform/physics-contact-listener'; import { PhysicsAABBQueryCallback } from './platform/physics-aabb-query-callback'; import { PhysicsRayCastCallback } from './platform/physics-ray-cast-callback'; -import { PhysicsContact, b2ContactExtends } from './physics-contact'; -import { Contact2DType, Collider2D, RaycastResult2D } from '../framework'; +import { Collider2D, RaycastResult2D } from '../framework'; import { b2Shape2D } from './shapes/shape-2d'; import { PhysicsDebugDraw } from './platform/physics-debug-draw'; -import { legacyCC } from '../../core/global-exports'; import { Node, find, Layers } from '../../scene-graph'; import { director } from '../../game'; @@ -34,6 +55,7 @@ export class b2PhysicsWorld implements IPhysicsWorld { protected _bodies: b2RigidBody2D[] = []; protected _animatedBodies: b2RigidBody2D[] = []; protected _rotationAxis: Vec3 = new Vec3(); + protected _physicsGroundBody: b2.Body; protected _contactListener: PhysicsContactListener; protected _aabbQueryCallback: PhysicsAABBQueryCallback; @@ -43,16 +65,17 @@ export class b2PhysicsWorld implements IPhysicsWorld { return this._world; } + get groundBodyImpl () { + return this._physicsGroundBody; + } + constructor () { this._world = new b2.World(new b2.Vec2(0, -10)); - + const tempBodyDef = new b2.BodyDef(); + //tempBodyDef.position.Set(480 / PHYSICS_2D_PTM_RATIO, 320 / PHYSICS_2D_PTM_RATIO);//temporary + this._physicsGroundBody = this._world.CreateBody(tempBodyDef); const listener = new PhysicsContactListener(); - listener.setBeginContact(this._onBeginContact); - listener.setEndContact(this._onEndContact); - listener.setPreSolve(this._onPreSolve); - listener.setPostSolve(this._onPostSolve); this._world.SetContactListener(listener); - this._contactListener = listener; this._aabbQueryCallback = new PhysicsAABBQueryCallback(); @@ -67,7 +90,7 @@ export class b2PhysicsWorld implements IPhysicsWorld { return this._debugDrawFlags; } set debugDrawFlags (v) { - if (EDITOR && !legacyCC.GAME_VIEW) return; + if (EDITOR && !cclegacy.GAME_VIEW) return; if (!v) { if (this._debugGraphics) { @@ -79,7 +102,7 @@ export class b2PhysicsWorld implements IPhysicsWorld { } _checkDebugDrawValid () { - if (EDITOR && !legacyCC.GAME_VIEW) return; + if (EDITOR && !cclegacy.GAME_VIEW) return; if (!this._debugGraphics || !this._debugGraphics.isValid) { let canvas = find('Canvas'); if (!canvas) { @@ -224,8 +247,7 @@ export class b2PhysicsWorld implements IPhysicsWorld { syncSceneToPhysics () { const bodies = this._bodies; for (let i = 0; i < bodies.length; i++) { - bodies[i].syncRotationToPhysics(); - bodies[i].syncPositionToPhysics(); + bodies[i].syncSceneToPhysics(); } } @@ -292,21 +314,14 @@ export class b2PhysicsWorld implements IPhysicsWorld { this._world.DestroyBody(body.impl); body._imp = null; } - array.remove(this._bodies, body); + js.array.remove(this._bodies, body); const comp = body.rigidBody; if (comp.type === ERigidBody2DType.Animated) { - array.remove(this._animatedBodies, body); + js.array.remove(this._animatedBodies, body); } } - registerContactFixture (fixture: b2.Fixture) { - this._contactListener.registerContactFixture(fixture); - } - unregisterContactFixture (fixture: b2.Fixture) { - this._contactListener.unregisterContactFixture(fixture); - } - testPoint (point: Vec2): readonly Collider2D[] { const x = tempVec2_1.x = point.x / PHYSICS_2D_PTM_RATIO; const y = tempVec2_1.y = point.y / PHYSICS_2D_PTM_RATIO; @@ -363,39 +378,7 @@ export class b2PhysicsWorld implements IPhysicsWorld { this._world.DrawDebugData(); } - _onBeginContact (b2contact: b2ContactExtends) { - const c = PhysicsContact.get(b2contact); - c.emit(Contact2DType.BEGIN_CONTACT); - } - - _onEndContact (b2contact: b2ContactExtends) { - const c = b2contact.m_userData as PhysicsContact; - if (!c) { - return; - } - c.emit(Contact2DType.END_CONTACT); - - PhysicsContact.put(b2contact); - } - - _onPreSolve (b2contact: b2ContactExtends) { - const c = b2contact.m_userData as PhysicsContact; - if (!c) { - return; - } - - c.emit(Contact2DType.PRE_SOLVE); - } - - _onPostSolve (b2contact: b2ContactExtends, impulse: b2.ContactImpulse) { - const c: PhysicsContact = b2contact.m_userData as PhysicsContact; - if (!c) { - return; - } - - // impulse only survive during post sole callback - c._setImpulse(impulse); - c.emit(Contact2DType.POST_SOLVE); - c._setImpulse(null); + finalizeContactEvent () { + this._contactListener.finalizeContactEvent(); } } diff --git a/cocos/physics-2d/box2d/platform/physics-aabb-query-callback.ts b/cocos/physics-2d/box2d/platform/physics-aabb-query-callback.ts index 7663647d03d..f06bd06ddc1 100644 --- a/cocos/physics-2d/box2d/platform/physics-aabb-query-callback.ts +++ b/cocos/physics-2d/box2d/platform/physics-aabb-query-callback.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import b2 from '@cocos/box2d'; import { Vec2 } from '../../../core'; diff --git a/cocos/physics-2d/box2d/platform/physics-contact-listener.ts b/cocos/physics-2d/box2d/platform/physics-contact-listener.ts index efec64b4a7f..4c640930950 100644 --- a/cocos/physics-2d/box2d/platform/physics-contact-listener.ts +++ b/cocos/physics-2d/box2d/platform/physics-contact-listener.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,74 +20,120 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import b2 from '@cocos/box2d'; -import { remove } from '../../../core/utils/array'; +import { assert, js } from '../../../core'; +import { fastRemove } from '../../../core/utils/array'; +import { Contact2DType, PhysicsSystem2D } from '../../framework'; +import { PhysicsContact } from '../physics-contact'; +import { b2Shape2D } from '../shapes/shape-2d'; export class PhysicsContactListener extends b2.ContactListener { - _contactFixtures: b2.Fixture[] = []; - - _BeginContact: Function | null = null; - _EndContact: Function | null = null; - _PreSolve: Function | null = null; - _PostSolve: Function | null = null; - - setBeginContact (cb) { - this._BeginContact = cb; + static readonly _contactMap = new Map(); + + private getContactKey (contact: b2.Contact) { + const colliderA = (contact.m_fixtureA.m_userData as b2Shape2D).collider; + const colliderB = (contact.m_fixtureB.m_userData as b2Shape2D).collider; + let key = colliderA.uuid + colliderB.uuid; + if (colliderA.uuid > colliderB.uuid) { + key = colliderB.uuid + colliderA.uuid; + } + return key; } - setEndContact (cb) { - this._EndContact = cb; + BeginContact (contact: b2.Contact) { + const key = this.getContactKey(contact); + + if (PhysicsContactListener._contactMap.has(key)) { + const retContact = PhysicsContactListener._contactMap.get(key)!; + retContact.ref++; + //console.log(' collision++', key, 'current ref is:', retContact.ref); + if (retContact.status === Contact2DType.END_CONTACT) { + retContact.status = Contact2DType.STAY_CONTACT; + //console.log(' set as stay'); + } else if (retContact.status !== Contact2DType.STAY_CONTACT) { + retContact.status = Contact2DType.BEGIN_CONTACT; + //console.log(' set as enter'); + } + } else { + //console.log(' new collision', key, 'current ref is:', 1); + const retCollision = new PhysicsContact(contact); + PhysicsContactListener._contactMap.set(key, retCollision); + retCollision.status = Contact2DType.BEGIN_CONTACT; + } } - setPreSolve (cb) { - this._PreSolve = cb; - } + EndContact (contact: b2.Contact) { + const key = this.getContactKey(contact); - setPostSolve (cb) { - this._PostSolve = cb; + const retContact = PhysicsContactListener._contactMap.get(key); + assert(retContact); + + retContact.ref--; + //console.log(' collision--', key, 'current ref is:', retCollision.ref); + if (retContact.ref <= 0) { + //console.log(' set as exit'); + retContact.status = Contact2DType.END_CONTACT; + } } - BeginContact (contact: b2.Contact) { - if (!this._BeginContact) return; + PreSolve (contact: b2.Contact, oldManifold: b2.Manifold) { + } - const fixtureA = contact.GetFixtureA(); - const fixtureB = contact.GetFixtureB(); - const fixtures = this._contactFixtures; + PostSolve (contact: b2.Contact, impulse: b2.ContactImpulse) { + } - (contact as any)._shouldReport = false; + public finalizeContactEvent () { + PhysicsContactListener._contactMap.forEach((contact: PhysicsContact, key: string) => { + //console.log('forEach', key, collision); + if (contact.status === Contact2DType.END_CONTACT) { + PhysicsContactListener._contactMap.delete(key); + //console.log(' report end collision', key, 'current ref is:', contact.ref); + this.emit(Contact2DType.END_CONTACT, contact); + } else if (contact.status === Contact2DType.BEGIN_CONTACT) { + contact.status = Contact2DType.STAY_CONTACT; + //console.log(' report enter collision', key, 'current ref is:', contact.ref); + this.emit(Contact2DType.BEGIN_CONTACT, contact); + } else if (contact.status === Contact2DType.STAY_CONTACT) { + //console.log(' report stay collision', key, 'current ref is:', contact.ref); + this.emit(Contact2DType.STAY_CONTACT, contact); + } + }); + } - if (fixtures.indexOf(fixtureA) !== -1 || fixtures.indexOf(fixtureB) !== -1) { - (contact as any)._shouldReport = true; // for quick check whether this contact should report - this._BeginContact(contact); + private emit (contactType, contact: PhysicsContact) { + const colliderA = contact.colliderA; + const colliderB = contact.colliderB; + if (!colliderA || !colliderB) { + return; } - } - EndContact (contact: b2.Contact) { - if (this._EndContact && (contact as any)._shouldReport) { - (contact as any)._shouldReport = false; - this._EndContact(contact); + const bodyA = colliderA.body; + const bodyB = colliderB.body; + //if rigid body doesn't exist, collider will be added to groundRigidbody automatically, + //hence it should emit event + if ((bodyA && !bodyA.enabledInHierarchy) || (bodyB && !bodyB.enabledInHierarchy) || (!bodyA && !bodyB)) { + return; } - } - PreSolve (contact: b2.Contact, oldManifold: b2.Manifold) { - if (this._PreSolve && (contact as any)._shouldReport) { - this._PreSolve(contact, oldManifold); + //bodyA exists and enabledContactListner, or bodyA doesn't exist + if ((bodyA && bodyA.enabledContactListener) || (!bodyA)) { + colliderA?.emit(contactType, colliderA, colliderB, contact); } - } - PostSolve (contact: b2.Contact, impulse: b2.ContactImpulse) { - if (this._PostSolve && (contact as any)._shouldReport) { - this._PostSolve(contact, impulse); + //bodyB exists and enabledContactListner, or bodyB doesn't exist + if ((bodyB && bodyB.enabledContactListener) || (!bodyB)) { + colliderB?.emit(contactType, colliderB, colliderA, contact); } - } - registerContactFixture (fixture) { - this._contactFixtures.push(fixture); - } + if ((bodyA && bodyA.enabledContactListener) || (bodyB && bodyB.enabledContactListener) || !bodyA || !bodyB) { + PhysicsSystem2D.instance.emit(contactType, colliderA, colliderB, contact); + } - unregisterContactFixture (fixture) { - remove(this._contactFixtures, fixture); + if (contact.disabled || contact.disabledOnce) { + contact.setEnabled(false); + contact.disabledOnce = false; + } } } diff --git a/cocos/physics-2d/box2d/platform/physics-debug-draw.ts b/cocos/physics-2d/box2d/platform/physics-debug-draw.ts index f488c66c020..b9ed99e180e 100644 --- a/cocos/physics-2d/box2d/platform/physics-debug-draw.ts +++ b/cocos/physics-2d/box2d/platform/physics-debug-draw.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import b2 from '@cocos/box2d'; import { Color } from '../../../core'; diff --git a/cocos/physics-2d/box2d/platform/physics-ray-cast-callback.ts b/cocos/physics-2d/box2d/platform/physics-ray-cast-callback.ts index 714ea8f42e9..7d6b2c9d34a 100644 --- a/cocos/physics-2d/box2d/platform/physics-ray-cast-callback.ts +++ b/cocos/physics-2d/box2d/platform/physics-ray-cast-callback.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import b2 from '@cocos/box2d'; import { Vec2 } from '../../../core'; diff --git a/cocos/physics-2d/box2d/rigid-body.ts b/cocos/physics-2d/box2d/rigid-body.ts index 5129ed9ab69..8d3ec48fcdb 100644 --- a/cocos/physics-2d/box2d/rigid-body.ts +++ b/cocos/physics-2d/box2d/rigid-body.ts @@ -1,9 +1,33 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { IRigidBody2D } from '../spec/i-rigid-body'; import { RigidBody2D } from '../framework/components/rigid-body-2d'; import { PhysicsSystem2D } from '../framework/physics-system'; import { b2PhysicsWorld } from './physics-world'; -import { Vec2, toRadian, Vec3, IVec2Like, toDegree } from '../../core'; +import { Vec2, toRadian, Vec3, Quat, IVec2Like, toDegree, TWO_PI, HALF_PI } from '../../core'; import { PHYSICS_2D_PTM_RATIO, ERigidBody2DType } from '../framework/physics-types'; import { Node } from '../../scene-graph/node'; @@ -58,17 +82,7 @@ export class b2RigidBody2D implements IRigidBody2D { this.setActive(false); } - _registerNodeEvents () { - const node = this.rigidBody.node; - node.on(NodeEventType.TRANSFORM_CHANGED, this._onNodeTransformChanged, this); - } - - _unregisterNodeEvents () { - const node = this.rigidBody.node; - node.off(NodeEventType.TRANSFORM_CHANGED, this._onNodeTransformChanged, this); - } - - _onNodeTransformChanged (type) { + nodeTransformChanged (type) { if (PhysicsSystem2D.instance.stepping) { return; } @@ -92,9 +106,8 @@ export class b2RigidBody2D implements IRigidBody2D { return; } - this._registerNodeEvents(); - (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).addBody(this); + this.setActive(false); this._inited = true; } @@ -103,7 +116,6 @@ export class b2RigidBody2D implements IRigidBody2D { if (!this._inited) return; (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).removeBody(this); - this._unregisterNodeEvents(); this._inited = false; } @@ -120,8 +132,26 @@ export class b2RigidBody2D implements IRigidBody2D { tempVec2_1.y = (this._animatedPos.y - b2Pos.y) * timeStep; b2body.SetLinearVelocity(tempVec2_1); - const b2Rotation = b2body.GetAngle(); - b2body.SetAngularVelocity((this._animatedAngle - b2Rotation) * timeStep); + //convert b2Rotation to [-PI~PI], which is the same as this._animatedAngle + let b2Rotation = b2body.GetAngle() % (TWO_PI); + if (b2Rotation > Math.PI) { + b2Rotation -= TWO_PI; + } + + //calculate angular velocity + let angularVelocity = (this._animatedAngle - b2Rotation) * timeStep; + if (this._animatedAngle < -HALF_PI && b2Rotation > HALF_PI) { //ccw, crossing PI + angularVelocity = (this._animatedAngle + TWO_PI - b2Rotation) * timeStep; + } if (this._animatedAngle > HALF_PI && b2Rotation < -HALF_PI) { //cw, crossing PI + angularVelocity = (this._animatedAngle - TWO_PI - b2Rotation) * timeStep; + } + + b2body.SetAngularVelocity(angularVelocity); + } + + syncSceneToPhysics () { + const dirty = this._rigidBody.node.hasChangedFlags; + if (dirty) { this.nodeTransformChanged(dirty); } } syncPositionToPhysics (enableAnimated = false) { @@ -152,7 +182,11 @@ export class b2RigidBody2D implements IRigidBody2D { const b2body = this._body; if (!b2body) return; - const rotation = toRadian(this._rigidBody.node.eulerAngles.z); + const rot = this._rigidBody.node.worldRotation; + const euler = tempVec3; + Quat.toEulerInYXZOrder(euler, rot); + const rotation = toRadian(euler.z); + const bodyType = this._rigidBody.type; if (bodyType === ERigidBody2DType.Animated && enableAnimated) { this._animatedAngle = rotation; diff --git a/cocos/physics-2d/box2d/shapes/box-shape-2d.ts b/cocos/physics-2d/box2d/shapes/box-shape-2d.ts index e01aabbfdae..b2bef265a60 100644 --- a/cocos/physics-2d/box2d/shapes/box-shape-2d.ts +++ b/cocos/physics-2d/box2d/shapes/box-shape-2d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { b2Shape2D } from './shape-2d'; import { BoxCollider2D } from '../../framework'; @@ -30,7 +54,7 @@ export class b2BoxShape extends b2Shape2D implements IBoxShape { return wps; } - _createShapes (scaleX: number, scaleY: number) { + _createShapes (scaleX: number, scaleY: number, relativePositionX: number, relativePositionY: number) { scaleX = Math.abs(scaleX); scaleY = Math.abs(scaleY); @@ -38,8 +62,8 @@ export class b2BoxShape extends b2Shape2D implements IBoxShape { const width = comp.size.width / 2 / PHYSICS_2D_PTM_RATIO * scaleX; const height = comp.size.height / 2 / PHYSICS_2D_PTM_RATIO * scaleY; - const offsetX = comp.offset.x / PHYSICS_2D_PTM_RATIO * scaleX; - const offsetY = comp.offset.y / PHYSICS_2D_PTM_RATIO * scaleY; + const offsetX = (relativePositionX + comp.offset.x * scaleX) / PHYSICS_2D_PTM_RATIO; + const offsetY = (relativePositionY + comp.offset.y * scaleY) / PHYSICS_2D_PTM_RATIO; const shape = new b2.PolygonShape(); shape.SetAsBox(width, height, new b2.Vec2(offsetX, offsetY), 0); diff --git a/cocos/physics-2d/box2d/shapes/circle-shape-2d.ts b/cocos/physics-2d/box2d/shapes/circle-shape-2d.ts index 3825e3443b6..1c453ba3cbf 100644 --- a/cocos/physics-2d/box2d/shapes/circle-shape-2d.ts +++ b/cocos/physics-2d/box2d/shapes/circle-shape-2d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { b2Shape2D } from './shape-2d'; import { CircleCollider2D } from '../../framework'; @@ -16,14 +40,14 @@ export class b2CircleShape extends b2Shape2D implements ICircleShape { return this._worldPosition.set(p.x * PHYSICS_2D_PTM_RATIO, p.y * PHYSICS_2D_PTM_RATIO); } - _createShapes (scaleX: number, scaleY: number) { + _createShapes (scaleX: number, scaleY: number, relativePositionX: number, relativePositionY: number) { scaleX = Math.abs(scaleX); scaleY = Math.abs(scaleY); const comp = this.collider as CircleCollider2D; - const offsetX = comp.offset.x / PHYSICS_2D_PTM_RATIO * scaleX; - const offsetY = comp.offset.y / PHYSICS_2D_PTM_RATIO * scaleY; + const offsetX = (relativePositionX + comp.offset.x * scaleX) / PHYSICS_2D_PTM_RATIO; + const offsetY = (relativePositionY + comp.offset.y * scaleY) / PHYSICS_2D_PTM_RATIO; const shape = new b2.CircleShape(); shape.m_radius = comp.radius / PHYSICS_2D_PTM_RATIO * scaleX; diff --git a/cocos/physics-2d/box2d/shapes/polygon-shape-2d.ts b/cocos/physics-2d/box2d/shapes/polygon-shape-2d.ts index a4b5a57c117..6a9a4e4b4a7 100644 --- a/cocos/physics-2d/box2d/shapes/polygon-shape-2d.ts +++ b/cocos/physics-2d/box2d/shapes/polygon-shape-2d.ts @@ -1,10 +1,35 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import b2 from '@cocos/box2d'; import { b2Shape2D } from './shape-2d'; import * as PolygonSeparator from '../../framework/utils/polygon-separator'; +import * as PolygonPartition from '../../framework/utils/polygon-partition'; import { PolygonCollider2D } from '../../framework'; import { PHYSICS_2D_PTM_RATIO } from '../../framework/physics-types'; import { IPolygonShape } from '../../spec/i-physics-shape'; -import { Vec2 } from '../../../core'; +import { Vec2, IVec2Like } from '../../../core'; export class b2PolygonShape extends b2Shape2D implements IPolygonShape { _worldPoints: Vec2[] = []; @@ -24,7 +49,7 @@ export class b2PolygonShape extends b2Shape2D implements IPolygonShape { return this._worldPoints; } - _createShapes (scaleX: number, scaleY: number) { + _createShapes (scaleX: number, scaleY: number, relativePositionX: number, relativePositionY: number) { const shapes: b2.PolygonShape[] = []; const comp = this.collider as PolygonCollider2D; @@ -35,7 +60,12 @@ export class b2PolygonShape extends b2Shape2D implements IPolygonShape { points.length -= 1; } - const polys = PolygonSeparator.ConvexPartition(points); + const polys = PolygonPartition.ConvexPartition(points); + if (!polys) { + console.log('[Physics2D] b2PolygonShape failed to decompose polygon into convex polygons, node name: ', comp.node.name); + return shapes; + } + const offset = comp.offset; for (let i = 0; i < polys.length; i++) { @@ -49,8 +79,8 @@ export class b2PolygonShape extends b2Shape2D implements IPolygonShape { shape = new b2.PolygonShape(); } const p = poly[j]; - const x = (p.x + offset.x) / PHYSICS_2D_PTM_RATIO * scaleX; - const y = (p.y + offset.y) / PHYSICS_2D_PTM_RATIO * scaleY; + const x = (relativePositionX + (p.x + offset.x) * scaleX) / PHYSICS_2D_PTM_RATIO; + const y = (relativePositionY + (p.y + offset.y) * scaleY) / PHYSICS_2D_PTM_RATIO; const v = new b2.Vec2(x, y); vertices.push(v); diff --git a/cocos/physics-2d/box2d/shapes/shape-2d.ts b/cocos/physics-2d/box2d/shapes/shape-2d.ts index 13d2d72ff2f..91bd0b4463c 100644 --- a/cocos/physics-2d/box2d/shapes/shape-2d.ts +++ b/cocos/physics-2d/box2d/shapes/shape-2d.ts @@ -1,8 +1,32 @@ -import b2 from '@cocos/box2d'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import b2, { Vec2 } from '@cocos/box2d'; import { IBaseShape } from '../../spec/i-physics-shape'; import { Collider2D, PhysicsSystem2D, RigidBody2D, PHYSICS_2D_PTM_RATIO } from '../../../../exports/physics-2d-framework'; -import { Rect } from '../../../core'; +import { Rect, Vec3 } from '../../../core'; import { b2PhysicsWorld } from '../physics-world'; import { PhysicsGroup } from '../../../physics/framework/physics-enum'; @@ -10,7 +34,11 @@ const tempFilter = new b2.Filter(); function getFilter (shape: b2Shape2D) { const comp = shape.collider; - tempFilter.categoryBits = comp.group === PhysicsGroup.DEFAULT ? comp.body!.group : comp.group; + if (comp.body) { + tempFilter.categoryBits = comp.group === PhysicsGroup.DEFAULT ? comp.body.group : comp.group; + } else { + tempFilter.categoryBits = comp.group; + } tempFilter.maskBits = PhysicsSystem2D.instance.collisionMatrix[tempFilter.categoryBits]; return tempFilter; } @@ -62,7 +90,9 @@ export class b2Shape2D implements IBaseShape { apply () { this._destroy(); - this._init(); + if (this.collider.enabledInHierarchy) { + this._init(); + } } get worldAABB (): Readonly { @@ -78,6 +108,10 @@ export class b2Shape2D implements IBaseShape { const count = fixture.GetShape().GetChildCount(); for (let j = 0; j < count; j++) { const aabb = fixture.GetAABB(j); + if (fixture.GetShape().m_type === 2) { //b2ShapeType.e_polygonShape + aabb.lowerBound.SelfAddXY(fixture.GetShape().m_radius, fixture.GetShape().m_radius); + aabb.upperBound.SelfSubXY(fixture.GetShape().m_radius, fixture.GetShape().m_radius); + } if (aabb.lowerBound.x < minX) minX = aabb.lowerBound.x; if (aabb.lowerBound.y < minY) minY = aabb.lowerBound.y; if (aabb.upperBound.x > maxX) maxX = aabb.upperBound.x; @@ -103,7 +137,8 @@ export class b2Shape2D implements IBaseShape { return this._fixtures.indexOf(fixture); } - _createShapes (scaleX: number, scaleY: number): b2.Shape[] { + //relativePositionX/Y : relative Position from shape to rigid body + _createShapes (scaleX: number, scaleY: number, relativePositionX: number, relativePositionY: number): b2.Shape[] { return []; } @@ -111,16 +146,21 @@ export class b2Shape2D implements IBaseShape { if (this._inited) return; const comp = this.collider; + const scale = comp.node.worldScale; + // relative Position from shape to rigid body + let relativePosition = Vec3.ZERO; const body = comp.getComponent(RigidBody2D); - if (!body) return; - const innerBody = body.impl?.impl as b2.Body; - if (!innerBody) return; - - const node = body.node; - const scale = node.worldScale; + //if rigid body is not attached to the same node of collider, this b2.shape is attached + // to the groundRigidBody(pos zero, rot zero) + if (body && body.impl && body.impl.impl) { + this._body = body.impl.impl as b2.Body; + } else { + this._body = (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).groundBodyImpl; + relativePosition = comp.node.worldPosition; + } - const shapes = scale.x === 0 && scale.y === 0 ? [] : this._createShapes(scale.x, scale.y); + const shapes = scale.x === 0 && scale.y === 0 ? [] : this._createShapes(scale.x, scale.y, relativePosition.x, relativePosition.y); const filter = getFilter(this); @@ -137,19 +177,13 @@ export class b2Shape2D implements IBaseShape { filter, }; - const fixture = innerBody.CreateFixture(fixDef); + const fixture = this._body.CreateFixture(fixDef); fixture.m_userData = this; - if (body.enabledContactListener) { - (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).registerContactFixture(fixture); - } - this._shapes.push(shape); this._fixtures.push(fixture); } - this._body = innerBody; - this._inited = true; } @@ -161,9 +195,6 @@ export class b2Shape2D implements IBaseShape { for (let i = fixtures.length - 1; i >= 0; i--) { const fixture = fixtures[i]; - fixture.m_userData = null; - - (PhysicsSystem2D.instance.physicsWorld as b2PhysicsWorld).unregisterContactFixture(fixture); if (body) { body.DestroyFixture(fixture); diff --git a/cocos/physics-2d/builtin/builtin-contact.ts b/cocos/physics-2d/builtin/builtin-contact.ts index a415f3daaea..ef245830db5 100644 --- a/cocos/physics-2d/builtin/builtin-contact.ts +++ b/cocos/physics-2d/builtin/builtin-contact.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BuiltinShape2D } from './shapes/shape-2d'; import Intersection2D from './intersection-2d'; diff --git a/cocos/physics-2d/builtin/builtin-world.ts b/cocos/physics-2d/builtin/builtin-world.ts index ac36d4364b0..d1429b976aa 100644 --- a/cocos/physics-2d/builtin/builtin-world.ts +++ b/cocos/physics-2d/builtin/builtin-world.ts @@ -1,7 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; import { IPhysicsWorld } from '../spec/i-physics-world'; import { Graphics } from '../../2d'; -import { CCObject, Vec3, Color, IVec2Like, Vec2, Rect } from '../../core'; +import { CCObject, Vec3, Color, IVec2Like, Vec2, Rect, cclegacy, js } from '../../core'; import { Canvas } from '../../2d/framework'; import { BuiltinShape2D } from './shapes/shape-2d'; import { BuiltinBoxShape } from './shapes/box-shape-2d'; @@ -10,7 +34,6 @@ import { BuiltinPolygonShape } from './shapes/polygon-shape-2d'; import { EPhysics2DDrawFlags, Contact2DType, ERaycast2DType, RaycastResult2D } from '../framework/physics-types'; import { PhysicsSystem2D, Collider2D } from '../framework'; import { BuiltinContact } from './builtin-contact'; -import { legacyCC } from '../../core/global-exports'; import { Node, find } from '../../scene-graph'; import { director } from '../../game'; @@ -48,6 +71,8 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld { if (this.shouldCollide(shape, other)) { const contact = new BuiltinContact(shape, other); this._contacts.push(contact); + if (shape._contacts.indexOf(contact) === -1) { shape._contacts.push(contact); } + if (other._contacts.indexOf(contact) === -1) { other._contacts.push(contact); } } } @@ -59,8 +84,7 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld { const shapes = this._shapes; const index = shapes.indexOf(shape); if (index >= 0) { - shapes.splice(index, 1); - + js.array.fastRemoveAt(shapes, index); const contacts = this._contacts; for (let i = contacts.length - 1; i >= 0; i--) { const contact = contacts[i]; @@ -69,7 +93,7 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld { this._emitCollide(contact, Contact2DType.END_CONTACT); } - contacts.splice(i, 1); + js.array.fastRemoveAt(contacts, i); } } } @@ -77,7 +101,9 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld { updateShapeGroup (shape: BuiltinShape2D) { this.removeShape(shape); - this.addShape(shape); + if (shape.collider.enabledInHierarchy) { + this.addShape(shape); + } } step (deltaTime: number, velocityIterations = 10, positionIterations = 10) { @@ -170,7 +196,7 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld { } private _checkDebugDrawValid () { - if (EDITOR && !legacyCC.GAME_VIEW) return; + if (EDITOR && !cclegacy.GAME_VIEW) return; if (!this._debugGraphics || !this._debugGraphics.isValid) { let canvas = find('Canvas'); if (!canvas) { @@ -234,4 +260,7 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld { raycast (p1: IVec2Like, p2: IVec2Like, type: ERaycast2DType): RaycastResult2D[] { return []; } + finalizeContactEvent () { + + } } diff --git a/cocos/physics-2d/builtin/instantiate.ts b/cocos/physics-2d/builtin/instantiate.ts index 2913d49efed..6d79741b8a9 100644 --- a/cocos/physics-2d/builtin/instantiate.ts +++ b/cocos/physics-2d/builtin/instantiate.ts @@ -1,23 +1,51 @@ -import { select } from '../framework/physics-selector'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { selector } from '../framework/physics-selector'; import { BuiltinPhysicsWorld } from './builtin-world'; import { BuiltinBoxShape } from './shapes/box-shape-2d'; import { BuiltinCircleShape } from './shapes/circle-shape-2d'; import { BuiltinPolygonShape } from './shapes/polygon-shape-2d'; -select('builtin', { - PhysicsWorld: BuiltinPhysicsWorld, - RigidBody: null, - - BoxShape: BuiltinBoxShape, - CircleShape: BuiltinCircleShape, - PolygonShape: BuiltinPolygonShape, - - MouseJoint: null, - DistanceJoint: null, - SpringJoint: null, - RelativeJoint: null, - SliderJoint: null, - FixedJoint: null, - WheelJoint: null, - HingeJoint: null, +import { Game, game } from '../../game'; + +game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { + selector.register('builtin', { + PhysicsWorld: BuiltinPhysicsWorld, + RigidBody: null, + + BoxShape: BuiltinBoxShape, + CircleShape: BuiltinCircleShape, + PolygonShape: BuiltinPolygonShape, + + MouseJoint: null, + DistanceJoint: null, + SpringJoint: null, + RelativeJoint: null, + SliderJoint: null, + FixedJoint: null, + WheelJoint: null, + HingeJoint: null, + }); }); diff --git a/cocos/physics-2d/builtin/intersection-2d.ts b/cocos/physics-2d/builtin/intersection-2d.ts index 1f660bd23e0..4bdbfc0e684 100644 --- a/cocos/physics-2d/builtin/intersection-2d.ts +++ b/cocos/physics-2d/builtin/intersection-2d.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec2, Rect } from '../../core'; diff --git a/cocos/physics-2d/builtin/shapes/box-shape-2d.ts b/cocos/physics-2d/builtin/shapes/box-shape-2d.ts index 3c33d965483..715cf87f5d2 100644 --- a/cocos/physics-2d/builtin/shapes/box-shape-2d.ts +++ b/cocos/physics-2d/builtin/shapes/box-shape-2d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { BuiltinShape2D } from './shape-2d'; import { Vec2, Rect } from '../../../core'; import { BoxCollider2D } from '../../framework'; diff --git a/cocos/physics-2d/builtin/shapes/circle-shape-2d.ts b/cocos/physics-2d/builtin/shapes/circle-shape-2d.ts index 1091f770aa7..0de30a2dedf 100644 --- a/cocos/physics-2d/builtin/shapes/circle-shape-2d.ts +++ b/cocos/physics-2d/builtin/shapes/circle-shape-2d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { BuiltinShape2D } from './shape-2d'; import { Vec2, Mat4, Rect } from '../../../core'; import { CircleCollider2D } from '../../framework'; diff --git a/cocos/physics-2d/builtin/shapes/polygon-shape-2d.ts b/cocos/physics-2d/builtin/shapes/polygon-shape-2d.ts index cd1d7079490..888ca092c00 100644 --- a/cocos/physics-2d/builtin/shapes/polygon-shape-2d.ts +++ b/cocos/physics-2d/builtin/shapes/polygon-shape-2d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { BuiltinShape2D } from './shape-2d'; import { Vec2, Rect } from '../../../core'; import { PolygonCollider2D } from '../../framework'; diff --git a/cocos/physics-2d/builtin/shapes/shape-2d.ts b/cocos/physics-2d/builtin/shapes/shape-2d.ts index 8a4e106a760..29360faced5 100644 --- a/cocos/physics-2d/builtin/shapes/shape-2d.ts +++ b/cocos/physics-2d/builtin/shapes/shape-2d.ts @@ -1,12 +1,39 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { IBaseShape } from '../../spec/i-physics-shape'; import { Collider2D, PhysicsSystem2D } from '../../../../exports/physics-2d-framework'; import { Rect, Vec2 } from '../../../core'; import { BuiltinPhysicsWorld } from '../builtin-world'; +import { BuiltinContact } from '../builtin-contact'; export class BuiltinShape2D implements IBaseShape { protected _collider: Collider2D | null = null; protected _worldAabb = new Rect(); + //contacts contain this Shape + public _contacts: BuiltinContact[] = []; get impl () { return null; diff --git a/cocos/physics-2d/framework/components/colliders/box-collider-2d.ts b/cocos/physics-2d/framework/components/colliders/box-collider-2d.ts index 29eb2acb6d3..f044fa0a196 100644 --- a/cocos/physics-2d/framework/components/colliders/box-collider-2d.ts +++ b/cocos/physics-2d/framework/components/colliders/box-collider-2d.ts @@ -1,22 +1,48 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ -import { ccclass, property, menu } from '../../../../core/data/class-decorator'; -import { Vec2, Size } from '../../../../core'; + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { Vec2, Size, _decorator } from '../../../../core'; import { Collider2D } from './collider-2d'; import { ECollider2DType } from '../../physics-types'; import { IBoxShape } from '../../../spec/i-physics-shape'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.BoxCollider2D') +@help('i18n:cc.BoxCollider2D') @menu('Physics2D/Colliders/BoxCollider2D') export class BoxCollider2D extends Collider2D { - @property + @serializable private _size = new Size(1, 1); /** - * @en Box size - * @zh 包围盒大小 + * @en Box size. + * @zh 包围盒大小。 */ - @property + @type(Size) + @tooltip('i18n:physics2d.collider.size') get size () { return this._size; } @@ -25,8 +51,8 @@ export class BoxCollider2D extends Collider2D { } /** - * @en Get world points - * @zh 世界坐标下 BoX 的四个点 + * @en Get world points. + * @zh 世界坐标下 BoX 的四个点。 */ get worldPoints (): readonly Readonly[] { if (this._shape) { diff --git a/cocos/physics-2d/framework/components/colliders/circle-collider-2d.ts b/cocos/physics-2d/framework/components/colliders/circle-collider-2d.ts index b0e0618a02a..22699791e7f 100644 --- a/cocos/physics-2d/framework/components/colliders/circle-collider-2d.ts +++ b/cocos/physics-2d/framework/components/colliders/circle-collider-2d.ts @@ -1,20 +1,48 @@ -import { ccclass, property, menu } from '../../../../core/data/class-decorator'; -import { Vec2 } from '../../../../core'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { CCFloat, Vec2, _decorator } from '../../../../core'; import { Collider2D } from './collider-2d'; import { ECollider2DType } from '../../physics-types'; import { ICircleShape } from '../../../spec/i-physics-shape'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.CircleCollider2D') +@help('i18n:cc.CircleCollider2D') @menu('Physics2D/Colliders/CircleCollider2D') export class CircleCollider2D extends Collider2D { - @property + @serializable private _radius = 1; /** - * @en Circle radius - * @zh 圆形半径 + * @en Circle radius. + * @zh 圆形半径。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.collider.radius') get radius () { return this._radius; } diff --git a/cocos/physics-2d/framework/components/colliders/collider-2d.ts b/cocos/physics-2d/framework/components/colliders/collider-2d.ts index 72f4fb60bf3..daf3e4db726 100644 --- a/cocos/physics-2d/framework/components/colliders/collider-2d.ts +++ b/cocos/physics-2d/framework/components/colliders/collider-2d.ts @@ -1,27 +1,52 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; -import { editable } from 'cc.decorator'; -import { ccclass, property, type } from '../../../../core/data/class-decorator'; -import { Vec2, Rect } from '../../../../core'; +import { Vec2, Rect, _decorator, Eventify, cclegacy, tooltip, CCInteger, serializable, CCFloat, CCBoolean, warnID } from '../../../../core'; import { PhysicsGroup } from '../../../../physics/framework/physics-enum'; -import { Eventify } from '../../../../core/event'; import { RigidBody2D } from '../rigid-body-2d'; -import { createShape } from '../../instance'; -import { ECollider2DType } from '../../physics-types'; +import { createShape } from '../../physics-selector'; +import { Contact2DType, ECollider2DType } from '../../physics-types'; import { IBaseShape } from '../../../spec/i-physics-shape'; -import { legacyCC } from '../../../../core/global-exports'; import { Component } from '../../../../scene-graph'; +const { ccclass, editable, property, type } = _decorator; + @ccclass('cc.Collider2D') export class Collider2D extends Eventify(Component) { @editable + @tooltip('i18n:physics2d.collider.editing') editing = false; /** * @en Tag. If a node has several collider components, you can judge which type of collider is collided according to the tag. * @zh 标签。当一个节点上有多个碰撞组件时,在发生碰撞后,可以使用此标签来判断是节点上的哪个碰撞组件被碰撞了。 */ - @property + @type(CCFloat) + @serializable + @tooltip('i18n:physics2d.collider.tag') tag = 0; /** @@ -31,6 +56,7 @@ export class Collider2D extends Eventify(Component) { * 获取或设置分组。 */ @type(PhysicsGroup) + @tooltip('i18n:physics2d.collider.group') public get group (): number { return this._group; } @@ -43,9 +69,10 @@ export class Collider2D extends Eventify(Component) { /** * @en The density. - * @zh 密度 + * @zh 密度。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.collider.density') get density () { return this._density; } @@ -59,7 +86,8 @@ export class Collider2D extends Eventify(Component) { * @zh * 一个传感器类型的碰撞体会产生碰撞回调,但是不会发生物理碰撞效果。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.collider.sensor') get sensor () { return this._sensor; } @@ -71,9 +99,10 @@ export class Collider2D extends Eventify(Component) { * @en * The friction coefficient, usually in the range [0,1]. * @zh - * 摩擦系数,取值一般在 [0, 1] 之间 + * 摩擦系数,取值一般在 [0, 1] 之间。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.collider.friction') get friction () { return this._friction; } @@ -85,9 +114,10 @@ export class Collider2D extends Eventify(Component) { * @en * The restitution (elasticity) usually in the range [0,1]. * @zh - * 弹性系数,取值一般在 [0, 1]之间 + * 弹性系数,取值一般在 [0, 1]之间。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.collider.restitution') get restitution () { return this._restitution; } @@ -98,7 +128,8 @@ export class Collider2D extends Eventify(Component) { * @en Position offset * @zh 位置偏移量 */ - @property + @type(Vec2) + @tooltip('i18n:physics2d.collider.offset') get offset () { return this._offset; } @@ -125,7 +156,7 @@ export class Collider2D extends Eventify(Component) { /// COMPONENT LIFECYCLE /// protected onLoad () { - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this._shape = createShape(this.TYPE); this._shape.initialize(this); @@ -169,9 +200,9 @@ export class Collider2D extends Eventify(Component) { /** * @en - * Get the world aabb of the collider + * Get the world aabb of the collider. * @zh - * 获取碰撞体的世界坐标系下的包围盒 + * 获取碰撞体的世界坐标系下的包围盒。 */ get worldAABB (): Readonly { if (this._shape) { @@ -181,21 +212,28 @@ export class Collider2D extends Eventify(Component) { return new Rect(); } + public on void>(type: string, callback: TFunction, thisArg?: any, once?: boolean): typeof callback { + if (type === Contact2DType.PRE_SOLVE || type === Contact2DType.POST_SOLVE) { + warnID(16002, type, '3.7.1'); + } + return super.on(type, callback, thisArg, once); + } + // protected properties protected _shape: IBaseShape | null = null; protected _body: RigidBody2D | null = null; - @property + @serializable protected _group = PhysicsGroup.DEFAULT; - @property + @serializable protected _density = 1.0; - @property + @serializable protected _sensor = false; - @property + @serializable protected _friction = 0.2; - @property + @serializable protected _restitution = 0; - @property + @serializable protected _offset = new Vec2(); } diff --git a/cocos/physics-2d/framework/components/colliders/polygon-collider-2d.ts b/cocos/physics-2d/framework/components/colliders/polygon-collider-2d.ts index be92a298321..3a6385178e4 100644 --- a/cocos/physics-2d/framework/components/colliders/polygon-collider-2d.ts +++ b/cocos/physics-2d/framework/components/colliders/polygon-collider-2d.ts @@ -1,23 +1,53 @@ -import { ccclass, property, menu } from '../../../../core/data/class-decorator'; -import { Vec2 } from '../../../../core'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { CCFloat, Vec2, _decorator } from '../../../../core'; import { Collider2D } from './collider-2d'; import { ECollider2DType } from '../../physics-types'; import { IPolygonShape } from '../../../spec/i-physics-shape'; +import { displayOrder, help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.PolygonCollider2D') +@help('i18n:cc.PolygonCollider2D') @menu('Physics2D/Colliders/PolygonCollider2D') export class PolygonCollider2D extends Collider2D { - @property({ serializable: false, displayOrder: 0 }) + @type(CCFloat) + @displayOrder(0) + @tooltip('i18n:physics2d.collider.threshold') threshold = 1; - @property + @serializable private _points = [new Vec2(-1, -1), new Vec2(1, -1), new Vec2(1, 1), new Vec2(-1, 1)]; /** - * @en Polygon points - * @zh 多边形顶点数组 + * @en Polygon points. + * @zh 多边形顶点数组。 */ - @property({ type: Vec2 }) + @type([Vec2]) + @tooltip('i18n:physics2d.collider.points') get points () { return this._points; } @@ -26,8 +56,8 @@ export class PolygonCollider2D extends Collider2D { } /** - * @en Get world points - * @zh 世界坐标下多边形碰撞体的点 + * @en Get world points. + * @zh 世界坐标下多边形碰撞体的点。 */ get worldPoints (): readonly Readonly[] { if (this._shape) { diff --git a/cocos/physics-2d/framework/components/joints/distance-joint-2d.ts b/cocos/physics-2d/framework/components/joints/distance-joint-2d.ts index 88c7074bb46..625bc0c2538 100644 --- a/cocos/physics-2d/framework/components/joints/distance-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/distance-joint-2d.ts @@ -1,11 +1,37 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; import { IDistanceJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; -import { Vec3 } from '../../../../core'; +import { CCBoolean, CCFloat, Vec3, _decorator } from '../../../../core'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.DistanceJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/DistanceJoint2D') export class DistanceJoint2D extends Joint2D { TYPE = EJoint2DType.DISTANCE; @@ -16,10 +42,15 @@ export class DistanceJoint2D extends Joint2D { * @zh * 最大长度。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxLength') get maxLength () { - if (this._autoCalcDistance && this.connectedBody) { - return Vec3.distance(this.node.worldPosition, this.connectedBody.node.worldPosition); + if (this._autoCalcDistance) { + if (this.connectedBody) { + return Vec3.distance(this.node.worldPosition, this.connectedBody.node.worldPosition); + } else { //if connected body is not set, use scene origin as connected body + return Vec3.len(this.node.worldPosition); + } } return this._maxLength; } @@ -34,9 +65,10 @@ export class DistanceJoint2D extends Joint2D { * @en * Auto calculate the distance between the connected two rigid bodies. * @zh - * 自动计算关节连接的两个刚体间的距离 + * 自动计算关节连接的两个刚体间的距离。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.autoCalcDistance') get autoCalcDistance () { return this._autoCalcDistance; } @@ -46,8 +78,9 @@ export class DistanceJoint2D extends Joint2D { /// private properties - @property + @serializable private _maxLength = 5; - @property + + @serializable private _autoCalcDistance = true; } diff --git a/cocos/physics-2d/framework/components/joints/fixed-joint-2d.ts b/cocos/physics-2d/framework/components/joints/fixed-joint-2d.ts index 63e3b1decce..96a44ebdf7f 100644 --- a/cocos/physics-2d/framework/components/joints/fixed-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/fixed-joint-2d.ts @@ -1,10 +1,37 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; +import { CCFloat, _decorator } from '../../../../core'; import { IFixedJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.FixedJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/FixedJoint2D') export class FixedJoint2D extends Joint2D { TYPE = EJoint2DType.FIXED; @@ -15,7 +42,8 @@ export class FixedJoint2D extends Joint2D { * @zh * 弹性系数。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.frequency') get frequency (): number { return this._frequency; } @@ -32,7 +60,8 @@ export class FixedJoint2D extends Joint2D { * @zh * 阻尼,表示关节变形后,恢复到初始状态受到的阻力。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.dampingRatio') get dampingRatio (): number { return this._dampingRatio; } @@ -45,8 +74,9 @@ export class FixedJoint2D extends Joint2D { /// private properties - @property + @serializable private _frequency = 0.7; - @property + + @serializable private _dampingRatio = 0.5; } diff --git a/cocos/physics-2d/framework/components/joints/hinge-joint-2d.ts b/cocos/physics-2d/framework/components/joints/hinge-joint-2d.ts index 16bf9874f33..b359515fcd9 100644 --- a/cocos/physics-2d/framework/components/joints/hinge-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/hinge-joint-2d.ts @@ -1,11 +1,37 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; +import { CCBoolean, CCFloat, _decorator } from '../../../../core'; import { IHingeJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.HingeJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/HingeJoint2D') export class HingeJoint2D extends Joint2D { TYPE = EJoint2DType.HINGE; @@ -16,7 +42,8 @@ export class HingeJoint2D extends Joint2D { * @zh * 是否开启关节的限制? */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.enableLimit') get enableLimit (): boolean { return this._enableLimit; } @@ -30,7 +57,8 @@ export class HingeJoint2D extends Joint2D { * @zh * 角度的最低限制。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.lowerAngle') get lowerAngle (): number { return this._lowerAngle; } @@ -47,7 +75,8 @@ export class HingeJoint2D extends Joint2D { * @zh * 角度的最高限制。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.upperAngle') get upperAngle (): number { return this._upperAngle; } @@ -64,7 +93,8 @@ export class HingeJoint2D extends Joint2D { * @zh * 是否开启关节马达? */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.enableMotor') get enableMotor (): boolean { return this._enableMotor; } @@ -81,7 +111,8 @@ export class HingeJoint2D extends Joint2D { * @zh * 可以施加到刚体的最大扭矩。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxMotorTorque') get maxMotorTorque (): number { return this._maxMotorTorque; } @@ -98,7 +129,8 @@ export class HingeJoint2D extends Joint2D { * @zh * 期望的马达速度。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.motorSpeed') get motorSpeed (): number { return this._motorSpeed; } @@ -111,16 +143,21 @@ export class HingeJoint2D extends Joint2D { /// private properties - @property + @serializable private _enableLimit = false; - @property + + @serializable private _lowerAngle = 0; - @property + + @serializable private _upperAngle = 0; - @property + + @serializable private _enableMotor = false; - @property + + @serializable private _maxMotorTorque = 1000; - @property + + @serializable private _motorSpeed = 0; } diff --git a/cocos/physics-2d/framework/components/joints/joint-2d.ts b/cocos/physics-2d/framework/components/joints/joint-2d.ts index 4d369e4dd83..b90a364c10a 100644 --- a/cocos/physics-2d/framework/components/joints/joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/joint-2d.ts @@ -1,27 +1,89 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; -import { Vec2 } from '../../../../core'; -import { property, type, ccclass } from '../../../../core/data/class-decorator'; +import { Vec2, _decorator, cclegacy, tooltip, serializable, CCBoolean } from '../../../../core'; import { RigidBody2D } from '../rigid-body-2d'; import { IJoint2D } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; -import { createJoint } from '../../instance'; -import { legacyCC } from '../../../../core/global-exports'; +import { createJoint } from '../../physics-selector'; import { Component } from '../../../../scene-graph'; +const { ccclass, type, property } = _decorator; + @ccclass('cc.Joint2D') export class Joint2D extends Component { - @property + /** + * @en + * The position of Joint2D in the attached rigid body's local space. + * @zh + * 在自身刚体的本地空间中,Joint2D的位置。 + */ + @type(Vec2) + @serializable + @tooltip('i18n:physics2d.joint.anchor') anchor = new Vec2(); - @property + /** + * @en + * The position of Joint2D in the connected rigid body's local space. + * @zh + * 在连接刚体的本地空间中,Joint2D的位置。 + */ + @type(Vec2) + @serializable + @tooltip('i18n:physics2d.joint.connectedAnchor') connectedAnchor = new Vec2(); - @property + /** + * @en + * whether collision is turned on between two rigid bodies connected by a joint. + * @zh + * 关节连接的两刚体之间是否开启碰撞。 + */ + @type(CCBoolean) + @serializable + @tooltip('i18n:physics2d.joint.collideConnected') collideConnected = false; + /** + * @en + * The jointed rigid body, null means link to a static rigid body at the world origin. + * @zh + * 关节连接的刚体,为空时表示连接到位于世界原点的静态刚体。 + */ @type(RigidBody2D) + @serializable + @tooltip('i18n:physics2d.joint.connectedBody') connectedBody: RigidBody2D | null = null; + /** + * @en + * the Joint2D attached rigid-body. + * @zh + * 关节所绑定的刚体组件。 + */ _body: RigidBody2D | null = null get body () { return this._body; @@ -33,10 +95,16 @@ export class Joint2D extends Component { protected _joint: IJoint2D | null = null; + /** + * @en + * the type of this joint. + * @zh + * 此关节的类型。 + */ TYPE = EJoint2DType.None; protected onLoad () { - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this._joint = createJoint(this.TYPE); this._joint.initialize(this); diff --git a/cocos/physics-2d/framework/components/joints/mouse-joint-2d.ts b/cocos/physics-2d/framework/components/joints/mouse-joint-2d.ts index 267ea8d054d..0ed1424f3f4 100644 --- a/cocos/physics-2d/framework/components/joints/mouse-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/mouse-joint-2d.ts @@ -1,12 +1,37 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; import { IMouseJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; -import { Vec2 } from '../../../../core'; +import { CCFloat, Vec2, _decorator } from '../../../../core'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.MouseJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/MouseJoint2D') export class MouseJoint2D extends Joint2D { TYPE = EJoint2DType.MOUSE; @@ -27,7 +52,8 @@ export class MouseJoint2D extends Joint2D { * @zh * 弹簧系数。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.frequency') get frequency (): number { return this._frequency; } @@ -44,7 +70,8 @@ export class MouseJoint2D extends Joint2D { * @zh * 阻尼,表示关节变形后,恢复到初始状态受到的阻力。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.dampingRatio') get dampingRatio (): number { return this._dampingRatio; } @@ -57,11 +84,12 @@ export class MouseJoint2D extends Joint2D { /** * @en - * The maximum force + * The maximum force. * @zh - * 最大阻力值 + * 最大阻力值。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxForce') get maxForce (): number { return this._maxForce; } @@ -76,11 +104,14 @@ export class MouseJoint2D extends Joint2D { this._joint!.update!(dt); } - @property + @serializable private _maxForce = 1000; - @property + + @serializable private _dampingRatio = 0.7; - @property + + @serializable private _frequency = 5; + private _target = new Vec2(); } diff --git a/cocos/physics-2d/framework/components/joints/relative-joint-2d.ts b/cocos/physics-2d/framework/components/joints/relative-joint-2d.ts index 76c711abb50..1d0845efc05 100644 --- a/cocos/physics-2d/framework/components/joints/relative-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/relative-joint-2d.ts @@ -1,15 +1,40 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; import { IRelativeJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; -import { Vec3, Vec2, IVec2Like, Quat } from '../../../../core'; +import { Vec3, Vec2, IVec2Like, Quat, _decorator, CCFloat, CCBoolean } from '../../../../core'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; const tempVec3_1 = new Vec3(); const tempVec3_2 = new Vec3(); +const { ccclass, menu, property } = _decorator; + @ccclass('cc.RelativeJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/RelativeJoint2D') export class RelativeJoint2D extends Joint2D { TYPE = EJoint2DType.RELATIVE; @@ -18,9 +43,10 @@ export class RelativeJoint2D extends Joint2D { * @en * The maximum force can be applied to rigidbody. * @zh - * 可以应用于刚体的最大的力值 + * 可以应用于刚体的最大的力值。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxForce') get maxForce (): number { return this._maxForce; } @@ -35,9 +61,10 @@ export class RelativeJoint2D extends Joint2D { * @en * The maximum torque can be applied to rigidbody. * @zh - * 可以应用于刚体的最大扭矩值 + * 可以应用于刚体的最大扭矩值。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxTorque') get maxTorque (): number { return this._maxTorque; } @@ -52,9 +79,10 @@ export class RelativeJoint2D extends Joint2D { * @en * The position correction factor in the range [0,1]. * @zh - * 位置矫正系数,范围为 [0, 1] + * 位置矫正系数,范围为 [0, 1]。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.correctionFactor') get correctionFactor (): number { return this._correctionFactor; } @@ -69,12 +97,19 @@ export class RelativeJoint2D extends Joint2D { * @en * The linear offset from connected rigidbody to rigidbody. * @zh - * 关节另一端的刚体相对于起始端刚体的位置偏移量 + * 关节另一端的刚体相对于起始端刚体的位置偏移量。 */ - @property + @type(Vec2) + @tooltip('i18n:physics2d.joint.linearOffset') get linearOffset (): Vec2 { - if (this._autoCalcOffset && this.connectedBody) { - return Vec2.subtract(this._linearOffset, this.connectedBody.node.worldPosition as IVec2Like, this.node.worldPosition as IVec2Like) as Vec2; + if (this._autoCalcOffset) { + if (this.connectedBody) { + return Vec2.subtract(this._linearOffset, this.connectedBody.node.worldPosition as IVec2Like, + this.node.worldPosition as IVec2Like) as Vec2; + } else { //if connected body is not set, use scene origin as connected body + return Vec2.subtract(this._linearOffset, new Vec2(0, 0), + this.node.worldPosition as IVec2Like) as Vec2; + } } return this._linearOffset; } @@ -89,13 +124,18 @@ export class RelativeJoint2D extends Joint2D { * @en * The angular offset from connected rigidbody to rigidbody. * @zh - * 关节另一端的刚体相对于起始端刚体的角度偏移量 + * 关节另一端的刚体相对于起始端刚体的角度偏移量。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.angularOffset') get angularOffset (): number { - if (this._autoCalcOffset && this.connectedBody) { + if (this._autoCalcOffset) { Quat.toEuler(tempVec3_1, this.node.worldRotation); - Quat.toEuler(tempVec3_2, this.connectedBody.node.worldRotation); + if (this.connectedBody) { + Quat.toEuler(tempVec3_2, this.connectedBody.node.worldRotation); + } else { //if connected body is not set, use scene origin as connected body + Quat.toEuler(tempVec3_2, new Quat());//? + } this._angularOffset = tempVec3_2.z - tempVec3_1.z; } return this._angularOffset; @@ -111,9 +151,10 @@ export class RelativeJoint2D extends Joint2D { * @en * Auto calculate the angularOffset and linearOffset between the connected two rigid bodies. * @zh - * 自动计算关节连接的两个刚体间的 angularOffset 和 linearOffset + * 自动计算关节连接的两个刚体间的 angularOffset 和 linearOffset。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.autoCalcOffset') get autoCalcOffset (): boolean { return this._autoCalcOffset; } @@ -123,16 +164,21 @@ export class RelativeJoint2D extends Joint2D { /// private properties - @property + @serializable private _maxForce = 5; - @property + + @serializable private _maxTorque = 0.7; - @property + + @serializable private _correctionFactor = 0.3; - @property + + @serializable private _angularOffset = 0; - @property + + @serializable private _linearOffset = new Vec2(); - @property + + @serializable private _autoCalcOffset = true; } diff --git a/cocos/physics-2d/framework/components/joints/slider-joint-2d.ts b/cocos/physics-2d/framework/components/joints/slider-joint-2d.ts index daec80b3d22..35364eb2d1d 100644 --- a/cocos/physics-2d/framework/components/joints/slider-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/slider-joint-2d.ts @@ -1,26 +1,55 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; import { ISliderJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; -import { Vec3, Vec2, IVec2Like, toDegree } from '../../../../core'; +import { Vec2, IVec2Like, toDegree, _decorator, CCFloat, CCBoolean } from '../../../../core'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; const tempVec2 = new Vec2(); +const { ccclass, menu, property } = _decorator; @ccclass('cc.SliderJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/SliderJoint2D') export class SliderJoint2D extends Joint2D { TYPE = EJoint2DType.SLIDER; /** - * @en Slide direction - * @zh 滑动的方向 + * @en Slide direction. + * @zh 滑动的方向。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.angle') get angle (): number { - if (this._autoCalcAngle && this.connectedBody) { - Vec2.subtract(tempVec2, this.connectedBody.node.worldPosition as IVec2Like, this.node.worldPosition as IVec2Like); + if (this._autoCalcAngle) { + if (this.connectedBody) { + Vec2.subtract(tempVec2, this.connectedBody.node.worldPosition as IVec2Like, this.node.worldPosition as IVec2Like); + } else { + Vec2.subtract(tempVec2, new Vec2(0, 0), this.node.worldPosition as IVec2Like); + } this._angle = toDegree(Math.atan2(tempVec2.y, tempVec2.x)); } return this._angle; @@ -30,10 +59,11 @@ export class SliderJoint2D extends Joint2D { } /** - * @en Auto calculate slide direction according to the slide direction - * @zh 根据连接的两个刚体自动计算滑动方向 + * @en Auto calculate slide direction according to the slide direction. + * @zh 根据连接的两个刚体自动计算滑动方向。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.autoCalcAngle') get autoCalcAngle (): boolean { return this._autoCalcAngle; } @@ -47,7 +77,8 @@ export class SliderJoint2D extends Joint2D { * @zh * 是否开启关节马达? */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.enableMotor') get enableMotor (): boolean { return this._enableMotor; } @@ -61,7 +92,8 @@ export class SliderJoint2D extends Joint2D { * @zh * 可以施加到刚体的最大力。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxMotorForce') get maxMotorForce (): number { return this._maxMotorForce; } @@ -78,7 +110,8 @@ export class SliderJoint2D extends Joint2D { * @zh * 期望的马达速度。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.motorSpeed') get motorSpeed (): number { return this._motorSpeed; } @@ -95,7 +128,8 @@ export class SliderJoint2D extends Joint2D { * @zh * 是否开启关节的距离限制? */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.enableLimit') get enableLimit (): boolean { return this._enableLimit; } @@ -107,9 +141,10 @@ export class SliderJoint2D extends Joint2D { * @en * The lower joint limit. * @zh - * 刚体能够移动的最小值 + * 刚体能够移动的最小值。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.lowerLimit') get lowerLimit (): number { return this._lowerLimit; } @@ -124,9 +159,10 @@ export class SliderJoint2D extends Joint2D { * @en * The lower joint limit. * @zh - * 刚体能够移动的最大值 + * 刚体能够移动的最大值。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.upperLimit') get upperLimit (): number { return this._upperLimit; } @@ -139,20 +175,27 @@ export class SliderJoint2D extends Joint2D { /// private properties - @property + @serializable private _angle = 0; - @property + + @serializable private _autoCalcAngle = true; - @property + + @serializable private _enableMotor = false; - @property + + @serializable private _maxMotorForce = 1000; - @property + + @serializable private _motorSpeed = 1000; - @property + + @serializable private _enableLimit = false; - @property + + @serializable private _lowerLimit = 0; - @property + + @serializable private _upperLimit = 0; } diff --git a/cocos/physics-2d/framework/components/joints/spring-joint-2d.ts b/cocos/physics-2d/framework/components/joints/spring-joint-2d.ts index 06e4b06790e..232bdcef97a 100644 --- a/cocos/physics-2d/framework/components/joints/spring-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/spring-joint-2d.ts @@ -1,12 +1,37 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; import { ISpringJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; -import { Vec3 } from '../../../../core'; +import { CCBoolean, CCFloat, Vec3, _decorator } from '../../../../core'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, property, menu } = _decorator; @ccclass('cc.SpringJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/SpringJoint2D') export class SpringJoint2D extends Joint2D { TYPE = EJoint2DType.SPRING; @@ -17,7 +42,8 @@ export class SpringJoint2D extends Joint2D { * @zh * 弹性系数。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.frequency') get frequency () { return this._frequency; } @@ -34,7 +60,8 @@ export class SpringJoint2D extends Joint2D { * @zh * 阻尼,表示关节变形后,恢复到初始状态受到的阻力。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.dampingRatio') get dampingRatio () { return this._dampingRatio; } @@ -49,12 +76,17 @@ export class SpringJoint2D extends Joint2D { * @en * The distance separating the two ends of the joint. * @zh - * 关节两端的距离 + * 关节两端的距离。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.distance') get distance () { - if (this._autoCalcDistance && this.connectedBody) { - return Vec3.distance(this.node.worldPosition, this.connectedBody.node.worldPosition); + if (this._autoCalcDistance) { + if (this.connectedBody) { + return Vec3.distance(this.node.worldPosition, this.connectedBody.node.worldPosition); + } else { //if connected body is not set, use scene origin as connected body + return Vec3.len(this.node.worldPosition); + } } return this._distance; } @@ -69,9 +101,10 @@ export class SpringJoint2D extends Joint2D { * @en * Auto calculate the distance between the connected two rigid bodies. * @zh - * 自动计算关节连接的两个刚体间的距离 + * 自动计算关节连接的两个刚体间的距离。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.autoCalcDistance') get autoCalcDistance () { return this._autoCalcDistance; } @@ -81,12 +114,15 @@ export class SpringJoint2D extends Joint2D { /// private properties - @property + @serializable private _frequency = 5; - @property + + @serializable private _dampingRatio = 0.7; - @property + + @serializable private _distance = 10; - @property + + @serializable private _autoCalcDistance = true; } diff --git a/cocos/physics-2d/framework/components/joints/wheel-joint-2d.ts b/cocos/physics-2d/framework/components/joints/wheel-joint-2d.ts index c4a97248c3d..eb352c681ad 100644 --- a/cocos/physics-2d/framework/components/joints/wheel-joint-2d.ts +++ b/cocos/physics-2d/framework/components/joints/wheel-joint-2d.ts @@ -1,20 +1,47 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Joint2D } from './joint-2d'; -import { ccclass, property, menu, type } from '../../../../core/data/class-decorator'; +import { CCBoolean, CCFloat, _decorator } from '../../../../core'; import { IWheelJoint } from '../../../spec/i-physics-joint'; import { EJoint2DType } from '../../physics-types'; +import { help, serializable, tooltip, type } from '../../../../core/data/decorators'; + +const { ccclass, menu, property } = _decorator; @ccclass('cc.WheelJoint2D') +@help('i18n:cc.Joint2D') @menu('Physics2D/Joints/WheelJoint2D') export class WheelJoint2D extends Joint2D { TYPE = EJoint2DType.WHEEL; /** - * @en Wheel susspension direction - * @zh 轮子震动方向 + * @en Wheel susspension direction. + * @zh 轮子震动方向。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.angle') get angle (): number { return this._angle; } @@ -28,7 +55,8 @@ export class WheelJoint2D extends Joint2D { * @zh * 是否开启关节马达? */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.joint.enableMotor') get enableMotor (): boolean { return this._enableMotor; } @@ -45,7 +73,8 @@ export class WheelJoint2D extends Joint2D { * @zh * 可以施加到刚体的最大扭矩。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.maxMotorTorque') get maxMotorTorque (): number { return this._maxMotorTorque; } @@ -62,7 +91,8 @@ export class WheelJoint2D extends Joint2D { * @zh * 期望的马达速度。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.motorSpeed') get motorSpeed (): number { return this._motorSpeed; } @@ -79,7 +109,8 @@ export class WheelJoint2D extends Joint2D { * @zh * 弹性系数。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.frequency') get frequency (): number { return this._frequency; } @@ -96,7 +127,8 @@ export class WheelJoint2D extends Joint2D { * @zh * 阻尼,表示关节变形后,恢复到初始状态受到的阻力。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.joint.dampingRatio') get dampingRatio (): number { return this._dampingRatio; } @@ -109,16 +141,21 @@ export class WheelJoint2D extends Joint2D { /// private properties - @property + @serializable private _angle = 90; - @property + + @serializable private _enableMotor = false; - @property + + @serializable private _maxMotorTorque = 1000; - @property + + @serializable private _motorSpeed = 0; - @property + + @serializable private _frequency = 5; - @property + + @serializable private _dampingRatio = 0.7; } diff --git a/cocos/physics-2d/framework/components/rigid-body-2d.ts b/cocos/physics-2d/framework/components/rigid-body-2d.ts index 7a9b569ab89..f46cf490226 100644 --- a/cocos/physics-2d/framework/components/rigid-body-2d.ts +++ b/cocos/physics-2d/framework/components/rigid-body-2d.ts @@ -1,16 +1,40 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; import { IRigidBody2D } from '../../spec/i-rigid-body'; -import { _decorator, Vec2, IVec2Like } from '../../../core'; +import { _decorator, Vec2, IVec2Like, cclegacy, CCBoolean, CCFloat } from '../../../core'; import { ERigidBody2DType } from '../physics-types'; -import { ccclass } from '../../../core/data/class-decorator'; -import { createRigidBody } from '../instance'; +import { createRigidBody } from '../physics-selector'; import { PhysicsGroup } from '../../../physics/framework/physics-enum'; -import { legacyCC } from '../../../core/global-exports'; import { Component } from '../../../scene-graph'; +import { help, serializable, tooltip } from '../../../core/data/decorators'; -const { property, type, menu } = _decorator; +const { property, type, menu, ccclass } = _decorator; @ccclass('cc.RigidBody2D') +@help('i18n:cc.RigidBody2D') @menu('Physics2D/RigidBody2D') export class RigidBody2D extends Component { /** @@ -20,6 +44,7 @@ export class RigidBody2D extends Component { * 获取或设置分组。 */ @type(PhysicsGroup) + @tooltip('i18n:physics2d.rigidbody.group') public get group (): number { return this._group; } @@ -27,7 +52,9 @@ export class RigidBody2D extends Component { this._group = v; } - @property + @type(CCBoolean) + @serializable + @tooltip('i18n:physics2d.rigidbody.enabledContactListener') enabledContactListener = false; /** @@ -43,7 +70,9 @@ export class RigidBody2D extends Component { * - 所有刚体都被禁止从 运动刚体 和 静态刚体 中穿过。此选项只关注于 动态刚体。 * - 应该尽量少的使用此选项,因为它会增加程序处理时间。 */ - @property + @type(CCBoolean) + @serializable + @tooltip('i18n:physics2d.rigidbody.bullet') bullet = false; /** @@ -53,6 +82,7 @@ export class RigidBody2D extends Component { * 刚体类型: Static, Kinematic, Dynamic or Animated. */ @type(ERigidBody2DType) + @tooltip('i18n:physics2d.rigidbody.type') get type (): ERigidBody2DType { return this._type; } @@ -75,7 +105,8 @@ export class RigidBody2D extends Component { * 如果此刚体永远都不应该进入睡眠,那么设置这个属性为 false。 * 需要注意这将使 CPU 占用率提高。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.rigidbody.allowSleep') get allowSleep (): boolean { return this._allowSleep; } @@ -90,9 +121,10 @@ export class RigidBody2D extends Component { * @en * Scale the gravity applied to this body. * @zh - * 缩放应用在此刚体上的重力值 + * 缩放应用在此刚体上的重力值。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.rigidbody.gravityScale') get gravityScale (): number { return this._gravityScale; } @@ -111,7 +143,8 @@ export class RigidBody2D extends Component { * @zh * Linear damping 用于衰减刚体的线性速度。衰减系数可以大于 1,但是当衰减系数比较大的时候,衰减的效果会变得比较敏感。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.rigidbody.linearDamping') get linearDamping (): number { return this._linearDamping; } @@ -130,7 +163,8 @@ export class RigidBody2D extends Component { * @zh * Angular damping 用于衰减刚体的角速度。衰减系数可以大于 1,但是当衰减系数比较大的时候,衰减的效果会变得比较敏感。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.rigidbody.angularDamping') get angularDamping (): number { return this._angularDamping; } @@ -145,9 +179,10 @@ export class RigidBody2D extends Component { * @en * The linear velocity of the body's origin in world co-ordinates. * @zh - * 刚体在世界坐标下的线性速度 + * 刚体在世界坐标下的线性速度。 */ - @property + @type(Vec2) + @tooltip('i18n:physics2d.rigidbody.linearVelocity') get linearVelocity (): Vec2 { if (this._body) { this._body.getLinearVelocity(this._linearVelocity); @@ -165,9 +200,10 @@ export class RigidBody2D extends Component { * @en * The angular velocity of the body. * @zh - * 刚体的角速度 + * 刚体的角速度。 */ - @property + @type(CCFloat) + @tooltip('i18n:physics2d.rigidbody.angularVelocity') get angularVelocity (): number { if (this._body) { this._angularVelocity = this._body.getAngularVelocity(); @@ -185,9 +221,10 @@ export class RigidBody2D extends Component { * @en * Should this body be prevented from rotating? * @zh - * 是否禁止此刚体进行旋转 + * 是否禁止此刚体进行旋转。 */ - @property + @type(CCBoolean) + @tooltip('i18n:physics2d.rigidbody.fixedRotation') get fixedRotation (): boolean { return this._fixedRotation; } @@ -200,11 +237,13 @@ export class RigidBody2D extends Component { /** * @en - * Whether to wake up this rigid body during initialization + * Whether to wake up this rigid body during initialization. * @zh - * 是否在初始化时唤醒此刚体 + * 是否在初始化时唤醒此刚体。 */ - @property + @type(CCBoolean) + @serializable + @tooltip('i18n:physics2d.rigidbody.awakeOnLoad') awakeOnLoad = true; // /** @@ -245,7 +284,7 @@ export class RigidBody2D extends Component { * @en * Whether the rigid body is awake. * @zh - * 获取刚体是否正在休眠 + * 获取刚体是否正在休眠。 */ isAwake () { if (this._body) { @@ -295,13 +334,13 @@ export class RigidBody2D extends Component { /** * @en * Apply a force at a world point. If the force is not - * applied at the center of mass, it will generate a torque and - * affect the angular velocity. + * applied at the center of mass, it will generate a torque and + * affect the angular velocity. * @zh * 施加一个力到刚体上的一个点。如果力没有施加到刚体的质心上,还会产生一个扭矩并且影响到角速度。 - * @param force - the world force vector. - * @param point - the world position. - * @param wake - also wake up the body. + * @param force @en the world force vector. @zh 世界坐标系下的力。 + * @param point @en the world position. @zh 世界坐标系下的力的作用点。 + * @param wake @en also wake up the body. @zh 唤醒刚体。 */ applyForce (force: Vec2, point: Vec2, wake: boolean) { if (this._body) { @@ -314,8 +353,8 @@ export class RigidBody2D extends Component { * Apply a force to the center of mass. * @zh * 施加一个力到刚体上的质心上。 - * @param force - the world force vector. - * @param wake - also wake up the body. + * @param force @en the world force vector. @zh 世界坐标系下的力。 + * @param wake @en also wake up the body. @zh 唤醒刚体。 */ applyForceToCenter (force: Vec2, wake: boolean) { if (this._body) { @@ -327,9 +366,9 @@ export class RigidBody2D extends Component { * @en * Apply a torque. This affects the angular velocity. * @zh - * 施加一个扭矩力,将影响刚体的角速度 - * @param torque - about the z-axis (out of the screen), usually in N-m. - * @param wake - also wake up the body + * 施加一个扭矩力,将影响刚体的角速度。 + * @param torque @en about the z-axis (out of the screen), usually in N-m. @zh 扭矩 N-m。 + * @param wake @en also wake up the body @zh 唤醒刚体。 */ applyTorque (torque: number, wake: boolean) { if (this._body) { @@ -340,14 +379,14 @@ export class RigidBody2D extends Component { /** * @en * Apply a impulse at a world point, this immediately modifies the velocity. - * If the impulse is not applied at the center of mass, it will generate a torque and - * affect the angular velocity. + * If the impulse is not applied at the center of mass, it will generate a torque and + * affect the angular velocity. * @zh * 施加冲量到刚体上的一个点,将立即改变刚体的线性速度。 * 如果冲量施加到的点不是刚体的质心,那么将产生一个扭矩并影响刚体的角速度。 - * @param impulse - the world impulse vector, usually in N-seconds or kg-m/s. - * @param point - the world position - * @param wake - alse wake up the body + * @param impulse @en the world impulse vector, usually in N-seconds or kg-m/s. @zh 冲量 N-seconds 或者 kg-m/s。 + * @param point @en the world position. @zh 世界坐标系下的作用点。 + * @param wake @en also wake up the body. @zh 唤醒刚体。 */ applyLinearImpulse (impulse: Vec2, point: Vec2, wake: boolean) { if (this._body) { @@ -360,9 +399,8 @@ export class RigidBody2D extends Component { * Apply a impulse at the center of mass, this immediately modifies the velocity. * @zh * 施加冲量到刚体上的质心点,将立即改变刚体的线性速度。 - * @param impulse - the world impulse vector, usually in N-seconds or kg-m/s. - * @param point - the world position - * @param wake - alse wake up the body + * @param impulse @en the world impulse vector, usually in N-seconds or kg-m/s. @zh 冲量 N-seconds 或者 kg-m/s。 + * @param wake @en also wake up the body @zh 唤醒刚体。 */ applyLinearImpulseToCenter (impulse: Vec2, wake: boolean) { if (this._body) { @@ -374,9 +412,9 @@ export class RigidBody2D extends Component { * @en * Apply an angular impulse. * @zh - * 施加一个角速度冲量。 - * @param impulse - the angular impulse in units of kg*m*m/s - * @param wake - also wake up the body + * 施加一个角冲量。 + * @param impulse @en the angular impulse in units of kg*m*m/s. @zh 角冲量 kg*m*m/s。 + * @param wake @en also wake up the body. @zh 唤醒刚体。 */ applyAngularImpulse (impulse: number, wake: boolean) { if (this._body) { @@ -388,9 +426,10 @@ export class RigidBody2D extends Component { * @en * Get the world linear velocity of a world point attached to this body. * @zh - * 获取刚体上指定点的线性速度 - * @param worldPoint - a point in world coordinates. - * @param out - optional, the receiving point + * 获取刚体上指定点的线性速度。 + * @param worldPoint @en a point in world coordinates. @zh 世界坐标系下的点。 + * @param out @en optional, the returned world velocity. @zh 可选,返回的世界坐标系下的速度。 + * @return @en the world linear velocity. @zh 指定点的世界坐标系下的速度。 */ getLinearVelocityFromWorldPoint (worldPoint: IVec2Like, out: Out): Out { if (this._body) { @@ -398,13 +437,15 @@ export class RigidBody2D extends Component { } return out; } + /** * @en * Converts a world coordinate point to the given rigid body coordinate. * @zh - * 将一个给定的世界坐标系下的向量转换为刚体本地坐标系下的向量 - * @param worldVector - a vector in world coordinates. - * @param out - optional, the receiving vector + * 将一个给定的世界坐标系下的向量转换为刚体本地坐标系下的向量。 + * @param worldVector @en a vector in world coordinates. @zh 世界坐标系下的向量。 + * @param out @en optional, the returned vector in local coordinate. @zh 可选,返回的本地坐标系下的向量。 + * @return @en a vector in local coordinate. @zh 本地坐标系下的向量。 */ getLocalVector (worldVector: IVec2Like, out: Out): Out { if (this._body) { @@ -412,13 +453,15 @@ export class RigidBody2D extends Component { } return out; } + /** * @en * Converts a given vector in this rigid body's local coordinate system to the world coordinate system * @zh - * 将一个给定的刚体本地坐标系下的向量转换为世界坐标系下的向量 - * @param localVector - a vector in world coordinates. - * @param out - optional, the receiving vector + * 将一个给定的刚体本地坐标系下的向量转换为世界坐标系下的向量。 + * @param localVector @en a vector in local coordinates. @zh 本地坐标系下的向量。 + * @param out @en optional, the returned vector in world coordinate. @zh 可选,返回的世界坐标系下的向量。 + * @return @en a vector in world coordinate. @zh 世界坐标系下的向量。 */ getWorldVector (localVector: IVec2Like, out: Out): Out { if (this._body) { @@ -429,11 +472,12 @@ export class RigidBody2D extends Component { /** * @en - * Converts a given point in the world coordinate system to this rigid body's local coordinate system + * Converts a given point in the world coordinate system to this rigid body's local coordinate system. * @zh - * 将一个给定的世界坐标系下的点转换为刚体本地坐标系下的点 - * @param worldPoint - a point in world coordinates. - * @param out - optional, the receiving point + * 将一个给定的世界坐标系下的点转换为刚体本地坐标系下的点。 + * @param worldPoint @en a point in world coordinates. @zh 世界坐标系下的点。 + * @param out @en optional, the returned point in local coordinate. @zh 可选,返回的本地坐标系下的点。 + * @return @en a point in local coordinate. @zh 本地坐标系下的点。 */ getLocalPoint (worldPoint: IVec2Like, out: Out): Out { if (this._body) { @@ -441,13 +485,15 @@ export class RigidBody2D extends Component { } return out; } + /** * @en - * Converts a given point in this rigid body's local coordinate system to the world coordinate system + * Converts a given point in this rigid body's local coordinate system to the world coordinate system. * @zh - * 将一个给定的刚体本地坐标系下的点转换为世界坐标系下的点 - * @param localPoint - a point in local coordinates. - * @param out - optional, the receiving point + * 将一个给定的刚体本地坐标系下的点转换为世界坐标系下的点。 + * @param localPoint @en a point in local coordinate. @zh 本地坐标系下的点。 + * @param out @en optional, the returned point in world coordinate. @zh 可选,返回的世界坐标系下的点。 + * @return @en a point in world coordinate. @zh 世界坐标系下的点。 */ getWorldPoint (localPoint: IVec2Like, out: Out): Out { if (this._body) { @@ -455,11 +501,12 @@ export class RigidBody2D extends Component { } return out; } + /** * @en * Get the local position of the center of mass. * @zh - * 获取刚体本地坐标系下的质心 + * 获取刚体本地坐标系下的质心。 */ getLocalCenter (out: Out): Out { if (this._body) { @@ -467,11 +514,12 @@ export class RigidBody2D extends Component { } return out; } + /** * @en * Get the world position of the center of mass. * @zh - * 获取刚体世界坐标系下的质心 + * 获取刚体世界坐标系下的质心。 */ getWorldCenter (out: Out): Out { if (this._body) { @@ -484,7 +532,7 @@ export class RigidBody2D extends Component { * @en * Get the rotational inertia of the body about the local origin. * @zh - * 获取刚体本地坐标系下原点的旋转惯性 + * 获取刚体本地坐标系下原点的旋转惯性。 */ getInertia () { if (this._body) { @@ -495,7 +543,7 @@ export class RigidBody2D extends Component { /// COMPONENT LIFECYCLE /// protected onLoad () { - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this._body = createRigidBody(); this._body.initialize(this); } @@ -524,22 +572,30 @@ export class RigidBody2D extends Component { return this._body; } - @property + @serializable private _group = PhysicsGroup.DEFAULT; - @property + + @serializable private _type = ERigidBody2DType.Dynamic; - @property + + @serializable private _allowSleep = true; - @property + + @serializable private _gravityScale = 1; - @property + + @serializable private _linearDamping = 0; - @property + + @serializable private _angularDamping = 0; - @property + + @serializable private _linearVelocity = new Vec2(); - @property + + @serializable private _angularVelocity = 0; - @property + + @serializable private _fixedRotation = false; } diff --git a/cocos/physics-2d/framework/index.ts b/cocos/physics-2d/framework/index.ts index 6d424cccf2b..df5b2ecce26 100644 --- a/cocos/physics-2d/framework/index.ts +++ b/cocos/physics-2d/framework/index.ts @@ -1,4 +1,33 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { cclegacy } from '../../core'; + import * as PolygonSeparator from './utils/polygon-separator'; +import * as PolygonPartition from './utils/polygon-partition'; + +import { selector } from './physics-selector'; export * from './physics-types'; @@ -28,4 +57,9 @@ export * from './components/joints/hinge-joint-2d'; export const Physics2DUtils = { PolygonSeparator, + PolygonPartition, +}; + +cclegacy.internal.physics2d = { + selector, }; diff --git a/cocos/physics-2d/framework/instance.ts b/cocos/physics-2d/framework/instance.ts deleted file mode 100644 index 37e4d5e12bc..00000000000 --- a/cocos/physics-2d/framework/instance.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { EDITOR, DEBUG, TEST } from 'internal:constants'; -import { IRigidBody2D } from '../spec/i-rigid-body'; -import { WRAPPER } from './physics-selector'; -import { IBoxShape, ICircleShape, IPolygonShape, IBaseShape } from '../spec/i-physics-shape'; -import { IPhysicsWorld } from '../spec/i-physics-world'; -import { errorID, warnID, warn } from '../../core'; -import { ECollider2DType, EJoint2DType } from './physics-types'; -import { legacyCC } from '../../core/global-exports'; -import { IJoint2D, IDistanceJoint, ISpringJoint, IFixedJoint, IMouseJoint, IRelativeJoint, ISliderJoint, IWheelJoint, IHingeJoint } from '../spec/i-physics-joint'; - -const FUNC = (...v: any) => 0 as any; - -export function checkPhysicsModule (obj: any) { - if (DEBUG && !TEST && (!EDITOR || legacyCC.GAME_VIEW) && obj == null) { - errorID(9600); - return true; - } - return false; -} - -export function createPhysicsWorld (): IPhysicsWorld { - if (DEBUG && checkPhysicsModule(WRAPPER.PhysicsWorld)) { return null as any; } - return new WRAPPER.PhysicsWorld() as IPhysicsWorld; -} - -type IEntireBody = IRigidBody2D -const EntireBody: IEntireBody = { - impl: null as any, - rigidBody: null as any, - isAwake: false, - isSleeping: false, - - initialize: FUNC, - - setType: FUNC, - - setLinearDamping: FUNC, - setAngularDamping: FUNC, - setGravityScale: FUNC, - setFixedRotation: FUNC, - setAllowSleep: FUNC, - - isActive: FUNC, - setActive: FUNC, - - wakeUp: FUNC, - sleep: FUNC, - - getMass: FUNC, - getInertia: FUNC, - - getLinearVelocity: FUNC, - setLinearVelocity: FUNC, - getLinearVelocityFromWorldPoint: FUNC, - getAngularVelocity: FUNC, - setAngularVelocity: FUNC, - - getLocalVector: FUNC, - getWorldVector: FUNC, - getLocalPoint: FUNC, - getWorldPoint: FUNC, - - getLocalCenter: FUNC, - getWorldCenter: FUNC, - - applyForce: FUNC, - applyForceToCenter: FUNC, - applyTorque: FUNC, - applyLinearImpulse: FUNC, - applyLinearImpulseToCenter: FUNC, - applyAngularImpulse: FUNC, - - onEnable: FUNC, - onDisable: FUNC, - onDestroy: FUNC, -}; - -export function createRigidBody (): IRigidBody2D { - const PHYSICS_2D_BUILTIN = legacyCC._global.CC_PHYSICS_2D_BUILTIN; - - if (PHYSICS_2D_BUILTIN) { - return EntireBody; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.RigidBody)) { return null as any; } - return new WRAPPER.RigidBody() as IRigidBody2D; - } -} - -// shapes -const CREATE_COLLIDER_PROXY = { INITED: false }; - -interface IEntireShape extends IBoxShape, ICircleShape, IPolygonShape { } -const ENTIRE_SHAPE: IEntireShape = { - impl: null, - collider: null as unknown as any, - worldAABB: null as unknown as any, - worldPoints: null as unknown as any, - worldPosition: null as unknown as any, - worldRadius: null as unknown as any, - - initialize: FUNC, - apply: FUNC, - - onLoad: FUNC, - onEnable: FUNC, - onDisable: FUNC, - onDestroy: FUNC, - onGroupChanged: FUNC, -}; - -export function createShape (type: ECollider2DType): IBaseShape { - initColliderProxy(); - return CREATE_COLLIDER_PROXY[type](); -} - -function initColliderProxy () { - if (CREATE_COLLIDER_PROXY.INITED) return; - CREATE_COLLIDER_PROXY.INITED = true; - - CREATE_COLLIDER_PROXY[ECollider2DType.BOX] = function createBoxShape (): IBoxShape { - if (DEBUG && checkPhysicsModule(WRAPPER.BoxShape)) { return ENTIRE_SHAPE; } - return new WRAPPER.BoxShape() as IBoxShape; - }; - - CREATE_COLLIDER_PROXY[ECollider2DType.CIRCLE] = function createCircleShape (): ICircleShape { - if (DEBUG && checkPhysicsModule(WRAPPER.CircleShape)) { return ENTIRE_SHAPE; } - return new WRAPPER.CircleShape() as ICircleShape; - }; - - CREATE_COLLIDER_PROXY[ECollider2DType.POLYGON] = function createPolygonShape (): IPolygonShape { - if (DEBUG && checkPhysicsModule(WRAPPER.PolygonShape)) { return ENTIRE_SHAPE; } - return new WRAPPER.PolygonShape() as IPolygonShape; - }; -} - -// joints -const CREATE_JOINT_PROXY = { INITED: false }; - -interface IEntireJoint extends IDistanceJoint, IFixedJoint, IMouseJoint, ISpringJoint, IRelativeJoint, ISliderJoint, IWheelJoint, IHingeJoint { } -const ENTIRE_JOINT: IEntireJoint = { - impl: null, - - initialize: FUNC, - - setDampingRatio: FUNC, - setFrequency: FUNC, - setMaxForce: FUNC, - setTarget: FUNC, - setDistance: FUNC, - setAngularOffset: FUNC, - setCorrectionFactor: FUNC, - setLinearOffset: FUNC, - setMaxLength: FUNC, - setMaxTorque: FUNC, - setLowerLimit: FUNC, - setUpperLimit: FUNC, - setMaxMotorForce: FUNC, - setMaxMotorTorque: FUNC, - setMotorSpeed: FUNC, - enableLimit: FUNC, - enableMotor: FUNC, - setLowerAngle: FUNC, - setUpperAngle: FUNC, -}; - -export function createJoint (type: EJoint2DType): IJoint2D { - initJointProxy(); - return CREATE_JOINT_PROXY[type](); -} - -function initJointProxy () { - if (CREATE_JOINT_PROXY.INITED) return; - CREATE_JOINT_PROXY.INITED = true; - - const PHYSICS_2D_BUILTIN = legacyCC._global.CC_PHYSICS_2D_BUILTIN; - - CREATE_JOINT_PROXY[EJoint2DType.SPRING] = function createSpringJoint (): ISpringJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.SpringJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.SpringJoint() as ISpringJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.DISTANCE] = function createDistanceJoint (): IDistanceJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.DistanceJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.DistanceJoint() as IDistanceJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.FIXED] = function createFixedJoint (): IFixedJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.FixedJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.FixedJoint() as IFixedJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.MOUSE] = function createMouseJoint (): IMouseJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.MouseJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.MouseJoint() as IMouseJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.RELATIVE] = function createRelativeJoint (): IRelativeJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.RelativeJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.RelativeJoint() as IRelativeJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.SLIDER] = function createSliderJoint (): ISliderJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.SliderJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.SliderJoint() as ISliderJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.WHEEL] = function createWheelJoint (): IWheelJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.WheelJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.WheelJoint() as IWheelJoint; - } - }; - - CREATE_JOINT_PROXY[EJoint2DType.HINGE] = function createHingeJoint (): IHingeJoint { - if (PHYSICS_2D_BUILTIN) { - return ENTIRE_JOINT; - } else { - if (DEBUG && checkPhysicsModule(WRAPPER.HingeJoint)) { return ENTIRE_JOINT; } - return new WRAPPER.HingeJoint() as IHingeJoint; - } - }; -} diff --git a/cocos/physics-2d/framework/physics-internal-types.ts b/cocos/physics-2d/framework/physics-internal-types.ts index 234bf27c32b..adf9917527b 100644 --- a/cocos/physics-2d/framework/physics-internal-types.ts +++ b/cocos/physics-2d/framework/physics-internal-types.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + export declare class DelayEvent { target: Object; func: Function; diff --git a/cocos/physics-2d/framework/physics-selector.ts b/cocos/physics-2d/framework/physics-selector.ts index 1e4763e9c13..124e6122f4d 100644 --- a/cocos/physics-2d/framework/physics-selector.ts +++ b/cocos/physics-2d/framework/physics-selector.ts @@ -1,33 +1,404 @@ -import { legacyCC } from '../../core/global-exports'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import { EDITOR, DEBUG, TEST } from 'internal:constants'; +import { IRigidBody2D } from '../spec/i-rigid-body'; +import { IBoxShape, ICircleShape, IPolygonShape, IBaseShape } from '../spec/i-physics-shape'; +import { IPhysicsWorld } from '../spec/i-physics-world'; +import { errorID, cclegacy } from '../../core'; +import { ECollider2DType, EJoint2DType } from './physics-types'; +import { IJoint2D, IDistanceJoint, ISpringJoint, IFixedJoint, IMouseJoint, + IRelativeJoint, ISliderJoint, IWheelJoint, IHingeJoint } from '../spec/i-physics-joint'; + +export type IPhysicsEngineId = 'builtin' | 'box2d' | string; interface IPhysicsWrapperObject { PhysicsWorld: any, RigidBody?: any, - BoxShape: any, - CircleShape: any, + BoxShape?: any, + CircleShape?: any, PolygonShape?: any, - DistanceJoint: any, - FixedJoint: any, - MouseJoint: any, - SpringJoint: any, - RelativeJoint: any, - SliderJoint: any, - WheelJoint: any, - HingeJoint: any, + DistanceJoint?: any, + FixedJoint?: any, + MouseJoint?: any, + SpringJoint?: any, + RelativeJoint?: any, + SliderJoint?: any, + WheelJoint?: any, + HingeJoint?: any, +} + +type IPhysicsBackend = { [key: string]: IPhysicsWrapperObject; } + +export interface IPhysicsSelector { + /** + * @en + * The id of the physics engine being used by the physics system. + * @zh + * 物理系统正在使用的物理引擎的唯一标志。 + */ + readonly id: IPhysicsEngineId, + + /** + * @en + * The wrapper of the physics engine being used by the physics system. + * @zh + * 物理系统使用的物理引擎的封装层。 + */ + readonly wrapper: IPhysicsWrapperObject, + + /** + * @en + * All physics engine backends that the physics module has registered. + * @zh + * 物理模块已注册的所有物理引擎后端。 + */ + readonly backend: IPhysicsBackend, + + /** + * @en + * An instance of the physical world through which you can access the lowlevel objects. + * @zh + * 物理世界实例,通过它可以访问到底层对象。 + */ + readonly physicsWorld: IPhysicsWorld | null; + + /** + * @en + * To register the backend, the system will use the last backend registered before initialization, + * and the registration after that needs to be switched manually. + * @zh + * 注册后端,系统将使用在初始化前注册的最后一个后端,此后注册的需要手动切换。 + */ + register: (id: IPhysicsEngineId, wrapper: IPhysicsWrapperObject) => void, + + /** + * @en + * Switch to the physics backend corresponding to the id in the registry. + * @zh + * 切换为注册表里对应 id 的物理后端。 + */ + switchTo: (id: IPhysicsEngineId) => void, + + // polyfill + [x: string]: any, +} + +function register (id: IPhysicsEngineId, wrapper: IPhysicsWrapperObject): void { + if (!EDITOR && !TEST) console.info(`[PHYSICS2D]: register ${id}.`); + selector.backend[id] = wrapper; + if (!selector.physicsWorld || selector.id === id) { + const mutableSelector = selector as Mutable; + mutableSelector.id = id; + mutableSelector.wrapper = wrapper; + } +} + +function switchTo (id: IPhysicsEngineId) { + //if (!selector.runInEditor) return; + const mutableSelector = selector as Mutable; + if (selector.physicsWorld && id !== selector.id && selector.backend[id] != null) { + //selector.physicsWorld.destroy();//todo + if (!TEST) console.info(`[PHYSICS2D]: switch from ${selector.id} to ${id}.`); + mutableSelector.id = id; + mutableSelector.wrapper = selector.backend[id]; + mutableSelector.physicsWorld = createPhysicsWorld(); + } else { + if (!EDITOR && !TEST) console.info(`[PHYSICS2D]: using ${mutableSelector.id}.`); + mutableSelector.physicsWorld = createPhysicsWorld(); + } +} + +/** + * @en + * The physics selector is used to register and switch the physics engine backend. + * @zh + * 物理选择器用于注册和切换物理引擎后端。 + */ +export const selector: IPhysicsSelector = { + id: '', + switchTo, + register, + wrapper: {} as any, + backend: {} as any, + physicsWorld: null as any, + + /// hide for now /// + runInEditor: !EDITOR, +}; + +const FUNC = (...v: any) => 0 as any; +const ENTIRE_WORLD: IPhysicsWorld = { + impl: null, + debugDrawFlags: 0, + setGravity: FUNC, + setAllowSleep: FUNC, + step: FUNC, + syncPhysicsToScene: FUNC, + syncSceneToPhysics: FUNC, + raycast: FUNC, + testPoint: FUNC, + testAABB: FUNC, + drawDebug: FUNC, + finalizeContactEvent: FUNC, +}; + +export function checkPhysicsModule (obj: any) { + if (DEBUG && !TEST && (!EDITOR || cclegacy.GAME_VIEW) && obj == null) { + errorID(9600); + return true; + } + return false; } -type IPhysicsEngineId = 'builtin' | 'box2d' | string | undefined; +export function createPhysicsWorld (): IPhysicsWorld { + if (DEBUG && checkPhysicsModule(selector.wrapper.PhysicsWorld)) { return ENTIRE_WORLD; } + return new selector.wrapper.PhysicsWorld(); +} + +const EntireBody: IRigidBody2D = { + impl: null as any, + rigidBody: null as any, + isAwake: false, + isSleeping: false, + + initialize: FUNC, + + setType: FUNC, + + setLinearDamping: FUNC, + setAngularDamping: FUNC, + setGravityScale: FUNC, + setFixedRotation: FUNC, + setAllowSleep: FUNC, + + isActive: FUNC, + setActive: FUNC, + + wakeUp: FUNC, + sleep: FUNC, + + getMass: FUNC, + getInertia: FUNC, + + getLinearVelocity: FUNC, + setLinearVelocity: FUNC, + getLinearVelocityFromWorldPoint: FUNC, + getAngularVelocity: FUNC, + setAngularVelocity: FUNC, + + getLocalVector: FUNC, + getWorldVector: FUNC, + getLocalPoint: FUNC, + getWorldPoint: FUNC, + + getLocalCenter: FUNC, + getWorldCenter: FUNC, + + applyForce: FUNC, + applyForceToCenter: FUNC, + applyTorque: FUNC, + applyLinearImpulse: FUNC, + applyLinearImpulseToCenter: FUNC, + applyAngularImpulse: FUNC, + + onEnable: FUNC, + onDisable: FUNC, + onDestroy: FUNC, +}; + +export function createRigidBody (): IRigidBody2D { + const PHYSICS_2D_BUILTIN = selector.id === 'builtin'; + + if (PHYSICS_2D_BUILTIN) { + return EntireBody; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.RigidBody)) { return EntireBody; } + return new selector.wrapper.RigidBody(); + } +} + +// shapes +const CREATE_COLLIDER_PROXY = { INITED: false }; + +interface IEntireShape extends IBoxShape, ICircleShape, IPolygonShape { } +const ENTIRE_SHAPE: IEntireShape = { + impl: null, + collider: null as unknown as any, + worldAABB: null as unknown as any, + worldPoints: null as unknown as any, + worldPosition: null as unknown as any, + worldRadius: null as unknown as any, + + initialize: FUNC, + apply: FUNC, + + onLoad: FUNC, + onEnable: FUNC, + onDisable: FUNC, + onDestroy: FUNC, + onGroupChanged: FUNC, +}; + +export function createShape (type: ECollider2DType): IBaseShape { + initColliderProxy(); + return CREATE_COLLIDER_PROXY[type](); +} + +function initColliderProxy () { + if (CREATE_COLLIDER_PROXY.INITED) return; + CREATE_COLLIDER_PROXY.INITED = true; + + CREATE_COLLIDER_PROXY[ECollider2DType.BOX] = function createBoxShape (): IBoxShape { + if (DEBUG && checkPhysicsModule(selector.wrapper.BoxShape)) { return ENTIRE_SHAPE; } + return new selector.wrapper.BoxShape(); + }; + + CREATE_COLLIDER_PROXY[ECollider2DType.CIRCLE] = function createCircleShape (): ICircleShape { + if (DEBUG && checkPhysicsModule(selector.wrapper.CircleShape)) { return ENTIRE_SHAPE; } + return new selector.wrapper.CircleShape(); + }; + + CREATE_COLLIDER_PROXY[ECollider2DType.POLYGON] = function createPolygonShape (): IPolygonShape { + if (DEBUG && checkPhysicsModule(selector.wrapper.PolygonShape)) { return ENTIRE_SHAPE; } + return new selector.wrapper.PolygonShape(); + }; +} + +// joints +const CREATE_JOINT_PROXY = { INITED: false }; + +interface IEntireJoint extends IDistanceJoint, IFixedJoint, IMouseJoint, ISpringJoint, IRelativeJoint, ISliderJoint, IWheelJoint, IHingeJoint { } +const ENTIRE_JOINT: IEntireJoint = { + impl: null, + + initialize: FUNC, + + setDampingRatio: FUNC, + setFrequency: FUNC, + setMaxForce: FUNC, + setTarget: FUNC, + setDistance: FUNC, + setAngularOffset: FUNC, + setCorrectionFactor: FUNC, + setLinearOffset: FUNC, + setMaxLength: FUNC, + setMaxTorque: FUNC, + setLowerLimit: FUNC, + setUpperLimit: FUNC, + setMaxMotorForce: FUNC, + setMaxMotorTorque: FUNC, + setMotorSpeed: FUNC, + enableLimit: FUNC, + enableMotor: FUNC, + setLowerAngle: FUNC, + setUpperAngle: FUNC, +}; + +export function createJoint (type: EJoint2DType): IJoint2D { + initJointProxy(); + return CREATE_JOINT_PROXY[type](); +} + +function initJointProxy () { + if (CREATE_JOINT_PROXY.INITED) return; + CREATE_JOINT_PROXY.INITED = true; + + const PHYSICS_2D_BUILTIN = selector.id === 'builtin'; + + CREATE_JOINT_PROXY[EJoint2DType.SPRING] = function createSpringJoint (): ISpringJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.SpringJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.SpringJoint(); + } + }; + + CREATE_JOINT_PROXY[EJoint2DType.DISTANCE] = function createDistanceJoint (): IDistanceJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.DistanceJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.DistanceJoint(); + } + }; + + CREATE_JOINT_PROXY[EJoint2DType.FIXED] = function createFixedJoint (): IFixedJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.FixedJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.FixedJoint(); + } + }; + + CREATE_JOINT_PROXY[EJoint2DType.MOUSE] = function createMouseJoint (): IMouseJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.MouseJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.MouseJoint(); + } + }; -export let WRAPPER: IPhysicsWrapperObject; + CREATE_JOINT_PROXY[EJoint2DType.RELATIVE] = function createRelativeJoint (): IRelativeJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.RelativeJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.RelativeJoint(); + } + }; -export let physicsEngineId: IPhysicsEngineId; + CREATE_JOINT_PROXY[EJoint2DType.SLIDER] = function createSliderJoint (): ISliderJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.SliderJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.SliderJoint(); + } + }; -export function select (id: IPhysicsEngineId, wrapper: IPhysicsWrapperObject) { - physicsEngineId = id; - legacyCC._global.CC_PHYSICS_2D_BUILTIN = id == 'builtin'; - legacyCC._global.CC_PHYSICS_2D_BOX2D = id == 'box2d'; + CREATE_JOINT_PROXY[EJoint2DType.WHEEL] = function createWheelJoint (): IWheelJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.WheelJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.WheelJoint(); + } + }; - WRAPPER = wrapper; + CREATE_JOINT_PROXY[EJoint2DType.HINGE] = function createHingeJoint (): IHingeJoint { + if (PHYSICS_2D_BUILTIN) { + return ENTIRE_JOINT; + } else { + if (DEBUG && checkPhysicsModule(selector.wrapper.HingeJoint)) { return ENTIRE_JOINT; } + return new selector.wrapper.HingeJoint(); + } + }; } diff --git a/cocos/physics-2d/framework/physics-system.ts b/cocos/physics-2d/framework/physics-system.ts index 670801b00fa..e5ae6f4f476 100644 --- a/cocos/physics-2d/framework/physics-system.ts +++ b/cocos/physics-2d/framework/physics-system.ts @@ -1,19 +1,40 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { EDITOR } from 'internal:constants'; -import { System, Vec2, IVec2Like, Rect, Eventify, Enum } from '../../core'; -import { IPhysicsWorld } from '../spec/i-physics-world'; -import { createPhysicsWorld } from './instance'; -import { physicsEngineId } from './physics-selector'; +import { System, Vec2, IVec2Like, Rect, Eventify, Enum, Settings, settings, cclegacy, warnID } from '../../core'; +import { createPhysicsWorld, selector, IPhysicsSelector } from './physics-selector'; + import { DelayEvent } from './physics-internal-types'; import { ICollisionMatrix } from '../../physics/framework/physics-config'; import { CollisionMatrix } from '../../physics/framework/collision-matrix'; -import { ERaycast2DType, RaycastResult2D, PHYSICS_2D_PTM_RATIO, PhysicsGroup } from './physics-types'; +import { ERaycast2DType, RaycastResult2D, PHYSICS_2D_PTM_RATIO, PhysicsGroup, Contact2DType } from './physics-types'; import { Collider2D } from './components/colliders/collider-2d'; -import { legacyCC } from '../../core/global-exports'; -import { Settings, settings } from '../../core/settings'; import { director, Director } from '../../game'; let instance: PhysicsSystem2D | null = null; -legacyCC.internal.PhysicsGroup2D = PhysicsGroup; +cclegacy.internal.PhysicsGroup2D = PhysicsGroup; export class PhysicsSystem2D extends Eventify(System) { /** @@ -40,7 +61,7 @@ export class PhysicsSystem2D extends Eventify(System) { } set allowSleep (v: boolean) { this._allowSleep = v; - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.physicsWorld.setAllowSleep(v); } } @@ -56,7 +77,7 @@ export class PhysicsSystem2D extends Eventify(System) { } set gravity (gravity: Vec2) { this._gravity.set(gravity); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.physicsWorld.setGravity(new Vec2(gravity.x / PHYSICS_2D_PTM_RATIO, gravity.y / PHYSICS_2D_PTM_RATIO)); } } @@ -114,14 +135,14 @@ export class PhysicsSystem2D extends Eventify(System) { * @en * The velocity iterations for the velocity constraint solver. * @zh - * 速度更新迭代数 + * 速度更新迭代数。 */ public velocityIterations = 10; /** * @en * The position Iterations for the position constraint solver. * @zh - * 位置迭代更新数 + * 位置迭代更新数。 */ public positionIterations = 10; @@ -131,7 +152,9 @@ export class PhysicsSystem2D extends Eventify(System) { * @zh * 获取物理世界的封装对象,通过它你可以访问到实际的底层对象。 */ - readonly physicsWorld: IPhysicsWorld; + public get physicsWorld () { + return selector.physicsWorld!; + } /** * @en @@ -142,15 +165,15 @@ export class PhysicsSystem2D extends Eventify(System) { static readonly ID = 'PHYSICS_2D'; static get PHYSICS_NONE () { - return !physicsEngineId; + return !selector.id; } static get PHYSICS_BUILTIN () { - return physicsEngineId === 'builtin'; + return selector.id === 'builtin'; } static get PHYSICS_BOX2D () { - return physicsEngineId === 'box2d'; + return selector.id === 'box2d'; } /** @@ -229,7 +252,9 @@ export class PhysicsSystem2D extends Eventify(System) { } } - this.physicsWorld = createPhysicsWorld(); + const mutableSelector = selector as Mutable; + mutableSelector.physicsWorld = createPhysicsWorld(); + this.gravity = this._gravity; this.allowSleep = this._allowSleep; } @@ -239,7 +264,7 @@ export class PhysicsSystem2D extends Eventify(System) { * Perform a simulation of the physics system, which will now be performed automatically on each frame. * @zh * 执行一次物理系统的模拟,目前将在每帧自动执行一次。 - * @param deltaTime 与上一次执行相差的时间,目前为每帧消耗时间 + * @param deltaTime @en time step. @zh 与上一次执行相差的时间,目前为每帧消耗时间。 */ postUpdate (deltaTime: number) { if (!this._enable) { @@ -251,6 +276,8 @@ export class PhysicsSystem2D extends Eventify(System) { director.emit(Director.EVENT_BEFORE_PHYSICS); + this.physicsWorld.syncSceneToPhysics(); + this._steping = true; const fixedTimeStep = this._fixedTimeStep; @@ -273,6 +300,8 @@ export class PhysicsSystem2D extends Eventify(System) { this.physicsWorld.syncPhysicsToScene(); + this.physicsWorld.finalizeContactEvent(); + if (this.debugDrawFlags) { this.physicsWorld.drawDebug(); } @@ -281,6 +310,7 @@ export class PhysicsSystem2D extends Eventify(System) { director.emit(Director.EVENT_AFTER_PHYSICS); } + // eslint-disable-next-line @typescript-eslint/ban-types _callAfterStep (target: object, func: Function) { if (this._steping) { this._delayEvents.push({ @@ -320,10 +350,10 @@ export class PhysicsSystem2D extends Eventify(System) { * @zh * 检测哪些碰撞体在给定射线的路径上,射线检测将忽略包含起始点的碰撞体。 * @method rayCast - * @param {Vec2} p1 - start point of the raycast - * @param {Vec2} p2 - end point of the raycast - * @param {RayCastType} type - optional, default is RayCastType.Closest - * @param {number} mask - optional, default is 0xffffffff + * @param {Vec2} p1 @en start point of the raycast. @zh 射线起点。 + * @param {Vec2} p2 @en end point of the raycast. @zh 射线终点。 + * @param {RayCastType} type - @en optional, default is RayCastType.Closest. @zh 可选,默认是RayCastType.Closest。 + * @param {number} mask - @en optional, default is 0xffffffff. @zh 可选,默认是0xffffffff。 * @return {[PhysicsRayCastResult]} */ raycast (p1: IVec2Like, p2: IVec2Like, type: ERaycast2DType = ERaycast2DType.Closest, mask = 0xffffffff): readonly Readonly[] { @@ -345,14 +375,17 @@ export class PhysicsSystem2D extends Eventify(System) { testAABB (rect: Rect): readonly Collider2D[] { return this.physicsWorld.testAABB(rect); } -} -director.once(Director.EVENT_INIT, () => { - initPhysicsSystem(); -}); + public on void>(type: string, callback: TFunction, thisArg?: any, once?: boolean): typeof callback { + if (type === Contact2DType.PRE_SOLVE || type === Contact2DType.POST_SOLVE) { + warnID(16002, type, '3.7.1'); + } + return super.on(type, callback, thisArg, once); + } +} function initPhysicsSystem () { - if (!PhysicsSystem2D.PHYSICS_NONE && (!EDITOR || legacyCC.GAME_VIEW)) { - director.registerSystem(PhysicsSystem2D.ID, PhysicsSystem2D.instance, System.Priority.LOW); - } + director.registerSystem(PhysicsSystem2D.ID, PhysicsSystem2D.instance, System.Priority.LOW); } + +director.once(Director.EVENT_INIT, () => { initPhysicsSystem(); }); diff --git a/cocos/physics-2d/framework/physics-types.ts b/cocos/physics-2d/framework/physics-types.ts index 9a2a1718fd0..426d1215653 100644 --- a/cocos/physics-2d/framework/physics-types.ts +++ b/cocos/physics-2d/framework/physics-types.ts @@ -1,4 +1,26 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Enum, Vec2 } from '../../core'; import { Collider2D } from './components/colliders/collider-2d'; @@ -63,15 +85,15 @@ Enum(PhysicsGroup); /** * @en Enum for ERaycast2DType. - * @zh 射线检测类型 - * @enum ERaycast2DType + * @zh 射线检测类型。 + * @enum ERaycast2DType. */ export enum ERaycast2DType { /** * @en * Detects closest collider on the raycast path. * @zh - * 检测射线路径上最近的碰撞体 + * 检测射线路径上最近的碰撞体。 */ Closest, /** @@ -108,8 +130,19 @@ export enum ERaycast2DType { export const Contact2DType = { None: 'none-contact', BEGIN_CONTACT: 'begin-contact', + STAY_CONTACT: 'stay-contact', END_CONTACT: 'end-contact', + + /** + * @deprecated Since v3.7.1, PhysicsSystem2D doesn't directly emit the contact events emitted by box2d. + * If you need this event, try to modify the relevant engine code(mainly PhysicsContactListener). + */ PRE_SOLVE: 'pre-solve', + + /** + * @deprecated Since v3.7.1, PhysicsSystem2D doesn't directly emit the contact events emitted by box2d. + * If you need this event, try to modify the relevant engine code(mainly PhysicsContactListener). + */ POST_SOLVE: 'post-solve', }; diff --git a/cocos/physics-2d/framework/utils/polygon-partition.ts b/cocos/physics-2d/framework/utils/polygon-partition.ts new file mode 100644 index 00000000000..0017946be71 --- /dev/null +++ b/cocos/physics-2d/framework/utils/polygon-partition.ts @@ -0,0 +1,316 @@ +/* + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { IVec2Like } from '../../../core'; + +//https://github.com/x6ud/poly-partition-js + +/** +* @en +* Decompose the polygon into several convex polygon using Hertel-Mehlhorn algorithm. +* If the polygon is already convex, it will return the original polygon. +* @zh +* 使用Hertel-Mehlhorn算法将输入多边形拆分成多个凸多边形。如果输入多边形是凸多边形,将返回原多边形。 +* @param polygon @en one polygon. @zh 一个多边形。 +* @return @en polygon array. @zh 多边形数组。 +*/ +export function ConvexPartition (polygon: IVec2Like[]) { + // We force it to CCW as it is a precondition in this algorithm. + ForceCounterClockWise(polygon); + + //check if the poly is already convex + let convex = true; + for (let i = 0, len = polygon.length; i < len; ++i) { + if (!isConvex(polygon[(i + len - 1) % len], polygon[i], polygon[(i + 1) % len])) { + convex = false; + break; + } + } + if (convex) { + return [polygon]; + } + + const ret: IVec2Like[][] = []; + const triangles = Triangulate(polygon); + if (!triangles) return null; + for (; triangles.length;) { + let poly = triangles.splice(0, 1)[0]; + for (let iPoly = 0, polyLen = poly.length; iPoly < polyLen; ++iPoly) { + const diag1 = poly[iPoly]; + const diag2 = poly[(iPoly + 1) % polyLen]; + // find diagonal + let tri3: (IVec2Like | null) = null; + let iTri2 = 0; + for (; iTri2 < triangles.length; ++iTri2) { + const triangle = triangles[iTri2] as [IVec2Like, IVec2Like, IVec2Like]; + for (let i = 0; i < 3; ++i) { + const tri1 = triangle[i]; + const tri2 = triangle[(i + 1) % 3]; + if (equals(diag1, tri2) && equals(diag2, tri1)) { + tri3 = triangle[(i + 2) % 3]; + break; + } + } + if (tri3) { + break; + } + } + if (!tri3) { // not a diagonal + continue; + } + if (area(poly[(iPoly + polyLen - 1) % polyLen], diag1, tri3) > 0) { // neither convex nor on the same line + continue; + } + if (area(tri3, diag2, poly[(iPoly + 2) % polyLen]) > 0) { + continue; + } + // merge triangle + const newPoly: IVec2Like[] = []; + for (let i = (iPoly + 1) % polyLen; i !== iPoly; i = (i + 1) % polyLen) { + newPoly.push(poly[i]); + } + newPoly.push(diag1, tri3); + poly = newPoly; + polyLen = newPoly.length; + iPoly = -1; + triangles.splice(iTri2, 1); + } + ret.push(poly); + } + return ret; +} + +class Vertex { + public isActive = false; + public isConvex = false; + public isEar = false; + public point: IVec2Like| null = null; + public angleCos = 0; + public shouldUpdate = false; + public index = 0; + public prev: Vertex| null = null; + public next: Vertex| null = null; +} + +// Signed area. +function area (a: IVec2Like, b: IVec2Like, c: IVec2Like) { + return (b.y - a.y) * (c.x - b.x) - (b.x - a.x) * (c.y - b.y); +} + +// Whether corner of a counterclockwise polygon is convex. +function isConvex (p1: IVec2Like, p2: IVec2Like, p3: IVec2Like) { + return area(p1, p2, p3) < 0; +} + +function equals (a: IVec2Like, b: IVec2Like) { + return a.x === b.x && a.y === b.y; +} + +function isClockwise (polygon: IVec2Like[]) { + let sum = 0; + for (let i = 0, len = polygon.length; i < len; ++i) { + const p1 = polygon[i]; + const p2 = polygon[(i + 1) % len]; + sum += (p2.x - p1.x) * (p2.y + p1.y); + } + return sum > 0; +} + +// Forces counter clock wise order. +function ForceCounterClockWise (vertices: IVec2Like[]) { + if (isClockwise(vertices)) { + vertices.reverse(); + } +} + +function updateVertex (vertex: Vertex, vertices: Vertex[]) { + if (!vertex.shouldUpdate) { + return; + } + vertex.shouldUpdate = false; + const v1 = vertex.prev!.point!; + const v2 = vertex.point!; + const v3 = vertex.next!.point!; + vertex.isConvex = isConvex(v1, v2, v3); + let v1x = v1.x - v2.x; + let v1y = v1.y - v2.y; + const v1Len = Math.sqrt(v1x * v1x + v1y * v1y); + v1x /= v1Len; + v1y /= v1Len; + let v3x = v3.x - v2.x; + let v3y = v3.y - v2.y; + const v3Len = Math.sqrt(v3x * v3x + v3y * v3y); + v3x /= v3Len; + v3y /= v3Len; + vertex.angleCos = v1x * v3x + v1y * v3y; + if (vertex.isConvex) { + vertex.isEar = true; + for (let i = 0, len = vertices.length; i < len; ++i) { + const curr = vertices[i]; + if (!curr.isActive || curr === vertex) { + continue; + } + const currentPoint = curr.point!; + if (equals(v1, currentPoint) || equals(v2, currentPoint) || equals(v3, currentPoint)) { + continue; + } + const areaA = area(v1, currentPoint, v2); + const areaB = area(v2, currentPoint, v3); + const areaC = area(v3, currentPoint, v1); + if (areaA > 0 && areaB > 0 && areaC > 0) { + vertex.isEar = false; + break; + } + if (areaA === 0 && areaB >= 0 && areaC >= 0) { + if (area(v1, curr.prev!.point!, v2) > 0 || area(v1, curr.next!.point!, v2) > 0) { + vertex.isEar = false; + break; + } + } + if (areaB === 0 && areaA >= 0 && areaC >= 0) { + if (area(v2, curr.prev!.point!, v3) > 0 || area(v2, curr.next!.point!, v3) > 0) { + vertex.isEar = false; + break; + } + } + if (areaC === 0 && areaA >= 0 && areaB >= 0) { + if (area(v3, curr.prev!.point!, v1) > 0 || area(v3, curr.next!.point!, v1) > 0) { + vertex.isEar = false; + break; + } + } + } + } else { + vertex.isEar = false; + } +} + +function removeCollinearOrDuplicate (start: Vertex) { + for (let curr = start, end = start; ;) { + if (equals(curr.point!, curr.next!.point!) + || area(curr.prev!.point!, curr.point!, curr.next!.point!) === 0) { + curr.prev!.next = curr.next; + curr.next!.prev = curr.prev; + curr.prev!.shouldUpdate = true; + curr.next!.shouldUpdate = true; + if (curr === curr.next) { + break; + } + end = curr.prev!; + curr = curr.next!; + continue; + } + curr = curr.next!; + if (curr === end) { + break; + } + } +} + +// Triangulation by ear clipping. +function Triangulate (polygon: IVec2Like[]) { + ForceCounterClockWise(polygon); + + if (polygon.length < 4) { + return [polygon]; + } + const len = polygon.length; + const vertices: Vertex[] = []; + const triangles: [IVec2Like, IVec2Like, IVec2Like][] = []; + // init + for (let i = 0; i < len; ++i) { + const v = new Vertex(); + v.isActive = true; + v.isConvex = false; + v.isEar = false; + v.point = polygon[i]; + v.angleCos = 0; + v.shouldUpdate = true; + v.index = i; + vertices.push(v); + } + for (let i = 0; i < len; ++i) { + const vertex = vertices[i]; + vertex.prev = vertices[(i + len - 1) % len]; + vertex.next = vertices[(i + 1) % len]; + } + vertices.forEach((vertex) => updateVertex(vertex, vertices)); + for (let i = 0; i < len - 3; ++i) { + let ear; + // find the most extruded ear + for (let j = 0; j < len; ++j) { + const vertex = vertices[j]; + if (!vertex.isActive || !vertex.isEar) { + continue; + } + if (!ear) { + ear = vertex; + } else if (vertex.angleCos > ear.angleCos) { + ear = vertex; + } + } + if (!ear) { + for (let i_1 = 0; i_1 < len; ++i_1) { + const vertex = vertices[i_1]; + if (vertex.isActive) { + const p1 = vertex.prev!.point!; + const p2 = vertex.point!; + const p3 = vertex.next!.point!; + if (Math.abs(area(p1, p2, p3)) > 1e-5) { + console.log('Failed to find ear. There might be self-intersection in the polygon.'); + return null; + } + } + } + break; + } + triangles.push([ear.prev.point, ear.point, ear.next.point]); + ear.isActive = false; + ear.prev.next = ear.next; + ear.next.prev = ear.prev; + ear.prev.shouldUpdate = true; + ear.next.shouldUpdate = true; + removeCollinearOrDuplicate(ear.next); + if (i === len - 4) { + break; + } + for (let i_2 = 0; i_2 < len; ++i_2) { + updateVertex(vertices[i_2], vertices); + } + } + for (let i = 0; i < len; ++i) { + const vertex = vertices[i]; + if (vertex.isActive) { + vertex.prev!.isActive = false; + vertex.next!.isActive = false; + const p1 = vertex.prev!.point!; + const p2 = vertex.point!; + const p3 = vertex.next!.point!; + if (Math.abs(area(p1, p2, p3)) > 1e-5) { + triangles.push([p1, p2, p3]); + } + } + } + return triangles; +} diff --git a/cocos/physics-2d/framework/utils/polygon-separator.ts b/cocos/physics-2d/framework/utils/polygon-separator.ts index 715c196c22a..2522dbd698f 100644 --- a/cocos/physics-2d/framework/utils/polygon-separator.ts +++ b/cocos/physics-2d/framework/utils/polygon-separator.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec2Like, Vec2 } from '../../../core'; @@ -55,13 +54,16 @@ function Copy (i: number, j: number, vertices: IVec2Like[]) { return p; } -/// -/// Decompose the polygon into several smaller non-concave polygon. -/// If the polygon is already convex, it will return the original polygon, unless it is over Settings.MaxPolygonVertices. -/// Precondition: Counter Clockwise polygon -/// -/// -/// +/** +* @en +* Decompose the polygon into several smaller non-concave polygon. +* If the polygon is already convex, it will return the original polygon, unless it is over Settings.MaxPolygonVertices. +* Precondition: Counter Clockwise polygon +* @zh +* 使用Mark Bayazit算法将输入多边形拆分成多个凸多边形。如果输入多边形是凸多边形,将返回原多边形。要求输入多边形是逆时针的。 +* @param polygon @en one polygon. @zh 一个多边形。 +* @return @en polygon array. @zh 多边形数组。 +*/ export function ConvexPartition (vertices: IVec2Like[]) { // We force it to CCW as it is a precondition in this algorithm. ForceCounterClockWise(vertices); diff --git a/cocos/physics-2d/spec/i-physics-contact.ts b/cocos/physics-2d/spec/i-physics-contact.ts index dd22d36b2f0..e661ff180fb 100644 --- a/cocos/physics-2d/spec/i-physics-contact.ts +++ b/cocos/physics-2d/spec/i-physics-contact.ts @@ -1,4 +1,26 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import { Vec2 } from '../../core'; import { Collider2D } from '../framework/components/colliders/collider-2d'; @@ -14,15 +36,15 @@ export interface IPhysics2DImpulse { * @en * Normal impulses. * @zh - * 法线方向的冲量 + * 法线方向的冲量。 * @property normalImpulses */ normalImpulses: number[], /** * @en - * Tangent impulses + * Tangent impulses. * @zh - * 切线方向的冲量 + * 切线方向的冲量。 * @property tangentImpulses */ tangentImpulses: number[], @@ -45,24 +67,24 @@ export interface IPhysics2DWorldManifold { /** * @en - * a negative value indicates overlap + * a negative value indicates overlap. * @zh - * 一个负数,用于指明重叠的部分 + * 一个负数,用于指明重叠的部分。 */ separations: number[], /** * @en - * world vector pointing from A to B + * world vector pointing from A to B. * @zh - * 世界坐标系下由 A 指向 B 的向量 + * 世界坐标系下由 A 指向 B 的向量。 */ normal: Vec2, } /** - * @en Manifold Type - * @zh 流形类型 + * @en Manifold Type. + * @zh 流形类型。 */ export enum Physics2DManifoldType { Circles, @@ -84,14 +106,14 @@ export interface IPhysics2DManifoldPoint { /** * @en * The local point usage depends on the manifold type: - * - Physics2DManifoldType.Circles: the local center of circleB - * - Physics2DManifoldType.FaceA: the local center of circleB or the clip point of polygonB - * - Physics2DManifoldType.FaceB: the clip point of polygonA + * - Physics2DManifoldType.Circles: the local center of circleB. + * - Physics2DManifoldType.FaceA: the local center of circleB or the clip point of polygonB. + * - Physics2DManifoldType.FaceB: the clip point of polygonA. * @zh - * 本地坐标点的用途取决于 manifold 的类型 - * - Physics2DManifoldType.Circles: circleB 的本地中心点 - * - Physics2DManifoldType.FaceA: circleB 的本地中心点 或者是 polygonB 的截取点 - * - Physics2DManifoldType.FaceB: polygonB 的截取点 + * 本地坐标点的用途取决于 manifold 的类型。 + * - Physics2DManifoldType.Circles: circleB 的本地中心点。 + * - Physics2DManifoldType.FaceA: circleB 的本地中心点 或者是 polygonB 的截取点。 + * - Physics2DManifoldType.FaceB: polygonB 的截取点。 */ localPoint: Vec2; /** @@ -111,39 +133,39 @@ export interface IPhysics2DManifoldPoint { } /** - * @en Manifold - * @zh 流形 + * @en Manifold. + * @zh 流形。 */ export interface IPhysics2DManifold { /** * @en - * Manifold type + * Manifold type. * @zh - * Manifold 类型 + * Manifold 类型。 */ type: Physics2DManifoldType, /** * @en * The local point usage depends on the manifold type: - * -Physics2DManifoldType.Circles: the local center of circleA - * -Physics2DManifoldType.FaceA: the center of faceA - * -Physics2DManifoldType.FaceB: the center of faceB + * -Physics2DManifoldType.Circles: the local center of circleA. + * -Physics2DManifoldType.FaceA: the center of faceA. + * -Physics2DManifoldType.FaceB: the center of faceB. * @zh * 用途取决于 manifold 类型 - * -Physics2DManifoldType.Circles: circleA 的本地中心点 - * -Physics2DManifoldType.FaceA: faceA 的本地中心点 - * -Physics2DManifoldType.FaceB: faceB 的本地中心点 + * -Physics2DManifoldType.Circles: circleA 的本地中心点。 + * -Physics2DManifoldType.FaceA: faceA 的本地中心点。 + * -Physics2DManifoldType.FaceB: faceB 的本地中心点。 */ localPoint: Vec2, /** * @en - * -Physics2DManifoldType.Circles: not used - * -Physics2DManifoldType.FaceA: the normal on polygonA - * -Physics2DManifoldType.FaceB: the normal on polygonB + * -Physics2DManifoldType.Circles: not used. + * -Physics2DManifoldType.FaceA: the normal on polygonA. + * -Physics2DManifoldType.FaceB: the normal on polygonB. * @zh - * -Physics2DManifoldType.Circles: 没被使用到 - * -Physics2DManifoldType.FaceA: polygonA 的法向量 - * -Physics2DManifoldType.FaceB: polygonB 的法向量 + * -Physics2DManifoldType.Circles: 没被使用到。 + * -Physics2DManifoldType.FaceA: polygonA 的法向量。 + * -Physics2DManifoldType.FaceB: polygonB 的法向量。 */ localNormal: Vec2, @@ -167,16 +189,16 @@ export interface IPhysics2DManifold { export interface IPhysics2DContact { /** * @en - * One of the collider that collided + * One of the collider that collided. * @zh - * 发生碰撞的碰撞体之一 + * 发生碰撞的碰撞体之一。 */ colliderA: Collider2D | null; /** * @en - * One of the collider that collided + * One of the collider that collided. * @zh - * 发生碰撞的碰撞体之一 + * 发生碰撞的碰撞体之一。 */ colliderB: Collider2D | null; /** @@ -217,8 +239,8 @@ export interface IPhysics2DContact { * Get the impulses. * Note: PhysicsImpulse can only used in onPostSolve callback. * @zh - * 获取冲量信息 - * 注意:这个信息只有在 onPostSolve 回调中才能获取到 + * 获取冲量信息。 + * 注意:这个信息只有在 onPostSolve 回调中才能获取到。 */ getImpulse (): IPhysics2DImpulse | null; @@ -233,14 +255,14 @@ export interface IPhysics2DContact { * @en * Set the desired tangent speed for a conveyor belt behavior. * @zh - * 为传送带设置期望的切线速度 + * 为传送带设置期望的切线速度。 */ setTangentSpeed (value: number); /** * @en * Get the desired tangent speed. * @zh - * 获取切线速度 + * 获取切线速度。 */ getTangentSpeed (): number; @@ -255,7 +277,7 @@ export interface IPhysics2DContact { * @en * Get the friction. * @zh - * 获取当前摩擦力系数 + * 获取当前摩擦力系数。 */ getFriction (): number; /** @@ -269,7 +291,7 @@ export interface IPhysics2DContact { * @en * Get the restitution. * @zh - * 获取当前恢复系数 + * 获取当前恢复系数。 */ getRestitution (): number; } diff --git a/cocos/physics-2d/spec/i-physics-joint.ts b/cocos/physics-2d/spec/i-physics-joint.ts index d01d5070479..67b5d7cd999 100644 --- a/cocos/physics-2d/spec/i-physics-joint.ts +++ b/cocos/physics-2d/spec/i-physics-joint.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { IVec2Like } from '../../core'; diff --git a/cocos/physics-2d/spec/i-physics-shape.ts b/cocos/physics-2d/spec/i-physics-shape.ts index e997faed6b7..8c1fc225646 100644 --- a/cocos/physics-2d/spec/i-physics-shape.ts +++ b/cocos/physics-2d/spec/i-physics-shape.ts @@ -1,4 +1,27 @@ -import { IVec3Like } from '../../core/math/type-define'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { Rect, Vec2 } from '../../core'; import { ILifecycle } from '../../physics/spec/i-lifecycle'; import { Collider2D, RigidBody2D } from '../../../exports/physics-2d-framework'; diff --git a/cocos/physics-2d/spec/i-physics-world.ts b/cocos/physics-2d/spec/i-physics-world.ts index 549c877b442..7109c439c8a 100644 --- a/cocos/physics-2d/spec/i-physics-world.ts +++ b/cocos/physics-2d/spec/i-physics-world.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { IVec2Like, Rect, Vec2 } from '../../core'; import { ERaycast2DType, RaycastResult2D, Collider2D } from '../framework'; @@ -14,4 +38,5 @@ export interface IPhysicsWorld { testPoint (p: Vec2): readonly Collider2D[]; testAABB (rect: Rect): readonly Collider2D[]; drawDebug (): void; + finalizeContactEvent(): void } diff --git a/cocos/physics-2d/spec/i-rigid-body.ts b/cocos/physics-2d/spec/i-rigid-body.ts index 8868959952f..7257937705c 100644 --- a/cocos/physics-2d/spec/i-rigid-body.ts +++ b/cocos/physics-2d/spec/i-rigid-body.ts @@ -1,8 +1,31 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ILifecycle } from '../../physics/spec/i-lifecycle'; -import { IVec2Like } from '../../core/math/type-define'; +import { IVec2Like, Vec2 } from '../../core'; import { RigidBody2D } from '../framework/components/rigid-body-2d'; import { ERigidBody2DType } from '../framework/physics-types'; -import { Vec2 } from '../../core'; export interface IRigidBody2D extends ILifecycle { readonly impl: any; diff --git a/cocos/physics/bullet/bullet-bvh-triangle-mesh-shape.ts b/cocos/physics/bullet/bullet-bvh-triangle-mesh-shape.ts new file mode 100644 index 00000000000..bb2805268dc --- /dev/null +++ b/cocos/physics/bullet/bullet-bvh-triangle-mesh-shape.ts @@ -0,0 +1,72 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { bt, EBulletType } from './instantiated'; +import { Mesh } from '../../3d/assets'; +import { cocos2BulletTriMesh } from './bullet-utils'; + +export class BulletBvhTriangleMeshShape { + private static readonly BulletBvhTriangleMeshShapeMap = new Map(); + + public static getBulletBvhTriangleMeshShape (key: number, mesh: Mesh) { + let newBulletBvhTriangleMeshShape!: BulletBvhTriangleMeshShape; + if (BulletBvhTriangleMeshShape.BulletBvhTriangleMeshShapeMap.has(key)) { //can be improved + newBulletBvhTriangleMeshShape = BulletBvhTriangleMeshShape.BulletBvhTriangleMeshShapeMap.get(key)!; + newBulletBvhTriangleMeshShape.reference = true; + } else { + newBulletBvhTriangleMeshShape = new BulletBvhTriangleMeshShape(key, mesh); + BulletBvhTriangleMeshShape.BulletBvhTriangleMeshShapeMap.set(key, newBulletBvhTriangleMeshShape); + } + return newBulletBvhTriangleMeshShape; + } + + private readonly key: number; + private ref = 0; + public bulletBvhTriangleMeshShapePtr: Bullet.ptr; + private btTriangleMeshPtr: Bullet.ptr = 0; + + public set reference (v: boolean) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + v ? this.ref++ : this.ref--; + if (this.ref === 0) { this.destroy(); } + } + + private constructor (key: number, mesh: Mesh) { + this.reference = true; + this.key = key; + this.btTriangleMeshPtr = bt.TriangleMesh_new(); + cocos2BulletTriMesh(this.btTriangleMeshPtr, mesh); + this.bulletBvhTriangleMeshShapePtr = bt.BvhTriangleMeshShape_new(this.btTriangleMeshPtr, true, true); + } + + private destroy () { + if (this.bulletBvhTriangleMeshShapePtr) { + bt._safe_delete(EBulletType.EBulletTypeCollisionShape, this.bulletBvhTriangleMeshShapePtr); + } + if (this.btTriangleMeshPtr) { + bt._safe_delete(EBulletType.EBulletTypeTriangleMesh, this.btTriangleMeshPtr); + } + BulletBvhTriangleMeshShape.BulletBvhTriangleMeshShapeMap.delete(this.key); + } +} diff --git a/cocos/physics/bullet/bullet-cache.ts b/cocos/physics/bullet/bullet-cache.ts index 44012241341..7f1e2a7f44b 100644 --- a/cocos/physics/bullet/bullet-cache.ts +++ b/cocos/physics/bullet/bullet-cache.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Collider, TriggerEventType, CollisionEventType, IContactEquation } from '../../../exports/physics-framework'; -import { Vec3, Quat } from '../../core'; +import { Vec3, Quat, Mat4 } from '../../core'; import { bt } from './instantiated'; export const TriggerEventObject = { @@ -77,5 +76,7 @@ export class BulletCache { export const CC_V3_0 = new Vec3(); export const CC_V3_1 = new Vec3(); export const CC_QUAT_0 = new Quat(); +export const CC_MAT4_0 = new Mat4(); +export const CC_MAT4_1 = new Mat4(); bt.CACHE = BulletCache; diff --git a/cocos/physics/bullet/bullet-contact-data.ts b/cocos/physics/bullet/bullet-contact-data.ts index 8e4602e117d..8023e26431c 100644 --- a/cocos/physics/bullet/bullet-contact-data.ts +++ b/cocos/physics/bullet/bullet-contact-data.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IContactEquation, ICollisionEvent } from '../framework'; import { IVec3Like, Vec3, Quat } from '../../core'; diff --git a/cocos/physics/bullet/bullet-enum.ts b/cocos/physics/bullet/bullet-enum.ts index 83eaa26b57b..935a943cbab 100644 --- a/cocos/physics/bullet/bullet-enum.ts +++ b/cocos/physics/bullet/bullet-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export enum EBtSharedBodyDirty { BODY_RE_ADD = 1, diff --git a/cocos/physics/bullet/bullet-env.ts b/cocos/physics/bullet/bullet-env.ts index 0d6c22b729f..07f4a9503d0 100644 --- a/cocos/physics/bullet/bullet-env.ts +++ b/cocos/physics/bullet/bullet-env.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ // Wasm Memory Page Size is 65536 export const pageSize = 65536; // 64KiB diff --git a/cocos/physics/bullet/bullet-interface.ts b/cocos/physics/bullet/bullet-interface.ts index d17692ab6a5..85097118cc4 100644 --- a/cocos/physics/bullet/bullet-interface.ts +++ b/cocos/physics/bullet/bullet-interface.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './shapes/bullet-shape'; diff --git a/cocos/physics/bullet/bullet-rigid-body.ts b/cocos/physics/bullet/bullet-rigid-body.ts index 051fe085a44..aaa6f04c41b 100644 --- a/cocos/physics/bullet/bullet-rigid-body.ts +++ b/cocos/physics/bullet/bullet-rigid-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,17 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../core'; +import { Vec3, IVec3Like } from '../../core'; import { BulletWorld } from './bullet-world'; import { cocos2BulletVec3, bullet2CocosVec3 } from './bullet-utils'; import { RigidBody, PhysicsSystem } from '../../../exports/physics-framework'; -import { btCollisionFlags, btRigidBodyFlags, btCollisionObjectStates, EBtSharedBodyDirty } from './bullet-enum'; +import { btRigidBodyFlags, btCollisionObjectStates, EBtSharedBodyDirty } from './bullet-enum'; import { IRigidBody } from '../spec/i-rigid-body'; import { ERigidBodyType } from '../framework/physics-enum'; import { BulletSharedBody } from './bullet-shared-body'; -import { IVec3Like } from '../../core/math/type-define'; import { BulletCache, CC_V3_0, CC_V3_1 } from './bullet-cache'; import { bt } from './instantiated'; @@ -185,8 +183,11 @@ export class BulletRigidBody implements IRigidBody { bt.CollisionObject_activate(this.impl, force); } - sleep (): any { - return bt.RigidBody_wantsSleeping(this.impl); + sleep (): void { + const state = bt.CollisionObject_getActivationState(this.impl); + if (state !== btCollisionObjectStates.DISABLE_DEACTIVATION && state !== btCollisionObjectStates.DISABLE_SIMULATION) { + bt.CollisionObject_forceActivationState(this.impl, btCollisionObjectStates.ISLAND_SLEEPING); + } } setSleepThreshold (v: number): void { diff --git a/cocos/physics/bullet/bullet-shared-body.ts b/cocos/physics/bullet/bullet-shared-body.ts index 67bac2f7630..3bddc758a6f 100644 --- a/cocos/physics/bullet/bullet-shared-body.ts +++ b/cocos/physics/bullet/bullet-shared-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { TransformBit } from '../../scene-graph/node-enum'; import { Node } from '../../scene-graph'; @@ -34,8 +33,8 @@ import { IBulletBodyStruct, IBulletGhostStruct } from './bullet-interface'; import { CC_V3_0, CC_QUAT_0, BulletCache } from './bullet-cache'; import { PhysicsSystem } from '../framework'; import { ERigidBodyType, PhysicsGroup } from '../framework/physics-enum'; -import { fastRemoveAt } from '../../core/utils/array'; -import { bt } from './instantiated'; +import { js } from '../../core'; +import { bt, EBulletType } from './instantiated'; import { BulletConstraint } from './constraints/bullet-constraint'; const v3_0 = CC_V3_0; @@ -346,7 +345,7 @@ export class BulletSharedBody { if (isTrigger) { const index = this.ghostStruct.wrappedShapes.indexOf(v); if (index >= 0) { - fastRemoveAt(this.ghostStruct.wrappedShapes, index); + js.array.fastRemoveAt(this.ghostStruct.wrappedShapes, index); v.setCompound(0); this.ghostEnabled = false; } @@ -360,7 +359,7 @@ export class BulletSharedBody { } bt.CollisionObject_activate(this.body, true); this.dirty |= EBtSharedBodyDirty.BODY_RE_ADD; - fastRemoveAt(this.bodyStruct.wrappedShapes, index); + js.array.fastRemoveAt(this.bodyStruct.wrappedShapes, index); this.bodyEnabled = false; } } @@ -379,10 +378,10 @@ export class BulletSharedBody { removeJoint (v: BulletConstraint, type: 0 | 1) { if (type) { const i = this.wrappedJoints1.indexOf(v); - if (i >= 0) fastRemoveAt(this.wrappedJoints1, i); + if (i >= 0) js.array.fastRemoveAt(this.wrappedJoints1, i); } else { const i = this.wrappedJoints0.indexOf(v); - if (i >= 0) fastRemoveAt(this.wrappedJoints0, i); + if (i >= 0) js.array.fastRemoveAt(this.wrappedJoints0, i); } } @@ -513,16 +512,16 @@ export class BulletSharedBody { if (this._bodyStruct) { const bodyStruct = this._bodyStruct; BulletCache.delWrapper(bodyStruct.body, bt.BODY_CACHE_NAME); - bt.MotionState_del(bodyStruct.motionState); - bt.CollisionShape_del(bodyStruct.compound); - bt.CollisionObject_del(bodyStruct.body); + bt._safe_delete(bodyStruct.motionState, EBulletType.EBulletTypeMotionState); + bt._safe_delete(bodyStruct.compound, EBulletType.EBulletTypeCollisionShape); + bt._safe_delete(bodyStruct.body, EBulletType.EBulletTypeCollisionObject); (this._bodyStruct as any) = null; } if (this._ghostStruct) { const ghostStruct = this._ghostStruct; - bt.CollisionShape_del(ghostStruct.compound); - bt.CollisionObject_del(ghostStruct.ghost); + bt._safe_delete(ghostStruct.compound, EBulletType.EBulletTypeCollisionShape); + bt._safe_delete(ghostStruct.ghost, EBulletType.EBulletTypeCollisionObject); (this._ghostStruct as any) = null; } } diff --git a/cocos/physics/bullet/bullet-utils.ts b/cocos/physics/bullet/bullet-utils.ts index 8035ac25454..59200863c02 100644 --- a/cocos/physics/bullet/bullet-utils.ts +++ b/cocos/physics/bullet/bullet-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { IVec3Like, IQuatLike } from '../../core/math/type-define'; +import { IVec3Like, IQuatLike } from '../../core'; import { Mesh } from '../../3d'; import { PrimitiveMode } from '../../gfx'; import { bt } from './instantiated'; diff --git a/cocos/physics/bullet/bullet-world.ts b/cocos/physics/bullet/bullet-world.ts index 503c1d1da12..ae2130901ee 100644 --- a/cocos/physics/bullet/bullet-world.ts +++ b/cocos/physics/bullet/bullet-world.ts @@ -1,19 +1,18 @@ /* eslint-disable new-cap */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletSharedBody } from './bullet-shared-body'; import { BulletRigidBody } from './bullet-rigid-body'; @@ -31,15 +30,12 @@ import { ArrayCollisionMatrix } from '../utils/array-collision-matrix'; import { TupleDictionary } from '../utils/tuple-dictionary'; import { TriggerEventObject, CollisionEventObject, CC_V3_0, CC_V3_1, BulletCache } from './bullet-cache'; import { bullet2CocosVec3, cocos2BulletVec3 } from './bullet-utils'; -import { Ray } from '../../core/geometry'; import { IRaycastOptions, IPhysicsWorld } from '../spec/i-physics-world'; import { PhysicsRayResult, PhysicsMaterial } from '../framework'; -import { error, RecyclePool, Vec3 } from '../../core'; -import { IVec3Like } from '../../core/math/type-define'; +import { error, RecyclePool, Vec3, js, IVec3Like, geometry } from '../../core'; import { BulletContactData } from './bullet-contact-data'; import { BulletConstraint } from './constraints/bullet-constraint'; -import { fastRemoveAt } from '../../core/utils/array'; -import { bt } from './instantiated'; +import { bt, EBulletType, EBulletTriangleRaycastFlag } from './instantiated'; import { Node } from '../../scene-graph'; const contactsPool: BulletContactData[] = []; @@ -118,10 +114,10 @@ export class BulletWorld implements IPhysicsWorld { destroy (): void { if (this.constraints.length || this.bodies.length) error('You should destroy all physics component first.'); - bt.CollisionWorld_del(this._world); - bt.DbvtBroadphase_del(this._broadphase); - bt.CollisionDispatcher_del(this._dispatcher); - bt.SequentialImpulseConstraintSolver_del(this._solver); + bt._safe_delete(this._world, EBulletType.EBulletTypeCollisionWorld); + bt._safe_delete(this._broadphase, EBulletType.EBulletTypeDbvtBroadPhase); + bt._safe_delete(this._dispatcher, EBulletType.EBulletTypeCollisionDispatcher); + bt._safe_delete(this._solver, EBulletType.EBulletTypeSequentialImpulseConstraintSolver); (this as any).bodies = null; (this as any).ghosts = null; (this as any).constraints = null; @@ -158,12 +154,13 @@ export class BulletWorld implements IPhysicsWorld { this.syncSceneToPhysics(); } - raycast (worldRay: Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { + raycast (worldRay: geometry.Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { worldRay.computeHit(v3_0, options.maxDistance); const to = cocos2BulletVec3(BulletCache.instance.BT_V3_0, v3_0); const from = cocos2BulletVec3(BulletCache.instance.BT_V3_1, worldRay.o); const allHitsCB = bt.ccAllRayCallback_static(); bt.ccAllRayCallback_reset(allHitsCB, from, to, options.mask, options.queryTrigger); + bt.ccAllRayCallback_setFlags(allHitsCB, EBulletTriangleRaycastFlag.UseSubSimplexConvexCastRaytest); bt.CollisionWorld_rayTest(this._world, from, to, allHitsCB); if (bt.RayCallback_hasHit(allHitsCB)) { const posArray = bt.ccAllRayCallback_getHitPointWorld(allHitsCB); @@ -181,12 +178,13 @@ export class BulletWorld implements IPhysicsWorld { return false; } - raycastClosest (worldRay: Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { + raycastClosest (worldRay: geometry.Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { worldRay.computeHit(v3_0, options.maxDistance); const to = cocos2BulletVec3(BulletCache.instance.BT_V3_0, v3_0); const from = cocos2BulletVec3(BulletCache.instance.BT_V3_1, worldRay.o); const closeHitCB = bt.ccClosestRayCallback_static(); bt.ccClosestRayCallback_reset(closeHitCB, from, to, options.mask, options.queryTrigger); + bt.ccClosestRayCallback_setFlags(closeHitCB, EBulletTriangleRaycastFlag.UseSubSimplexConvexCastRaytest); bt.CollisionWorld_rayTest(this._world, from, to, closeHitCB); if (bt.RayCallback_hasHit(closeHitCB)) { bullet2CocosVec3(v3_0, bt.ccClosestRayCallback_getHitPointWorld(closeHitCB)); @@ -213,7 +211,7 @@ export class BulletWorld implements IPhysicsWorld { removeSharedBody (sharedBody: BulletSharedBody) { const i = this.bodies.indexOf(sharedBody); if (i >= 0) { - fastRemoveAt(this.bodies, i); + js.array.fastRemoveAt(this.bodies, i); bt.DynamicsWorld_removeRigidBody(this._world, sharedBody.body); } } @@ -229,7 +227,7 @@ export class BulletWorld implements IPhysicsWorld { removeGhostObject (sharedBody: BulletSharedBody) { const i = this.ghosts.indexOf(sharedBody); if (i >= 0) { - fastRemoveAt(this.ghosts, i); + js.array.fastRemoveAt(this.ghosts, i); bt.CollisionWorld_removeCollisionObject(this._world, sharedBody.ghost); } } diff --git a/cocos/physics/bullet/constraints/bullet-constraint.ts b/cocos/physics/bullet/constraints/bullet-constraint.ts index 853b8a4745b..93a59e6d98a 100644 --- a/cocos/physics/bullet/constraints/bullet-constraint.ts +++ b/cocos/physics/bullet/constraints/bullet-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable new-cap */ import { IBaseConstraint } from '../../spec/i-physics-constraint'; import { Constraint, RigidBody } from '../../framework'; import { BulletRigidBody } from '../bullet-rigid-body'; -import { bt } from '../instantiated'; +import { bt, EBulletType } from '../instantiated'; export abstract class BulletConstraint implements IBaseConstraint { setConnectedBody (v: RigidBody | null): void { @@ -101,7 +100,7 @@ export abstract class BulletConstraint implements IBaseConstraint { } onDestroy (): void { - bt.TypedConstraint_del(this._impl); + bt._safe_delete(this._impl, EBulletType.EBulletTypeTypedConstraint); (this._com as any) = null; (this._rigidBody as any) = null; } diff --git a/cocos/physics/bullet/constraints/bullet-fixed-constraint.ts b/cocos/physics/bullet/constraints/bullet-fixed-constraint.ts new file mode 100644 index 00000000000..334c4ac1925 --- /dev/null +++ b/cocos/physics/bullet/constraints/bullet-fixed-constraint.ts @@ -0,0 +1,101 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* eslint-disable new-cap */ +import { BulletConstraint } from './bullet-constraint'; +import { IFixedConstraint } from '../../spec/i-physics-constraint'; +import { IVec3Like, Quat, Vec3, Mat4 } from '../../../core'; +import { FixedConstraint, HingeConstraint, PhysicsSystem } from '../../framework'; +import { BulletRigidBody } from '../bullet-rigid-body'; +import { BulletCache, CC_MAT4_0, CC_QUAT_0, CC_V3_0 } from '../bullet-cache'; +import { bt } from '../instantiated'; +import { bullet2CocosVec3, cocos2BulletQuat, cocos2BulletVec3 } from '../bullet-utils'; +import { BulletWorld } from '../bullet-world'; + +export class BulletFixedConstraint extends BulletConstraint implements IFixedConstraint { + setBreakForce (v: number): void { + bt.TypedConstraint_setMaxImpulseThreshold(this._impl, v); + } + + setBreakTorque (v: number): void { + // not supported + } + + get constraint (): FixedConstraint { + return this._com as FixedConstraint; + } + + onComponentSet () { + const cb = this.constraint.connectedBody; + const bodyA = (this._rigidBody.body as BulletRigidBody).sharedBody; + const bodyB = cb ? (cb.body as BulletRigidBody).sharedBody : (PhysicsSystem.instance.physicsWorld as BulletWorld).getSharedBody(bodyA.node); + const trans0 = BulletCache.instance.BT_TRANSFORM_0; + const trans1 = BulletCache.instance.BT_TRANSFORM_1; + this._impl = bt.FixedConstraint_new(bodyA.body, bodyB.body, trans0, trans1); + this.setBreakForce(this.constraint.breakForce); + this.setBreakTorque(this.constraint.breakTorque); + this.updateFrames(); + } + + updateFrames () { + const cb = this.constraint.connectedBody; + const bodyA = (this._rigidBody.body as BulletRigidBody).sharedBody; + const bodyB = cb ? (cb.body as BulletRigidBody).sharedBody : (PhysicsSystem.instance.physicsWorld as BulletWorld).getSharedBody(bodyA.node); + + const pos : Vec3 = CC_V3_0; + const rot : Quat = CC_QUAT_0; + const trans0 = BulletCache.instance.BT_TRANSFORM_0; + const trans1 = BulletCache.instance.BT_TRANSFORM_1; + const quat = BulletCache.instance.BT_QUAT_0; + + const trans = CC_MAT4_0; + // the local frame transform respect to bodyA + Mat4.fromRT(trans, bodyA.node.worldRotation, bodyA.node.worldPosition); + Mat4.invert(trans, trans); + Mat4.getRotation(rot, trans); + Mat4.getTranslation(pos, trans); + cocos2BulletVec3(bt.Transform_getOrigin(trans0), pos); + cocos2BulletQuat(quat, rot); + bt.Transform_setRotation(trans0, quat); + + // the local frame transform respect to bodyB + Mat4.fromRT(trans, bodyB.node.worldRotation, bodyB.node.worldPosition); + Mat4.invert(trans, trans); + Mat4.getRotation(rot, trans); + Mat4.getTranslation(pos, trans); + cocos2BulletVec3(bt.Transform_getOrigin(trans1), pos); + cocos2BulletQuat(quat, rot); + bt.Transform_setRotation(trans1, quat); + + bt.FixedConstraint_setFrames(this._impl, trans0, trans1); + } + + updateScale0 () { + this.updateFrames(); + } + + updateScale1 () { + this.updateFrames(); + } +} diff --git a/cocos/physics/bullet/constraints/bullet-hinge-constraint.ts b/cocos/physics/bullet/constraints/bullet-hinge-constraint.ts index 130ed292c41..aab0cbc767f 100644 --- a/cocos/physics/bullet/constraints/bullet-hinge-constraint.ts +++ b/cocos/physics/bullet/constraints/bullet-hinge-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable new-cap */ import { BulletConstraint } from './bullet-constraint'; diff --git a/cocos/physics/bullet/constraints/bullet-p2p-constraint.ts b/cocos/physics/bullet/constraints/bullet-p2p-constraint.ts index 0c6b9e5a570..5b1fa1a7cd4 100644 --- a/cocos/physics/bullet/constraints/bullet-p2p-constraint.ts +++ b/cocos/physics/bullet/constraints/bullet-p2p-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable new-cap */ import { BulletConstraint } from './bullet-constraint'; diff --git a/cocos/physics/bullet/instantiate.ts b/cocos/physics/bullet/instantiate.ts index 51bd5417434..c41cd35ecc7 100644 --- a/cocos/physics/bullet/instantiate.ts +++ b/cocos/physics/bullet/instantiate.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Game, game } from '../../game'; import { selector } from '../framework/physics-selector'; @@ -37,6 +36,7 @@ import { BulletTerrainShape } from './shapes/bullet-terrain-shape'; import { BulletSimplexShape } from './shapes/bullet-simplex-shape'; import { BulletPlaneShape } from './shapes/bullet-plane-shape'; import { BulletP2PConstraint } from './constraints/bullet-p2p-constraint'; +import { BulletFixedConstraint } from './constraints/bullet-fixed-constraint'; import { BulletHingeConstraint } from './constraints/bullet-hinge-constraint'; game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { @@ -56,5 +56,6 @@ game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { PointToPointConstraint: BulletP2PConstraint, HingeConstraint: BulletHingeConstraint, + FixedConstraint: BulletFixedConstraint, }); }); diff --git a/cocos/physics/bullet/instantiated.ts b/cocos/physics/bullet/instantiated.ts index 570d791733e..d64533d435f 100644 --- a/cocos/physics/bullet/instantiated.ts +++ b/cocos/physics/bullet/instantiated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ // eslint-disable-next-line import/no-extraneous-dependencies import bulletModule, { bulletType } from '@cocos/bullet'; import { WECHAT, RUNTIME_BASED } from 'internal:constants'; import { game } from '../../game'; -import { sys } from '../../core/platform'; +import { sys } from '../../core'; import { pageSize, pageCount, importFunc } from './bullet-env'; let bulletLibs: any = bulletModule; @@ -36,6 +35,32 @@ if (globalThis.BULLET) { bulletLibs = globalThis.BULLET; } +//corresponds to bulletType in bullet-compile +export enum EBulletType{ + EBulletTypeVec3 = 0, + EBulletTypeQuat, + EBulletTypeTransform, + EBulletTypeMotionState, + EBulletTypeCollisionObject, + EBulletTypeCollisionShape, + EBulletTypeStridingMeshInterface, + EBulletTypeTriangleMesh, + EBulletTypeCollisionDispatcher, + EBulletTypeDbvtBroadPhase, + EBulletTypeSequentialImpulseConstraintSolver, + EBulletTypeCollisionWorld, + EBulletTypeTypedConstraint +} + +//corresponds to btTriangleRaycastCallback::EFlags +export enum EBulletTriangleRaycastFlag { + NONE = 0, + FilterBackfaces = 1 << 0, + KeepUnflippedNormal = 1 << 1, //Prevents returned face normal getting flipped when a ray hits a back-facing triangle + UseSubSimplexConvexCastRaytest = 1 << 2, //default, uses an approximate but faster ray versus convex intersection algorithm + UseGjkConvexCastRaytest = 1 << 3 +} + interface instanceExt extends Bullet.instance { CACHE: any, BODY_CACHE_NAME: string, diff --git a/cocos/physics/bullet/shapes/bullet-box-shape.ts b/cocos/physics/bullet/shapes/bullet-box-shape.ts index 66f2af7174e..7b9e4f462e3 100644 --- a/cocos/physics/bullet/shapes/bullet-box-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-box-shape.ts @@ -1,19 +1,18 @@ /* eslint-disable new-cap */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { Vec3 } from '../../../core'; diff --git a/cocos/physics/bullet/shapes/bullet-capsule-shape.ts b/cocos/physics/bullet/shapes/bullet-capsule-shape.ts index db7e6db0799..b2fe17e8911 100644 --- a/cocos/physics/bullet/shapes/bullet-capsule-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-capsule-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { absMax } from '../../../core'; +import { absMax, IVec3Like } from '../../../core'; import { BulletShape } from './bullet-shape'; import { CapsuleCollider } from '../../../../exports/physics-framework'; import { ICapsuleShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; import { bt } from '../instantiated'; export class BulletCapsuleShape extends BulletShape implements ICapsuleShape { diff --git a/cocos/physics/bullet/shapes/bullet-cone-shape.ts b/cocos/physics/bullet/shapes/bullet-cone-shape.ts index 53ae7c4ca00..73de1a3cc57 100644 --- a/cocos/physics/bullet/shapes/bullet-cone-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-cone-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { ConeCollider } from '../../../../exports/physics-framework'; import { ICylinderShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; -import { absMax } from '../../../core'; +import { IVec3Like, absMax } from '../../../core'; import { bt } from '../instantiated'; import { BulletCache } from '../bullet-cache'; diff --git a/cocos/physics/bullet/shapes/bullet-cylinder-shape.ts b/cocos/physics/bullet/shapes/bullet-cylinder-shape.ts index ea399741169..2a03fbef3f1 100644 --- a/cocos/physics/bullet/shapes/bullet-cylinder-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-cylinder-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { CylinderCollider } from '../../../../exports/physics-framework'; import { ICylinderShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; -import { absMax } from '../../../core'; +import { IVec3Like, absMax } from '../../../core'; import { BulletCache } from '../bullet-cache'; import { bt } from '../instantiated'; diff --git a/cocos/physics/bullet/shapes/bullet-plane-shape.ts b/cocos/physics/bullet/shapes/bullet-plane-shape.ts index e940e80a960..f16739ed99c 100644 --- a/cocos/physics/bullet/shapes/bullet-plane-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-plane-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { PlaneCollider } from '../../../../exports/physics-framework'; import { cocos2BulletVec3 } from '../bullet-utils'; import { IPlaneShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; +import { IVec3Like } from '../../../core'; import { BulletCache } from '../bullet-cache'; import { bt } from '../instantiated'; diff --git a/cocos/physics/bullet/shapes/bullet-shape.ts b/cocos/physics/bullet/shapes/bullet-shape.ts index c49f312cd01..fc81046fb72 100644 --- a/cocos/physics/bullet/shapes/bullet-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,19 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../../core/math'; +import { Vec3, IVec3Like, geometry } from '../../../core'; import { Collider, PhysicsMaterial, PhysicsSystem } from '../../../../exports/physics-framework'; import { BulletWorld } from '../bullet-world'; import { EBtSharedBodyDirty } from '../bullet-enum'; import { cocos2BulletQuat, cocos2BulletVec3 } from '../bullet-utils'; import { IBaseShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; import { BulletSharedBody } from '../bullet-shared-body'; -import { AABB, Sphere } from '../../../core/geometry'; import { BulletCache, CC_V3_0 } from '../bullet-cache'; -import { bt } from '../instantiated'; +import { bt, EBulletType } from '../instantiated'; import { EColliderType } from '../../framework'; const v3_0 = CC_V3_0; @@ -44,14 +41,15 @@ export abstract class BulletShape implements IBaseShape { } setMaterial (v: PhysicsMaterial | null) { - if (!this._isTrigger && this._isEnabled && v) { + const v1 = (v == null) ? PhysicsSystem.instance.defaultMaterial : v; + if (!this._isTrigger && this._isEnabled) { if (this._compound) { - if (!ccMaterialBooks[v._uuid]) ccMaterialBooks[v._uuid] = bt.ccMaterial_new(); - const mat = ccMaterialBooks[v._uuid]; - bt.ccMaterial_set(mat, v.restitution, v.friction, v.rollingFriction, v.spinningFriction); + if (!ccMaterialBooks[v1._uuid]) ccMaterialBooks[v1._uuid] = bt.ccMaterial_new(); + const mat = ccMaterialBooks[v1._uuid]; + bt.ccMaterial_set(mat, v1.restitution, v1.friction, v1.rollingFriction, v1.spinningFriction); bt.CollisionShape_setMaterial(this._impl, mat); } else { - bt.CollisionObject_setMaterial(this._sharedBody.body, v.restitution, v.friction, v.rollingFriction, v.spinningFriction); + bt.CollisionObject_setMaterial(this._sharedBody.body, v1.restitution, v1.friction, v1.rollingFriction, v1.spinningFriction); } } } @@ -95,7 +93,7 @@ export abstract class BulletShape implements IBaseShape { protected _collider!: Collider; protected _sharedBody!: BulletSharedBody; - getAABB (v: AABB) { + getAABB (v: geometry.AABB) { const bt_transform = BulletCache.instance.BT_TRANSFORM_0; bt.Transform_setIdentity(bt_transform); bt.Transform_setRotation(bt_transform, cocos2BulletQuat(BulletCache.instance.BT_QUAT_0, this._collider.node.worldRotation)); @@ -108,7 +106,7 @@ export abstract class BulletShape implements IBaseShape { Vec3.add(v.center, this._collider.node.worldPosition, this._collider.center); } - getBoundingSphere (v: Sphere) { + getBoundingSphere (v: geometry.Sphere) { v.radius = bt.CollisionShape_getLocalBoundingSphere(this._impl); Vec3.add(v.center, this._collider.node.worldPosition, this._collider.center); } @@ -152,11 +150,11 @@ export abstract class BulletShape implements IBaseShape { onDestroy () { this._sharedBody.reference = false; (this._collider as any) = null; - bt.Quat_del(this.quat); - bt.Transform_del(this.transform); - if (this._compound) bt.CollisionShape_del(this._compound); + bt._safe_delete(this.quat, EBulletType.EBulletTypeQuat); + bt._safe_delete(this.transform, EBulletType.EBulletTypeTransform); + if (this._compound) bt._safe_delete(this._compound, EBulletType.EBulletTypeCollisionShape); if (BulletCache.isNotEmptyShape(this._impl)) { - bt.CollisionShape_del(this._impl); + bt._safe_delete(this._impl, EBulletType.EBulletTypeCollisionShape); BulletCache.delWrapper(this._impl, BulletShape.TYPE); } } diff --git a/cocos/physics/bullet/shapes/bullet-simplex-shape.ts b/cocos/physics/bullet/shapes/bullet-simplex-shape.ts index b873355f179..877f7c0e618 100644 --- a/cocos/physics/bullet/shapes/bullet-simplex-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-simplex-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { SimplexCollider } from '../../../../exports/physics-framework'; import { cocos2BulletVec3 } from '../bullet-utils'; import { ISimplexShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; +import { IVec3Like } from '../../../core'; import { bt } from '../instantiated'; import { BulletCache } from '../bullet-cache'; diff --git a/cocos/physics/bullet/shapes/bullet-sphere-shape.ts b/cocos/physics/bullet/shapes/bullet-sphere-shape.ts index 28d423cad81..f1d5c0c73c2 100644 --- a/cocos/physics/bullet/shapes/bullet-sphere-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-sphere-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { PhysicsSystem, SphereCollider } from '../../../../exports/physics-framework'; diff --git a/cocos/physics/bullet/shapes/bullet-terrain-shape.ts b/cocos/physics/bullet/shapes/bullet-terrain-shape.ts index 2621a19c793..8d7b6002602 100644 --- a/cocos/physics/bullet/shapes/bullet-terrain-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-terrain-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; -import { Vec3, warn } from '../../../core'; +import { Vec3, warn, IVec3Like } from '../../../core'; import { TerrainCollider } from '../../../../exports/physics-framework'; import { cocos2BulletVec3 } from '../bullet-utils'; import { ITerrainShape } from '../../spec/i-physics-shape'; import { ITerrainAsset } from '../../spec/i-external'; import { CC_V3_0, BulletCache } from '../bullet-cache'; -import { IVec3Like } from '../../../core/math/type-define'; import { bt } from '../instantiated'; export class BulletTerrainShape extends BulletShape implements ITerrainShape { diff --git a/cocos/physics/bullet/shapes/bullet-trimesh-shape.ts b/cocos/physics/bullet/shapes/bullet-trimesh-shape.ts index f129d2ccbb8..0fe6f75f4b0 100644 --- a/cocos/physics/bullet/shapes/bullet-trimesh-shape.ts +++ b/cocos/physics/bullet/shapes/bullet-trimesh-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BulletShape } from './bullet-shape'; import { warnID } from '../../../core'; @@ -30,9 +29,11 @@ import { MeshCollider } from '../../../../exports/physics-framework'; import { cocos2BulletVec3, cocos2BulletTriMesh } from '../bullet-utils'; import { ITrimeshShape } from '../../spec/i-physics-shape'; import { BulletCache } from '../bullet-cache'; -import { bt } from '../instantiated'; +import { bt, EBulletType } from '../instantiated'; +import { BulletBvhTriangleMeshShape } from '../bullet-bvh-triangle-mesh-shape'; export class BulletTrimeshShape extends BulletShape implements ITrimeshShape { + private btBVHMeshShape; public get collider () { return this._collider as MeshCollider; } @@ -46,16 +47,17 @@ export class BulletTrimeshShape extends BulletShape implements ITrimeshShape { } else { const mesh = v; if (mesh && mesh.renderingSubMeshes.length > 0) { - const btTriangleMesh = this._getBtTriangleMesh(mesh); if (this.collider.convex) { + const btTriangleMesh = this._getBtTriangleMesh(mesh); this._impl = bt.ConvexTriangleMeshShape_new(btTriangleMesh); } else { - this._impl = bt.BvhTriangleMeshShape_new(btTriangleMesh, true, true); + this.btBVHMeshShape = BulletBvhTriangleMeshShape.getBulletBvhTriangleMeshShape(mesh.hash, mesh); + this._impl = bt.ScaledBvhTriangleMeshShape_new(this.btBVHMeshShape.bulletBvhTriangleMeshShapePtr, 1, 1, 1); } const bt_v3 = BulletCache.instance.BT_V3_0; cocos2BulletVec3(bt_v3, this._collider.node.worldScale); - bt.CollisionShape_setMargin(this._impl, 0.01); bt.CollisionShape_setLocalScaling(this._impl, bt_v3); + bt.CollisionShape_setMargin(this._impl, 0.01); this.setCompound(this._compound); this.updateByReAdd(); this.setWrapper(); @@ -72,7 +74,13 @@ export class BulletTrimeshShape extends BulletShape implements ITrimeshShape { } onDestroy () { - if (this.refBtTriangleMesh) { bt.TriangleMesh_del(this.refBtTriangleMesh); } + if (this.collider.convex) { + if (this.refBtTriangleMesh) { + bt._safe_delete(this.refBtTriangleMesh, EBulletType.EBulletTypeTriangleMesh); + } + } else if (this.btBVHMeshShape) { + this.btBVHMeshShape.reference = false; + } super.onDestroy(); } diff --git a/cocos/physics/cannon/cannon-contact-equation.ts b/cocos/physics/cannon/cannon-contact-equation.ts index da77ad78fd4..c4e418bfa86 100644 --- a/cocos/physics/cannon/cannon-contact-equation.ts +++ b/cocos/physics/cannon/cannon-contact-equation.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IContactEquation, ICollisionEvent } from '../framework'; import { IVec3Like, Quat, Vec3 } from '../../core'; diff --git a/cocos/physics/cannon/cannon-rigid-body.ts b/cocos/physics/cannon/cannon-rigid-body.ts index ecb446bb427..4f04ec8fddf 100644 --- a/cocos/physics/cannon/cannon-rigid-body.ts +++ b/cocos/physics/cannon/cannon-rigid-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Vec3 } from '../../core/math'; +import { Vec3, IVec3Like } from '../../core'; import { IRigidBody } from '../spec/i-rigid-body'; import { CannonSharedBody } from './cannon-shared-body'; import { CannonWorld } from './cannon-world'; import { PhysicsSystem } from '../framework/physics-system'; import { ERigidBodyType, RigidBody } from '../framework'; -import { IVec3Like } from '../../core/math/type-define'; const v3_cannon0 = new CANNON.Vec3(); const v3_cannon1 = new CANNON.Vec3(); diff --git a/cocos/physics/cannon/cannon-shared-body.ts b/cocos/physics/cannon/cannon-shared-body.ts index 2ed84d704a6..40aa339013d 100644 --- a/cocos/physics/cannon/cannon-shared-body.ts +++ b/cocos/physics/cannon/cannon-shared-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Quat, Vec3 } from '../../core/math'; +import { Quat, Vec3, js } from '../../core'; import { ERigidBodyType, PhysicsGroup } from '../framework/physics-enum'; import { getWrap, setWrap } from '../utils/util'; import { CannonWorld } from './cannon-world'; @@ -37,7 +36,6 @@ import { CannonRigidBody } from './cannon-rigid-body'; import { commitShapeUpdates } from './cannon-util'; import { CannonContactEquation } from './cannon-contact-equation'; import { CannonConstraint } from './constraints/cannon-constraint'; -import { fastRemoveAt } from '../../core/utils/array'; const v3_0 = new Vec3(); const quat_0 = new Quat(); @@ -51,9 +49,9 @@ const CollisionEventObject = { }; /** - * node : shared-body = 1 : 1 - * static - */ + * node : shared-body = 1 : 1 + * static + */ export class CannonSharedBody { private static readonly sharedBodesMap = new Map(); @@ -68,6 +66,8 @@ export class CannonSharedBody { const m = PhysicsSystem.instance.collisionMatrix[g]; newSB.body.collisionFilterGroup = g; newSB.body.collisionFilterMask = m; + newSB.body.position = new CANNON.Vec3(node.worldPosition.x, node.worldPosition.y, node.worldPosition.z); + newSB.body.quaternion = new CANNON.Quaternion(node.worldRotation.x, node.worldRotation.y, node.worldRotation.z, node.worldRotation.w); CannonSharedBody.sharedBodesMap.set(node.uuid, newSB); } if (wrappedBody) { @@ -76,6 +76,8 @@ export class CannonSharedBody { const m = PhysicsSystem.instance.collisionMatrix[g]; newSB.body.collisionFilterGroup = g; newSB.body.collisionFilterMask = m; + newSB.body.position = new CANNON.Vec3(node.worldPosition.x, node.worldPosition.y, node.worldPosition.z); + newSB.body.quaternion = new CANNON.Quaternion(node.worldRotation.x, node.worldRotation.y, node.worldRotation.z, node.worldRotation.w); } return newSB; } @@ -93,10 +95,10 @@ export class CannonSharedBody { private onCollidedListener = this.onCollided.bind(this); /** - * add or remove from world \ - * add, if enable \ - * remove, if disable & shapes.length == 0 & wrappedBody disable - */ + * add or remove from world \ + * add, if enable \ + * remove, if disable & shapes.length == 0 & wrappedBody disable + */ set enabled (v: boolean) { if (v) { if (this.index < 0) { @@ -106,7 +108,7 @@ export class CannonSharedBody { } } else if (this.index >= 0) { const isRemove = (this.wrappedShapes.length === 0 && this.wrappedBody == null) - || (this.wrappedShapes.length === 0 && this.wrappedBody != null && !this.wrappedBody.isEnabled); + || (this.wrappedShapes.length === 0 && this.wrappedBody != null && !this.wrappedBody.isEnabled); if (isRemove) { this.body.sleep(); // clear velocity etc. @@ -117,7 +119,7 @@ export class CannonSharedBody { } set reference (v: boolean) { - // eslint-disable-next-line no-unused-expressions + // eslint-disable-next-line @typescript-eslint/no-unused-expressions v ? this.ref++ : this.ref--; if (this.ref === 0) { this.destroy(); } } @@ -151,7 +153,7 @@ export class CannonSharedBody { removeShape (v: CannonShape) { const index = this.wrappedShapes.indexOf(v); if (index >= 0) { - fastRemoveAt(this.wrappedShapes, index); + js.array.fastRemoveAt(this.wrappedShapes, index); this.body.removeShape(v.impl); v.setIndex(-1); if (this.body.isSleeping()) this.body.wakeUp(); @@ -171,10 +173,10 @@ export class CannonSharedBody { removeJoint (v: CannonConstraint, type: 0 | 1) { if (type) { const i = this.wrappedJoints1.indexOf(v); - if (i >= 0) fastRemoveAt(this.wrappedJoints1, i); + if (i >= 0) js.array.fastRemoveAt(this.wrappedJoints1, i); } else { const i = this.wrappedJoints0.indexOf(v); - if (i >= 0) fastRemoveAt(this.wrappedJoints0, i); + if (i >= 0) js.array.fastRemoveAt(this.wrappedJoints0, i); } } diff --git a/cocos/physics/cannon/cannon-util.ts b/cocos/physics/cannon/cannon-util.ts index 1f80015edc8..29d8f42d105 100644 --- a/cocos/physics/cannon/cannon-util.ts +++ b/cocos/physics/cannon/cannon-util.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; import { getWrap } from '../utils/util'; diff --git a/cocos/physics/cannon/cannon-world.ts b/cocos/physics/cannon/cannon-world.ts index 193156a4712..e701baf097a 100644 --- a/cocos/physics/cannon/cannon-world.ts +++ b/cocos/physics/cannon/cannon-world.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Vec3 } from '../../core/math'; +import { Vec3, RecyclePool, error, js, geometry, IVec3Like } from '../../core'; import { fillRaycastResult, toCannonRaycastOptions } from './cannon-util'; import { CannonConstraint } from './constraints/cannon-constraint'; import { CannonShape } from './shapes/cannon-shape'; -import { Ray } from '../../core/geometry'; -import { RecyclePool, error } from '../../core'; import { CannonSharedBody } from './cannon-shared-body'; import { IPhysicsWorld, IRaycastOptions } from '../spec/i-physics-world'; import { PhysicsMaterial, PhysicsRayResult } from '../framework'; -import { IVec3Like } from '../../core/math/type-define'; import { CannonRigidBody } from './cannon-rigid-body'; -import { fastRemoveAt } from '../../core/utils/array'; import { Node } from '../../scene-graph'; export class CannonWorld implements IPhysicsWorld { @@ -112,7 +107,7 @@ export class CannonWorld implements IPhysicsWorld { } } - raycastClosest (worldRay: Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { + raycastClosest (worldRay: geometry.Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { setupFromAndTo(worldRay, options.maxDistance); toCannonRaycastOptions(raycastOpt, options); const hit = this._world.raycastClosest(from, to, raycastOpt, CannonWorld.rayResult); @@ -122,7 +117,7 @@ export class CannonWorld implements IPhysicsWorld { return hit; } - raycast (worldRay: Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { + raycast (worldRay: geometry.Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { setupFromAndTo(worldRay, options.maxDistance); toCannonRaycastOptions(raycastOpt, options); const hit = this._world.raycastAll(from, to, raycastOpt, (result: CANNON.RaycastResult): any => { @@ -148,7 +143,7 @@ export class CannonWorld implements IPhysicsWorld { removeSharedBody (sharedBody: CannonSharedBody) { const i = this.bodies.indexOf(sharedBody); if (i >= 0) { - fastRemoveAt(this.bodies, i); + js.array.fastRemoveAt(this.bodies, i); this._world.remove(sharedBody.body); } } @@ -168,7 +163,7 @@ export class CannonWorld implements IPhysicsWorld { removeConstraint (constraint: CannonConstraint) { const i = this.constraints.indexOf(constraint); if (i >= 0) { - fastRemoveAt(this.constraints, i); + js.array.fastRemoveAt(this.constraints, i); this._world.removeConstraint(constraint.impl); } } @@ -176,7 +171,7 @@ export class CannonWorld implements IPhysicsWorld { const from = new CANNON.Vec3(); const to = new CANNON.Vec3(); -function setupFromAndTo (worldRay: Ray, distance: number) { +function setupFromAndTo (worldRay: geometry.Ray, distance: number) { Vec3.copy(from, worldRay.o); worldRay.computeHit(to, distance); } diff --git a/cocos/physics/cannon/constraints/cannon-constraint.ts b/cocos/physics/cannon/constraints/cannon-constraint.ts index 7983727c397..4ae5d9cfa17 100644 --- a/cocos/physics/cannon/constraints/cannon-constraint.ts +++ b/cocos/physics/cannon/constraints/cannon-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; import { IBaseConstraint } from '../../spec/i-physics-constraint'; diff --git a/cocos/physics/cannon/constraints/cannon-distance-constraint.ts b/cocos/physics/cannon/constraints/cannon-distance-constraint.ts index 22db41ce254..7bbf7adfeaf 100644 --- a/cocos/physics/cannon/constraints/cannon-distance-constraint.ts +++ b/cocos/physics/cannon/constraints/cannon-distance-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ // import CANNON from '@cocos/cannon'; // import { CannonConstraint } from './cannon-constraint'; diff --git a/cocos/physics/cannon/constraints/cannon-hinge-constraint.ts b/cocos/physics/cannon/constraints/cannon-hinge-constraint.ts index ca8e8ff1027..8c5b5d08b16 100644 --- a/cocos/physics/cannon/constraints/cannon-hinge-constraint.ts +++ b/cocos/physics/cannon/constraints/cannon-hinge-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; import { CannonConstraint } from './cannon-constraint'; diff --git a/cocos/physics/cannon/constraints/cannon-lock-constraint.ts b/cocos/physics/cannon/constraints/cannon-lock-constraint.ts index 54f277adf29..ac827839ccd 100644 --- a/cocos/physics/cannon/constraints/cannon-lock-constraint.ts +++ b/cocos/physics/cannon/constraints/cannon-lock-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,54 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -// import CANNON from '@cocos/cannon'; -// import { CannonConstraint } from './cannon-constraint'; -// import { CannonSharedBody } from '../cannon-shared-body'; - -// export class CannonDistanceConstraint extends CannonConstraint { -// constructor (first: CannonSharedBody, second: CannonSharedBody, distance?: number, options?: any) { -// super(new CANNON.DistanceConstraint( -// first.body, -// second.body, -// distance!, -// options === undefined ? undefined : options.maxForce)); -// } -// } +*/ + +import CANNON from '@cocos/cannon'; +import { IVec3Like, Vec3 } from '../../../core'; +import { FixedConstraint } from '../../framework'; +import { IFixedConstraint } from '../../spec/i-physics-constraint'; +import { CannonConstraint } from './cannon-constraint'; +import { CannonRigidBody } from '../cannon-rigid-body'; + +export class CannonLockConstraint extends CannonConstraint implements IFixedConstraint { + protected _breakForce = 1e9; + + setBreakForce (v: number): void { + this._breakForce = v; + this.updateFrame(); + } + setBreakTorque (v: number): void { + // not supported + } + + public get impl () { + return this._impl as CANNON.LockConstraint; + } + + get constraint (): FixedConstraint { + return this._com as FixedConstraint; + } + + onComponentSet (): void { + this._breakForce = this.constraint.breakForce; + this.updateFrame(); + } + + updateFrame (): void { + const bodyA = (this._rigidBody.body as CannonRigidBody).impl; + const cb = this.constraint.connectedBody; + let bodyB: CANNON.Body = (CANNON.World as any).staticBody; + if (cb) { + bodyB = (cb.body as CannonRigidBody).impl; + } + this._impl = new CANNON.LockConstraint(bodyA, bodyB, { maxForce: this._breakForce }); + } + + updateScale0 (): void { + this.updateFrame(); + } + + updateScale1 (): void { + this.updateFrame(); + } +} diff --git a/cocos/physics/cannon/constraints/cannon-point-to-point-constraint.ts b/cocos/physics/cannon/constraints/cannon-point-to-point-constraint.ts index 8d3f1911f59..55d34994491 100644 --- a/cocos/physics/cannon/constraints/cannon-point-to-point-constraint.ts +++ b/cocos/physics/cannon/constraints/cannon-point-to-point-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; import { CannonConstraint } from './cannon-constraint'; diff --git a/cocos/physics/cannon/instantiate.ts b/cocos/physics/cannon/instantiate.ts index 67a0abb8be4..2feb8075881 100644 --- a/cocos/physics/cannon/instantiate.ts +++ b/cocos/physics/cannon/instantiate.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { selector } from '../framework/physics-selector'; @@ -39,6 +38,7 @@ import { CannonPlaneShape } from './shapes/cannon-plane-shape'; import { CannonPointToPointConstraint } from './constraints/cannon-point-to-point-constraint'; import { CannonHingeConstraint } from './constraints/cannon-hinge-constraint'; +import { CannonLockConstraint } from './constraints/cannon-lock-constraint'; import { Game, game } from '../../game'; game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { @@ -57,5 +57,6 @@ game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { PointToPointConstraint: CannonPointToPointConstraint, HingeConstraint: CannonHingeConstraint, + FixedConstraint: CannonLockConstraint, }); }); diff --git a/cocos/physics/cannon/shapes/cannon-box-shape.ts b/cocos/physics/cannon/shapes/cannon-box-shape.ts index 0f820941ae4..461d131ea87 100644 --- a/cocos/physics/cannon/shapes/cannon-box-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-box-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { clamp, Vec3 } from '../../../core/math'; +import { clamp, Vec3 } from '../../../core'; import { commitShapeUpdates } from '../cannon-util'; import { CannonShape } from './cannon-shape'; import { IBoxShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; -import { BoxCollider, physics, PhysicsSystem } from '../../../../exports/physics-framework'; +import { BoxCollider, PhysicsSystem } from '../../../../exports/physics-framework'; import { absolute, VEC3_0 } from '../../utils/util'; export class CannonBoxShape extends CannonShape implements IBoxShape { diff --git a/cocos/physics/cannon/shapes/cannon-cone-shape.ts b/cocos/physics/cannon/shapes/cannon-cone-shape.ts index 9f0e8161cab..9c6a078829b 100644 --- a/cocos/physics/cannon/shapes/cannon-cone-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-cone-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Vec3 } from '../../../core/math'; +import { Vec3, IVec3Like } from '../../../core'; import { CannonShape } from './cannon-shape'; import { IConeShape } from '../../spec/i-physics-shape'; import { ConeCollider } from '../../../../exports/physics-framework'; import { EAxisDirection } from '../../framework/physics-enum'; -import { IVec3Like } from '../../../core/math/type-define'; import { commitShapeUpdates } from '../cannon-util'; const v3_0 = new Vec3(); diff --git a/cocos/physics/cannon/shapes/cannon-cylinder-shape.ts b/cocos/physics/cannon/shapes/cannon-cylinder-shape.ts index 5f44172b8b6..22f27b2eb59 100644 --- a/cocos/physics/cannon/shapes/cannon-cylinder-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-cylinder-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Vec3 } from '../../../core/math'; +import { Vec3, IVec3Like } from '../../../core'; import { CannonShape } from './cannon-shape'; import { ICylinderShape } from '../../spec/i-physics-shape'; import { CylinderCollider } from '../../../../exports/physics-framework'; import { EAxisDirection } from '../../framework/physics-enum'; -import { IVec3Like } from '../../../core/math/type-define'; import { commitShapeUpdates } from '../cannon-util'; export class CannonCylinderShape extends CannonShape implements ICylinderShape { diff --git a/cocos/physics/cannon/shapes/cannon-plane-shape.ts b/cocos/physics/cannon/shapes/cannon-plane-shape.ts index 4f50ea51610..66c94a8bad6 100644 --- a/cocos/physics/cannon/shapes/cannon-plane-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-plane-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Vec3, Quat } from '../../../core/math'; +import { Vec3, Quat, IVec3Like } from '../../../core'; import { commitShapeUpdates } from '../cannon-util'; import { CannonShape } from './cannon-shape'; import { IPlaneShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; import { PlaneCollider } from '../../../../exports/physics-framework'; export class CannonPlaneShape extends CannonShape implements IPlaneShape { diff --git a/cocos/physics/cannon/shapes/cannon-shape.ts b/cocos/physics/cannon/shapes/cannon-shape.ts index c66b52c413e..5bcf26b3557 100644 --- a/cocos/physics/cannon/shapes/cannon-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { Vec3, Quat } from '../../../core/math'; +import { Vec3, Quat, IVec3Like, geometry } from '../../../core'; import { getWrap, setWrap } from '../../utils/util'; import { commitShapeUpdates } from '../cannon-util'; import { PhysicsMaterial } from '../../framework/assets/physics-material'; import { IBaseShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; import { CannonSharedBody } from '../cannon-shared-body'; import { CannonWorld } from '../cannon-world'; import { TriggerEventType } from '../../framework/physics-interface'; import { PhysicsSystem } from '../../framework/physics-system'; import { Collider, RigidBody } from '../../framework'; -import { AABB, Sphere } from '../../../core/geometry'; const TriggerEventObject = { type: 'onTriggerEnter' as TriggerEventType, @@ -63,20 +60,18 @@ export class CannonShape implements IBaseShape { get sharedBody (): CannonSharedBody { return this._sharedBody; } setMaterial (mat: PhysicsMaterial | null) { - if (mat == null) { - (this._shape.material as unknown) = null; - } else { - if (CannonShape.idToMaterial[mat.id] == null) { - CannonShape.idToMaterial[mat.id] = new CANNON.Material(mat.id as any); - } + const mat1 = (mat == null) ? PhysicsSystem.instance.defaultMaterial : mat; - this._shape.material = CannonShape.idToMaterial[mat.id]; - const smat = this._shape.material; - smat.friction = mat.friction; - smat.restitution = mat.restitution; - const coef = (CANNON as any).CC_CONFIG.correctInelastic; - (smat as any).correctInelastic = smat.restitution === 0 ? coef : 0; + if (CannonShape.idToMaterial[mat1.id] == null) { + CannonShape.idToMaterial[mat1.id] = new CANNON.Material(mat1.id as any); } + + this._shape.material = CannonShape.idToMaterial[mat1.id]; + const smat = this._shape.material; + smat.friction = mat1.friction; + smat.restitution = mat1.restitution; + const coef = (CANNON as any).CC_CONFIG.correctInelastic; + (smat as any).correctInelastic = smat.restitution === 0 ? coef : 0; } setAsTrigger (v: boolean) { @@ -112,7 +107,7 @@ export class CannonShape implements IBaseShape { } } - getAABB (v: AABB) { + getAABB (v: geometry.AABB) { Quat.copy(cannonQuat_0, this._collider.node.worldRotation); (this._shape as any).calculateWorldAABB(CANNON.Vec3.ZERO, cannonQuat_0, cannonVec3_0, cannonVec3_1); Vec3.subtract(v.halfExtents, cannonVec3_1, cannonVec3_0); @@ -120,7 +115,7 @@ export class CannonShape implements IBaseShape { Vec3.add(v.center, this._collider.node.worldPosition, this._collider.center); } - getBoundingSphere (v: Sphere) { + getBoundingSphere (v: geometry.Sphere) { v.radius = this._shape.boundingSphereRadius; Vec3.add(v.center, this._collider.node.worldPosition, this._collider.center); } diff --git a/cocos/physics/cannon/shapes/cannon-simplex-shape.ts b/cocos/physics/cannon/shapes/cannon-simplex-shape.ts index 6530bc866dc..f4b2d43b3e7 100644 --- a/cocos/physics/cannon/shapes/cannon-simplex-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-simplex-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable func-names */ import CANNON from '@cocos/cannon'; -import { Vec3 } from '../../../core/math'; +import { Vec3, IVec3Like } from '../../../core'; import { commitShapeUpdates } from '../cannon-util'; import { CannonShape } from './cannon-shape'; import { ISimplexShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; import { SimplexCollider } from '../../../../exports/physics-framework'; export class CannonSimplexShape extends CannonShape implements ISimplexShape { diff --git a/cocos/physics/cannon/shapes/cannon-sphere-shape.ts b/cocos/physics/cannon/shapes/cannon-sphere-shape.ts index 6f7b7febc61..f482e160ef4 100644 --- a/cocos/physics/cannon/shapes/cannon-sphere-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-sphere-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; -import { absMaxComponent, clamp, Vec3 } from '../../../core/math'; +import { absMaxComponent, clamp, Vec3 } from '../../../core'; import { commitShapeUpdates } from '../cannon-util'; import { CannonShape } from './cannon-shape'; import { ISphereShape } from '../../spec/i-physics-shape'; diff --git a/cocos/physics/cannon/shapes/cannon-terrain-shape.ts b/cocos/physics/cannon/shapes/cannon-terrain-shape.ts index 2a0001bbcc3..98b4be71364 100644 --- a/cocos/physics/cannon/shapes/cannon-terrain-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-terrain-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,16 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import CANNON from '@cocos/cannon'; import { CannonShape } from './cannon-shape'; import { TerrainCollider } from '../../framework'; -import { Vec3, Quat } from '../../../core'; +import { Vec3, Quat, IVec3Like } from '../../../core'; import { ITerrainShape } from '../../spec/i-physics-shape'; import { ITerrainAsset } from '../../spec/i-external'; import { commitShapeUpdates } from '../cannon-util'; -import { IVec3Like } from '../../../core/math/type-define'; const CANNON_AABB_LOCAL = new CANNON.AABB(); const CANNON_AABB = new CANNON.AABB(); diff --git a/cocos/physics/cannon/shapes/cannon-trimesh-shape.ts b/cocos/physics/cannon/shapes/cannon-trimesh-shape.ts index 2d0c8eafc2f..d425c66aa75 100644 --- a/cocos/physics/cannon/shapes/cannon-trimesh-shape.ts +++ b/cocos/physics/cannon/shapes/cannon-trimesh-shape.ts @@ -1,27 +1,26 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ import CANNON from '@cocos/cannon'; import { CannonShape } from './cannon-shape'; diff --git a/cocos/physics/cocos/builtin-interface.ts b/cocos/physics/cocos/builtin-interface.ts index c424f9c9d6f..ac6d5337b98 100644 --- a/cocos/physics/cocos/builtin-interface.ts +++ b/cocos/physics/cocos/builtin-interface.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Mat4, Quat, Vec3 } from '../../core/math'; -import { IVec3Like, IQuatLike } from '../../core/math/type-define'; +import { Mat4, Vec3, IVec3Like, IQuatLike } from '../../core'; /** * declare interface diff --git a/cocos/physics/cocos/builtin-rigid-body.ts b/cocos/physics/cocos/builtin-rigid-body.ts index e9e3383e194..5ac14431fcd 100644 --- a/cocos/physics/cocos/builtin-rigid-body.ts +++ b/cocos/physics/cocos/builtin-rigid-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IRigidBody } from '../spec/i-rigid-body'; import { IVec3Like } from '../../core'; diff --git a/cocos/physics/cocos/builtin-shared-body.ts b/cocos/physics/cocos/builtin-shared-body.ts index 662838b6d5b..8a192bc1c04 100644 --- a/cocos/physics/cocos/builtin-shared-body.ts +++ b/cocos/physics/cocos/builtin-shared-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Mat4, Quat, Vec3 } from '../../core/math'; -import { intersect } from '../../core/geometry'; +import { Mat4, Quat, Vec3, js, geometry } from '../../core'; import { BuiltInWorld } from './builtin-world'; import { BuiltinObject } from './object/builtin-object'; import { BuiltinShape } from './shapes/builtin-shape'; @@ -32,7 +30,6 @@ import { Node } from '../../scene-graph'; import { BuiltinRigidBody } from './builtin-rigid-body'; import { PhysicsSystem } from '../framework'; import { PhysicsGroup } from '../framework/physics-enum'; -import { fastRemoveAt } from '../../core/utils/array'; const m4_0 = new Mat4(); const v3_0 = new Vec3(); @@ -124,7 +121,7 @@ export class BuiltinSharedBody extends BuiltinObject { for (let j = 0; j < body.shapes.length; j++) { const shapeB = body.shapes[j]; if (shapeA.collider.needTriggerEvent || shapeB.collider.needTriggerEvent) { - if (intersect.resolve(shapeA.worldShape, shapeB.worldShape)) { + if (geometry.intersect.resolve(shapeA.worldShape, shapeB.worldShape)) { this.world.shapeArr.push(shapeA); this.world.shapeArr.push(shapeB); } @@ -143,7 +140,7 @@ export class BuiltinSharedBody extends BuiltinObject { removeShape (shape: BuiltinShape): void { const i = this.shapes.indexOf(shape); if (i >= 0) { - fastRemoveAt(this.shapes, i); + js.array.fastRemoveAt(this.shapes, i); } } diff --git a/cocos/physics/cocos/builtin-world.ts b/cocos/physics/cocos/builtin-world.ts index c072104d86f..bf9b1a119bd 100644 --- a/cocos/physics/cocos/builtin-world.ts +++ b/cocos/physics/cocos/builtin-world.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,22 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../core/math'; +import { Vec3, RecyclePool, error, js, IVec3Like, geometry } from '../../core'; import { PhysicsRayResult } from '../framework/physics-ray-result'; import { BuiltinSharedBody } from './builtin-shared-body'; import { BuiltinShape } from './shapes/builtin-shape'; import { ArrayCollisionMatrix } from '../utils/array-collision-matrix'; -import { Ray, intersect } from '../../core/geometry'; -import { RecyclePool, error } from '../../core'; import { IPhysicsWorld, IRaycastOptions } from '../spec/i-physics-world'; -import { IVec3Like } from '../../core/math/type-define'; import { PhysicsMaterial } from '../framework/assets/physics-material'; import { TriggerEventType } from '../framework/physics-interface'; import { Collider } from '../../../exports/physics-framework'; import { BuiltinRigidBody } from './builtin-rigid-body'; -import { fastRemoveAt } from '../../core/utils/array'; import { Node } from '../../scene-graph'; const hitPoint = new Vec3(); @@ -105,7 +100,7 @@ export class BuiltInWorld implements IPhysicsWorld { this.emitTriggerEvent(); } - raycastClosest (worldRay: Ray, options: IRaycastOptions, out: PhysicsRayResult): boolean { + raycastClosest (worldRay: geometry.Ray, options: IRaycastOptions, out: PhysicsRayResult): boolean { let tmp_d = Infinity; const max_d = options.maxDistance; const mask = options.mask; @@ -114,7 +109,7 @@ export class BuiltInWorld implements IPhysicsWorld { if (!(body.collisionFilterGroup & mask)) continue; for (let i = 0; i < body.shapes.length; i++) { const shape = body.shapes[i]; - const distance = intersect.resolve(worldRay, shape.worldShape); + const distance = geometry.intersect.resolve(worldRay, shape.worldShape); if (distance === 0 || distance > max_d) { continue; } @@ -130,7 +125,7 @@ export class BuiltInWorld implements IPhysicsWorld { return !(tmp_d === Infinity); } - raycast (worldRay: Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { + raycast (worldRay: geometry.Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { const max_d = options.maxDistance; const mask = options.mask; for (let i = 0; i < this.bodies.length; i++) { @@ -138,7 +133,7 @@ export class BuiltInWorld implements IPhysicsWorld { if (!(body.collisionFilterGroup & mask)) continue; for (let i = 0; i < body.shapes.length; i++) { const shape = body.shapes[i]; - const distance = intersect.resolve(worldRay, shape.worldShape); + const distance = geometry.intersect.resolve(worldRay, shape.worldShape); if (distance === 0 || distance > max_d) { continue; } else { @@ -166,7 +161,7 @@ export class BuiltInWorld implements IPhysicsWorld { removeSharedBody (body: BuiltinSharedBody) { const index = this.bodies.indexOf(body); if (index >= 0) { - fastRemoveAt(this.bodies, index); + js.array.fastRemoveAt(this.bodies, index); } } diff --git a/cocos/physics/cocos/instantiate.ts b/cocos/physics/cocos/instantiate.ts index 22366ecbe57..a4b9e3cf826 100644 --- a/cocos/physics/cocos/instantiate.ts +++ b/cocos/physics/cocos/instantiate.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { selector } from '../framework/physics-selector'; import { BuiltInWorld } from './builtin-world'; diff --git a/cocos/physics/cocos/object/builtin-object.ts b/cocos/physics/cocos/object/builtin-object.ts index 1f08600bd54..2ae35688a6f 100644 --- a/cocos/physics/cocos/object/builtin-object.ts +++ b/cocos/physics/cocos/object/builtin-object.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PhysicsSystem } from '../../framework'; diff --git a/cocos/physics/cocos/shapes/builtin-box-shape.ts b/cocos/physics/cocos/shapes/builtin-box-shape.ts index 7b200ed3d81..41ae4830c3d 100644 --- a/cocos/physics/cocos/shapes/builtin-box-shape.ts +++ b/cocos/physics/cocos/shapes/builtin-box-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,22 +20,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../../core/math'; -import { OBB } from '../../../core/geometry'; +import { Vec3, geometry } from '../../../core'; import { BuiltinShape } from './builtin-shape'; import { IBoxShape } from '../../spec/i-physics-shape'; import { BoxCollider } from '../../../../exports/physics-framework'; -import { IVec3Like } from '../../../core/math/type-define'; export class BuiltinBoxShape extends BuiltinShape implements IBoxShape { get localObb () { - return this._localShape as OBB; + return this._localShape as geometry.OBB; } get worldObb () { - return this._worldShape as OBB; + return this._worldShape as geometry.OBB; } get collider () { @@ -45,8 +42,8 @@ export class BuiltinBoxShape extends BuiltinShape implements IBoxShape { constructor () { super(); - this._localShape = new OBB(); - this._worldShape = new OBB(); + this._localShape = new geometry.OBB(); + this._worldShape = new geometry.OBB(); } updateSize () { diff --git a/cocos/physics/cocos/shapes/builtin-capsule-shape.ts b/cocos/physics/cocos/shapes/builtin-capsule-shape.ts index bb06fd138cf..36e5dce08e6 100644 --- a/cocos/physics/cocos/shapes/builtin-capsule-shape.ts +++ b/cocos/physics/cocos/shapes/builtin-capsule-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,20 +20,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BuiltinShape } from './builtin-shape'; import { ICapsuleShape } from '../../spec/i-physics-shape'; -import { Capsule } from '../../../core/geometry'; +import { geometry } from '../../../core'; import { EAxisDirection, CapsuleCollider } from '../../framework'; export class BuiltinCapsuleShape extends BuiltinShape implements ICapsuleShape { get localCapsule () { - return this._localShape as Capsule; + return this._localShape as geometry.Capsule; } get worldCapsule () { - return this._worldShape as Capsule; + return this._worldShape as geometry.Capsule; } get collider () { @@ -45,8 +44,8 @@ export class BuiltinCapsuleShape extends BuiltinShape implements ICapsuleShape { super(); const halfHeight = (height - radius * 2) / 2; const h = halfHeight < 0 ? 0 : halfHeight; - this._localShape = new Capsule(radius, h, direction); - this._worldShape = new Capsule(radius, h, direction); + this._localShape = new geometry.Capsule(radius, h, direction); + this._worldShape = new geometry.Capsule(radius, h, direction); } setRadius (v: number) { diff --git a/cocos/physics/cocos/shapes/builtin-shape.ts b/cocos/physics/cocos/shapes/builtin-shape.ts index d217da55c7b..e4b672535e0 100644 --- a/cocos/physics/cocos/shapes/builtin-shape.ts +++ b/cocos/physics/cocos/shapes/builtin-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,20 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Mat4, Quat, Vec3 } from '../../../core/math'; +import { Mat4, Quat, Vec3, IVec3Like, geometry } from '../../../core'; import { BuiltinSharedBody } from '../builtin-shared-body'; import { IBuiltinShape } from '../builtin-interface'; import { Collider, RigidBody, PhysicsMaterial, PhysicsSystem } from '../../../../exports/physics-framework'; import { IBaseShape } from '../../spec/i-physics-shape'; -import { IVec3Like } from '../../../core/math/type-define'; import { BuiltInWorld } from '../builtin-world'; -import { AABB, Sphere } from '../../../core/geometry'; export class BuiltinShape implements IBaseShape { - getAABB (v: AABB) { } - getBoundingSphere (v: Sphere) { } + getAABB (v: geometry.AABB) { } + getBoundingSphere (v: geometry.Sphere) { } updateEventListener (): void { } setMaterial (v: PhysicsMaterial | null) { } setAsTrigger (v: boolean) { } diff --git a/cocos/physics/cocos/shapes/builtin-sphere-shape.ts b/cocos/physics/cocos/shapes/builtin-sphere-shape.ts index 21828cea1b0..0be5941017d 100644 --- a/cocos/physics/cocos/shapes/builtin-sphere-shape.ts +++ b/cocos/physics/cocos/shapes/builtin-sphere-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Sphere } from '../../../core/geometry'; +import { geometry } from '../../../core'; import { BuiltinShape } from './builtin-shape'; import { ISphereShape } from '../../spec/i-physics-shape'; import { maxComponent } from '../../utils/util'; @@ -37,11 +36,11 @@ export class BuiltinSphereShape extends BuiltinShape implements ISphereShape { } get localSphere () { - return this._localShape as Sphere; + return this._localShape as geometry.Sphere; } get worldSphere () { - return this._worldShape as Sphere; + return this._worldShape as geometry.Sphere; } get collider () { @@ -50,8 +49,8 @@ export class BuiltinSphereShape extends BuiltinShape implements ISphereShape { constructor (radius = 0.5) { super(); - this._localShape = new Sphere(0, 0, 0, radius); - this._worldShape = new Sphere(0, 0, 0, radius); + this._localShape = new geometry.Sphere(0, 0, 0, radius); + this._worldShape = new geometry.Sphere(0, 0, 0, radius); } onLoad () { diff --git a/cocos/physics/framework/assets/physics-material.ts b/cocos/physics/framework/assets/physics-material.ts index d6f95bb8ad5..cbe97b669a1 100644 --- a/cocos/physics/framework/assets/physics-material.ts +++ b/cocos/physics/framework/assets/physics-material.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ // @ts-check diff --git a/cocos/physics/framework/collision-matrix.ts b/cocos/physics/framework/collision-matrix.ts index 642aef313fa..575440de1ab 100644 --- a/cocos/physics/framework/collision-matrix.ts +++ b/cocos/physics/framework/collision-matrix.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PhysicsGroup } from './physics-enum'; diff --git a/cocos/physics/framework/components/colliders/box-collider.ts b/cocos/physics/framework/components/colliders/box-collider.ts index d8a0f34ba03..ec2ed63f2ec 100644 --- a/cocos/physics/framework/components/colliders/box-collider.ts +++ b/cocos/physics/framework/components/colliders/box-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -32,7 +31,7 @@ import { type, serializable, } from 'cc.decorator'; -import { Vec3 } from '../../../../core/math'; +import { Vec3 } from '../../../../core'; import { Collider } from './collider'; import { IBoxShape } from '../../../spec/i-physics-shape'; import { EColliderType } from '../../physics-enum'; diff --git a/cocos/physics/framework/components/colliders/capsule-collider.ts b/cocos/physics/framework/components/colliders/capsule-collider.ts index 2bacea503d3..8b1d82585df 100644 --- a/cocos/physics/framework/components/colliders/capsule-collider.ts +++ b/cocos/physics/framework/components/colliders/capsule-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, diff --git a/cocos/physics/framework/components/colliders/collider.ts b/cocos/physics/framework/components/colliders/collider.ts index 661354338d1..9638881fa5d 100644 --- a/cocos/physics/framework/components/colliders/collider.ts +++ b/cocos/physics/framework/components/colliders/collider.ts @@ -1,19 +1,18 @@ /* eslint-disable @typescript-eslint/no-namespace */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,22 +21,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, tooltip, displayOrder, displayName, readOnly, type, serializable } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; -import { Eventify } from '../../../../core/event'; -import { Vec3 } from '../../../../core/math'; +import { Eventify, Vec3, error, geometry } from '../../../../core'; import { CollisionEventType, TriggerEventType } from '../../physics-interface'; import { RigidBody } from '../rigid-body'; import { PhysicsMaterial } from '../../assets/physics-material'; import { PhysicsSystem } from '../../physics-system'; import { Component, Node } from '../../../../scene-graph'; import { IBaseShape } from '../../../spec/i-physics-shape'; -import { AABB, Sphere } from '../../../../core/geometry'; import { EColliderType, EAxisDirection } from '../../physics-enum'; import { selector, createShape } from '../../physics-selector'; -import { error } from '../../../../core'; /** * @en @@ -190,14 +186,14 @@ export class Collider extends Eventify(Component) { return this._shape; } - public get worldBounds (): Readonly { - if (this._aabb == null) this._aabb = new AABB(); + public get worldBounds (): Readonly { + if (this._aabb == null) this._aabb = new geometry.AABB(); if (this._shape) this._shape.getAABB(this._aabb); return this._aabb; } - public get boundingSphere (): Readonly { - if (this._boundingSphere == null) this._boundingSphere = new Sphere(); + public get boundingSphere (): Readonly { + if (this._boundingSphere == null) this._boundingSphere = new geometry.Sphere(); if (this._shape) this._shape.getBoundingSphere(this._boundingSphere); return this._boundingSphere; } @@ -215,8 +211,8 @@ export class Collider extends Eventify(Component) { /// PROTECTED PROPERTY /// protected _shape: IBaseShape | null = null; - protected _aabb: AABB | null = null; - protected _boundingSphere: Sphere | null = null; + protected _aabb: geometry.AABB | null = null; + protected _boundingSphere: geometry.Sphere | null = null; protected _isSharedMaterial = true; protected _needTriggerEvent = false; protected _needCollisionEvent = false; @@ -413,7 +409,8 @@ export class Collider extends Eventify(Component) { protected onLoad () { if (!selector.runInEditor) return; - this.sharedMaterial = this._material == null ? PhysicsSystem.instance.defaultMaterial : this._material; + + this.sharedMaterial = this._material; this._shape = createShape(this.type); this._shape.initialize(this); this._shape.onLoad!(); diff --git a/cocos/physics/framework/components/colliders/cone-collider.ts b/cocos/physics/framework/components/colliders/cone-collider.ts index c4a1157a765..9489b3e91fd 100644 --- a/cocos/physics/framework/components/colliders/cone-collider.ts +++ b/cocos/physics/framework/components/colliders/cone-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, diff --git a/cocos/physics/framework/components/colliders/cylinder-collider.ts b/cocos/physics/framework/components/colliders/cylinder-collider.ts index 83a917f0b21..072b60fc2a4 100644 --- a/cocos/physics/framework/components/colliders/cylinder-collider.ts +++ b/cocos/physics/framework/components/colliders/cylinder-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, diff --git a/cocos/physics/framework/components/colliders/mesh-collider.ts b/cocos/physics/framework/components/colliders/mesh-collider.ts index daf7c09ec8b..705f6eee9bc 100644 --- a/cocos/physics/framework/components/colliders/mesh-collider.ts +++ b/cocos/physics/framework/components/colliders/mesh-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -84,6 +83,8 @@ export class MeshCollider extends Collider { set convex (value) { if (this._convex === value) return; this._convex = value; + + if (this._shape && this._mesh) this.shape.setMesh(this._mesh); } /** diff --git a/cocos/physics/framework/components/colliders/plane-collider.ts b/cocos/physics/framework/components/colliders/plane-collider.ts index cf329e5ddd2..93d5a685f4e 100644 --- a/cocos/physics/framework/components/colliders/plane-collider.ts +++ b/cocos/physics/framework/components/colliders/plane-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -33,7 +32,7 @@ import { editable, serializable, } from 'cc.decorator'; -import { Vec3 } from '../../../../core/math'; +import { Vec3 } from '../../../../core'; import { Collider } from './collider'; import { IPlaneShape } from '../../../spec/i-physics-shape'; import { EColliderType } from '../../physics-enum'; diff --git a/cocos/physics/framework/components/colliders/simplex-collider.ts b/cocos/physics/framework/components/colliders/simplex-collider.ts index 88a27359362..66b5e6b5e66 100644 --- a/cocos/physics/framework/components/colliders/simplex-collider.ts +++ b/cocos/physics/framework/components/colliders/simplex-collider.ts @@ -1,20 +1,19 @@ /* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable func-names */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -36,11 +35,10 @@ import { serializable, tooltip, } from 'cc.decorator'; -import { Vec3 } from '../../../../core/math'; +import { Vec3, IVec3Like } from '../../../../core'; import { Collider } from './collider'; import { ISimplexShape } from '../../../spec/i-physics-shape'; import { ESimplexType, EColliderType } from '../../physics-enum'; -import { IVec3Like } from '../../../../core/math/type-define'; /** * @en diff --git a/cocos/physics/framework/components/colliders/sphere-collider.ts b/cocos/physics/framework/components/colliders/sphere-collider.ts index c938d8b0ce7..e4895bc94b2 100644 --- a/cocos/physics/framework/components/colliders/sphere-collider.ts +++ b/cocos/physics/framework/components/colliders/sphere-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, diff --git a/cocos/physics/framework/components/colliders/terrain-collider.ts b/cocos/physics/framework/components/colliders/terrain-collider.ts index 5dcc6f9440d..d6f7ecefac4 100644 --- a/cocos/physics/framework/components/colliders/terrain-collider.ts +++ b/cocos/physics/framework/components/colliders/terrain-collider.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, diff --git a/cocos/physics/framework/components/constant-force.ts b/cocos/physics/framework/components/constant-force.ts index b7788c7ba5f..9e1f127b866 100644 --- a/cocos/physics/framework/components/constant-force.ts +++ b/cocos/physics/framework/components/constant-force.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -37,8 +36,7 @@ import { import { EDITOR } from 'internal:constants'; import { Component } from '../../../scene-graph/component'; import { RigidBody } from './rigid-body'; -import { Vec3 } from '../../../core/math/vec3'; -import { legacyCC } from '../../../core/global-exports'; +import { Vec3, geometry, cclegacy } from '../../../core'; /** * @en @@ -146,7 +144,7 @@ export class ConstantForce extends Component { } public lateUpdate (dt: number) { - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this._rigidBody != null && this._mask !== 0) { if (this._mask & 1) this._rigidBody.applyForce(this._force); if (this._mask & 2) this._rigidBody.applyLocalForce(this.localForce); diff --git a/cocos/physics/framework/components/constraints/constraint.ts b/cocos/physics/framework/components/constraints/constraint.ts index 0f06de99469..beb31e4b424 100644 --- a/cocos/physics/framework/components/constraints/constraint.ts +++ b/cocos/physics/framework/components/constraints/constraint.ts @@ -1,19 +1,18 @@ /* eslint-disable @typescript-eslint/no-namespace */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,17 +21,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, requireComponent, displayOrder, type, readOnly, serializable } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; import { Component } from '../../../../scene-graph'; import { RigidBody } from '../rigid-body'; -import { Eventify } from '../../../../core/event'; +import { Eventify, cclegacy } from '../../../../core'; import { IBaseConstraint } from '../../../spec/i-physics-constraint'; import { selector, createConstraint } from '../../physics-selector'; import { EConstraintType } from '../../physics-enum'; -import { legacyCC } from '../../../../core/global-exports'; /** * @en @@ -78,7 +76,7 @@ export class Constraint extends Eventify(Component) { set connectedBody (v: RigidBody | null) { this._connectedBody = v; - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this._constraint) this._constraint.setConnectedBody(v); } } @@ -96,7 +94,7 @@ export class Constraint extends Eventify(Component) { set enableCollision (v) { this._enableCollision = v; - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { if (this._constraint) this._constraint.setEnableCollision(v); } } diff --git a/cocos/physics/framework/components/constraints/fixed-constraint.ts b/cocos/physics/framework/components/constraints/fixed-constraint.ts new file mode 100644 index 00000000000..ec5973961ab --- /dev/null +++ b/cocos/physics/framework/components/constraints/fixed-constraint.ts @@ -0,0 +1,95 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { + ccclass, + help, + menu, + serializable, + formerlySerializedAs, + type, +} from 'cc.decorator'; +import { EDITOR } from 'internal:constants'; +import { Constraint } from './constraint'; +import { CCFloat, IVec3Like, Vec3 } from '../../../../core'; +import { EConstraintType } from '../../physics-enum'; +import { IFixedConstraint } from '../../../spec/i-physics-constraint'; +import { legacyCC } from '../../../../core/global-exports'; + +@ccclass('cc.FixedConstraint') +@help('i18n:cc.FixedConstraint') +@menu('Physics/FixedConstraint(beta)') +export class FixedConstraint extends Constraint { + /** + * @en + * The break force threshold of the constraint. + * @zh + * 约束的断裂力阈值。 + */ + @type(CCFloat) + get breakForce (): number { + return this._breakForce; + } + + set breakForce (v: number) { + this._breakForce = v; + if (!EDITOR || legacyCC.GAME_VIEW) { + this.constraint.setBreakForce(v); + } + } + + /** + * @en + * The break torque threshold of the constraint. + * @zh + * 约束的断裂扭矩阈值。 + */ + @type(CCFloat) + get breakTorque (): number { + return this._breakTorque; + } + + set breakTorque (v: number) { + this._breakTorque = v; + if (!EDITOR || legacyCC.GAME_VIEW) { + this.constraint.setBreakTorque(v); + } + } + + get constraint (): IFixedConstraint { + return this._constraint as IFixedConstraint; + } + + @serializable + @formerlySerializedAs('breakForce') + private _breakForce = 1e8; + + @serializable + @formerlySerializedAs('breakTorque') + private _breakTorque = 1e8; + + constructor () { + super(EConstraintType.FIXED); + } +} diff --git a/cocos/physics/framework/components/constraints/hinge-constraint.ts b/cocos/physics/framework/components/constraints/hinge-constraint.ts index d13a317412c..1e153f91b5a 100644 --- a/cocos/physics/framework/components/constraints/hinge-constraint.ts +++ b/cocos/physics/framework/components/constraints/hinge-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -33,10 +32,9 @@ import { } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; import { Constraint } from './constraint'; -import { IVec3Like, Vec3 } from '../../../../core'; +import { Vec3, cclegacy } from '../../../../core'; import { EConstraintType } from '../../physics-enum'; import { IHingeConstraint } from '../../../spec/i-physics-constraint'; -import { legacyCC } from '../../../../core/global-exports'; @ccclass('cc.HingeConstraint') @help('i18n:cc.HingeConstraint') @@ -55,7 +53,7 @@ export class HingeConstraint extends Constraint { set pivotA (v: Vec3) { Vec3.copy(this._pivotA, v); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.constraint.setPivotA(this._pivotA); } } @@ -73,7 +71,7 @@ export class HingeConstraint extends Constraint { set pivotB (v: Vec3) { Vec3.copy(this._pivotB, v); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.constraint.setPivotB(this._pivotB); } } @@ -91,7 +89,7 @@ export class HingeConstraint extends Constraint { set axis (v: Vec3) { Vec3.copy(this._axis, v); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.constraint.setAxis(this._axis); } } diff --git a/cocos/physics/framework/components/constraints/point-to-point-constraint.ts b/cocos/physics/framework/components/constraints/point-to-point-constraint.ts index c772254e548..3e16fbe2954 100644 --- a/cocos/physics/framework/components/constraints/point-to-point-constraint.ts +++ b/cocos/physics/framework/components/constraints/point-to-point-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,22 +20,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, help, - executeInEditMode, menu, type, serializable, } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; import { Constraint } from './constraint'; -import { Vec3, IVec3Like } from '../../../../core'; +import { Vec3, IVec3Like, cclegacy } from '../../../../core'; import { EConstraintType } from '../../physics-enum'; import { IPointToPointConstraint } from '../../../spec/i-physics-constraint'; -import { legacyCC } from '../../../../core/global-exports'; @ccclass('cc.PointToPointConstraint') @help('i18n:cc.PointToPointConstraint') @@ -55,7 +52,7 @@ export class PointToPointConstraint extends Constraint { set pivotA (v: IVec3Like) { Vec3.copy(this._pivotA, v); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.constraint.setPivotA(this._pivotA); } } @@ -73,7 +70,7 @@ export class PointToPointConstraint extends Constraint { set pivotB (v: IVec3Like) { Vec3.copy(this._pivotB, v); - if (!EDITOR || legacyCC.GAME_VIEW) { + if (!EDITOR || cclegacy.GAME_VIEW) { this.constraint.setPivotB(this._pivotB); } } diff --git a/cocos/physics/framework/components/rigid-body.ts b/cocos/physics/framework/components/rigid-body.ts index e7250243cb9..4125815e402 100644 --- a/cocos/physics/framework/components/rigid-body.ts +++ b/cocos/physics/framework/components/rigid-body.ts @@ -1,20 +1,19 @@ /* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable func-names */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, @@ -39,9 +38,8 @@ import { serializable, } from 'cc.decorator'; import { DEBUG } from 'internal:constants'; -import { Vec3 } from '../../../core/math'; +import { Vec3, error, warn } from '../../../core'; import { Component } from '../../../scene-graph'; -import { error, warn } from '../../../core'; import { IRigidBody } from '../../spec/i-rigid-body'; import { selector, createRigidBody } from '../physics-selector'; import { ERigidBodyType } from '../physics-enum'; diff --git a/cocos/physics/framework/deprecated.ts b/cocos/physics/framework/deprecated.ts index b0e75b5517d..9473bf7a3d8 100644 --- a/cocos/physics/framework/deprecated.ts +++ b/cocos/physics/framework/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PhysicsSystem } from './physics-system'; -import { replaceProperty, removeProperty } from '../../core/utils/x-deprecated'; +import { replaceProperty, removeProperty, js, cclegacy } from '../../core'; import { BoxCollider } from './components/colliders/box-collider'; import { SphereCollider } from './components/colliders/sphere-collider'; import { CapsuleCollider } from './components/colliders/capsule-collider'; @@ -32,8 +31,6 @@ import { CylinderCollider } from './components/colliders/cylinder-collider'; import { MeshCollider } from './components/colliders/mesh-collider'; import { RigidBody } from './components/rigid-body'; import { Collider } from './components/colliders/collider'; -import { js } from '../../core/utils/js'; -import { legacyCC } from '../../core/global-exports'; import { PhysicsMaterial } from './assets/physics-material'; import { Constraint } from './components/constraints/constraint'; @@ -155,28 +152,28 @@ removeProperty(RigidBody.prototype, 'RigidBody.prototype', [ * @deprecated Since v1.2 */ export { RigidBody as RigidBodyComponent }; -legacyCC.RigidBodyComponent = RigidBody; +cclegacy.RigidBodyComponent = RigidBody; js.setClassAlias(RigidBody, 'cc.RigidBodyComponent'); /** * Alias of [[Collider]] * @deprecated Since v1.2 */ export { Collider as ColliderComponent }; -legacyCC.ColliderComponent = Collider; +cclegacy.ColliderComponent = Collider; js.setClassAlias(Collider, 'cc.ColliderComponent'); /** * Alias of [[BoxCollider]] * @deprecated Since v1.2 */ export { BoxCollider as BoxColliderComponent }; -legacyCC.BoxColliderComponent = BoxCollider; +cclegacy.BoxColliderComponent = BoxCollider; js.setClassAlias(BoxCollider, 'cc.BoxColliderComponent'); /** * Alias of [[SphereCollider]] * @deprecated Since v1.2 */ export { SphereCollider as SphereColliderComponent }; -legacyCC.SphereColliderComponent = SphereCollider; +cclegacy.SphereColliderComponent = SphereCollider; js.setClassAlias(SphereCollider, 'cc.SphereColliderComponent'); /** * Alias of [[CapsuleCollider]] @@ -201,5 +198,5 @@ js.setClassAlias(CylinderCollider, 'cc.CylinderColliderComponent'); * @deprecated Since v1.2 */ export { PhysicsMaterial as PhysicMaterial }; -legacyCC.PhysicMaterial = PhysicsMaterial; +cclegacy.PhysicMaterial = PhysicsMaterial; js.setClassAlias(PhysicsMaterial, 'cc.PhysicMaterial'); diff --git a/cocos/physics/framework/index.ts b/cocos/physics/framework/index.ts index 530128cbd51..54a0bd6074e 100644 --- a/cocos/physics/framework/index.ts +++ b/cocos/physics/framework/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PhysicsSystem } from './physics-system'; import { PhysicsMaterial } from './assets/physics-material'; @@ -42,9 +41,11 @@ import { PlaneCollider } from './components/colliders/plane-collider'; // constraints import { Constraint } from './components/constraints/constraint'; import { HingeConstraint } from './components/constraints/hinge-constraint'; +import { FixedConstraint } from './components/constraints/fixed-constraint'; + import { PointToPointConstraint } from './components/constraints/point-to-point-constraint'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; import { selector } from './physics-selector'; import * as utils from '../utils/util'; @@ -65,6 +66,7 @@ export { Constraint, HingeConstraint, + FixedConstraint, PointToPointConstraint, RigidBody, @@ -75,11 +77,11 @@ export { utils, }; -legacyCC.PhysicsSystem = PhysicsSystem; +cclegacy.PhysicsSystem = PhysicsSystem; -legacyCC.PhysicsMaterial = PhysicsMaterial; -legacyCC.PhysicsRayResult = PhysicsRayResult; -legacyCC.ConstantForce = ConstantForce; +cclegacy.PhysicsMaterial = PhysicsMaterial; +cclegacy.PhysicsRayResult = PhysicsRayResult; +cclegacy.ConstantForce = ConstantForce; export * from './physics-interface'; export * from './physics-config'; diff --git a/cocos/physics/framework/physics-config.ts b/cocos/physics/framework/physics-config.ts index 090262d9633..c570ac0fd1d 100644 --- a/cocos/physics/framework/physics-config.ts +++ b/cocos/physics/framework/physics-config.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like } from '../../core'; @@ -29,13 +28,6 @@ export interface ICollisionMatrix { [x: string]: number; } -export interface IPhysicsMaterial { - friction: number; - rollingFriction: number; - spinningFriction: number; - restitution: number; -} - export interface ICollisionGroup { index: number, name: string, @@ -49,7 +41,6 @@ export interface IPhysicsConfig { sleepThreshold?: number; collisionMatrix?: ICollisionMatrix; collisionGroups?: ICollisionGroup[]; - defaultMaterial?: IPhysicsMaterial; autoSimulation?: boolean; useNodeChains?: boolean; physicsEngine?: 'builtin' | 'cannon.js' | 'ammo.js' | string; diff --git a/cocos/physics/framework/physics-enum.ts b/cocos/physics/framework/physics-enum.ts index 579de3f6d22..f5bf0fc2dcb 100644 --- a/cocos/physics/framework/physics-enum.ts +++ b/cocos/physics/framework/physics-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Enum } from '../../core'; @@ -63,7 +62,8 @@ Enum(EColliderType); export enum EConstraintType { POINT_TO_POINT, HINGE, - CONE_TWIST + CONE_TWIST, + FIXED, } Enum(EConstraintType); diff --git a/cocos/physics/framework/physics-interface.ts b/cocos/physics/framework/physics-interface.ts index f785d31b076..0c3179ed35d 100644 --- a/cocos/physics/framework/physics-interface.ts +++ b/cocos/physics/framework/physics-interface.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { IVec3Like } from '../../core/math'; +import { IVec3Like } from '../../core'; import { Collider } from './components/colliders/collider'; /** diff --git a/cocos/physics/framework/physics-ray-result.ts b/cocos/physics/framework/physics-ray-result.ts index 177afdceed6..374055979f2 100644 --- a/cocos/physics/framework/physics-ray-result.ts +++ b/cocos/physics/framework/physics-ray-result.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../core/math'; +import { Vec3, IVec3Like } from '../../core'; import { Collider } from '../../../exports/physics-framework'; -import { IVec3Like } from '../../core/math/type-define'; /** * @en @@ -74,10 +72,10 @@ export class PhysicsRayResult { return this._hitNormal; } - private _hitPoint: Vec3 = new Vec3(); - private _hitNormal: Vec3 = new Vec3(); - private _distance = 0; - private _collider: Collider | null = null; + protected _hitPoint: Vec3 = new Vec3(); + protected _hitNormal: Vec3 = new Vec3(); + protected _distance = 0; + protected _collider: Collider | null = null; /** * @en @@ -109,3 +107,51 @@ export class PhysicsRayResult { return c; } } + +/** + * @en + * Used to store physics line strip cast test results. + * @zh + * 用于保存物理逐线段检测结果。 + */ +export class PhysicsLineStripCastResult extends PhysicsRayResult { + private _id = 0; + + /** + * @en + * The line id of the line segments. This is only for lineStripCast + * @zh + * id + */ + get id (): number { + return this._id; + } + + /** + * @en + * internal methods. + * @zh + * 设置射线,此方法由引擎内部使用,请勿在外部脚本调用。 + * @engineInternal + */ + public _assign (hitPoint: IVec3Like, distance: number, collider: Collider, hitNormal: IVec3Like, id = 0) { + super._assign(hitPoint, distance, collider, hitNormal); + this._id = id; + } + + /** + * @en + * clone. + * @zh + * 克隆。 + */ + public clone () { + const c = new PhysicsLineStripCastResult(); + Vec3.copy(c._hitPoint, this._hitPoint); + Vec3.copy(c._hitNormal, this._hitNormal); + c._distance = this._distance; + c._collider = this._collider; + c._id = this._id; + return c; + } +} diff --git a/cocos/physics/framework/physics-selector.ts b/cocos/physics/framework/physics-selector.ts index 27bffe39316..8bd60eb3b75 100644 --- a/cocos/physics/framework/physics-selector.ts +++ b/cocos/physics/framework/physics-selector.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,21 +20,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable import/no-mutable-exports */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { EDITOR, TEST } from 'internal:constants'; -import { legacyCC } from '../../core/global-exports'; -import { IBaseConstraint, IPointToPointConstraint, IHingeConstraint, IConeTwistConstraint } from '../spec/i-physics-constraint'; +import { IBaseConstraint, IPointToPointConstraint, IHingeConstraint, IConeTwistConstraint, IFixedConstraint } from '../spec/i-physics-constraint'; import { IBoxShape, ISphereShape, ICapsuleShape, ITrimeshShape, ICylinderShape, IConeShape, ITerrainShape, ISimplexShape, IPlaneShape, IBaseShape, } from '../spec/i-physics-shape'; import { IPhysicsWorld } from '../spec/i-physics-world'; import { IRigidBody } from '../spec/i-rigid-body'; -import { errorID, IVec3Like, warn } from '../../core'; +import { errorID, IVec3Like, warn, cclegacy } from '../../core'; import { EColliderType, EConstraintType } from './physics-enum'; import { PhysicsMaterial } from '.'; @@ -56,6 +54,7 @@ interface IPhysicsWrapperObject { PointToPointConstraint?: Constructor, HingeConstraint?: Constructor, ConeTwistConstraint?: Constructor, + FixedConstraint?: Constructor, } type IPhysicsBackend = { [key: string]: IPhysicsWrapperObject; } @@ -115,9 +114,9 @@ interface IPhysicsSelector { } function updateLegacyMacro (id: string) { - legacyCC._global.CC_PHYSICS_BUILTIN = id === 'builtin'; - legacyCC._global.CC_PHYSICS_CANNON = id === 'cannon.js'; - legacyCC._global.CC_PHYSICS_AMMO = id === 'bullet'; + cclegacy._global.CC_PHYSICS_BUILTIN = id === 'builtin'; + cclegacy._global.CC_PHYSICS_CANNON = id === 'cannon.js'; + cclegacy._global.CC_PHYSICS_AMMO = id === 'bullet'; } function register (id: IPhysicsEngineId, wrapper: IPhysicsWrapperObject): void { @@ -223,6 +222,7 @@ enum ECheckType { PointToPointConstraint, HingeConstraint, ConeTwistConstraint, + FixedConstraint, } function check (obj: any, type: ECheckType) { @@ -400,7 +400,7 @@ function initColliderProxy () { const CREATE_CONSTRAINT_PROXY = { INITED: false }; -interface IEntireConstraint extends IPointToPointConstraint, IHingeConstraint, IConeTwistConstraint { } +interface IEntireConstraint extends IPointToPointConstraint, IHingeConstraint, IConeTwistConstraint, IFixedConstraint { } const ENTIRE_CONSTRAINT: IEntireConstraint = { impl: null, initialize: FUNC, @@ -413,6 +413,8 @@ const ENTIRE_CONSTRAINT: IEntireConstraint = { setPivotA: FUNC, setPivotB: FUNC, setAxis: FUNC, + setBreakForce: FUNC, + setBreakTorque: FUNC, }; export function createConstraint (type: EConstraintType): IBaseConstraint { @@ -438,4 +440,9 @@ function initConstraintProxy () { if (check(selector.wrapper.ConeTwistConstraint, ECheckType.ConeTwistConstraint)) { return ENTIRE_CONSTRAINT; } return new selector.wrapper.ConeTwistConstraint!(); }; + + CREATE_CONSTRAINT_PROXY[EConstraintType.FIXED] = function createFixedConstraint (): IFixedConstraint { + if (check(selector.wrapper.FixedConstraint, ECheckType.FixedConstraint)) { return ENTIRE_CONSTRAINT; } + return new selector.wrapper.FixedConstraint!(); + }; } diff --git a/cocos/physics/framework/physics-system.ts b/cocos/physics/framework/physics-system.ts index fcb11b442a4..f75cb425a85 100644 --- a/cocos/physics/framework/physics-system.ts +++ b/cocos/physics/framework/physics-system.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,24 +20,21 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; -import { Vec3, RecyclePool, Enum, System } from '../../core'; +import { Vec3, RecyclePool, Enum, System, cclegacy, Settings, settings, geometry, warn } from '../../core'; import { IRaycastOptions } from '../spec/i-physics-world'; import { director, Director, game } from '../../game'; import { PhysicsMaterial } from './assets/physics-material'; -import { Ray } from '../../core/geometry'; -import { PhysicsRayResult } from './physics-ray-result'; -import { IPhysicsConfig, ICollisionMatrix, IPhysicsMaterial } from './physics-config'; +import { PhysicsRayResult, PhysicsLineStripCastResult } from './physics-ray-result'; +import { IPhysicsConfig, ICollisionMatrix } from './physics-config'; import { CollisionMatrix } from './collision-matrix'; import { PhysicsGroup } from './physics-enum'; import { constructDefaultWorld, IWorldInitData, selector } from './physics-selector'; -import { legacyCC } from '../../core/global-exports'; -import { Settings, settings } from '../../core/settings'; -import { builtinResMgr } from '../../asset/asset-manager'; +import { assetManager, builtinResMgr } from '../../asset/asset-manager'; -legacyCC.internal.PhysicsGroup = PhysicsGroup; +cclegacy.internal.PhysicsGroup = PhysicsGroup; /** * @en @@ -209,22 +205,44 @@ export class PhysicsSystem extends System implements IWorldInitData { return this._material; } - initDefaultMaterial () : void { - if (this._material != null) { - return; + /** + * @en + * Set the default physics material. + * @zh + * 设置默认物理材质。 + */ + public setDefaultPhysicsMaterial (material : PhysicsMaterial) { + this._material = material; + this.physicsWorld.setDefaultMaterial(this._material); + this._material.on(PhysicsMaterial.EVENT_UPDATE, this._updateMaterial, this); + } + + // eslint-disable-next-line consistent-return + private initDefaultMaterial (): Promise { + if (this._material != null) return Promise.resolve(); + + const builtinMaterial = builtinResMgr.get('default-physics-material'); + if (!builtinMaterial) { + console.error('PhysicsSystem initDefaultMaterial() Failed to load builtinMaterial'); + return Promise.resolve(); } - this._material = builtinResMgr.get('default-physics-material'); - if (this._material != null) { - //console.log('initDefaultMaterial'); - //console.log('this._materialConfig', this._materialConfig); - this.physicsWorld.setDefaultMaterial(this._material); - this._material.on(PhysicsMaterial.EVENT_UPDATE, this._updateMaterial, this); - - //set default physics material using material config - this.setDefaultMaterial(this._materialConfig); - } else { - console.error('PhysicsSystem initDefaultMaterial failed'); + const userMaterial = settings.querySettings(Settings.Category.PHYSICS, 'defaultMaterial'); + if (!userMaterial) { //use built-in default physics material + this.setDefaultPhysicsMaterial(builtinMaterial); + return Promise.resolve(); + } else { //use user customized default physics material + return new Promise((resolve, reject) => { + assetManager.loadAny(userMaterial, (err, asset) => ((err || !(asset instanceof PhysicsMaterial)) + ? reject(err) + : resolve(asset))); + }).then((asset) => { + this.setDefaultPhysicsMaterial(asset); + }).catch((reason) => { + warn(reason); + warn(`Failed to load user customized default physics material: ${userMaterial}, will fallback to built-in default physics material`); + this.setDefaultPhysicsMaterial(builtinMaterial); + }); } } @@ -254,6 +272,22 @@ export class PhysicsSystem extends System implements IWorldInitData { */ public readonly raycastResults: PhysicsRayResult[] = []; + /** + * @en + * Gets the lineStripCastClosest test result. + * @zh + * 获取 lineStripCastClosest 的检测结果。 + */ + public lineStripCastClosestResult = new PhysicsLineStripCastResult(); + + /** + * @en + * Gets the lineStripCast test results. + * @zh + * 获取 lineStripCast 的检测结果。 + */ + public lineStripCastResults: PhysicsLineStripCastResult[] = []; + /** * @en * Gets the collision matrix that used for initialization only. @@ -282,7 +316,6 @@ export class PhysicsSystem extends System implements IWorldInitData { private _sleepThreshold = 0.1; private readonly _gravity = new Vec3(0, -10, 0); private _material!: PhysicsMaterial; //default physics material - private _materialConfig: IPhysicsMaterial = new PhysicsMaterial(); private static readonly _instance: PhysicsSystem | null = null; private readonly raycastOptions: IRaycastOptions = { group: -1, @@ -298,7 +331,7 @@ export class PhysicsSystem extends System implements IWorldInitData { } postUpdate (deltaTime: number) { - if (EDITOR && !legacyCC.GAME_VIEW && !this._executeInEditMode && !selector.runInEditor) return; + if (EDITOR && !cclegacy.GAME_VIEW && !this._executeInEditMode && !selector.runInEditor) return; if (!this.physicsWorld) return; @@ -349,11 +382,6 @@ export class PhysicsSystem extends System implements IWorldInitData { const gravity = config ? config.gravity : settings.querySettings(Settings.Category.PHYSICS, 'gravity'); if (gravity) Vec3.copy(this._gravity, gravity); - const defaultMaterialConfig = config ? config.defaultMaterial : settings.querySettings(Settings.Category.PHYSICS, 'defaultMaterial'); - //console.log('resetConfiguration'); - //console.log('defaultMaterialConfig', defaultMaterialConfig); - this._materialConfig = defaultMaterialConfig; - const collisionMatrix = config ? config.collisionMatrix : settings.querySettings(Settings.Category.PHYSICS, 'collisionMatrix'); if (collisionMatrix) { for (const i in collisionMatrix) { @@ -375,24 +403,6 @@ export class PhysicsSystem extends System implements IWorldInitData { } } - /** - * @en - * Set the default physics material to given value. - * @zh - * 设置默认物理材质到指定的值。 - */ - setDefaultMaterial (materialConfig : IPhysicsMaterial):void { - if (!this._material) return; - if (!materialConfig) return; - - this._material.setValues( - materialConfig.friction, - materialConfig.rollingFriction, - materialConfig.spinningFriction, - materialConfig.restitution, - ); - } - /** * @en * Reset the accumulator of time to given value. @@ -446,7 +456,7 @@ export class PhysicsSystem extends System implements IWorldInitData { * @param queryTrigger @zh 是否检测触发器 @en Whether to detect triggers * @return {boolean} @zh 表示是否有检测到碰撞 @en Indicates whether a collision has been detected */ - raycast (worldRay: Ray, mask = 0xffffffff, maxDistance = 10000000, queryTrigger = true): boolean { + raycast (worldRay: geometry.Ray, mask = 0xffffffff, maxDistance = 10000000, queryTrigger = true): boolean { if (!this.physicsWorld) return false; this.raycastResultPool.reset(); this.raycastResults.length = 0; @@ -469,7 +479,7 @@ export class PhysicsSystem extends System implements IWorldInitData { * @param queryTrigger @zh 是否检测触发器 @en Whether to detect triggers * @return {boolean} @zh 表示是否有检测到碰撞 @en Indicates whether a collision has been detected */ - raycastClosest (worldRay: Ray, mask = 0xffffffff, maxDistance = 10000000, queryTrigger = true): boolean { + raycastClosest (worldRay: geometry.Ray, mask = 0xffffffff, maxDistance = 10000000, queryTrigger = true): boolean { if (!this.physicsWorld) return false; this.raycastOptions.mask = mask >>> 0; this.raycastOptions.maxDistance = maxDistance; @@ -477,6 +487,93 @@ export class PhysicsSystem extends System implements IWorldInitData { return this.physicsWorld.raycastClosest(worldRay, this.raycastOptions, this.raycastClosestResult); } + /** + * @en + * Collision detect all collider and record all the detected results, using + * PhysicsSystem.Instance.lineStripCastResults to access the results. + * @zh + * 逐线段检测所有的碰撞盒,并记录所有检测结果。通过 PhysicsSystem.instance.lineStripCastResults 访问结果。 + * @param samplePointsWorldSpace @zh 世界空间下的采样点/直线段 @en sample points/line segments in world space + * @param mask @zh 掩码,默认为 0xffffffff @en Mask, default value is 0xffffffff + * @param maxDistance @zh 沿着直线段的最大检测距离,默认为 10000000,目前请勿传入 Infinity 或 Number.MAX_VALUE + * @en Maximum detection distance along the line segments, default value is 10000000, do not pass Infinity or Number.MAX_VALUE for now + * @param queryTrigger @zh 是否检测触发器 @en Whether to detect triggers + * @return {boolean} @zh 表示是否有检测到碰撞 @en Indicates whether a collision has been detected + */ + lineStripCast (samplePointsWorldSpace: Array, mask = 0xffffffff, maxDistance = 10000000, queryTrigger = true): boolean { + if (samplePointsWorldSpace.length < 2) return false; + this.lineStripCastResults = []; + let distance = 0; + const worldRay = new geometry.Ray(); + for (let i = 1; i < samplePointsWorldSpace.length; ++i) { + if (distance > maxDistance) break; + + const fromPoint = samplePointsWorldSpace[i - 1]; + const toPoint = samplePointsWorldSpace[i]; + const direction = new Vec3(); + Vec3.subtract(direction, toPoint, fromPoint); + const stepLength = Vec3.len(direction); + distance += stepLength; + Vec3.multiplyScalar(direction, direction, 1.0 / stepLength); + worldRay.d = direction; + worldRay.o = fromPoint; + const hit = this.raycast(worldRay, mask, stepLength, queryTrigger); + if (hit) { + for (let re = 0; re < this.raycastResults.length; re++) { + const result = this.raycastResults[re]; + //if ray starts inside shape and hit point equals to start point, this should be ignored + if (re === 0 && Vec3.equals(fromPoint, result.hitPoint)) { continue; } + const copiedResult = new PhysicsLineStripCastResult(); + copiedResult._assign(result.hitPoint, result.distance, result.collider, result.hitNormal, i - 1); + this.lineStripCastResults.push(copiedResult); + } + } + } + return this.lineStripCastResults.length > 0; + } + + /** + * @en + * Collision detect all collider, and record the ray test results with the shortest distance. + * Using PhysicsSystem.Instance.lineStripCastClosestResult to access the result. + * @zh + * 逐线段检测所有的碰撞盒,并记录沿这些线段距离最短的检测结果,通过 PhysicsSystem.instance.lineStripCastClosestResult 访问结果。 + * @param samplePointsWorldSpace @zh 世界空间下的采样点/直线段 @en sample points/line segments in world space + * @param mask @zh 掩码,默认为 0xffffffff @en Mask, default value is 0xffffffff + * @param maxDistance @zh 沿着直线段的最大检测距离,默认为 10000000,目前请勿传入 Infinity 或 Number.MAX_VALUE + * @en Maximum detection distance along the line segments, default value is 10000000, do not pass Infinity or Number.MAX_VALUE for now + * @param queryTrigger @zh 是否检测触发器 @en Whether to detect triggers + * @return {boolean} @zh 表示是否有检测到碰撞 @en Indicates whether a collision has been detected + */ + lineStripCastClosest (samplePointsWorldSpace: Array, mask = 0xffffffff, maxDistance = 10000000, queryTrigger = true): boolean { + if (samplePointsWorldSpace.length < 2) { return false; } + let distance = 0; + const worldRay = new geometry.Ray(); + let hit = false; + for (let i = 1; i < samplePointsWorldSpace.length; ++i) { + if (distance > maxDistance) break; + + const fromPoint = samplePointsWorldSpace[i - 1]; + const toPoint = samplePointsWorldSpace[i]; + const direction = new Vec3(); + Vec3.subtract(direction, toPoint, fromPoint); + const stepLength = Vec3.len(direction); + distance += stepLength; + Vec3.multiplyScalar(direction, direction, 1.0 / stepLength); + worldRay.d = direction; + worldRay.o = fromPoint; + hit = this.raycastClosest(worldRay, mask, stepLength, queryTrigger); + if (hit) { + const result = this.raycastClosestResult; + const copiedResult = new PhysicsLineStripCastResult(); + copiedResult._assign(result.hitPoint, result.distance, result.collider, result.hitNormal, i - 1); + this.lineStripCastClosestResult = copiedResult; + break; + } + } + return hit; + } + private _updateMaterial () { if (this.physicsWorld) this.physicsWorld.setDefaultMaterial(this._material); } @@ -490,6 +587,8 @@ export class PhysicsSystem extends System implements IWorldInitData { * 预先加载模块的情况下,会自动执行。 */ static constructAndRegister () { + const enabled = settings.querySettings(Settings.Category.PHYSICS, 'enabled') ?? true; + if (!enabled) { return; } if (!PhysicsSystem._instance) { // Construct physics world and physics system only once const sys = new PhysicsSystem(); @@ -498,11 +597,7 @@ export class PhysicsSystem extends System implements IWorldInitData { (PhysicsSystem._instance as unknown as PhysicsSystem) = sys; director.registerSystem(PhysicsSystem.ID, sys, sys.priority); - if (!builtinResMgr.get('default-physics-material')) { - game.onPostProjectInitDelegate.add(sys.initDefaultMaterial.bind(sys)); - } else { - sys.initDefaultMaterial(); - } + game.onPostProjectInitDelegate.add(sys.initDefaultMaterial.bind(sys)); } } } diff --git a/cocos/physics/physx/instantiate.jsb.ts b/cocos/physics/physx/instantiate.jsb.ts index f5325cc416b..972a27ee0a7 100644 --- a/cocos/physics/physx/instantiate.jsb.ts +++ b/cocos/physics/physx/instantiate.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * hack for jsb, shoule be refactor in futrue diff --git a/cocos/physics/physx/instantiate.ts b/cocos/physics/physx/instantiate.ts index 78fb601e8ae..f2d27ef2a07 100644 --- a/cocos/physics/physx/instantiate.ts +++ b/cocos/physics/physx/instantiate.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { selector } from '../framework/physics-selector'; @@ -37,8 +36,8 @@ import { PhysXTerrainShape } from './shapes/physx-terrain-shape'; import { PhysXCylinderShape } from './shapes/physx-cylinder-shape'; import { PhysXConeShape } from './shapes/physx-cone-shape'; -// import { PhysXFixedJoint } from './joints/physx-fixed-joint'; -import { PhysXDistanceJoint } from './joints/physx-distance-joint'; +import { PhysXFixedJoint } from './joints/physx-fixed-joint'; +import { PhysXSphericalJoint } from './joints/physx-spherical-joint'; import { PhysXRevoluteJoint } from './joints/physx-revolute-joint'; import { Game, game } from '../../game'; @@ -57,8 +56,9 @@ game.once(Game.EVENT_PRE_SUBSYSTEM_INIT, () => { // SimplexShape: PhysXSimplexShape, PlaneShape: PhysXPlaneShape, - PointToPointConstraint: PhysXDistanceJoint, + PointToPointConstraint: PhysXSphericalJoint, // PointToPointConstraint: PhysXFixedJoint, HingeConstraint: PhysXRevoluteJoint, + FixedConstraint: PhysXFixedJoint, }); }); diff --git a/cocos/physics/physx/joints/physx-fixed-joint.ts b/cocos/physics/physx/joints/physx-fixed-joint.ts index 1af6df9159c..543c2f12e06 100644 --- a/cocos/physics/physx/joints/physx-fixed-joint.ts +++ b/cocos/physics/physx/joints/physx-fixed-joint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,31 +20,70 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { IVec3Like } from '../../../core'; -import { PointToPointConstraint } from '../../framework'; -import { IPointToPointConstraint } from '../../spec/i-physics-constraint'; -import { PX, _trans } from '../physx-adapter'; +import { IVec3Like, Vec3, Quat, Mat4 } from '../../../core'; +import { FixedConstraint, PhysicsSystem } from '../../framework'; +import { IFixedConstraint } from '../../spec/i-physics-constraint'; +import { PX, _trans, getTempTransform, _pxtrans } from '../physx-adapter'; +import { PxContactPairFlag } from '../physx-enum'; +import { PhysXInstance } from '../physx-instance'; +import { PhysXRigidBody } from '../physx-rigid-body'; import { PhysXWorld } from '../physx-world'; import { PhysXJoint } from './physx-joint'; -export class PhysXFixedJoint extends PhysXJoint implements IPointToPointConstraint { - setPivotA (v: IVec3Like): void { +export class PhysXFixedJoint extends PhysXJoint implements IFixedConstraint { + setBreakForce (v: number): void { + this._breakForce = this.constraint.breakForce; + this._impl.setBreakForce(this._breakForce, this._breakTorque); } - setPivotB (v: IVec3Like): void { + setBreakTorque (v: number): void { + this._breakTorque = this.constraint.breakTorque; + this._impl.setBreakForce(this._breakForce, this._breakTorque); } - get constraint (): PointToPointConstraint { - return this._com as PointToPointConstraint; + get constraint (): FixedConstraint { + return this._com as FixedConstraint; } + private _breakForce = 0; + private _breakTorque = 0; + onComponentSet (): void { - if (this._rigidBody) { - this._impl = PX.PxFixedJointCreate(PhysXInstance.physics, null, _trans, null, _trans); - this.setPivotA(this.constraint.pivotA); - this.setPivotB(this.constraint.pivotB); - } + this._impl = PX.createFixedConstraint(PhysXJoint.tempActor, _pxtrans, null, _pxtrans); + this.setBreakForce(this.constraint.breakForce); + this.setBreakTorque(this.constraint.breakTorque); + this.updateFrame(); + } + + updateFrame () { + const bodyA = (this._rigidBody.body as PhysXRigidBody).sharedBody; + const cb = this.constraint.connectedBody; + const bodyB = cb ? (cb.body as PhysXRigidBody).sharedBody : (PhysicsSystem.instance.physicsWorld as PhysXWorld).getSharedBody(bodyA.node); + + const pos : Vec3 = new Vec3(); + const rot : Quat = new Quat(); + + const trans = new Mat4(); + Mat4.fromRT(trans, bodyA.node.worldRotation, bodyA.node.worldPosition); + Mat4.invert(trans, trans); + Mat4.getRotation(rot, trans); + Mat4.getTranslation(pos, trans); + this._impl.setLocalPose(0, getTempTransform(pos, rot)); + + Mat4.fromRT(trans, bodyB.node.worldRotation, bodyB.node.worldPosition); + Mat4.invert(trans, trans); + Mat4.getRotation(rot, trans); + Mat4.getTranslation(pos, trans); + this._impl.setLocalPose(1, getTempTransform(pos, rot)); + } + + updateScale0 () { + this.updateFrame(); + } + + updateScale1 () { + this.updateFrame(); } } diff --git a/cocos/physics/physx/joints/physx-joint.ts b/cocos/physics/physx/joints/physx-joint.ts index 53eddb1b8d6..dedff979d86 100644 --- a/cocos/physics/physx/joints/physx-joint.ts +++ b/cocos/physics/physx/joints/physx-joint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { Constraint, RigidBody } from '../../framework'; diff --git a/cocos/physics/physx/joints/physx-revolute-joint.ts b/cocos/physics/physx/joints/physx-revolute-joint.ts index 8110e588f2e..52694c12730 100644 --- a/cocos/physics/physx/joints/physx-revolute-joint.ts +++ b/cocos/physics/physx/joints/physx-revolute-joint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like, Quat, Vec3 } from '../../../core'; import { HingeConstraint } from '../../framework'; diff --git a/cocos/physics/physx/joints/physx-distance-joint.ts b/cocos/physics/physx/joints/physx-spherical-joint.ts similarity index 73% rename from cocos/physics/physx/joints/physx-distance-joint.ts rename to cocos/physics/physx/joints/physx-spherical-joint.ts index 743fb3777e6..d85af26c140 100644 --- a/cocos/physics/physx/joints/physx-distance-joint.ts +++ b/cocos/physics/physx/joints/physx-spherical-joint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like, Quat, Vec3 } from '../../../core'; import { PointToPointConstraint } from '../../framework'; @@ -29,7 +28,7 @@ import { IPointToPointConstraint } from '../../spec/i-physics-constraint'; import { PX, _trans, getTempTransform, _pxtrans } from '../physx-adapter'; import { PhysXJoint } from './physx-joint'; -export class PhysXDistanceJoint extends PhysXJoint implements IPointToPointConstraint { +export class PhysXSphericalJoint extends PhysXJoint implements IPointToPointConstraint { setPivotA (v: IVec3Like): void { const cs = this.constraint; const pos = _trans.translation; @@ -64,7 +63,7 @@ export class PhysXDistanceJoint extends PhysXJoint implements IPointToPointConst } onComponentSet (): void { - this._impl = PX.createDistanceJoint(PhysXJoint.tempActor, _pxtrans, null, _pxtrans); + this._impl = PX.createSphericalJoint(PhysXJoint.tempActor, _pxtrans, null, _pxtrans); this.setPivotA(this.constraint.pivotA); this.setPivotB(this.constraint.pivotB); } diff --git a/cocos/physics/physx/physx-adapter.ts b/cocos/physics/physx/physx-adapter.ts index 9157a284486..6451ec1a128 100644 --- a/cocos/physics/physx/physx-adapter.ts +++ b/cocos/physics/physx/physx-adapter.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable import/no-mutable-exports */ /* eslint-disable no-console */ @@ -33,22 +32,19 @@ import { PhysX } from './physx.asmjs'; import { BYTEDANCE, DEBUG, EDITOR, TEST } from 'internal:constants'; -import { IQuatLike, IVec3Like, Quat, RecyclePool, Vec3 } from '../../core'; +import { IQuatLike, IVec3Like, Quat, RecyclePool, Vec3, cclegacy, geometry, Settings, settings } from '../../core'; import { shrinkPositions } from '../utils/util'; -import { legacyCC } from '../../core/global-exports'; -import { AABB, Ray } from '../../core/geometry'; import { IRaycastOptions } from '../spec/i-physics-world'; import { IPhysicsConfig, PhysicsRayResult, PhysicsSystem } from '../framework'; import { PhysXWorld } from './physx-world'; import { PhysXInstance } from './physx-instance'; import { PhysXShape } from './shapes/physx-shape'; import { PxHitFlag, PxPairFlag, PxQueryFlag, EFilterDataWord3 } from './physx-enum'; -import { Settings, settings } from '../../core/settings'; import { Node } from '../../scene-graph'; import { Director, director, game } from '../../game'; export const PX = {} as any; -const globalThis = legacyCC._global; +const globalThis = cclegacy._global; // Use bytedance native or js physics if nativePhysX is not null. const USE_BYTEDANCE = BYTEDANCE && globalThis.nativePhysX; const USE_EXTERNAL_PHYSX = !!globalThis.PHYSX; @@ -114,7 +110,8 @@ function initAdaptWrapper (obj: any) { obj.TriangleMeshGeometry = obj.PxTriangleMeshGeometry; obj.RigidDynamicLockFlag = obj.PxRigidDynamicLockFlag; obj.createRevoluteJoint = (a: any, b: any, c: any, d: any): any => obj.PxRevoluteJointCreate(PX.physics, a, b, c, d); - obj.createDistanceJoint = (a: any, b: any, c: any, d: any): any => obj.PxDistanceJointCreate(PX.physics, a, b, c, d); + obj.createFixedConstraint = (a: any, b: any, c: any, d: any): any => obj.PxFixedJointCreate(PX.physics, a, b, c, d); + obj.createSphericalJoint = (a: any, b: any, c: any, d: any): any => obj.PxSphericalJointCreate(PX.physics, a, b, c, d); } const _v3: IVec3Like = { x: 0, y: 0, z: 0 }; @@ -278,13 +275,13 @@ export function getShapeFlags (isTrigger: boolean): any { return new PX.PxShapeFlags(flag); } -export function getShapeWorldBounds (shape: any, actor: any, i = 1.01, out: AABB) { +export function getShapeWorldBounds (shape: any, actor: any, i = 1.01, out: geometry.AABB) { if (USE_BYTEDANCE) { const b3 = PX.RigidActorExt.getWorldBounds(shape, actor, i); - AABB.fromPoints(out, b3.minimum, b3.maximum); + geometry.AABB.fromPoints(out, b3.minimum, b3.maximum); } else { const b3 = shape.getWorldBounds(actor, i); - AABB.fromPoints(out, b3.minimum, b3.maximum); + geometry.AABB.fromPoints(out, b3.minimum, b3.maximum); } } @@ -468,7 +465,7 @@ export function simulateScene (scene: any, deltaTime: number) { } } -export function raycastAll (world: PhysXWorld, worldRay: Ray, options: IRaycastOptions, +export function raycastAll (world: PhysXWorld, worldRay: geometry.Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { const maxDistance = options.maxDistance; const flags = PxHitFlag.ePOSITION | PxHitFlag.eNORMAL; @@ -520,7 +517,7 @@ export function raycastAll (world: PhysXWorld, worldRay: Ray, options: IRaycastO return false; } -export function raycastClosest (world: PhysXWorld, worldRay: Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { +export function raycastClosest (world: PhysXWorld, worldRay: geometry.Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { const maxDistance = options.maxDistance; const flags = PxHitFlag.ePOSITION | PxHitFlag.eNORMAL; const word3 = EFilterDataWord3.QUERY_FILTER | (options.queryTrigger ? 0 : EFilterDataWord3.QUERY_CHECK_TRIGGER) @@ -778,8 +775,8 @@ function hackForMultiThread () { const yieldTime = performance.now() - sys._mutiThreadYield; sys.physicsWorld.syncPhysicsToScene(); sys.physicsWorld.emitEvents(); - if (legacyCC.profiler && legacyCC.profiler._stats) { - legacyCC.profiler._stats.physics.counter._time += yieldTime; + if (cclegacy.profiler && cclegacy.profiler._stats) { + cclegacy.profiler._stats.physics.counter._time += yieldTime; } director.emit(Director.EVENT_AFTER_PHYSICS); } diff --git a/cocos/physics/physx/physx-contact-equation.ts b/cocos/physics/physx/physx-contact-equation.ts index 33016b59f70..d7df69ac6bb 100644 --- a/cocos/physics/physx/physx-contact-equation.ts +++ b/cocos/physics/physx/physx-contact-equation.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like, Vec3, Quat } from '../../core'; import { IContactEquation, ICollisionEvent, Collider } from '../framework'; diff --git a/cocos/physics/physx/physx-enum.ts b/cocos/physics/physx/physx-enum.ts index 4b1cb940371..8a2fee5dc52 100644 --- a/cocos/physics/physx/physx-enum.ts +++ b/cocos/physics/physx/physx-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable max-len */ /* eslint-disable no-tabs */ diff --git a/cocos/physics/physx/physx-instance.ts b/cocos/physics/physx/physx-instance.ts index 1aed8057372..889e89b8017 100644 --- a/cocos/physics/physx/physx-instance.ts +++ b/cocos/physics/physx/physx-instance.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import './physx.null'; /** diff --git a/cocos/physics/physx/physx-rigid-body.ts b/cocos/physics/physx/physx-rigid-body.ts index 3420a5f7ed5..8e78a30fd88 100644 --- a/cocos/physics/physx/physx-rigid-body.ts +++ b/cocos/physics/physx/physx-rigid-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { IVec3Like, Vec3 } from '../../core'; diff --git a/cocos/physics/physx/physx-shared-body.ts b/cocos/physics/physx/physx-shared-body.ts index bbd869cbae3..52c1fbec195 100644 --- a/cocos/physics/physx/physx-shared-body.ts +++ b/cocos/physics/physx/physx-shared-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/no-unsafe-return */ -import { Quat, Vec3 } from '../../core'; +import { Quat, Vec3, js } from '../../core'; import { PhysXRigidBody } from './physx-rigid-body'; import { PhysXWorld } from './physx-world'; import { PhysXInstance } from './physx-instance'; @@ -38,7 +37,6 @@ import { VEC3_0 } from '../utils/util'; import { ERigidBodyType, PhysicsSystem } from '../framework'; import { PhysXJoint } from './joints/physx-joint'; import { PhysicsGroup } from '../framework/physics-enum'; -import { fastRemoveAt } from '../../core/utils/array'; import { Node } from '../../scene-graph'; export class PhysXSharedBody { @@ -194,13 +192,6 @@ export class PhysXSharedBody { if (isStaticBefore) { const da = this._dynamicActor; setMassAndUpdateInertia(da, this._wrappedBody!.rigidBody.mass); - const center = VEC3_0; - center.set(0, 0, 0); - for (let i = 0; i < this.wrappedShapes.length; i++) { - const collider = this.wrappedShapes[i].collider; - if (!collider.isTrigger) center.subtract(collider.center); - } - da.setCMassLocalPose(getTempTransform(center, Quat.IDENTITY)); } } @@ -212,7 +203,6 @@ export class PhysXSharedBody { this.impl.attachShape(ws.impl); this.wrappedShapes.push(ws); if (!ws.collider.isTrigger) { - if (!Vec3.strictEquals(ws.collider.center, Vec3.ZERO)) this.updateCenterOfMass(); if (this.isDynamic) setMassAndUpdateInertia(this.impl, this._wrappedBody!.rigidBody.mass); } } @@ -223,9 +213,8 @@ export class PhysXSharedBody { if (index >= 0) { ws.setIndex(-1); this.impl.detachShape(ws.impl, true); - fastRemoveAt(this.wrappedShapes, index); + js.array.fastRemoveAt(this.wrappedShapes, index); if (!ws.collider.isTrigger) { - if (!Vec3.strictEquals(ws.collider.center, Vec3.ZERO)) this.updateCenterOfMass(); if (this.isDynamic) setMassAndUpdateInertia(this.impl, this._wrappedBody!.rigidBody.mass); } } @@ -244,10 +233,10 @@ export class PhysXSharedBody { removeJoint (v: PhysXJoint, type: 0 | 1) { if (type) { const i = this.wrappedJoints1.indexOf(v); - if (i >= 0) fastRemoveAt(this.wrappedJoints1, i); + if (i >= 0) js.array.fastRemoveAt(this.wrappedJoints1, i); } else { const i = this.wrappedJoints0.indexOf(v); - if (i >= 0) fastRemoveAt(this.wrappedJoints0, i); + if (i >= 0) js.array.fastRemoveAt(this.wrappedJoints0, i); } } @@ -389,18 +378,6 @@ export class PhysXSharedBody { } } - updateCenterOfMass (): void { - this._initActor(); - if (this._isStatic) return; - const center = VEC3_0; - center.set(0, 0, 0); - for (let i = 0; i < this.wrappedShapes.length; i++) { - const collider = this.wrappedShapes[i].collider; - if (!collider.isTrigger) center.subtract(collider.center); - } - this.impl.setCMassLocalPose(getTempTransform(center, Quat.IDENTITY)); - } - clearForces (): void { if (this._isStatic || this._isKinematic) return; this.impl.clearForce(PX.ForceMode.eFORCE); // this.impl.clearForce(PX.ForceMode.eACCELERATION); diff --git a/cocos/physics/physx/physx-world.ts b/cocos/physics/physx/physx-world.ts index 504c4b2f476..20de83abbba 100644 --- a/cocos/physics/physx/physx-world.ts +++ b/cocos/physics/physx/physx-world.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/no-unsafe-return */ -import { Ray } from '../../core/geometry'; import { IPhysicsWorld, IRaycastOptions } from '../spec/i-physics-world'; import { PhysicsMaterial, PhysicsRayResult, CollisionEventType, TriggerEventType } from '../framework'; -import { error, RecyclePool } from '../../core'; -import { IVec3Like } from '../../core/math/type-define'; +import { error, RecyclePool, js, IVec3Like, geometry } from '../../core'; import { IBaseConstraint } from '../spec/i-physics-constraint'; import { PhysXRigidBody } from './physx-rigid-body'; import { @@ -36,7 +33,6 @@ import { gatherEvents, getWrapShape, PX, getContactDataOrByteOffset, } from './physx-adapter'; import { PhysXSharedBody } from './physx-shared-body'; -import { fastRemoveAt } from '../../core/utils/array'; import { TupleDictionary } from '../utils/tuple-dictionary'; import { PhysXContactEquation } from './physx-contact-equation'; import { CollisionEventObject, TriggerEventObject } from '../utils/util'; @@ -134,7 +130,7 @@ export class PhysXWorld extends PhysXInstance implements IPhysicsWorld { const index = this.wrappedBodies.indexOf(body); if (index >= 0) { this.scene.removeActor(body.impl, true); - fastRemoveAt(this.wrappedBodies, index); + js.array.fastRemoveAt(this.wrappedBodies, index); } } @@ -142,11 +138,11 @@ export class PhysXWorld extends PhysXInstance implements IPhysicsWorld { removeConstraint (_constraint: IBaseConstraint): void { } - raycast (worldRay: Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { + raycast (worldRay: geometry.Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean { return raycastAll(this, worldRay, options, pool, results); } - raycastClosest (worldRay: Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { + raycastClosest (worldRay: geometry.Ray, options: IRaycastOptions, result: PhysicsRayResult): boolean { return raycastClosest(this, worldRay, options, result); } diff --git a/cocos/physics/physx/physx.asmjs.ts b/cocos/physics/physx/physx.asmjs.ts index d01c92ab25c..42c0a7a9b00 100644 --- a/cocos/physics/physx/physx.asmjs.ts +++ b/cocos/physics/physx/physx.asmjs.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * export PhysX from internal module diff --git a/cocos/physics/physx/physx.null.ts b/cocos/physics/physx/physx.null.ts index adb72452f75..23af4b8b640 100644 --- a/cocos/physics/physx/physx.null.ts +++ b/cocos/physics/physx/physx.null.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * export null for module elimination diff --git a/cocos/physics/physx/shapes/physx-box-shape.ts b/cocos/physics/physx/shapes/physx-box-shape.ts index 2f7413224e3..ddbbd684cf5 100644 --- a/cocos/physics/physx/shapes/physx-box-shape.ts +++ b/cocos/physics/physx/shapes/physx-box-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BoxCollider } from '../../framework'; import { absolute, VEC3_0 } from '../../utils/util'; diff --git a/cocos/physics/physx/shapes/physx-capsule-shape.ts b/cocos/physics/physx/shapes/physx-capsule-shape.ts index 81ae841e768..a56b6972ae9 100644 --- a/cocos/physics/physx/shapes/physx-capsule-shape.ts +++ b/cocos/physics/physx/shapes/physx-capsule-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { absMax, Quat } from '../../../core'; import { CapsuleCollider, EAxisDirection } from '../../framework'; diff --git a/cocos/physics/physx/shapes/physx-cone-shape.ts b/cocos/physics/physx/shapes/physx-cone-shape.ts index ca32aad38e8..4925ef17e14 100644 --- a/cocos/physics/physx/shapes/physx-cone-shape.ts +++ b/cocos/physics/physx/shapes/physx-cone-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Quat, Vec3 } from '../../../core'; import cylinder from '../../../primitive/cylinder'; diff --git a/cocos/physics/physx/shapes/physx-cylinder-shape.ts b/cocos/physics/physx/shapes/physx-cylinder-shape.ts index d1aeef5ec05..f0f5fcf22c5 100644 --- a/cocos/physics/physx/shapes/physx-cylinder-shape.ts +++ b/cocos/physics/physx/shapes/physx-cylinder-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Quat, Vec3 } from '../../../core'; import cylinder from '../../../primitive/cylinder'; @@ -67,7 +66,7 @@ export class PhysXCylinderShape extends PhysXShape implements ICylinderShape { meshScale.setScale(Vec3.ONE); meshScale.setRotation(Quat.IDENTITY); const convexMesh = PhysXCylinderShape.CONVEX_MESH; - const pxmat = this.getSharedMaterial(collider.sharedMaterial!); + const pxmat = this.getSharedMaterial(collider.sharedMaterial); this.geometry = new PX.ConvexMeshGeometry(convexMesh, meshScale, createMeshGeometryFlags(0, true)); this.updateGeometry(); this._impl = physics.createShape(this.geometry, pxmat, true, this._flags); diff --git a/cocos/physics/physx/shapes/physx-plane-shape.ts b/cocos/physics/physx/shapes/physx-plane-shape.ts index 28ea3e2f6f3..569424ad85f 100644 --- a/cocos/physics/physx/shapes/physx-plane-shape.ts +++ b/cocos/physics/physx/shapes/physx-plane-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like, Quat, Vec3 } from '../../../core'; import { PlaneCollider } from '../../framework'; @@ -64,7 +63,7 @@ export class PhysXPlaneShape extends PhysXShape implements IPlaneShape { onComponentSet (): void { const co = this.collider; - const pxmat = this.getSharedMaterial(co.sharedMaterial!); + const pxmat = this.getSharedMaterial(co.sharedMaterial); this._impl = PhysXInstance.physics.createShape(PhysXPlaneShape.PLANE_GEOMETRY, pxmat, true, this._flags); this.setCenter(); } diff --git a/cocos/physics/physx/shapes/physx-shape.ts b/cocos/physics/physx/shapes/physx-shape.ts index 9f1cb4f9f0d..9f90e57702b 100644 --- a/cocos/physics/physx/shapes/physx-shape.ts +++ b/cocos/physics/physx/shapes/physx-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* eslint-disable @typescript-eslint/no-unsafe-return */ -import { IVec3Like, Quat, Vec3 } from '../../../core'; -import { AABB, Sphere } from '../../../core/geometry'; +import { IVec3Like, Quat, Vec3, geometry } from '../../../core'; import { Collider, RigidBody, PhysicsMaterial, PhysicsSystem } from '../../framework'; import { IBaseShape } from '../../spec/i-physics-shape'; import { @@ -126,24 +124,24 @@ export class PhysXShape implements IBaseShape { } setMaterial (v: PhysicsMaterial | null): void { - if (v == null) v = PhysicsSystem.instance.defaultMaterial; const mat = this.getSharedMaterial(v); this._impl.setMaterials(getShapeMaterials(mat)); } - protected getSharedMaterial (v: PhysicsMaterial): any { - if (!PX.CACHE_MAT[v.id]) { + protected getSharedMaterial (v: PhysicsMaterial | null): any { + const v1 = (v == null) ? PhysicsSystem.instance.defaultMaterial : v; + if (!PX.CACHE_MAT[v1.id]) { const physics = PhysXInstance.physics; - const mat = physics.createMaterial(v.friction, v.friction, v.restitution); + const mat = physics.createMaterial(v1.friction, v1.friction, v1.restitution); mat.setFrictionCombineMode(PX.CombineMode.eMULTIPLY); mat.setRestitutionCombineMode(PX.CombineMode.eMULTIPLY); - PX.CACHE_MAT[v.id] = mat; + PX.CACHE_MAT[v1.id] = mat; return mat; } - const mat = PX.CACHE_MAT[v.id]; - mat.setStaticFriction(v.friction); - mat.setDynamicFriction(v.friction); - mat.setRestitution(v.restitution); + const mat = PX.CACHE_MAT[v1.id]; + mat.setStaticFriction(v1.friction); + mat.setDynamicFriction(v1.friction); + mat.setRestitution(v1.restitution); return mat; } @@ -168,17 +166,14 @@ export class PhysXShape implements IBaseShape { Quat.copy(rot, this._rotation); const trans = getTempTransform(pos, rot); this._impl.setLocalPose(trans); - if (this._collider.enabled && !this._collider.isTrigger) { - this._sharedBody.updateCenterOfMass(); - } } - getAABB (v: AABB): void { + getAABB (v: geometry.AABB): void { getShapeWorldBounds(this.impl, this._sharedBody.impl, 1, v); } - getBoundingSphere (v: Sphere): void { - AABB.toBoundingSphere(v, this._collider.worldBounds as AABB); + getBoundingSphere (v: geometry.Sphere): void { + geometry.AABB.toBoundingSphere(v, this._collider.worldBounds as geometry.AABB); } setGroup (v: number): void { diff --git a/cocos/physics/physx/shapes/physx-sphere-shape.ts b/cocos/physics/physx/shapes/physx-sphere-shape.ts index 2799023623b..d7e99de1164 100644 --- a/cocos/physics/physx/shapes/physx-sphere-shape.ts +++ b/cocos/physics/physx/shapes/physx-sphere-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { absMaxComponent } from '../../../core'; import { SphereCollider } from '../../framework'; @@ -50,7 +49,7 @@ export class PhysXSphereShape extends PhysXShape implements ISphereShape { onComponentSet () { this.updateGeometry(); - const pxmat = this.getSharedMaterial(this.collider.sharedMaterial!); + const pxmat = this.getSharedMaterial(this.collider.sharedMaterial); this._impl = PhysXInstance.physics.createShape(PhysXSphereShape.SPHERE_GEOMETRY, pxmat, true, this._flags); } diff --git a/cocos/physics/physx/shapes/physx-terrain-shape.ts b/cocos/physics/physx/shapes/physx-terrain-shape.ts index aac0767c6a0..f25ee0a81d7 100644 --- a/cocos/physics/physx/shapes/physx-terrain-shape.ts +++ b/cocos/physics/physx/shapes/physx-terrain-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like } from '../../../core'; import { PhysicsMaterial, TerrainCollider } from '../../framework'; diff --git a/cocos/physics/physx/shapes/physx-trimesh-shape.ts b/cocos/physics/physx/shapes/physx-trimesh-shape.ts index 41ee41b7cd9..d4437a9060e 100644 --- a/cocos/physics/physx/shapes/physx-trimesh-shape.ts +++ b/cocos/physics/physx/shapes/physx-trimesh-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IVec3Like, Quat, Vec3 } from '../../../core'; import { Mesh } from '../../../3d/assets'; import { MeshCollider, PhysicsMaterial } from '../../framework'; import { ITrimeshShape } from '../../spec/i-physics-shape'; -import { createConvexMesh, createMeshGeometryFlags, createTriangleMesh, PX, _trans } from '../physx-adapter'; +import { createConvexMesh, createMeshGeometryFlags, createTriangleMesh, PX, _trans, removeReference } from '../physx-adapter'; import { EPhysXShapeType, PhysXShape } from './physx-shape'; import { AttributeName } from '../../../gfx'; import { PhysXInstance } from '../physx-instance'; @@ -41,7 +40,13 @@ export class PhysXTrimeshShape extends PhysXShape implements ITrimeshShape { } setMesh (v: Mesh | null): void { - if (v && v.renderingSubMeshes.length > 0 && this._impl == null) { + if (v && v.renderingSubMeshes.length > 0) { + if (this._impl != null) { + removeReference(this, this._impl); + this._impl.release(); + this._impl = null; + } + const physics = PhysXInstance.physics; const collider = this.collider; const pxmat = this.getSharedMaterial(collider.sharedMaterial!); diff --git a/cocos/physics/spec/i-external.ts b/cocos/physics/spec/i-external.ts index 7ce0bb3c8dc..49e1f5fe3fe 100644 --- a/cocos/physics/spec/i-external.ts +++ b/cocos/physics/spec/i-external.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export interface ITerrainAsset { _uuid: string; diff --git a/cocos/physics/spec/i-group-mask.ts b/cocos/physics/spec/i-group-mask.ts index 439698f353c..2fd4bcb2e7e 100644 --- a/cocos/physics/spec/i-group-mask.ts +++ b/cocos/physics/spec/i-group-mask.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export interface IGroupMask { setGroup (v: number): void; diff --git a/cocos/physics/spec/i-lifecycle.ts b/cocos/physics/spec/i-lifecycle.ts index 6b9c740925c..5b010e012b3 100644 --- a/cocos/physics/spec/i-lifecycle.ts +++ b/cocos/physics/spec/i-lifecycle.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export interface ILifecycle { /** diff --git a/cocos/physics/spec/i-physics-constraint.ts b/cocos/physics/spec/i-physics-constraint.ts index 8141bffa26a..c117d7a8e5e 100644 --- a/cocos/physics/spec/i-physics-constraint.ts +++ b/cocos/physics/spec/i-physics-constraint.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ILifecycle } from './i-lifecycle'; import { Constraint, RigidBody } from '../framework'; @@ -45,4 +44,9 @@ export interface IHingeConstraint extends IBaseConstraint { setAxis (v: IVec3Like): void; } +export interface IFixedConstraint extends IBaseConstraint { + setBreakForce(v: number): void; + setBreakTorque(v: number): void; +} + export type IConeTwistConstraint = IBaseConstraint diff --git a/cocos/physics/spec/i-physics-shape.ts b/cocos/physics/spec/i-physics-shape.ts index 8c218b13825..0199d84a6d1 100644 --- a/cocos/physics/spec/i-physics-shape.ts +++ b/cocos/physics/spec/i-physics-shape.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ILifecycle } from './i-lifecycle'; import { IGroupMask } from './i-group-mask'; -import { IVec3Like } from '../../core/math/type-define'; +import { IVec3Like, geometry } from '../../core'; import { Collider, RigidBody, PhysicsMaterial, SimplexCollider } from '../../../exports/physics-framework'; import { Mesh } from '../../3d/assets'; import { ITerrainAsset } from './i-external'; -import { AABB, Sphere } from '../../core/geometry'; export interface IBaseShape extends ILifecycle, IGroupMask { readonly impl: any; @@ -40,8 +38,8 @@ export interface IBaseShape extends ILifecycle, IGroupMask { setAsTrigger: (v: boolean) => void; setCenter: (v: IVec3Like) => void; // setAttachedBody: (body: RigidBody | null) => void; - getAABB: (v: AABB) => void; - getBoundingSphere: (v: Sphere) => void; + getAABB: (v: geometry.AABB) => void; + getBoundingSphere: (v: geometry.Sphere) => void; updateEventListener: () => void; } diff --git a/cocos/physics/spec/i-physics-world.ts b/cocos/physics/spec/i-physics-world.ts index 22544ffb574..5733679a7d3 100644 --- a/cocos/physics/spec/i-physics-world.ts +++ b/cocos/physics/spec/i-physics-world.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { IVec3Like } from '../../core/math/type-define'; +import { IVec3Like, RecyclePool, geometry } from '../../core'; import { PhysicsRayResult } from '../framework/physics-ray-result'; -import { Ray } from '../../core/geometry'; -import { RecyclePool } from '../../core'; import { PhysicsMaterial } from '../framework'; export interface IRaycastOptions { @@ -42,8 +39,8 @@ export interface IPhysicsWorld { setAllowSleep: (v: boolean) => void; setDefaultMaterial: (v: PhysicsMaterial) => void; step (fixedTimeStep: number, timeSinceLastCalled?: number, maxSubSteps?: number): void; - raycast (worldRay: Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean - raycastClosest (worldRay: Ray, options: IRaycastOptions, out: PhysicsRayResult): boolean; + raycast (worldRay: geometry.Ray, options: IRaycastOptions, pool: RecyclePool, results: PhysicsRayResult[]): boolean + raycastClosest (worldRay: geometry.Ray, options: IRaycastOptions, out: PhysicsRayResult): boolean; emitEvents (): void; syncSceneToPhysics (): void; syncAfterEvents (): void; diff --git a/cocos/physics/spec/i-rigid-body.ts b/cocos/physics/spec/i-rigid-body.ts index 6300f273367..d7287a3ef0b 100644 --- a/cocos/physics/spec/i-rigid-body.ts +++ b/cocos/physics/spec/i-rigid-body.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ILifecycle } from './i-lifecycle'; import { IGroupMask } from './i-group-mask'; -import { IVec3Like } from '../../core/math/type-define'; +import { IVec3Like } from '../../core'; import { RigidBody } from '../framework/components/rigid-body'; import { ERigidBodyType } from '../framework'; diff --git a/cocos/physics/utils/array-collision-matrix.ts b/cocos/physics/utils/array-collision-matrix.ts index 11e06373a18..9123f67aaec 100644 --- a/cocos/physics/utils/array-collision-matrix.ts +++ b/cocos/physics/utils/array-collision-matrix.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * Collision "matrix". It's actually a triangular-shaped array of whether two bodies are touching this step, for reference next step diff --git a/cocos/physics/utils/object-collision-matrix.ts b/cocos/physics/utils/object-collision-matrix.ts index 3272e226f4b..94c4ccdfdb4 100644 --- a/cocos/physics/utils/object-collision-matrix.ts +++ b/cocos/physics/utils/object-collision-matrix.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * Records what objects are colliding with each other diff --git a/cocos/physics/utils/tuple-dictionary.ts b/cocos/physics/utils/tuple-dictionary.ts index f89ff816b45..d308a8fb7bb 100644 --- a/cocos/physics/utils/tuple-dictionary.ts +++ b/cocos/physics/utils/tuple-dictionary.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @class TupleDictionary diff --git a/cocos/physics/utils/util.ts b/cocos/physics/utils/util.ts index c306656d069..bda38e84363 100644 --- a/cocos/physics/utils/util.ts +++ b/cocos/physics/utils/util.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { equals, Vec3 } from '../../core'; -import { IVec3Like, IQuatLike } from '../../core/math/type-define'; +import { equals, Vec3, IVec3Like } from '../../core'; import { Collider, CollisionEventType, IContactEquation, TriggerEventType } from '../framework'; export { cylinder } from '../../primitive'; diff --git a/cocos/primitive/box.ts b/cocos/primitive/box.ts index 1ae25ee5756..4cdf7668e0c 100644 --- a/cocos/primitive/box.ts +++ b/cocos/primitive/box.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../core/math'; +import { Vec3 } from '../core'; import { IGeometry, IGeometryOptions } from './define'; /** diff --git a/cocos/primitive/capsule.ts b/cocos/primitive/capsule.ts index 38a5cdc5868..0f04ab78be8 100644 --- a/cocos/primitive/capsule.ts +++ b/cocos/primitive/capsule.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../core/math'; +import { Vec3 } from '../core'; /** * @en diff --git a/cocos/primitive/circle.ts b/cocos/primitive/circle.ts index 6c32c28b99d..a2d0604f969 100644 --- a/cocos/primitive/circle.ts +++ b/cocos/primitive/circle.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PrimitiveMode } from '../gfx'; import { applyDefaultGeometryOptions, IGeometry, IGeometryOptions } from './define'; diff --git a/cocos/primitive/cone.ts b/cocos/primitive/cone.ts index 433ef823e12..61cbc7a0ff2 100644 --- a/cocos/primitive/cone.ts +++ b/cocos/primitive/cone.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import cylinder, { ICylinderOptions } from './cylinder'; import { IGeometry } from './define'; diff --git a/cocos/primitive/cylinder.ts b/cocos/primitive/cylinder.ts index 4947cb8090c..ae9a6fffe7c 100644 --- a/cocos/primitive/cylinder.ts +++ b/cocos/primitive/cylinder.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../core/math'; +import { Vec3 } from '../core'; import { IGeometry, IGeometryOptions } from './define'; /** diff --git a/cocos/primitive/define.ts b/cocos/primitive/define.ts index 8193bfaa036..5c2e11ffe14 100644 --- a/cocos/primitive/define.ts +++ b/cocos/primitive/define.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PrimitiveMode, Attribute } from '../gfx'; diff --git a/cocos/primitive/index.ts b/cocos/primitive/index.ts index 77608aad3a5..0ca9d1a9ea2 100644 --- a/cocos/primitive/index.ts +++ b/cocos/primitive/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './utils'; export * from './define'; diff --git a/cocos/primitive/plane.ts b/cocos/primitive/plane.ts index a2de1dac335..7ad00b708e2 100644 --- a/cocos/primitive/plane.ts +++ b/cocos/primitive/plane.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../core/math'; +import { Vec3 } from '../core'; import { applyDefaultGeometryOptions, IGeometry, IGeometryOptions } from './define'; /** diff --git a/cocos/primitive/primitive.ts b/cocos/primitive/primitive.ts index 286c2b31d4c..0fd0ac9f49f 100644 --- a/cocos/primitive/primitive.ts +++ b/cocos/primitive/primitive.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, type, serializable, editable } from 'cc.decorator'; import { createMesh } from '../3d/misc'; import { Mesh } from '../3d/assets/mesh'; import * as primitives from '.'; -import { ccenum } from '../core/value-types/enum'; -import { legacyCC } from '../core/global-exports'; +import { ccenum, cclegacy } from '../core'; enum PrimitiveType { BOX = 0, @@ -91,4 +89,4 @@ export declare namespace Primitive { export type PrimitiveType = EnumAlias; } -legacyCC.Primitive = Primitive; +cclegacy.Primitive = Primitive; diff --git a/cocos/primitive/quad.ts b/cocos/primitive/quad.ts index 94337a53bbe..66dab1d94d1 100644 --- a/cocos/primitive/quad.ts +++ b/cocos/primitive/quad.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { applyDefaultGeometryOptions, IGeometry, IGeometryOptions } from './define'; diff --git a/cocos/primitive/sphere.ts b/cocos/primitive/sphere.ts index 0398b16b8da..87f9008baf2 100644 --- a/cocos/primitive/sphere.ts +++ b/cocos/primitive/sphere.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../core/math'; +import { Vec3 } from '../core'; import { IGeometry, IGeometryOptions } from './define'; /** diff --git a/cocos/primitive/torus.ts b/cocos/primitive/torus.ts index 62fa6dd4b7f..b3628fe80a7 100644 --- a/cocos/primitive/torus.ts +++ b/cocos/primitive/torus.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../core/math'; +import { Vec3 } from '../core'; import { IGeometryOptions } from './define'; /** diff --git a/cocos/primitive/transform.ts b/cocos/primitive/transform.ts index 754e2db4c68..17ff15e8fa4 100644 --- a/cocos/primitive/transform.ts +++ b/cocos/primitive/transform.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PrimitiveMode } from '../gfx'; import { IGeometry } from './define'; diff --git a/cocos/primitive/utils.ts b/cocos/primitive/utils.ts index fa823a6a484..181e6e069fc 100644 --- a/cocos/primitive/utils.ts +++ b/cocos/primitive/utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { PrimitiveMode } from '../gfx'; import { IGeometry } from './define'; diff --git a/cocos/profiler/counter.ts b/cocos/profiler/counter.ts index 7d0ded45540..461f44992dc 100644 --- a/cocos/profiler/counter.ts +++ b/cocos/profiler/counter.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export interface ICounterOption { desc: string; @@ -44,9 +43,9 @@ export class Counter { this._value = val; } - protected _id: string; + protected declare _id: string; protected _opts: ICounterOption; - protected _accumStart: number; + protected declare _accumStart: number; protected _total = 0; protected _value = 0; protected _averageValue = 0; diff --git a/cocos/profiler/perf-counter.ts b/cocos/profiler/perf-counter.ts index 1eccb398c83..d6597d21406 100644 --- a/cocos/profiler/perf-counter.ts +++ b/cocos/profiler/perf-counter.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; import { Counter, ICounterOption } from './counter'; @ccclass('cc.PerfCounter') export class PerfCounter extends Counter { - private _time: number; + private declare _time: number; constructor (id: string, opts: ICounterOption, now: number) { super(id, opts, now); this._time = now; diff --git a/cocos/profiler/profiler.ts b/cocos/profiler/profiler.ts index a8bf786b353..49ce9e2d920 100644 --- a/cocos/profiler/profiler.ts +++ b/cocos/profiler/profiler.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -33,14 +32,12 @@ import { Layers } from '../scene-graph'; import { Node } from '../scene-graph/node'; import { ICounterOption } from './counter'; import { PerfCounter } from './perf-counter'; -import { legacyCC } from '../core/global-exports'; import { Pass } from '../render-scene'; -import { preTransforms } from '../core/math/mat4'; +import { preTransforms, System, sys, cclegacy, Settings, settings } from '../core'; import { Root } from '../root'; import { PipelineRuntime } from '../rendering/custom/pipeline'; -import { System, sys } from '../core'; -import { Settings, settings } from '../core/settings'; import { director } from '../game'; +import { ccwindow } from '../core/global-exports'; const _characters = '0123456789. '; @@ -69,6 +66,7 @@ interface IProfilerState { logic: ICounterOption; physics: ICounterOption; render: ICounterOption; + present: ICounterOption; textureMemory: ICounterOption; bufferMemory: ICounterOption; } @@ -82,6 +80,7 @@ const _profileInfo = { logic: { desc: 'Game Logic (ms)', min: 0, max: 50, average: _average, color: '#080' }, physics: { desc: 'Physics (ms)', min: 0, max: 50, average: _average }, render: { desc: 'Renderer (ms)', min: 0, max: 50, average: _average, color: '#f90' }, + present: { desc: 'Present (ms)', min: 0, max: 50, average: _average, color: '#f90' }, textureMemory: { desc: 'GFX Texture Mem(M)' }, bufferMemory: { desc: 'GFX Buffer Mem(M)' }, }; @@ -90,8 +89,8 @@ const _constants = { fontSize: 23, quadHeight: 0.4, segmentsPerLine: 8, - textureWidth: 256, - textureHeight: 256, + textureWidth: 280, + textureHeight: 280, }; export class Profiler extends System { @@ -105,7 +104,6 @@ export class Profiler extends System { private _rootNode: Node | null = null; private _device: Device | null = null; private _swapchain: Swapchain | null = null; - private _pipeline: PipelineRuntime = null!; private _meshRenderer: MeshRenderer = null!; private readonly _canvas: HTMLCanvasElement | null = null; private readonly _ctx: CanvasRenderingContext2D | null = null; @@ -131,7 +129,7 @@ export class Profiler extends System { constructor () { super(); if (!TEST) { - this._canvas = document.createElement('canvas'); + this._canvas = ccwindow.document.createElement('canvas'); this._ctx = this._canvas.getContext('2d')!; this._canvasArr.push(this._canvas); } @@ -156,51 +154,48 @@ export class Profiler extends System { this._rootNode.active = false; } - legacyCC.director.off(legacyCC.Director.EVENT_BEFORE_UPDATE, this.beforeUpdate, this); - legacyCC.director.off(legacyCC.Director.EVENT_AFTER_UPDATE, this.afterUpdate, this); - legacyCC.director.off(legacyCC.Director.EVENT_BEFORE_PHYSICS, this.beforePhysics, this); - legacyCC.director.off(legacyCC.Director.EVENT_AFTER_PHYSICS, this.afterPhysics, this); - legacyCC.director.off(legacyCC.Director.EVENT_BEFORE_DRAW, this.beforeDraw, this); - legacyCC.director.off(legacyCC.Director.EVENT_AFTER_DRAW, this.afterDraw, this); + cclegacy.director.off(cclegacy.Director.EVENT_BEFORE_UPDATE, this.beforeUpdate, this); + cclegacy.director.off(cclegacy.Director.EVENT_AFTER_UPDATE, this.afterUpdate, this); + cclegacy.director.off(cclegacy.Director.EVENT_BEFORE_PHYSICS, this.beforePhysics, this); + cclegacy.director.off(cclegacy.Director.EVENT_AFTER_PHYSICS, this.afterPhysics, this); + cclegacy.director.off(cclegacy.Director.EVENT_BEFORE_DRAW, this.beforeDraw, this); + cclegacy.director.off(cclegacy.Director.EVENT_AFTER_RENDER, this.afterRender, this); + cclegacy.director.off(cclegacy.Director.EVENT_AFTER_DRAW, this.afterPresent, this); this._showFPS = false; director.root!.pipeline.profiler = null; - legacyCC.game.config.showFPS = false; + cclegacy.game.config.showFPS = false; } } public showStats () { if (!this._showFPS) { if (!this._device) { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; this._device = deviceManager.gfxDevice; this._swapchain = root.mainWindow!.swapchain; - this._pipeline = root.pipeline; - } - if (!EDITOR || legacyCC.GAME_VIEW) { - this.generateCanvas(); } + + this.generateCanvas(); this.generateStats(); - if (!EDITOR || legacyCC.GAME_VIEW) { - legacyCC.game.once(legacyCC.Game.EVENT_ENGINE_INITED, this.generateNode, this); - legacyCC.game.on(legacyCC.Game.EVENT_RESTART, this.generateNode, this); - } else { - this._inited = true; - } + cclegacy.game.once(cclegacy.Game.EVENT_ENGINE_INITED, this.generateNode, this); + cclegacy.game.on(cclegacy.Game.EVENT_RESTART, this.generateNode, this); + if (this._rootNode) { this._rootNode.active = true; } - legacyCC.director.on(legacyCC.Director.EVENT_BEFORE_UPDATE, this.beforeUpdate, this); - legacyCC.director.on(legacyCC.Director.EVENT_AFTER_UPDATE, this.afterUpdate, this); - legacyCC.director.on(legacyCC.Director.EVENT_BEFORE_PHYSICS, this.beforePhysics, this); - legacyCC.director.on(legacyCC.Director.EVENT_AFTER_PHYSICS, this.afterPhysics, this); - legacyCC.director.on(legacyCC.Director.EVENT_BEFORE_DRAW, this.beforeDraw, this); - legacyCC.director.on(legacyCC.Director.EVENT_AFTER_DRAW, this.afterDraw, this); + cclegacy.director.on(cclegacy.Director.EVENT_BEFORE_UPDATE, this.beforeUpdate, this); + cclegacy.director.on(cclegacy.Director.EVENT_AFTER_UPDATE, this.afterUpdate, this); + cclegacy.director.on(cclegacy.Director.EVENT_BEFORE_PHYSICS, this.beforePhysics, this); + cclegacy.director.on(cclegacy.Director.EVENT_AFTER_PHYSICS, this.afterPhysics, this); + cclegacy.director.on(cclegacy.Director.EVENT_BEFORE_DRAW, this.beforeDraw, this); + cclegacy.director.on(cclegacy.Director.EVENT_AFTER_RENDER, this.afterRender, this); + cclegacy.director.on(cclegacy.Director.EVENT_AFTER_DRAW, this.afterPresent, this); this._showFPS = true; this._canvasDone = true; this._statsDone = true; - legacyCC.game.config.showFPS = true; + cclegacy.game.config.showFPS = true; } } @@ -248,26 +243,24 @@ export class Profiler extends System { let i = 0; for (const id in _profileInfo) { const element = _profileInfo[id]; - if (!EDITOR || legacyCC.GAME_VIEW) this._ctx.fillText(element.desc, 0, i * this._lineHeight); + this._ctx.fillText(element.desc, 0, i * this._lineHeight); element.counter = new PerfCounter(id, element, now); i++; } this._totalLines = i; this._wordHeight = this._totalLines * this._lineHeight / this._canvas.height; - if (!EDITOR || legacyCC.GAME_VIEW) { - for (let j = 0; j < _characters.length; ++j) { - const offset = this._ctx.measureText(_characters[j]).width; - this._eachNumWidth = Math.max(this._eachNumWidth, offset); - } - for (let j = 0; j < _characters.length; ++j) { - this._ctx.fillText(_characters[j], j * this._eachNumWidth, this._totalLines * this._lineHeight); - } + for (let j = 0; j < _characters.length; ++j) { + const offset = this._ctx.measureText(_characters[j]).width; + this._eachNumWidth = Math.max(this._eachNumWidth, offset); + } + for (let j = 0; j < _characters.length; ++j) { + this._ctx.fillText(_characters[j], j * this._eachNumWidth, this._totalLines * this._lineHeight); } this._eachNumWidth /= this._canvas.width; this._stats = _profileInfo as IProfilerState; this._canvasArr[0] = this._canvas; - if (!EDITOR || legacyCC.GAME_VIEW) this._device!.copyTexImagesToTexture(this._canvasArr, this._texture!, this._regionArr); + this._device!.copyTexImagesToTexture(this._canvasArr, this._texture!, this._regionArr); } public generateNode () { @@ -276,8 +269,8 @@ export class Profiler extends System { } this._rootNode = new Node('PROFILER_NODE'); - this._rootNode._objFlags = legacyCC.Object.Flags.DontSave | legacyCC.Object.Flags.HideInHierarchy; - legacyCC.game.addPersistRootNode(this._rootNode); + this._rootNode._objFlags = cclegacy.Object.Flags.DontSave | cclegacy.Object.Flags.HideInHierarchy; + cclegacy.game.addPersistRootNode(this._rootNode); const managerNode = new Node('Profiler_Root'); managerNode.parent = this._rootNode; @@ -363,7 +356,7 @@ export class Profiler extends System { } const now = performance.now(); - if (legacyCC.director.isPaused()) { + if (cclegacy.director.isPaused()) { (this._stats.frame.counter as PerfCounter).start(now); } else { (this._stats.logic.counter as PerfCounter).end(now); @@ -393,25 +386,23 @@ export class Profiler extends System { return; } - if (!EDITOR || legacyCC.GAME_VIEW) { - const surfaceTransform = this._swapchain!.surfaceTransform; - const clipSpaceSignY = this._device!.capabilities.clipSpaceSignY; - if (surfaceTransform !== this.offsetData[3]) { - const preTransform = preTransforms[surfaceTransform]; - let x = -0.9; let y = -0.9 * clipSpaceSignY; - if (sys.isXR) { - x = -0.5; y = -0.5 * clipSpaceSignY; - } - this.offsetData[0] = x * preTransform[0] + y * preTransform[2]; - this.offsetData[1] = x * preTransform[1] + y * preTransform[3]; - this.offsetData[2] = this._eachNumWidth; - this.offsetData[3] = surfaceTransform; + const surfaceTransform = this._swapchain!.surfaceTransform; + const clipSpaceSignY = this._device!.capabilities.clipSpaceSignY; + if (surfaceTransform !== this.offsetData[3]) { + const preTransform = preTransforms[surfaceTransform]; + let x = -0.9; let y = -0.9 * clipSpaceSignY; + if (sys.isXR) { + x = -0.5; y = -0.5 * clipSpaceSignY; } - - // @ts-expect-error using private members for efficiency. - this.pass._rootBufferDirty = true; + this.offsetData[0] = x * preTransform[0] + y * preTransform[2]; + this.offsetData[1] = x * preTransform[1] + y * preTransform[3]; + this.offsetData[2] = this._eachNumWidth; + this.offsetData[3] = surfaceTransform; } + // @ts-expect-error using private members for efficiency. + this.pass._rootBufferDirty = true; + if (this._meshRenderer.model) { director.root!.pipeline.profiler = this._meshRenderer.model; } else { @@ -422,15 +413,24 @@ export class Profiler extends System { (this._stats.render.counter as PerfCounter).start(now); } - public afterDraw () { + public afterRender () { if (!this._stats || !this._inited) { return; } const now = performance.now(); + (this._stats.render.counter as PerfCounter).end(now); + (this._stats.present.counter as PerfCounter).start(now); + } + public afterPresent () { + if (!this._stats || !this._inited) { + return; + } + + const now = performance.now(); (this._stats.frame.counter as PerfCounter).end(now); (this._stats.fps.counter as PerfCounter).frame(now); - (this._stats.render.counter as PerfCounter).end(now); + (this._stats.present.counter as PerfCounter).end(now); if (now - this.lastTime < _average) { return; @@ -445,25 +445,23 @@ export class Profiler extends System { (this._stats.tricount.counter as PerfCounter).value = device.numTris; let i = 0; - if (!EDITOR || legacyCC.GAME_VIEW) { - const view = this.digitsData; - for (const id in this._stats) { - const stat = this._stats[id] as ICounterOption; - stat.counter.sample(now); - const result = stat.counter.human().toString(); - for (let j = _constants.segmentsPerLine - 1; j >= 0; j--) { - const index = i * _constants.segmentsPerLine + j; - const character = result[result.length - (_constants.segmentsPerLine - j)]; - let offset = _string2offset[character]; - if (offset === undefined) { offset = 11; } - view[index] = offset; - } - i++; + const view = this.digitsData; + for (const id in this._stats) { + const stat = this._stats[id] as ICounterOption; + stat.counter.sample(now); + const result = stat.counter.human().toString(); + for (let j = _constants.segmentsPerLine - 1; j >= 0; j--) { + const index = i * _constants.segmentsPerLine + j; + const character = result[result.length - (_constants.segmentsPerLine - j)]; + let offset = _string2offset[character]; + if (offset === undefined) { offset = 11; } + view[index] = offset; } + i++; } } } export const profiler = new Profiler(); director.registerSystem('profiler', profiler, 0); -legacyCC.profiler = profiler; +cclegacy.profiler = profiler; diff --git a/cocos/render-scene/config.ts b/cocos/render-scene/config.ts index 4b1a9bba576..0ea358ca99a 100644 --- a/cocos/render-scene/config.ts +++ b/cocos/render-scene/config.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ let _stageOffset = 0; const _name2stageID = {}; diff --git a/cocos/render-scene/core/constants.ts b/cocos/render-scene/core/constants.ts index c3bdb5ac45e..4c8b03cc085 100644 --- a/cocos/render-scene/core/constants.ts +++ b/cocos/render-scene/core/constants.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export enum RenderQueue { OPAQUE = 0, diff --git a/cocos/render-scene/core/material-instance.jsb.ts b/cocos/render-scene/core/material-instance.jsb.ts index a6597c9f1be..5d7c4ae3945 100644 --- a/cocos/render-scene/core/material-instance.jsb.ts +++ b/cocos/render-scene/core/material-instance.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Material } from '../../asset/assets/material'; import { Renderer } from '../../core/components/renderer'; diff --git a/cocos/render-scene/core/material-instance.ts b/cocos/render-scene/core/material-instance.ts index d5b26b04680..835db5e06f4 100644 --- a/cocos/render-scene/core/material-instance.ts +++ b/cocos/render-scene/core/material-instance.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/render-scene/core/memory-pools.ts b/cocos/render-scene/core/memory-pools.ts index 6f0459ee9a0..74f15db6cb2 100644 --- a/cocos/render-scene/core/memory-pools.ts +++ b/cocos/render-scene/core/memory-pools.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/render-scene/core/native-pools.jsb.ts b/cocos/render-scene/core/native-pools.jsb.ts index 82cacca2a8f..bc22e530972 100644 --- a/cocos/render-scene/core/native-pools.jsb.ts +++ b/cocos/render-scene/core/native-pools.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ declare const jsb: any; diff --git a/cocos/render-scene/core/native-pools.ts b/cocos/render-scene/core/native-pools.ts index b846ae14fc1..3d3b9de1b7d 100644 --- a/cocos/render-scene/core/native-pools.ts +++ b/cocos/render-scene/core/native-pools.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/render-scene/core/pass-instance.ts b/cocos/render-scene/core/pass-instance.ts index 81df1f10cda..85932419a9e 100644 --- a/cocos/render-scene/core/pass-instance.ts +++ b/cocos/render-scene/core/pass-instance.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/render-scene/core/pass-utils.ts b/cocos/render-scene/core/pass-utils.ts index 84afb08bac7..64fa3825fbd 100644 --- a/cocos/render-scene/core/pass-utils.ts +++ b/cocos/render-scene/core/pass-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,7 +23,7 @@ */ import { Type } from '../../gfx'; -import { Color, Mat3, Mat4, Vec2, Vec3, Vec4, Quat, IVec2Like, IVec3Like, IVec4Like, IMat3Like, IMat4Like } from '../../core/math'; +import { Color, Mat3, Mat4, Vec2, Vec3, Vec4, Quat, IVec2Like, IVec3Like, IVec4Like, IMat3Like, IMat4Like, warnID } from '../../core'; const typeMask = 0xfc000000; // 6 bits => 64 types const bindingMask = 0x03f00000; // 6 bits => 64 bindings @@ -46,7 +45,7 @@ export const customizeType = (handle: number, type: Type): number => (handle & ~ export type MaterialProperty = number | Vec2 | Vec3 | Vec4 | Color | Mat3 | Mat4 | Quat; export const type2reader = { - [Type.UNKNOWN]: (a: Float32Array, v: number, idx = 0): void => console.warn('illegal uniform handle'), + [Type.UNKNOWN]: (a: Float32Array, v: number, idx = 0): void => warnID(12010, idx), [Type.INT]: (a: Int32Array, v: number, idx = 0): number => a[idx], [Type.INT2]: (a: Int32Array, v: IVec2Like, idx = 0): IVec2Like => Vec2.fromArray(v, a, idx), [Type.INT3]: (a: Int32Array, v: IVec3Like, idx = 0): IVec3Like => Vec3.fromArray(v, a, idx), @@ -60,17 +59,30 @@ export const type2reader = { }; export const type2writer = { - [Type.UNKNOWN]: (a: Float32Array, v: number, idx = 0): void => console.warn('illegal uniform handle'), + [Type.UNKNOWN]: (a: Float32Array, v: number, idx = 0): void => warnID(12010, idx), [Type.INT]: (a: Int32Array, v: number, idx = 0): number => a[idx] = v, - [Type.INT2]: (a: Int32Array, v: IVec2Like, idx = 0): Int32Array => Vec2.toArray(a, v, idx), - [Type.INT3]: (a: Int32Array, v: IVec3Like, idx = 0): Int32Array => Vec3.toArray(a, v, idx), - [Type.INT4]: (a: Int32Array, v: IVec4Like, idx = 0): Int32Array => Vec4.toArray(a, v, idx), + [Type.INT2]: (a: Int32Array, v: Vec2, idx = 0): Int32Array => Vec2.toArray(a, v, idx), + [Type.INT3]: (a: Int32Array, v: Vec3, idx = 0): Int32Array => Vec3.toArray(a, v, idx), + [Type.INT4]: (a: Int32Array, v: Vec4, idx = 0): Int32Array => Vec4.toArray(a, v, idx), [Type.FLOAT]: (a: Float32Array, v: number, idx = 0): number => a[idx] = v, - [Type.FLOAT2]: (a: Float32Array, v: IVec2Like, idx = 0): Float32Array => Vec2.toArray(a, v, idx), - [Type.FLOAT3]: (a: Float32Array, v: IVec3Like, idx = 0): Float32Array => Vec3.toArray(a, v, idx), - [Type.FLOAT4]: (a: Float32Array, v: IVec4Like, idx = 0): Float32Array => Vec4.toArray(a, v, idx), - [Type.MAT3]: (a: Float32Array, v: IMat3Like, idx = 0): Float32Array => Mat3.toArray(a, v, idx), - [Type.MAT4]: (a: Float32Array, v: IMat4Like, idx = 0): Float32Array => Mat4.toArray(a, v, idx), + [Type.FLOAT2]: (a: Float32Array, v: Vec2, idx = 0): Float32Array => Vec2.toArray(a, v, idx), + [Type.FLOAT3]: (a: Float32Array, v: Vec3, idx = 0): Float32Array => Vec3.toArray(a, v, idx), + [Type.FLOAT4]: (a: Float32Array, v: Vec4, idx = 0): Float32Array => Vec4.toArray(a, v, idx), + [Type.MAT3]: (a: Float32Array, v: Mat3, idx = 0): Float32Array => Mat3.toArray(a, v, idx), + [Type.MAT4]: (a: Float32Array, v: Mat4, idx = 0): Float32Array => Mat4.toArray(a, v, idx), +}; + +export const type2validator = { + [Type.INT]: (v: number): boolean => typeof v === 'number', + [Type.FLOAT]: (v: number): boolean => typeof v === 'number', + [Type.INT2]: (v: Vec2): boolean => !!(v instanceof Vec2), + [Type.FLOAT2]: (v: Vec2): boolean => !!(v instanceof Vec2), + [Type.INT3]: (v: Vec3): boolean => !!(v instanceof Vec3), + [Type.FLOAT3]: (v: Vec3): boolean => !!(v instanceof Vec3), + [Type.INT4]: (v: Vec4): boolean => !!(v instanceof Vec4), + [Type.FLOAT4]: (v: Vec4 | Color | Quat): boolean => !!((v instanceof Vec4) || (v instanceof Color) || (v instanceof Quat)), + [Type.MAT3]: (v: Mat3): boolean => !!(v instanceof Mat3), + [Type.MAT4]: (v: Mat4): boolean => !!(v instanceof Mat4), }; const defaultValues = [ diff --git a/cocos/render-scene/core/pass.jsb.ts b/cocos/render-scene/core/pass.jsb.ts index 34656492256..d5aba28ba25 100644 --- a/cocos/render-scene/core/pass.jsb.ts +++ b/cocos/render-scene/core/pass.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { MacroRecord } from "./pass-utils"; import { EffectAsset } from '../../asset/assets/effect-asset'; diff --git a/cocos/render-scene/core/pass.ts b/cocos/render-scene/core/pass.ts index 951deb2480e..8128db8df4d 100644 --- a/cocos/render-scene/core/pass.ts +++ b/cocos/render-scene/core/pass.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,25 +22,25 @@ THE SOFTWARE. */ -import { EDITOR } from 'internal:constants'; +import { DEBUG, EDITOR } from 'internal:constants'; import { Root } from '../../root'; import { TextureBase } from '../../asset/assets/texture-base'; import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; import { getPhaseID } from '../../rendering/pass-phase'; -import { murmurhash2_32_gc } from '../../core/algorithm/murmurhash2_gc'; +import { murmurhash2_32_gc, errorID, assertID, cclegacy } from '../../core'; import { BufferUsageBit, DynamicStateFlagBit, DynamicStateFlags, Feature, GetTypeSize, MemoryUsageBit, PrimitiveMode, Type, Color, BlendState, BlendTarget, Buffer, BufferInfo, BufferViewInfo, DepthStencilState, DescriptorSet, - DescriptorSetInfo, DescriptorSetLayout, Device, RasterizerState, Sampler, Texture, Shader, PipelineLayout, deviceManager, + DescriptorSetInfo, DescriptorSetLayout, Device, RasterizerState, Sampler, Texture, Shader, PipelineLayout, deviceManager, UniformBlock, } from '../../gfx'; import { EffectAsset } from '../../asset/assets/effect-asset'; import { IProgramInfo, programLib } from './program-lib'; import { MacroRecord, MaterialProperty, customizeType, getBindingFromHandle, getDefaultFromType, getStringFromType, - getOffsetFromHandle, getTypeFromHandle, type2reader, type2writer, getCountFromHandle, + getOffsetFromHandle, getTypeFromHandle, type2reader, type2writer, getCountFromHandle, type2validator, } from './pass-utils'; import { RenderPassStage, RenderPriority } from '../../rendering/define'; -import { errorID } from '../../core/platform/debug'; import { InstancedBuffer } from '../../rendering/instanced-buffer'; import { BatchedBuffer } from '../../rendering/batched-buffer'; +import { ProgramLibrary } from '../../rendering/custom/private'; export interface IPassInfoFull extends EffectAsset.IPassInfo { // generated part @@ -72,6 +71,8 @@ const _bufferViewInfo = new BufferViewInfo(null!); const _dsInfo = new DescriptorSetInfo(null!); +const _materialSet = 1; + export enum BatchingSchemes { NONE = 0, INSTANCING = 1, @@ -121,7 +122,9 @@ export class Pass { if (info.primitive !== undefined) { pass._primitive = info.primitive; } if (info.stage !== undefined) { pass._stage = info.stage; } if (info.dynamicStates !== undefined) { pass._dynamicStates = info.dynamicStates; } - if (info.phase !== undefined) { pass._phase = getPhaseID(info.phase); } + if (info.phase !== undefined) { + pass._phase = getPhaseID(info.phase); + } const bs = pass._bs; if (info.blendState) { @@ -148,7 +151,14 @@ export class Pass { * @param hPass Handle of the pass info used to compute hash value. */ public static getPassHash (pass: Pass): number { - const shaderKey = programLib.getKey(pass.program, pass.defines); + let shaderKey = ''; + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const key = (cclegacy.rendering.programLib as ProgramLibrary) + .getKey(pass._phaseID, pass.program, pass.defines); + shaderKey = `${pass._phaseID.toString()},${key}`; + } else { + shaderKey = programLib.getKey(pass.program, pass.defines); + } let res = `${shaderKey},${pass._primitive},${pass._dynamicStates}`; res += serializeBlendState(pass._bs); res += serializeDepthStencilState(pass._dss); @@ -181,6 +191,8 @@ export class Pass { protected _priority: RenderPriority = RenderPriority.DEFAULT; protected _stage: RenderPassStage = RenderPassStage.DEFAULT; protected _phase = getPhaseID('default'); + protected _passID = 0xFFFFFFFF; + protected _phaseID = 0xFFFFFFFF; protected _primitive: PrimitiveMode = PrimitiveMode.TRIANGLE_LIST; protected _batchingScheme: BatchingSchemes = BatchingSchemes.NONE; protected _dynamicStates: DynamicStateFlagBit = DynamicStateFlagBit.NONE; @@ -259,6 +271,10 @@ export class Pass { const type = Pass.getTypeFromHandle(handle); const ofs = Pass.getOffsetFromHandle(handle); const block = this._getBlockView(type, binding); + if (DEBUG) { + const validator = type2validator[type]; + assertID(validator && validator(value), 12011, binding, Type[type]); + } type2writer[type](block, value, ofs); this._rootBufferDirty = true; } @@ -480,12 +496,32 @@ export class Pass { */ public tryCompile (): boolean { const { pipeline } = this._root; - if (!pipeline) { return false; } + if (!pipeline) { + return false; + } this._syncBatchingScheme(); - const shader = programLib.getGFXShader(this._device, this._programName, this._defines, pipeline); - if (!shader) { console.warn(`create shader ${this._programName} failed`); return false; } - this._shader = shader; - this._pipelineLayout = programLib.getTemplateInfo(this._programName).pipelineLayout; + + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const programLib = cclegacy.rendering.programLib as ProgramLibrary; + const program = programLib.getProgramVariant( + this._device, this._phaseID, this._programName, this._defines, + ); + if (!program) { + console.warn(`create shader ${this._programName} failed`); + return false; + } + this._shader = program.shader; + this._pipelineLayout = programLib.getPipelineLayout(this.device, this._phaseID, this._programName); + } else { + const shader = programLib.getGFXShader(this._device, this._programName, this._defines, pipeline); + if (!shader) { + console.warn(`create shader ${this._programName} failed`); + return false; + } + this._shader = shader; + this._pipelineLayout = programLib.getTemplateInfo(this._programName).pipelineLayout; + } + this._hash = Pass.getPassHash(this); return true; } @@ -520,7 +556,16 @@ export class Pass { this._defines[patch.name] = patch.value; } - const shader = programLib.getGFXShader(this._device, this._programName, this._defines, pipeline); + let shader: Shader | null = null; + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const program = (cclegacy.rendering.programLib as ProgramLibrary) + .getProgramVariant(this._device, this._phaseID, this._programName, this._defines); + if (program) { + shader = program.shader; + } + } else { + shader = programLib.getGFXShader(this._device, this._programName, this._defines, pipeline); + } for (let i = 0; i < patches.length; i++) { const patch = patches[i]; @@ -543,6 +588,26 @@ export class Pass { protected _doInit (info: IPassInfoFull, copyDefines = false): void { this._priority = RenderPriority.DEFAULT; this._stage = RenderPassStage.DEFAULT; + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const r = cclegacy.rendering; + if (typeof info.phase === 'number') { + this._passID = (info as Pass)._passID; + this._phaseID = (info as Pass)._phaseID; + } else { + this._passID = r.getPassID(info.pass); + if (this._passID !== r.INVALID_ID) { + this._phaseID = r.getPhaseID(this._passID, info.phase); + } + } + if (this._passID === r.INVALID_ID) { + console.error(`Invalid render pass, program: ${info.program}`); + return; + } + if (this._phaseID === r.INVALID_ID) { + console.error(`Invalid render phase, program: ${info.program}`); + return; + } + } this._phase = getPhaseID('default'); this._primitive = PrimitiveMode.TRIANGLE_LIST; @@ -550,21 +615,63 @@ export class Pass { this._propertyIndex = info.propertyIndex !== undefined ? info.propertyIndex : info.passIndex; this._programName = info.program; this._defines = copyDefines ? ({ ...info.defines }) : info.defines; - this._shaderInfo = programLib.getTemplate(info.program); + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + this._shaderInfo = (cclegacy.rendering.programLib as ProgramLibrary) + .getProgramInfo(this._phaseID, this._programName); + } else { + this._shaderInfo = programLib.getTemplate(info.program); + } this._properties = info.properties || this._properties; + // init gfx const device = this._device; Pass.fillPipelineInfo(this, info); if (info.stateOverrides) { Pass.fillPipelineInfo(this, info.stateOverrides); } // init descriptor set - _dsInfo.layout = programLib.getDescriptorSetLayout(this._device, info.program); + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + _dsInfo.layout = (cclegacy.rendering.programLib as ProgramLibrary) + .getMaterialDescriptorSetLayout(this._device, this._phaseID, info.program); + } else { + _dsInfo.layout = programLib.getDescriptorSetLayout(this._device, info.program); + } this._descriptorSet = this._device.createDescriptorSet(_dsInfo); // calculate total size required const blocks = this._shaderInfo.blocks; - const tmplInfo = programLib.getTemplateInfo(info.program); - const { blockSizes, handleMap } = tmplInfo; + let blockSizes: number[]; + let handleMap: Record; + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const programLib = (cclegacy.rendering.programLib as ProgramLibrary); + blockSizes = programLib.getBlockSizes(this._phaseID, this._programName); + handleMap = programLib.getHandleMap(this._phaseID, this._programName); + } else { + const tmplInfo = programLib.getTemplateInfo(info.program); + blockSizes = tmplInfo.blockSizes; + handleMap = tmplInfo.handleMap; + } + + // build uniform blocks + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const programLib = (cclegacy.rendering.programLib as ProgramLibrary); + const shaderInfo = programLib.getShaderInfo(this._phaseID, this.program); + this._buildMaterialUniformBlocks(device, shaderInfo.blocks, blockSizes); + } else { + this._buildUniformBlocks(device, blocks, blockSizes); + } + + // store handles + const directHandleMap = this._propertyHandleMap = handleMap; + const indirectHandleMap: Record = {}; + for (const name in this._properties) { + const prop = this._properties[name]; + if (!prop.handleInfo) { continue; } + indirectHandleMap[name] = this.getHandle.apply(this, prop.handleInfo)!; + } + Object.assign(directHandleMap, indirectHandleMap); + } + + private _buildUniformBlocks (device: Device, blocks: EffectAsset.IBlockInfo[], blockSizes: number[]) { const alignment = device.capabilities.uboOffsetAlignment; const startOffsets: number[] = []; let lastSize = 0; let lastOffset = 0; @@ -597,15 +704,51 @@ export class Pass { this._blocksInt[binding] = new Int32Array(this._blocks[binding].buffer, this._blocks[binding].byteOffset, this._blocks[binding].length); this._descriptorSet.bindBuffer(binding, bufferView); } - // store handles - const directHandleMap = this._propertyHandleMap = handleMap; - const indirectHandleMap: Record = {}; - for (const name in this._properties) { - const prop = this._properties[name]; - if (!prop.handleInfo) { continue; } - indirectHandleMap[name] = this.getHandle.apply(this, prop.handleInfo)!; + } + + private _buildMaterialUniformBlocks (device: Device, blocks: UniformBlock[], blockSizes: number[]) { + const alignment = device.capabilities.uboOffsetAlignment; + const startOffsets: number[] = []; + let lastSize = 0; let lastOffset = 0; + for (let i = 0; i < blocks.length; i++) { + const block = blocks[i]; + if (block.set !== _materialSet) { + continue; + } + const size = blockSizes[i]; + startOffsets.push(lastOffset); + lastOffset += Math.ceil(size / alignment) * alignment; + lastSize = size; + } + // create gfx buffer resource + if (lastSize !== 0) { + const totalSize = startOffsets[startOffsets.length - 1] + lastSize; + if (totalSize) { + // https://bugs.chromium.org/p/chromium/issues/detail?id=988988 + _bufferInfo.size = Math.ceil(totalSize / 16) * 16; + this._rootBuffer = device.createBuffer(_bufferInfo); + this._rootBlock = new ArrayBuffer(totalSize); + } + } + // create buffer views + for (let i = 0, count = 0; i < blocks.length; i++) { + const block = blocks[i]; + if (block.set !== _materialSet) { + continue; + } + const { binding } = blocks[i]; + const size = blockSizes[i]; + _bufferViewInfo.buffer = this._rootBuffer!; + _bufferViewInfo.offset = startOffsets[count++]; + _bufferViewInfo.range = Math.ceil(size / 16) * 16; + const bufferView = this._buffers[binding] = device.createBuffer(_bufferViewInfo); + // non-builtin UBO data pools, note that the effect compiler + // guarantees these bindings to be consecutive, starting from 0 and non-array-typed + this._blocks[binding] = new Float32Array(this._rootBlock!, _bufferViewInfo.offset, + size / Float32Array.BYTES_PER_ELEMENT); + this._blocksInt[binding] = new Int32Array(this._blocks[binding].buffer, this._blocks[binding].byteOffset, this._blocks[binding].length); + this._descriptorSet.bindBuffer(binding, bufferView); } - Object.assign(directHandleMap, indirectHandleMap); } protected _syncBatchingScheme (): void { @@ -632,6 +775,8 @@ export class Pass { this._priority = target.priority; this._stage = target.stage; this._phase = target.phase; + this._phaseID = target._phaseID; + this._passID = target._passID; this._batchingScheme = target.batchingScheme; this._primitive = target.primitive; this._dynamicStates = target.dynamicStates; @@ -652,7 +797,12 @@ export class Pass { this._shader = target._shader; - this._pipelineLayout = programLib.getTemplateInfo(this._programName).pipelineLayout; + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + this._pipelineLayout = (cclegacy.rendering.programLib as ProgramLibrary) + .getPipelineLayout(this.device, this._phaseID, this._programName); + } else { + this._pipelineLayout = programLib.getTemplateInfo(this._programName).pipelineLayout; + } this._hash = target._hash ^ hashFactor; } @@ -665,7 +815,14 @@ export class Pass { get root (): Root { return this._root; } get device (): Device { return this._device; } get shaderInfo (): IProgramInfo { return this._shaderInfo; } - get localSetLayout (): DescriptorSetLayout { return programLib.getDescriptorSetLayout(this._device, this._programName, true); } + get localSetLayout (): DescriptorSetLayout { + if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + return (cclegacy.rendering.programLib as ProgramLibrary) + .getLocalDescriptorSetLayout(this._device, this._phaseID, this._programName); + } else { + return programLib.getDescriptorSetLayout(this._device, this._programName, true); + } + } get program (): string { return this._programName; } get properties (): Record { return this._properties; } get defines (): Record { return this._defines; } @@ -681,6 +838,8 @@ export class Pass { get primitive (): PrimitiveMode { return this._primitive; } get stage (): RenderPassStage { return this._stage; } get phase (): number { return this._phase; } + get passID (): number { return this._passID; } + get phaseID (): number { return this._phaseID; } get rasterizerState (): RasterizerState { return this._rs; } get depthStencilState (): DepthStencilState { return this._dss; } get blendState (): BlendState { return this._bs; } diff --git a/cocos/render-scene/core/program-lib.jsb.ts b/cocos/render-scene/core/program-lib.jsb.ts index 8a1c5d92fd9..80170504e8c 100644 --- a/cocos/render-scene/core/program-lib.jsb.ts +++ b/cocos/render-scene/core/program-lib.jsb.ts @@ -1,5 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { API, } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; +import { cclegacy } from '../../core'; export interface ITemplateInfo { gfxAttributes: Attribute[]; @@ -30,4 +54,4 @@ export function getDeviceShaderVersion (device) { } export const programLib = jsb.ProgramLib.getInstance(); -legacyCC.programLib = programLib; \ No newline at end of file +cclegacy.programLib = programLib; \ No newline at end of file diff --git a/cocos/render-scene/core/program-lib.ts b/cocos/render-scene/core/program-lib.ts index 008a53d2603..ed1e581cbda 100644 --- a/cocos/render-scene/core/program-lib.ts +++ b/cocos/render-scene/core/program-lib.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,17 +22,21 @@ THE SOFTWARE. */ +import * as env from 'internal:constants'; import { EffectAsset } from '../../asset/assets/effect-asset'; import { SetIndex, IDescriptorSetLayoutInfo, globalDescriptorSetLayout, localDescriptorSetLayout } from '../../rendering/define'; import { PipelineRuntime } from '../../rendering/custom/pipeline'; -import { genHandle, MacroRecord } from './pass-utils'; -import { legacyCC } from '../../core/global-exports'; -import { PipelineLayoutInfo, Device, Attribute, UniformBlock, ShaderInfo, +import { MacroRecord } from './pass-utils'; +import { + PipelineLayoutInfo, Device, Attribute, UniformBlock, ShaderInfo, Uniform, ShaderStage, DESCRIPTOR_SAMPLER_TYPE, DESCRIPTOR_BUFFER_TYPE, DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorSetLayoutInfo, - DescriptorType, GetTypeSize, ShaderStageFlagBit, API, UniformSamplerTexture, PipelineLayout, - Shader, UniformStorageBuffer, UniformStorageImage, UniformSampler, UniformTexture, UniformInputAttachment } from '../../gfx'; -import { debug } from '../../core/platform/debug'; + DescriptorType, ShaderStageFlagBit, API, UniformSamplerTexture, PipelineLayout, + Shader, UniformStorageBuffer, UniformStorageImage, UniformSampler, UniformTexture, UniformInputAttachment, +} from '../../gfx'; +import { genHandles, getActiveAttributes, getShaderInstanceName, getSize, + getVariantKey, IMacroInfo, populateMacros, prepareDefines } from './program-utils'; +import { debug, cclegacy } from '../../core'; const _dsLayoutInfo = new DescriptorSetLayoutInfo(); @@ -60,44 +63,6 @@ export interface IProgramInfo extends EffectAsset.IShaderInfo { uber: boolean; // macro number exceeds default limits, will fallback to string hash } -interface IMacroInfo { - name: string; - value: string; - isDefault: boolean; -} - -function getBitCount (cnt: number) { - return Math.ceil(Math.log2(Math.max(cnt, 2))); -} - -function mapDefine (info: EffectAsset.IDefineInfo, def: number | string | boolean) { - switch (info.type) { - case 'boolean': return typeof def === 'number' ? def.toString() : (def ? '1' : '0'); - case 'string': return def !== undefined ? def as string : info.options![0]; - case 'number': return def !== undefined ? def.toString() : info.range![0].toString(); - default: - console.warn(`unknown define type '${info.type}'`); - return '-1'; // should neven happen - } -} - -function prepareDefines (defs: MacroRecord, tDefs: EffectAsset.IDefineInfo[]) { - const macros: IMacroInfo[] = []; - for (let i = 0; i < tDefs.length; i++) { - const tmpl = tDefs[i]; - const name = tmpl.name; - const v = defs[name]; - const value = mapDefine(tmpl, v); - const isDefault = !v || v === '0'; - macros.push({ name, value, isDefault }); - } - return macros; -} - -function getShaderInstanceName (name: string, macros: IMacroInfo[]) { - return name + macros.reduce((acc, cur) => (cur.isDefault ? acc : `${acc}|${cur.name}${cur.value}`), ''); -} - function insertBuiltinBindings ( tmpl: IProgramInfo, tmplInfo: ITemplateInfo, source: IDescriptorSetLayoutInfo, type: 'locals' | 'globals', outBindings?: DescriptorSetLayoutBinding[], @@ -132,51 +97,218 @@ function insertBuiltinBindings ( if (outBindings) outBindings.sort((a, b) => a.binding - b.binding); } -function getSize (block: EffectAsset.IBlockInfo) { - return block.members.reduce((s, m) => s + GetTypeSize(m.type) * m.count, 0); +// find those location which won't be affected by defines, and replace by ascending order of existing slot if location > 15 +function findDefineIndependent (source: string, tmpl: IProgramInfo, attrMap: Map, locSet: Set) { + const locExistingRegStr = `layout\\(location = (\\d+)\\)\\s+in.*?\\s(\\w+)[;,\\)]`; + const locExistingReg = new RegExp(locExistingRegStr, 'g'); + let locExistingRes = locExistingReg.exec(source); + let code = source; + // layout(location = 3) in mediump vec3 v_normal; + // 3 + // v_normal + while (locExistingRes) { + const attrName = locExistingRes[2]; + const attrInfo = tmpl.attributes.find((ele) => ele.name === attrName); + // no define required. + const preExisted = attrInfo?.defines.length === 0 || attrInfo?.defines.every((ele) => ele === ''); + if (preExisted) { + let loc = parseInt(locExistingRes[1]); + if (loc > 15) { + // fill hole by ascending order if location > 15 + let n = 0; + while (locSet.has(n)) { + n++; + } + loc = n; + // flatten location index + const locDefStr = locExistingRes[0].replace(locExistingRes[1], `${loc}`); + code = source.replace(locExistingRes[0], locDefStr); + } + locSet.add(loc); + attrMap.set(locExistingRes[2], loc); + } + locExistingRes = locExistingReg.exec(source); + } + return code; } -function genHandles (tmpl: IProgramInfo) { - const handleMap: Record = {}; - // block member handles - for (let i = 0; i < tmpl.blocks.length; i++) { - const block = tmpl.blocks[i]; - const members = block.members; - let offset = 0; - for (let j = 0; j < members.length; j++) { - const uniform = members[j]; - handleMap[uniform.name] = genHandle(block.binding, uniform.type, uniform.count, offset); - offset += (GetTypeSize(uniform.type) >> 2) * uniform.count; // assumes no implicit padding, which is guaranteed by effect compiler +// replace those which could be affected by defines +function replaceVertexMutableLocation ( + source: string, + tmpl: IProgramInfo, + macroInfo: IMacroInfo[], + inOrOut: string, + attrMap: Map, + locSet: Set = new Set(), +) { + const locHolderRegStr = `layout\\(location = ([^\\)]+)\\)\\s+${inOrOut}.*?\\s(\\w+)[;,\\)]`; + const locHolderReg = new RegExp(locHolderRegStr, 'g'); + + let code = source; + // layout(location = 3) in mediump vec3 v_normal; + // 3 + // v_normal + let locHolder = locHolderReg.exec(source); + while (locHolder) { + const attrName = locHolder[2]; + if (!attrMap.has(attrName)) { + const attrInfo = tmpl.attributes.find((ele) => ele.name === attrName); + let active = true; + let location = 0; + // only vertexshader input is checked + if (inOrOut === 'in') { + const targetStr = source.slice(0, locHolder.index); + // attrInfo?.defines store defines need to be satisfied + // macroInfo stores value of defines + // '!CC_USE_XXX' starts with a '!' is inverse condition. + // all defines satisfied? + active = !!attrInfo?.defines.every((defStrIn) => { + const inverseCond = defStrIn.startsWith('!'); + const defStr = inverseCond ? defStrIn.slice(1) : defStrIn; + const v = macroInfo.find((ele) => ele.name === defStr); + let res = !!v; + if (v) { + res = !(v.value === '0' || v.value === 'false' || v.value === 'FALSE'); + } + res = inverseCond ? !res : res; + if (res) { + // #if CC_RENDER_MODE == xx ...... + // 'CC_RENDER_MODE == 1' or ' CC_RENDER_MODE == 1 || CC_RENDER_MODE == 4' + const lastIfRegStr = `[\\n|\\s]+#(?:if|elif)(.*?${defStr}.*?(?:(?!#if|#elif).)*)[\\n|\\s]+$`; + const lastIfReg = new RegExp(lastIfRegStr, 'g'); + const lastIfRes = lastIfReg.exec(targetStr); + if (lastIfRes) { + const evalStr = lastIfRes[1]; + const evalORElements = evalStr.split('||'); + // simple grammar, no parenthesses support yet. + const evalRes = evalORElements.some((eleOrTestStr) => { + const evalANDElements = eleOrTestStr.split('&&'); + return evalANDElements.every((eleAndTestStr) => { + let evalEleRes = true; + if (eleAndTestStr.includes('==')) { + const opVars = eleAndTestStr.split('=='); + if ((opVars[0] as any).replaceAll(' ', '') === defStr) { + evalEleRes = (opVars[1] as any).replaceAll(' ', '') === v!.value; + } + } else if (eleAndTestStr.includes('!=')) { + const opVars = eleAndTestStr.split('!='); + if ((opVars[0] as any).replaceAll(' ', '') === defStr) { + evalEleRes = (opVars[1] as any).replaceAll(' ', '') !== v!.value; + } + } else { + // no compare just define or not + // expect to be true + } + return evalEleRes; + }); + }); + res = res && evalRes; + } + } + return res; + }); + } + + // those didn't pass the check above are deactive, ignore + if (active) { + while (locSet.has(location)) { + location++; + } + locSet.add(location); + // const attrInfo = tmpl.attributes.find((ele) => ele.name === attrName); + if (attrInfo) { + attrInfo.location = location; + } + + attrMap.set(attrName, location); + } + + const locInstStr = locHolder[0].replace(locHolder[1], `${location}`); + code = code.replace(locHolder[0], locInstStr); } + locHolder = locHolderReg.exec(source); } - // samplerTexture handles - for (let i = 0; i < tmpl.samplerTextures.length; i++) { - const samplerTexture = tmpl.samplerTextures[i]; - handleMap[samplerTexture.name] = genHandle(samplerTexture.binding, samplerTexture.type, samplerTexture.count); - } - return handleMap; + return code; } -function dependencyCheck (dependencies: string[], defines: MacroRecord) { - for (let i = 0; i < dependencies.length; i++) { - const d = dependencies[i]; - if (d[0] === '!') { // negative dependency - if (defines[d.slice(1)]) { return false; } - } else if (!defines[d]) { - return false; +function replaceFragmentLocation ( + source: string, + inOrOut: string, + attrMap: Map, +) { + let code = source; + const locHolderRegStr = `layout\\(location = ([^\\)]+)\\)\\s+${inOrOut}.*?\\s(\\w+)[;,\\)]`; + const locHolderReg = new RegExp(locHolderRegStr, 'g'); + + // layout(location = 3) in mediump vec3 v_normal; + // 3 + // v_normal + let locHolder = locHolderReg.exec(source); + while (locHolder) { + const attrName = locHolder[2]; + if (!attrMap.has(attrName)) { + let location = 0; + + if (inOrOut === 'in') { + // {...fragment_in} === {...vertex_out} + location = attrMap.get(attrName) || 0; + + const locInstStr = locHolder[0].replace(locHolder[1], `${location}`); + code = code.replace(locHolder[0], locInstStr); + } } + locHolder = locHolderReg.exec(source); + } + return code; +} + +// eslint-disable-next-line max-len +export function flattenShaderLocation ( + source: string, + tmpl: IProgramInfo, + macroInfo: IMacroInfo[], + shaderStage, + attrMap: Map, +) { + let code = source; + if (shaderStage === 'vert') { + const locSet = new Set(); + code = findDefineIndependent(source, tmpl, attrMap, locSet); + code = replaceVertexMutableLocation(code, tmpl, macroInfo, 'in', attrMap, locSet); + + code = replaceVertexMutableLocation(code, tmpl, macroInfo, 'out', attrMap); + } else if (shaderStage === 'frag') { + code = replaceFragmentLocation(code, 'in', attrMap); + } else { + // error } - return true; + + return code; } -function getActiveAttributes (tmpl: IProgramInfo, tmplInfo: ITemplateInfo, defines: MacroRecord) { - const out: Attribute[] = []; - const attributes = tmpl.attributes; - const gfxAttributes = tmplInfo.gfxAttributes; - for (let i = 0; i < attributes.length; i++) { - if (!dependencyCheck(attributes[i].defines, defines)) { continue; } - out.push(gfxAttributes[i]); + +function processShaderInfo ( + tmpl: IProgramInfo, + macroInfo: IMacroInfo[], + shaderInfo, +) { + // during configuring vertex state when make a pipelinestate + // webgpu request max location of vertex attribute should not be greater than 15 + // shader source comes from offline effect-compiler can't have sense what macro is activate + // so here we flatten attribute location in runtime + const attrMap = new Map(); + + shaderInfo.stages[0].source = flattenShaderLocation(shaderInfo.stages[0].source, tmpl, macroInfo, 'vert', attrMap); + shaderInfo.stages[1].source = flattenShaderLocation(shaderInfo.stages[1].source, tmpl, macroInfo, 'frag', attrMap); + // don't forget to change location 'shaderInfo.attributes' which comes from serialization + // to keep consistency with shader source + for (let i = 0; i < shaderInfo.attributes.length; ++i) { + const name = shaderInfo.attributes[i].name; + let loc = 0; + if (attrMap.has(name)) { + loc = attrMap.get(name)!; + shaderInfo.attributes[i].location = loc; + } } - return out; } /** @@ -213,30 +345,10 @@ class ProgramLib { const curTmpl = this._templates[shader.name]; if (curTmpl && curTmpl.hash === shader.hash) { return curTmpl; } const tmpl = ({ ...shader }) as IProgramInfo; - // calculate option mask offset - let offset = 0; - for (let i = 0; i < tmpl.defines.length; i++) { - const def = tmpl.defines[i]; - let cnt = 1; - if (def.type === 'number') { - const range = def.range!; - cnt = getBitCount(range[1] - range[0] + 1); // inclusive on both ends - def._map = (value: number) => value - range[0]; - } else if (def.type === 'string') { - cnt = getBitCount(def.options!.length); - def._map = (value: any) => Math.max(0, def.options!.findIndex((s) => s === value)); - } else if (def.type === 'boolean') { - def._map = (value: any) => (value ? 1 : 0); - } - def._offset = offset; - offset += cnt; - } - if (offset > 31) { tmpl.uber = true; } - // generate constant macros - tmpl.constantMacros = ''; - for (const key in tmpl.builtins.statistics) { - tmpl.constantMacros += `#define ${key} ${tmpl.builtins.statistics[key]}\n`; - } + + // update defines and constant macros + populateMacros(tmpl); + // store it this._templates[shader.name] = tmpl; if (!this._templateInfos[tmpl.hash]) { @@ -247,7 +359,7 @@ class ProgramLib { tmplInfo.blockSizes = []; tmplInfo.bindings = []; for (let i = 0; i < tmpl.blocks.length; i++) { const block = tmpl.blocks[i]; - tmplInfo.blockSizes.push(getSize(block)); + tmplInfo.blockSizes.push(getSize(block.members)); tmplInfo.bindings.push(new DescriptorSetLayoutBinding(block.binding, DescriptorType.UNIFORM_BUFFER, 1, block.stageFlags)); tmplInfo.shaderInfo.blocks.push(new UniformBlock(SetIndex.MATERIAL, block.binding, block.name, @@ -374,33 +486,7 @@ class ProgramLib { */ public getKey (name: string, defines: MacroRecord) { const tmpl = this._templates[name]; - const tmplDefs = tmpl.defines; - if (tmpl.uber) { - let key = ''; - for (let i = 0; i < tmplDefs.length; i++) { - const tmplDef = tmplDefs[i]; - const value = defines[tmplDef.name]; - if (!value || !tmplDef._map) { - continue; - } - const mapped = tmplDef._map(value); - const offset = tmplDef._offset; - key += `${offset}${mapped}|`; - } - return `${key}${tmpl.hash}`; - } - let key = 0; - for (let i = 0; i < tmplDefs.length; i++) { - const tmplDef = tmplDefs[i]; - const value = defines[tmplDef.name]; - if (!value || !tmplDef._map) { - continue; - } - const mapped = tmplDef._map(value); - const offset = tmplDef._offset; - key |= mapped << offset; - } - return `${key.toString(16)}|${tmpl.hash}`; + return getVariantKey(tmpl, defines); } /** @@ -463,10 +549,19 @@ class ProgramLib { tmplInfo.shaderInfo.stages[1].source = prefix + src.frag; // strip out the active attributes only, instancing depend on this - tmplInfo.shaderInfo.attributes = getActiveAttributes(tmpl, tmplInfo, defines); + tmplInfo.shaderInfo.attributes = getActiveAttributes(tmpl, tmplInfo.gfxAttributes, defines); tmplInfo.shaderInfo.name = getShaderInstanceName(name, macroArray); - return this._cache[key] = device.createShader(tmplInfo.shaderInfo); + + let shaderInfo = tmplInfo.shaderInfo; + if (env.WEBGPU) { + // keep 'tmplInfo.shaderInfo' originally + shaderInfo = new ShaderInfo(); + shaderInfo.copy(tmplInfo.shaderInfo); + processShaderInfo(tmpl, macroArray, shaderInfo); + } + + return this._cache[key] = device.createShader(shaderInfo); } } @@ -481,4 +576,4 @@ export function getDeviceShaderVersion (device: Device) { } export const programLib = new ProgramLib(); -legacyCC.programLib = programLib; +cclegacy.programLib = programLib; diff --git a/cocos/render-scene/core/program-utils.ts b/cocos/render-scene/core/program-utils.ts new file mode 100644 index 00000000000..00c16bdc7a7 --- /dev/null +++ b/cocos/render-scene/core/program-utils.ts @@ -0,0 +1,217 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + +import { EffectAsset } from '../../asset/assets/effect-asset'; +import { Attribute, GetTypeSize, ShaderInfo, Uniform } from '../../gfx/base/define'; +import { UBOForwardLight, UBOSkinning } from '../../rendering/define'; +import { genHandle, MacroRecord } from './pass-utils'; +import { IProgramInfo } from './program-lib'; + +export interface IMacroInfo { + name: string; + value: string; + isDefault: boolean; +} + +function mapDefine (info: EffectAsset.IDefineInfo, def: number | string | boolean) { + switch (info.type) { + case 'boolean': return typeof def === 'number' ? def.toString() : (def ? '1' : '0'); + case 'string': return def !== undefined ? def as string : info.options![0]; + case 'number': return def !== undefined ? def.toString() : info.range![0].toString(); + default: + console.warn(`unknown define type '${info.type}'`); + return '-1'; // should neven happen + } +} + +export function prepareDefines (defs: MacroRecord, tDefs: EffectAsset.IDefineInfo[]) { + const macros: IMacroInfo[] = []; + for (let i = 0; i < tDefs.length; i++) { + const tmpl = tDefs[i]; + const name = tmpl.name; + const v = defs[name]; + const value = mapDefine(tmpl, v); + const isDefault = !v || v === '0'; + macros.push({ name, value, isDefault }); + } + return macros; +} + +export function getShaderInstanceName (name: string, macros: IMacroInfo[]) { + return name + macros.reduce((acc, cur) => (cur.isDefault ? acc : `${acc}|${cur.name}${cur.value}`), ''); +} + +function dependencyCheck (dependencies: string[], defines: MacroRecord) { + for (let i = 0; i < dependencies.length; i++) { + const d = dependencies[i]; + if (d[0] === '!') { // negative dependency + if (defines[d.slice(1)]) { return false; } + } else if (!defines[d]) { + return false; + } + } + return true; +} + +export function getActiveAttributes (tmpl: IProgramInfo, gfxAttributes: Attribute[], defines: MacroRecord) { + const out: Attribute[] = []; + const attributes = tmpl.attributes; + for (let i = 0; i < attributes.length; i++) { + if (!dependencyCheck(attributes[i].defines, defines)) { continue; } + out.push(gfxAttributes[i]); + } + return out; +} + +export function getVariantKey (programInfo: IProgramInfo, defines: MacroRecord) { + const tmplDefs = programInfo.defines; + if (programInfo.uber) { + let key = ''; + for (let i = 0; i < tmplDefs.length; i++) { + const tmplDef = tmplDefs[i]; + const value = defines[tmplDef.name]; + if (!value || !tmplDef._map) { + continue; + } + const mapped = tmplDef._map(value); + const offset = tmplDef._offset; + key += `${offset}${mapped}|`; + } + return `${key}${programInfo.hash}`; + } + let key = 0; + for (let i = 0; i < tmplDefs.length; i++) { + const tmplDef = tmplDefs[i]; + const value = defines[tmplDef.name]; + if (!value || !tmplDef._map) { + continue; + } + const mapped = tmplDef._map(value); + const offset = tmplDef._offset; + key |= mapped << offset; + } + return `${key.toString(16)}|${programInfo.hash}`; +} + +const defaultUniformCounts = new Map(); +defaultUniformCounts.set('cc_joints', UBOSkinning.LAYOUT.members[0].count); +defaultUniformCounts.set('cc_lightPos', UBOForwardLight.LIGHTS_PER_PASS); +defaultUniformCounts.set('cc_lightColor', UBOForwardLight.LIGHTS_PER_PASS); +defaultUniformCounts.set('cc_lightSizeRangeAngle', UBOForwardLight.LIGHTS_PER_PASS); +defaultUniformCounts.set('cc_lightDir', UBOForwardLight.LIGHTS_PER_PASS); + +function getUniformSize (prevSize: number, m: Uniform) { + if (m.count) { + return prevSize + GetTypeSize(m.type) * m.count; + } else { + const count = defaultUniformCounts.get(m.name); + if (count !== undefined) { + return prevSize + GetTypeSize(m.type) * count; + } + console.error(`uniform '${m.name}' must have a count`); + } + return prevSize; +} + +export function getSize (blockMembers: Uniform[]) { + return blockMembers.reduce(getUniformSize, 0); +} + +export function genHandles (tmpl: EffectAsset.IShaderInfo | ShaderInfo) { + const handleMap: Record = {}; + // block member handles + for (let i = 0; i < tmpl.blocks.length; i++) { + const block = tmpl.blocks[i]; + const members = block.members; + let offset = 0; + for (let j = 0; j < members.length; j++) { + const uniform = members[j]; + handleMap[uniform.name] = genHandle(block.binding, uniform.type, uniform.count, offset); + offset += (GetTypeSize(uniform.type) >> 2) * uniform.count; // assumes no implicit padding, which is guaranteed by effect compiler + } + } + // samplerTexture handles + for (let i = 0; i < tmpl.samplerTextures.length; i++) { + const samplerTexture = tmpl.samplerTextures[i]; + handleMap[samplerTexture.name] = genHandle(samplerTexture.binding, samplerTexture.type, samplerTexture.count); + } + return handleMap; +} + +function getBitCount (cnt: number) { + return Math.ceil(Math.log2(Math.max(cnt, 2))); +} + +export function populateMacros (tmpl: IProgramInfo) { + // calculate option mask offset + let offset = 0; + for (let i = 0; i < tmpl.defines.length; i++) { + const def = tmpl.defines[i]; + let cnt = 1; + if (def.type === 'number') { + const range = def.range!; + cnt = getBitCount(range[1] - range[0] + 1); // inclusive on both ends + def._map = (value: number) => value - range[0]; + } else if (def.type === 'string') { + cnt = getBitCount(def.options!.length); + def._map = (value: any) => Math.max(0, def.options!.findIndex((s) => s === value)); + } else if (def.type === 'boolean') { + def._map = (value: any) => (value ? 1 : 0); + } + def._offset = offset; + offset += cnt; + } + if (offset > 31) { tmpl.uber = true; } + // generate constant macros + tmpl.constantMacros = ''; + for (const key in tmpl.builtins.statistics) { + tmpl.constantMacros += `#define ${key} ${tmpl.builtins.statistics[key]}\n`; + } +} + +export function getCombinationDefines (combination: EffectAsset.IPreCompileInfo) { + const defines = Object.keys(combination).reduce((out, name) => out.reduce((acc, cur) => { + const choices = combination[name]; + for (let i = 0; i < choices.length; ++i) { + const defines = { ...cur }; + defines[name] = choices[i]; + acc.push(defines); + } + return acc; + }, [] as MacroRecord[]), [{}] as MacroRecord[]); + return defines; +} + +export function addEffectDefaultProperties (effect: EffectAsset) { + for (let i = 0; i < effect.techniques.length; i++) { + const tech = effect.techniques[i]; + for (let j = 0; j < tech.passes.length; j++) { + const pass = tech.passes[j]; + // grab default property declaration if there is none + if (pass.propertyIndex !== undefined && pass.properties === undefined) { + pass.properties = tech.passes[pass.propertyIndex].properties; + } + } + } +} diff --git a/cocos/render-scene/core/render-scene.jsb.ts b/cocos/render-scene/core/render-scene.jsb.ts index f8e88da359c..78d99ea2b76 100644 --- a/cocos/render-scene/core/render-scene.jsb.ts +++ b/cocos/render-scene/core/render-scene.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Node } from '../../core/scene-graph'; +import { Node } from '../../scene-graph'; export interface IRenderSceneInfo { name: string; diff --git a/cocos/render-scene/core/render-scene.ts b/cocos/render-scene/core/render-scene.ts index a4b68f0689d..9fb3ec782b4 100644 --- a/cocos/render-scene/core/render-scene.ts +++ b/cocos/render-scene/core/render-scene.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Root } from '../../root'; import { Node } from '../../scene-graph'; import { Camera } from '../scene/camera'; @@ -29,8 +28,11 @@ import { DirectionalLight } from '../scene/directional-light'; import { Model } from '../scene/model'; import { SphereLight } from '../scene/sphere-light'; import { SpotLight } from '../scene/spot-light'; +import { PointLight } from '../scene/point-light'; +import { RangedDirectionalLight } from '../scene/ranged-directional-light'; import { TransformBit } from '../../scene-graph/node-enum'; import { DrawBatch2D } from '../../2d/renderer/draw-batch'; +import { LODGroup } from '../scene/lod-group'; export interface IRenderSceneInfo { name: string; @@ -64,79 +66,106 @@ export interface IRaycastResult { */ export class RenderScene { /** - * @en The root manager of the renderer - * @zh 基础渲染管理器 + * @en The root manager of the renderer. + * @zh 基础渲染管理器。 */ get root (): Root { return this._root; } /** - * @en The name of the render scene - * @zh 渲染场景的名称 + * @en The name of the render scene. + * @zh 渲染场景的名称。 */ get name (): string { return this._name; } /** - * @en All cameras of the render scene - * @zh 渲染场景管理的所有相机 + * @en All cameras of the render scene. + * @zh 渲染场景管理的所有相机。 */ get cameras (): Camera[] { return this._cameras; } /** - * @en The main directional light source of the render scene - * @zh 渲染场景管理的主方向光源 + * @en The main directional light source of the render scene. + * @zh 渲染场景管理的主方向光源。 */ get mainLight (): DirectionalLight | null { return this._mainLight; } /** - * @en All sphere light sources of the render scene - * @zh 渲染场景管理的所有球面光源 + * @en All sphere light sources of the render scene. + * @zh 渲染场景管理的所有球面光源。 */ - get sphereLights (): SphereLight[] { + get sphereLights (): Readonly { return this._sphereLights; } /** - * @en All spot light sources of the render scene - * @zh 渲染场景管理的所有聚光灯光源 + * @en All spot light sources of the render scene. + * @zh 渲染场景管理的所有聚光灯光源。 */ - get spotLights (): SpotLight[] { + get spotLights (): Readonly { return this._spotLights; } /** - * @en All active models of the render scene - * @zh 渲染场景管理的所有模型 + * @en All point light sources of the render scene. + * @zh 渲染场景管理的所有点光源。 + */ + get pointLights (): Readonly { + return this._pointLights; + } + + /** + * @en All ranged directional light sources of the render scene. + * @zh 渲染场景管理的所有范围平行光光源。 + */ + get rangedDirLights (): Readonly { + return this._rangedDirLights; + } + + /** + * @en All active models of the render scene. + * @zh 渲染场景管理的所有模型。 */ get models (): Model[] { return this._models; } /** - * @en All active 2d draw batches of the render scene - * @zh 渲染场景管理的所有 2D 渲染批次对象 + * @en All active 2d draw batches of the render scene. + * @zh 渲染场景管理的所有 2D 渲染批次对象。 */ get batches () { return this._batches; } + /** + * @engineInternal + * @en All LOD groups of the render scene. + * @zh 渲染场景管理的所有 LOD 组。 + */ + get lodGroups (): readonly LODGroup[] { return this._lodGroups; } + private _root: Root; private _name = ''; private _cameras: Camera[] = []; private _models: Model[] = []; + private _lodGroups: LODGroup[] = []; // LOD Group gathered private _batches: DrawBatch2D[] = []; private _directionalLights: DirectionalLight[] = []; private _sphereLights: SphereLight[] = []; private _spotLights: SpotLight[] = []; + private _pointLights: PointLight[] = []; + private _rangedDirLights: RangedDirectionalLight[] = []; private _mainLight: DirectionalLight | null = null; private _modelId = 0; + private _lodStateCache: LodStateCache = null!; /** * Register the creation function of the render scene to root. @@ -157,6 +186,7 @@ export class RenderScene { */ public initialize (info: IRenderSceneInfo): boolean { this._name = info.name; + this._lodStateCache = new LodStateCache(this); return true; } @@ -184,6 +214,18 @@ export class RenderScene { light.update(); } + const pointLights = this._pointLights; + for (let i = 0; i < pointLights.length; i++) { + const light = pointLights[i]; + light.update(); + } + + const rangedDirLights = this._rangedDirLights; + for (let i = 0; i < rangedDirLights.length; i++) { + const light = rangedDirLights[i]; + light.update(); + } + const models = this._models; for (let i = 0; i < models.length; i++) { const model = models[i]; @@ -193,6 +235,7 @@ export class RenderScene { model.updateUBOs(stamp); } } + this._lodStateCache.updateLodState(); } /** @@ -203,7 +246,14 @@ export class RenderScene { this.removeCameras(); this.removeSphereLights(); this.removeSpotLights(); + this.removeRangedDirLights(); this.removeModels(); + this.removeLODGroups(); + this._lodStateCache.clearCache(); + } + + public isCulledByLod (camera: Camera, model: Model) { + return this._lodStateCache.isLodModelCulled(camera, model); } /** @@ -213,6 +263,7 @@ export class RenderScene { public addCamera (cam: Camera) { cam.attachToScene(this); this._cameras.push(cam); + this._lodStateCache.addCamera(cam); } /** @@ -224,6 +275,7 @@ export class RenderScene { if (this._cameras[i] === camera) { this._cameras.splice(i, 1); camera.detachFromScene(); + this._lodStateCache.removeCamera(camera); return; } } @@ -236,6 +288,7 @@ export class RenderScene { public removeCameras () { for (const camera of this._cameras) { camera.detachFromScene(); + this._lodStateCache.removeCamera(camera); } this._cameras.splice(0); } @@ -364,7 +417,79 @@ export class RenderScene { for (let i = 0; i < this._spotLights.length; ++i) { this._spotLights[i].detachFromScene(); } - this._spotLights = []; + this._spotLights.length = 0; + } + + /** + * @en Add a point light source. + * @zh 增加一个点光源。 + * @param pl @en The point light. @zh 点光源。 + */ + public addPointLight (pl: PointLight) { + pl.attachToScene(this); + this._pointLights.push(pl); + } + + /** + * @en Remove a sphere light source. + * @zh 删除一个点光源。 + * @param pl @en The point light. @zh 点光源。 + */ + public removePointLight (pl: PointLight) { + for (let i = 0; i < this._pointLights.length; ++i) { + if (this._pointLights[i] === pl) { + pl.detachFromScene(); + this._pointLights.splice(i, 1); + return; + } + } + } + + /** + * @en Remove all point light sources. + * @zh 删除所有点光源。 + */ + public removePointLights () { + for (let i = 0; i < this._pointLights.length; ++i) { + this._pointLights[i].detachFromScene(); + } + this._pointLights.length = 0; + } + + /** + * @en Add a ranged directional light source. + * @zh 增加一个范围平行光源。 + * @param l @en The ranged directional light. @zh 范围平行光。 + */ + public addRangedDirLight (l: RangedDirectionalLight) { + l.attachToScene(this); + this._rangedDirLights.push(l); + } + + /** + * @en Remove a ranged directional light source. + * @zh 删除一个范围平行光源。 + * @param l @en The ranged directional light. @zh 范围平行光。 + */ + public removeRangedDirLight (l: RangedDirectionalLight) { + for (let i = 0; i < this._rangedDirLights.length; ++i) { + if (this._rangedDirLights[i] === l) { + l.detachFromScene(); + this._rangedDirLights.splice(i, 1); + return; + } + } + } + + /** + * @en Remove all ranged directional light sources. + * @zh 删除所有范围平行光源。 + */ + public removeRangedDirLights () { + for (let i = 0; i < this._rangedDirLights.length; ++i) { + this._rangedDirLights[i].detachFromScene(); + } + this._rangedDirLights.length = 0; } /** @@ -385,6 +510,7 @@ export class RenderScene { public removeModel (model: Model) { for (let i = 0; i < this._models.length; ++i) { if (this._models[i] === model) { + this._lodStateCache.removeModel(model); model.detachFromScene(); this._models.splice(i, 1); @@ -399,6 +525,7 @@ export class RenderScene { */ public removeModels () { for (const m of this._models) { + this._lodStateCache.removeModel(m); m.detachFromScene(); m.destroy(); } @@ -442,6 +569,45 @@ export class RenderScene { this._batches.length = 0; } + /** + * @engineInternal + * @en Add a LOD group, all LOD groups attached to the render scene will be submitted for rendering. + * @zh 增加一个LOD 组,渲染场景上挂载的所有LOD 组都会被提交渲染。 + * @param lodGroup the LOD group + */ + addLODGroup (lodGroup: LODGroup) { + this._lodGroups.push(lodGroup); + lodGroup.attachToScene(this); + this._lodStateCache.addLodGroup(lodGroup); + } + + /** + * @engineInternal + * @en Remove a LOD group, the LOD group removed will no longer be submitted for rendering. + * @zh 删除一个LOD 组,移除的LOD 组将不再被提交渲染。 + * @param lodGroup the LOD group + */ + removeLODGroup (lodGroup: LODGroup) { + const index = this._lodGroups.indexOf(lodGroup); + if (index >= 0) { + this._lodGroups.splice(index, 1); + lodGroup.detachFromScene(); + this._lodStateCache.removeLodGroup(lodGroup); + } + } + + /** + * @engineInternal + * @en Remove all LOD groups. + * @zh 删除所有LOD 组。 + */ + removeLODGroups () { + for (const group of this._lodGroups) { + this._lodStateCache.removeLodGroup(group); + } + this._lodGroups.length = 0; + } + /** * @en Notify all models that the global pipeline state have been updated so that they can update their render data and states. * @zh 通知所有模型全局管线状态已更新,需要更新自身状态。 @@ -461,3 +627,285 @@ export class RenderScene { return this._modelId++; } } + +class LODInfo { + /** + * @zh 当前使用哪一级的 LOD, -1 表示没有层级被使用 + * @en Which level of LOD is currently in use, -1 means no levels are used + */ + usedLevel = -1; + lastUsedLevel = -1; + transformDirty = true; +} + +/** + * @zh 管理LODGroup的使用状态,包含使用层级及其上的model可见相机列表;便于判断当前model是否被LODGroup裁剪 + * @en Manage the usage status of LODGroup, including the usage level and the list of visible cameras on its models; + * easy to determine whether the current mod is cropped by LODGroup。 + */ +class LodStateCache { + constructor (scene: RenderScene) { + this._renderScene = scene; + } + + addCamera (camera: Camera) { + const needRegisterChanged = false; + for (const lodGroup of this._renderScene.lodGroups) { + const layer = lodGroup.node.layer; + if ((camera.visibility & layer) === layer) { + if (!this._lodStateInCamera.has(camera)) { + this._lodStateInCamera.set(camera, new Map()); + } + break; + } + } + } + + removeCamera (camera: Camera) { + if (this._lodStateInCamera.has(camera)) { + this._lodStateInCamera.delete(camera); + } + } + + addLodGroup (lodGroup: LODGroup) { + this._newAddedLodGroupVec.push(lodGroup); + + for (const camera of this._renderScene.cameras) { + if (this._lodStateInCamera.has(camera)) { + continue; + } + const layer = lodGroup.node.layer; + if ((camera.visibility & layer) === layer) { + this._lodStateInCamera.set(camera, new Map()); + } + } + } + + removeLodGroup (lodGroup: LODGroup) { + for (let index = 0; index < lodGroup.lodCount; index++) { + const lod = lodGroup.lodDataArray[index]; + for (const model of lod.models) { + this._modelsInLODGroup.delete(model); + } + } + for (const visibleCamera of this._lodStateInCamera) { + visibleCamera[1].delete(lodGroup); + } + this._levelModels.delete(lodGroup); + } + + removeModel (model: Model) { + if (this._modelsInLODGroup.has(model)) { + this._modelsInLODGroup.delete(model); + } + } + + // Update list of visible cameras on _modelsInLODGroup and update lod usage level under specified camera. + updateLodState () { + // insert vecAddedLodGroup's model into modelsByAnyLODGroup + for (const addedLodGroup of this._newAddedLodGroupVec) { + let levelModels = this._levelModels.get(addedLodGroup); + if (!levelModels) { + levelModels = new Map>(); + this._levelModels.set(addedLodGroup, levelModels); + } + for (let index = 0; index < addedLodGroup.lodCount; index++) { + let lodModels = levelModels.get(index); + if (!lodModels) { + lodModels = new Array(); + } + const lod = addedLodGroup.lodDataArray[index]; + for (const model of lod.models) { + let modelInfo = this._modelsInLODGroup.get(model); + if (!modelInfo) { + modelInfo = new Map(); + } + this._modelsInLODGroup.set(model, modelInfo); + lodModels.push(model); + } + levelModels.set(index, lodModels); + } + } + this._newAddedLodGroupVec.length = 0; + + // update current visible lod index & model's visible cameras list + for (const lodGroup of this._renderScene.lodGroups) { + if (lodGroup.enabled) { + const lodLevels = lodGroup.getLockedLODLevels(); + const count = lodLevels.length; + // count > 0, indicating that the user force to use certain layers of + // lod + if (count > 0) { + // Update the dirty flag to make it easier to update the visible + // index of lod after lifting the forced use of lod. + if (lodGroup.node.hasChangedFlags > 0) { + for (const visibleCamera of this._lodStateInCamera) { + let lodInfo = visibleCamera[1].get(lodGroup); + if (!lodInfo) { + lodInfo = new LODInfo(); + visibleCamera[1].set(lodGroup, lodInfo); + } + lodInfo.transformDirty = true; + } + } + // Update the visible camera list of all models on lodGroup when the + // visible level changes. + if (lodGroup.isLockLevelChanged()) { + lodGroup.resetLockChangeFlag(); + + const lodModels = this._levelModels.get(lodGroup); + if (lodModels) { + lodModels.forEach((vecArray, index) => { + vecArray.forEach((model) => { + const modelInfo = this._modelsInLODGroup.get(model); + if (modelInfo) { + modelInfo.clear(); + } + }); + }); + + for (const visibleIndex of lodLevels) { + const vecModels = lodModels.get(visibleIndex); + if (vecModels) { + vecModels.forEach((model) => { + const modelInfo = this._modelsInLODGroup.get(model); + if (modelInfo && model.node && model.node.active) { + for (const visibleCamera of this._lodStateInCamera) { + modelInfo.set(visibleCamera[0], true); + } + } + }); + } + } + } + } + continue; + } + + // Normal Process, no LOD is forced. + let hasUpdated = false; + for (const visibleCamera of this._lodStateInCamera) { + let lodInfo = visibleCamera[1].get(lodGroup); + if (!lodInfo) { + lodInfo = new LODInfo(); + visibleCamera[1].set(lodGroup, lodInfo); + } + const cameraChangeFlags = visibleCamera[0].node.hasChangedFlags; + const lodChangeFlags = lodGroup.node.hasChangedFlags; + // Changes in the camera matrix or changes in the matrix of the node + // where lodGroup is located or the transformDirty marker is true, + // etc. All need to recalculate the visible level of LOD. + if (cameraChangeFlags > 0 || lodChangeFlags > 0 || lodInfo.transformDirty) { + if (lodInfo.transformDirty) { + lodInfo.transformDirty = false; + } + const index = lodGroup.getVisibleLODLevel(visibleCamera[0]); + if (index !== lodInfo.usedLevel) { + lodInfo.lastUsedLevel = lodInfo.usedLevel; + lodInfo.usedLevel = index; + hasUpdated = true; + } + } + } + + const lodModels = this._levelModels.get(lodGroup); + if (!lodModels) { + continue; + } + + // The LOD of the last frame is forced to be used, the list of visible + // cameras of modelInfo needs to be updated. + if (lodGroup.isLockLevelChanged()) { + lodGroup.resetLockChangeFlag(); + + lodModels.forEach((vecArray, index) => { + vecArray.forEach((model) => { + const modelInfo = this._modelsInLODGroup.get(model); + if (modelInfo) { + modelInfo.clear(); + } + }); + }); + hasUpdated = true; + } else if (hasUpdated) { + this._lodStateInCamera.forEach((lodState, camera) => { + const lodInfo = lodState.get(lodGroup); + if (lodInfo && lodInfo.usedLevel !== lodInfo.lastUsedLevel) { + const vecModels = lodModels.get(lodInfo.lastUsedLevel); + if (vecModels) { + vecModels.forEach((model) => { + const modelInfo = this._modelsInLODGroup.get(model); + if (modelInfo) { + modelInfo.clear(); + } + }); + } + } + }); + } + + if (hasUpdated) { + this._lodStateInCamera.forEach((lodState, camera) => { + const lodInfo = lodState.get(lodGroup); + if (lodInfo) { + const usedLevel = lodInfo.usedLevel; + const vecModels = lodModels.get(usedLevel); + if (vecModels) { + vecModels.forEach((model) => { + const modelInfo = this._modelsInLODGroup.get(model); + if (modelInfo && model.node && model.node.active) { + modelInfo.set(camera, true); + } + }); + } + } + }); + } + } + } + } + + isLodModelCulled (camera: Camera, model: Model) { + const modelInfo = this._modelsInLODGroup.get(model); + if (!modelInfo) { + return false; + } + + return !modelInfo.has(camera); + } + + clearCache () { + this._levelModels.clear(); + this._modelsInLODGroup.clear(); + this._lodStateInCamera.clear(); + this._newAddedLodGroupVec.length = 0; + } + + private isLodGroupVisibleByCamera (lodGroup: LODGroup, camera: Camera): boolean { + const layer = lodGroup.node.layer; + return (camera.visibility & layer) === layer; + } + + private _renderScene: RenderScene = null!; + + /** + * @zh LOD使用的model集合以及每个model当前能被看到的相机列表;包含每个LODGroup的每一级LOD + * @en The set of models used by the LOD and the list of cameras that each models can currently be seen, + * contains each level of LOD for each LODGroup. + */ + private _modelsInLODGroup: Map> = new Map>(); + + /** + * @zh 指定相机下,LODGroup使用哪一级的LOD + * @en Specify which level of LOD is used by the LODGroup under the camera. + */ + private _lodStateInCamera: Map> = new Map>(); + + /** + * @zh 上一帧添加的lodgroup + * @en The lodgroup added in the previous frame. + */ + private _newAddedLodGroupVec: Array = new Array(); + + private _levelModels: Map>> = new Map>>(); +} diff --git a/cocos/render-scene/core/render-window.jsb.ts b/cocos/render-scene/core/render-window.jsb.ts index d1944dbbb70..7280835d5d9 100644 --- a/cocos/render-scene/core/render-window.jsb.ts +++ b/cocos/render-scene/core/render-window.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export interface IRenderWindowInfo { title?: string; width: number; diff --git a/cocos/render-scene/core/render-window.ts b/cocos/render-scene/core/render-window.ts index 39f991f63cd..970b56f1565 100644 --- a/cocos/render-scene/core/render-window.ts +++ b/cocos/render-scene/core/render-window.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { screenAdapter } from 'pal/screen-adapter'; import { Orientation } from '../../../pal/screen-adapter/enum-type'; import { diff --git a/cocos/render-scene/core/sampler-lib.jsb.ts b/cocos/render-scene/core/sampler-lib.jsb.ts index eae04b7a207..1962e86e03b 100644 --- a/cocos/render-scene/core/sampler-lib.jsb.ts +++ b/cocos/render-scene/core/sampler-lib.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -import { legacyCC } from "../../core/global-exports"; +*/ +import { cclegacy } from "../../core"; const SamplerLib = nr.SamplerLib; export const samplerLib = new SamplerLib(); -legacyCC.samplerLib = samplerLib; +cclegacy.samplerLib = samplerLib; diff --git a/cocos/render-scene/core/texture-buffer-pool.ts b/cocos/render-scene/core/texture-buffer-pool.ts index e2ea29de815..ceb76399405 100644 --- a/cocos/render-scene/core/texture-buffer-pool.ts +++ b/cocos/render-scene/core/texture-buffer-pool.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { getTypedArrayConstructor, Format, FormatInfos, TextureType, TextureUsageBit, Texture, TextureInfo, Device, BufferTextureCopy } from '../../gfx'; -import { debug } from '../../core/platform/debug'; +import { debug } from '../../core'; export function nearestPOT (num: number): number { --num; diff --git a/cocos/render-scene/deprecated.ts b/cocos/render-scene/deprecated.ts index 151853f4fbe..6e40912ffdf 100644 --- a/cocos/render-scene/deprecated.ts +++ b/cocos/render-scene/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { replaceProperty, removeProperty } from '../core/utils/x-deprecated'; +import { replaceProperty, removeProperty } from '../core'; import { RenderScene } from './core/render-scene'; import { Layers } from '../scene-graph/layers'; import { legacyCC } from '../core/global-exports'; diff --git a/cocos/render-scene/index.ts b/cocos/render-scene/index.ts index 90494f7070f..a290c4c846c 100644 --- a/cocos/render-scene/index.ts +++ b/cocos/render-scene/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import config from './config'; diff --git a/cocos/render-scene/scene/ambient.ts b/cocos/render-scene/scene/ambient.ts index 2b3a212dc6a..389c056218b 100644 --- a/cocos/render-scene/scene/ambient.ts +++ b/cocos/render-scene/scene/ambient.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec4 } from '../../core/math'; -import { legacyCC } from '../../core/global-exports'; +import { Vec4, cclegacy } from '../../core'; import { AmbientInfo } from '../../scene-graph/scene-globals'; /** @@ -60,7 +58,7 @@ export class Ambient { * @zh 天空颜色 */ get skyColor (): Vec4 { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._skyColorHDR; } else { @@ -68,7 +66,7 @@ export class Ambient { } } set skyColor (color: Vec4) { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._skyColorHDR.set(color); } else { @@ -81,7 +79,7 @@ export class Ambient { * @zh 天空亮度 */ get skyIllum (): number { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._skyIllumHDR; } else { @@ -89,7 +87,7 @@ export class Ambient { } } set skyIllum (illum: number) { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._skyIllumHDR = illum; } else { @@ -101,7 +99,7 @@ export class Ambient { * @zh 地面颜色 */ get groundAlbedo (): Vec4 { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._groundAlbedoHDR; } else { @@ -109,7 +107,7 @@ export class Ambient { } } set groundAlbedo (color: Vec4) { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._groundAlbedoHDR.set(color); } else { @@ -141,4 +139,4 @@ export class Ambient { } } -legacyCC.Ambient = Ambient; +cclegacy.Ambient = Ambient; diff --git a/cocos/render-scene/scene/camera.jsb.ts b/cocos/render-scene/scene/camera.jsb.ts index 636f80871f7..1b20aec76bd 100644 --- a/cocos/render-scene/scene/camera.jsb.ts +++ b/cocos/render-scene/scene/camera.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -import { Ray } from '../../core/geometry'; +*/ +import { geometry } from '../../core'; import { RenderWindow } from '../core/render-window'; import { ClearFlagBit } from '../../gfx'; import { _tempFloatArray, fillMat4WithTempFloatArray } from '../../scene-graph/utils.jsb'; -import { Mat4, Vec3 } from '../../core/math'; +import { Mat4, Vec3 } from '../../core'; + declare const jsb: any; @@ -213,7 +213,7 @@ const oldWorldMatrixToScreen = cameraProto.worldMatrixToScreen; /** * transform a screen position (in oriented space) to a world space ray */ -cameraProto.screenPointToRay = function screenPointToRay (out: Ray, x: number, y: number): Ray { +cameraProto.screenPointToRay = function screenPointToRay (out: geometry.Ray, x: number, y: number): geometry.Ray { _tempFloatArray[0] = x; _tempFloatArray[1] = y; oldScreenPointToRay.call(this); diff --git a/cocos/render-scene/scene/camera.ts b/cocos/render-scene/scene/camera.ts index 8b8792661aa..c5305b3e906 100644 --- a/cocos/render-scene/scene/camera.ts +++ b/cocos/render-scene/scene/camera.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,56 +20,155 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; -import { Frustum, Ray } from '../../core/geometry'; import { SurfaceTransform, ClearFlagBit, Device, Color, ClearFlags } from '../../gfx'; -import { lerp, Mat4, Rect, toRadian, Vec3, IVec4Like } from '../../core/math'; +import { lerp, Mat4, Rect, toRadian, Vec3, IVec4Like, preTransforms, warnID, geometry, cclegacy, Vec4 } from '../../core'; import { CAMERA_DEFAULT_MASK } from '../../rendering/define'; import { Node } from '../../scene-graph'; import { RenderScene } from '../core/render-scene'; -import { legacyCC } from '../../core/global-exports'; import { RenderWindow } from '../core/render-window'; -import { preTransforms } from '../../core/math/mat4'; -import { warnID } from '../../core/platform/debug'; import { GeometryRenderer } from '../../rendering/geometry-renderer'; +/** + * @en The enumeration type for the fixed axis of the camera. + * The field of view along the corresponding axis would be fixed regardless of screen aspect changes. + * @zh 相机视角的锁定轴向枚举,在对应轴上不会跟随屏幕长宽比例变化。 + */ export enum CameraFOVAxis { + /** + * @en Vertically fixed camera + * @zh 在垂直轴向上锁定的相机 + */ VERTICAL, + /** + * @en Horizontally fixed camera + * @zh 在水平轴向上锁定的相机 + */ HORIZONTAL, } +/** + * @en The projection type enumeration of the camera. + * @zh 相机的投影类型枚举。 + */ export enum CameraProjection { + /** + * @en Orthogonal projection type + * @zh 正交投影类型 + */ ORTHO, + /** + * @en Perspective projection type + * @zh 透视投影类型 + */ PERSPECTIVE, } +/** + * @en The aperture enumeration of the camera, represent in f-number. + * The smaller the value is, the bigger the aperture is, and more light it can capture, but less depth it supports. + * @zh 相机的快门枚举,使用 f 值来表示。f 值越小,光圈就越大,进光量也越大,景深越浅。 + */ export enum CameraAperture { + /** + * f/1.8 + */ F1_8, + /** + * f/2.0 + */ F2_0, + /** + * f/2.2 + */ F2_2, + /** + * f/2.5 + */ F2_5, + /** + * f/2.8 + */ F2_8, + /** + * f/3.2 + */ F3_2, + /** + * f/3.5 + */ F3_5, + /** + * f/4.0 + */ F4_0, + /** + * f/4.5 + */ F4_5, + /** + * f/5.0 + */ F5_0, + /** + * f/5.6 + */ F5_6, + /** + * f/6.3 + */ F6_3, + /** + * f/7.1 + */ F7_1, + /** + * f/8 + */ F8_0, + /** + * f/9 + */ F9_0, + /** + * f/10 + */ F10_0, + /** + * f/11 + */ F11_0, + /** + * f/13 + */ F13_0, + /** + * f/14 + */ F14_0, + /** + * f/16 + */ F16_0, + /** + * f/18 + */ F18_0, + /** + * f/20 + */ F20_0, + /** + * f/22 + */ F22_0, } +/** + * @en The ISO enumeration of the camera, lower ISO means the camera is less sensitive to light. + * @zh 相机感光度枚举,越低的 ISO 数值表示相机对光更加不敏感。 + */ export enum CameraISO { ISO100, ISO200, @@ -78,41 +176,151 @@ export enum CameraISO { ISO800, } +/** + * @en Camera shutter enumeration, the value represents the speed of the shutter. + * @zh 相机快门枚举,枚举值表示快门速度。 + */ export enum CameraShutter { + /** + * 1 second + */ D1, + /** + * 1/2 second + */ D2, + /** + * 1/4 second + */ D4, + /** + * 1/8 second + */ D8, + /** + * 1/15 second + */ D15, + /** + * 1/30 second + */ D30, + /** + * 1/60 second + */ D60, + /** + * 1/125 second + */ D125, + /** + * 1/250 second + */ D250, + /** + * 1/500 second + */ D500, + /** + * 1/1000 second + */ D1000, + /** + * 1/2000 second + */ D2000, + /** + * 1/4000 second + */ D4000, } +/** + * @en The type of the camera, mainly for marking different camera usage in XR, it determines the camera's viewport and parameters. + * @zh 相机类型,主要服务于标记 XR 中的不同相机用途,影响渲染的视口和对应的参数。 + */ export enum CameraType { + /** + * @en Default camera type + * @zh 默认相机类型 + */ DEFAULT = -1, + /** + * @en If a camera is set to be left eye, it will be used to render the left eye screen, + * otherwise, the left eye screen will be rendered using adjusted parameters based on XR main camera. + * @zh 如果设置了左眼相机,则在绘制左眼屏幕时使用,否则,就根据 XR 主相机的参数来计算左眼参数。 + */ LEFT_EYE = 0, + /** + * @en If a camera is set to be right eye, it will be used to render the right eye screen, + * otherwise, the right eye screen will be rendered using adjusted parameters based on XR main camera. + * @zh 如果设置了右眼相机,则在绘制右眼屏幕时使用,否则,就根据 XR 主相机的参数来计算左眼参数。 + */ RIGHT_EYE = 1, + /** + * @en The main camera, it could be used to calculate the parameters for both left eye and the right eye cameras. + * It could be converted from the default 3d camera. + * @zh XR 主相机,可以通过默认相机转换,也可以手动创建新的 XR 相机,可以计算出左右两个相机的相对参数。 + */ MAIN = 2, } +/** + * @en The spatial tracking signal type used by the camera in XR. + * @zh 相机使用的 XR 空间定位追踪信号类型。 + */ export enum TrackingType { + /** + * @en Camera without signal tracking in XR device. + * @zh 无追踪相机,不对 XR 设备的信号进行追踪。 + */ NO_TRACKING = 0, + /** + * @en Camera tracking position and rotation signals from XR device. + * @zh 相机追踪 XR 设备移动位置和旋转角度信号。 + */ POSITION_AND_ROTATION = 1, + /** + * @en Camera only tracking position signals from XR device. + * @zh 相机只追踪 XR 设备位置信号。 + */ POSITION = 2, + /** + * @en Camera only tracking rotation signals from XR device. + * @zh 相机只追踪 XR 设备旋转角度信号。 + */ ROTATION = 3, } +/** + * @en The usage of the camera, it's an engine internal marker enumeration. + * @zh 相机的用途枚举,这是引擎内部使用的标记枚举。 + */ export enum CameraUsage { + /** + * @en Camera used in editor + * @zh 编辑器下使用的相机 + */ EDITOR, + /** + * @en Camera used in editor's game view. + * @zh 编辑器 GameView 视图下使用的相机。 + */ GAME_VIEW, + /** + * @en Camera used in editor's scene view. + * @zh 编辑器场景编辑器视图下使用的相机。 + */ SCENE_VIEW, + /** + * @en Camera used in editor's camera preview window. + * @zh 编辑器预览小窗视图下使用的相机。 + */ PREVIEW, + /** + * @en Camera used in game, normally user created cameras are all GAME type. + * @zh 游戏视图下使用的相机,一般情况下用户创建的相机都是 GAME 类型。 + */ GAME = 100, } @@ -121,16 +329,58 @@ const SHUTTERS: number[] = [1.0, 1.0 / 2.0, 1.0 / 4.0, 1.0 / 8.0, 1.0 / 15.0, 1. 1.0 / 250.0, 1.0 / 500.0, 1.0 / 1000.0, 1.0 / 2000.0, 1.0 / 4000.0]; const ISOS: number[] = [100.0, 200.0, 400.0, 800.0]; +/** + * @en The camera creation information struct + * @zh 用来创建相机的结构体 + */ export interface ICameraInfo { + /** + * @en The name of the camera. + * @zh 相机命名。 + */ name: string; + /** + * @en The node which the camera is attached to. + * @zh 相机挂载的节点。 + */ node: Node; - projection: number; + /** + * @en The projection type of the camera. + * @zh 相机的投影类型。 + */ + projection: CameraProjection; + /** + * @en The id of the target display, if absent, it will be rendered on the default one. + * @zh 相机的目标屏幕,如果缺省,将会使用默认屏幕。 + */ targetDisplay?: number; + /** + * @en The target render window of the camera, is absent, the camera won't be rendered. + * @zh 相机的目标渲染窗口,如果缺省,该相机不会执行渲染流程。 + */ window?: RenderWindow | null; + /** + * @en Render priority of the camera. Cameras with higher depth are rendered after cameras with lower depth. + * @zh 相机的渲染优先级,值越小越优先渲染。 + */ priority: number; + /** + * @internal + */ pipeline?: string; + /** + * @en The type of the camera, mainly for marking different camera usage in XR, it determines the camera's viewport and parameters. + * @zh 相机类型,主要服务于标记 XR 中的不同相机用途,影响渲染的视口和对应的参数。 + */ cameraType?: CameraType; + /** + * @en The spatial tracking signal type used by the camera in XR. + * @zh 相机使用的 XR 空间定位追踪信号类型。 + */ trackingType?: TrackingType; + /** + * @internal + */ usage?: CameraUsage; } @@ -356,7 +606,7 @@ export class Camera { * @en Clearing flags of the camera, specifies which part of the framebuffer will be actually cleared every frame. * @zh 相机的缓冲清除标志位,指定帧缓冲的哪部分要每帧清除。 */ - get clearFlag () : ClearFlags { + get clearFlag (): ClearFlags { return this._clearFlag; } set clearFlag (flag: ClearFlags) { @@ -381,7 +631,7 @@ export class Camera { * @en Clearing depth of the camera. * @zh 相机的深度缓冲默认值。 */ - get clearDepth () : number { + get clearDepth (): number { return this._clearDepth; } set clearDepth (depth: number) { @@ -392,7 +642,7 @@ export class Camera { * @en Clearing stencil of the camera. * @zh 相机的模板缓冲默认值。 */ - get clearStencil () : number { + get clearStencil (): number { return this._clearStencil; } set clearStencil (stencil: number) { @@ -577,7 +827,7 @@ export class Camera { private _matProjInv: Mat4 = new Mat4(); private _matViewProj: Mat4 = new Mat4(); private _matViewProjInv: Mat4 = new Mat4(); - private _frustum: Frustum = new Frustum(); + private _frustum: geometry.Frustum = new geometry.Frustum(); private _forward: Vec3 = new Vec3(); private _position: Vec3 = new Vec3(); private _priority = 0; @@ -703,7 +953,6 @@ export class Camera { public resize (width: number, height: number): void { if (!this._window) return; - this._width = width; this._width = width; this._height = height; this._aspect = (width * this._viewport.width) / (height * this._viewport.height); @@ -845,7 +1094,7 @@ export class Camera { */ public initGeometryRenderer () { if (!this._geometryRenderer) { - this._geometryRenderer = legacyCC.internal.GeometryRenderer ? new legacyCC.internal.GeometryRenderer() : null; + this._geometryRenderer = cclegacy.internal.GeometryRenderer ? new cclegacy.internal.GeometryRenderer() : null; this._geometryRenderer?.activate(this._device); } } @@ -859,7 +1108,7 @@ export class Camera { return this._geometryRenderer; } - get cameraType () : CameraType { + get cameraType (): CameraType { return this._cameraType; } @@ -867,7 +1116,7 @@ export class Camera { this._cameraType = type; } - get trackingType () : TrackingType { + get trackingType (): TrackingType { return this._trackingType; } @@ -875,7 +1124,7 @@ export class Camera { this._trackingType = type; } - get cameraUsage () : CameraUsage { + get cameraUsage (): CameraUsage { return this._usage; } @@ -892,7 +1141,7 @@ export class Camera { if (this._window) { this._window.detachCamera(this); } - const win = window || legacyCC.director.root.mainWindow; + const win = window || cclegacy.director.root.mainWindow; if (win) { win.attachCamera(this); this.window = win; @@ -923,7 +1172,7 @@ export class Camera { * @param y the screen y of the position * @returns the resulting ray */ - public screenPointToRay (out: Ray, x: number, y: number): Ray { + public screenPointToRay (out: geometry.Ray, x: number, y: number): geometry.Ray { if (!this._node) return null!; const width = this.width; @@ -947,7 +1196,7 @@ export class Camera { if (isProj) { // camera origin this._node.getWorldPosition(v_b); - Ray.fromPoints(out, v_b, v_a); + geometry.Ray.fromPoints(out, v_b, v_a); } else { Vec3.transformQuat(out.d, Vec3.FORWARD, this._node.worldRotation); } @@ -1060,6 +1309,27 @@ export class Camera { return out; } + /** + * @en Calculate and set oblique view frustum projection matrix. + * @zh 计算并设置斜视锥体投影矩阵 + * @param clipPlane clip plane in camera space + */ + public calculateObliqueMat (viewSpacePlane: Vec4) { + const clipFar = new Vec4(Math.sign(viewSpacePlane.x), Math.sign(viewSpacePlane.y), 1.0, 1.0); + const viewFar = clipFar.transformMat4(this._matProjInv); + + const m4 = new Vec4(this._matProj.m03, this._matProj.m07, this._matProj.m11, this._matProj.m15); + const scale = 2.0 / Vec4.dot(viewSpacePlane, viewFar); + const newViewSpaceNearPlane = viewSpacePlane.multiplyScalar(scale); + + const m3 = newViewSpaceNearPlane.subtract(m4); + + this._matProj.m02 = m3.x; + this._matProj.m06 = m3.y; + this._matProj.m10 = m3.z; + this._matProj.m14 = m3.w; + } + /** * @en Set exposure with actual value. * @zh 设置相机的曝光值 @@ -1076,7 +1346,7 @@ export class Camera { private setDefaultUsage () { if (EDITOR) { - if (legacyCC.GAME_VIEW) { + if (cclegacy.GAME_VIEW) { this._usage = CameraUsage.GAME_VIEW; } else { this._usage = CameraUsage.EDITOR; diff --git a/cocos/render-scene/scene/directional-light.ts b/cocos/render-scene/scene/directional-light.ts index cc81361a632..87667942b0b 100644 --- a/cocos/render-scene/scene/directional-light.ts +++ b/cocos/render-scene/scene/directional-light.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { legacyCC } from '../../core/global-exports'; -import { Vec3 } from '../../core/math'; +import { Vec3, cclegacy } from '../../core'; import { Ambient } from './ambient'; import { Light, LightType } from './light'; import { CSMLevel, CSMOptimizationMode, PCFType, Shadows } from './shadows'; @@ -56,6 +54,8 @@ export class DirectionalLight extends Light { protected _csmNeedUpdate = false; protected _csmLayerLambda = 0.75; protected _csmOptimizationMode = CSMOptimizationMode.DisableRotationFix; + protected _csmLayersTransition = false; + protected _csmTransitionRange = 0.05; // fixed area properties protected _shadowFixedArea = false; @@ -80,7 +80,7 @@ export class DirectionalLight extends Light { * @zh 光源的辐照度,单位是 Lux(lx) */ get illuminance (): number { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._illuminanceHDR; } else { @@ -88,7 +88,7 @@ export class DirectionalLight extends Light { } } set illuminance (value: number) { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this.illuminanceHDR = value; } else { @@ -287,6 +287,29 @@ export class DirectionalLight extends Light { this._shadowOrthoSize = val; } + /** + * @en Enabled csm layers transition + * @zh 是否启用级联阴影层级过渡? + */ + get csmLayersTransition () { + return this._csmLayersTransition; + } + set csmLayersTransition (val) { + this._csmLayersTransition = val; + this._activate(); + } + + /** + * @en get or set csm layers transition range + * @zh 获取或者设置级联阴影层级过渡范围? + */ + get csmTransitionRange () { + return this._csmTransitionRange; + } + set csmTransitionRange (val) { + this._csmTransitionRange = val; + } + constructor () { super(); this._type = LightType.DIRECTIONAL; @@ -310,13 +333,16 @@ export class DirectionalLight extends Light { } private _activate () { - const root = legacyCC.director.root; + const root = cclegacy.director.root; const pipeline = root.pipeline; if (this._shadowEnabled) { if (this._shadowFixedArea || !pipeline.pipelineSceneData.csmSupported) { pipeline.macros.CC_DIR_LIGHT_SHADOW_TYPE = 1; + } else if (this.csmLevel > 1 && pipeline.pipelineSceneData.csmSupported) { + pipeline.macros.CC_DIR_LIGHT_SHADOW_TYPE = 2; + pipeline.macros.CC_CASCADED_LAYERS_TRANSITION = this._csmLayersTransition; } else { - pipeline.macros.CC_DIR_LIGHT_SHADOW_TYPE = this.csmLevel > 1 ? 2 : 1; + pipeline.macros.CC_DIR_LIGHT_SHADOW_TYPE = 1; } pipeline.macros.CC_DIR_SHADOW_PCF_TYPE = this._shadowPcf; } else { diff --git a/cocos/render-scene/scene/fog.ts b/cocos/render-scene/scene/fog.ts index 73e52a7ba9f..be04c19d2d1 100644 --- a/cocos/render-scene/scene/fog.ts +++ b/cocos/render-scene/scene/fog.ts @@ -1,31 +1,28 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import { Enum } from '../../core/value-types'; -import { Color, Vec4 } from '../../core/math'; -import { legacyCC } from '../../core/global-exports'; +import { Enum, Color, Vec4, cclegacy } from '../../core'; import { FogInfo } from '../../scene-graph/scene-globals'; import { SRGBToLinear } from '../../rendering/pipeline-funcs'; @@ -252,7 +249,7 @@ export class Fog { } protected _updatePipeline () { - const root = legacyCC.director.root; + const root = cclegacy.director.root; const value = this.enabled ? this.type : FOG_TYPE_NONE; const accurateValue = this.accurate ? 1 : 0; const pipeline = root.pipeline; @@ -267,4 +264,4 @@ export class Fog { } } -legacyCC.Fog = Fog; +cclegacy.Fog = Fog; diff --git a/cocos/render-scene/scene/index.jsb.ts b/cocos/render-scene/scene/index.jsb.ts index ea57decd0fc..3a55b250a02 100644 --- a/cocos/render-scene/scene/index.jsb.ts +++ b/cocos/render-scene/scene/index.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -import { legacyCC } from '../../core/global-exports'; -import { Vec3 } from '../../core/math'; -import { Enum } from '../../core/value-types'; +*/ +import { Vec3, Enum, cclegacy } from '../../core'; export type Ambient = jsb.Ambient; export const Ambient = jsb.Ambient; -legacyCC.Ambient = Ambient; +cclegacy.Ambient = Ambient; + +export const LODData = jsb.LODData; +export const LODGroup = jsb.LODGroup; /** * Light related. @@ -65,25 +65,35 @@ export enum LightType { DIRECTIONAL, SPHERE, SPOT, + POINT, + RANGED_DIRECTIONAL, UNKNOWN, } export const nt2lm = (size: number) => 4 * Math.PI * Math.PI * size * size; export const Light = jsb.Light; export type Light = jsb.Light; -legacyCC.Light = jsb.Light; +cclegacy.Light = jsb.Light; export const DirectionalLight = jsb.DirectionalLight; export type DirectionalLight = jsb.DirectionalLight; -legacyCC.DirectionalLight = jsb.DirectionalLight; +cclegacy.DirectionalLight = jsb.DirectionalLight; export const SpotLight = jsb.SpotLight; export type SpotLight = jsb.SpotLight; -legacyCC.SpotLight = jsb.SpotLight; +cclegacy.SpotLight = jsb.SpotLight; export const SphereLight = jsb.SphereLight; export type SphereLight = jsb.SphereLight; -legacyCC.SphereLight = jsb.SphereLight; +cclegacy.SphereLight = jsb.SphereLight; + +export const PointLight = jsb.PointLight; +export type PointLight = jsb.PointLight; +cclegacy.PointLight = jsb.PointLight; + +export const RangedDirectionalLight = jsb.RangedDirectionalLight; +export type RangedDirectionalLight = jsb.RangedDirectionalLight; +cclegacy.RangedDirectionalLight = jsb.RangedDirectionalLight; /** * Fog related. @@ -127,7 +137,7 @@ export const FogInfo = jsb.FogInfo; export type FogInfo = jsb.FogInfo; export const Fog = jsb.Fog; export type Fog = jsb.Fog; -legacyCC.Fog = Fog; +cclegacy.Fog = Fog; /** * Shadows related. @@ -285,14 +295,15 @@ export const EnvironmentLightingType = Enum({ }); export const ShadowsInfo = jsb.ShadowsInfo; export type ShadowsInfo = jsb.ShadowsInfo; -export const Shadows = jsb.Shadow; -export type Shadows = jsb.Shadow; -legacyCC.Shadows = Shadows; +export const Shadows = jsb.Shadows; +export type Shadows = jsb.Shadows; +cclegacy.Shadows = Shadows; export const Skybox = jsb.Skybox; export type Skybox = jsb.Skybox; -legacyCC.Skybox = Skybox; +cclegacy.Skybox = Skybox; export * from './model'; export * from './submodel'; export * from './camera'; +export * from './reflection-probe'; diff --git a/cocos/render-scene/scene/index.ts b/cocos/render-scene/scene/index.ts index c488c1063d1..d9edb9e5e3b 100644 --- a/cocos/render-scene/scene/index.ts +++ b/cocos/render-scene/scene/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './camera'; export * from './model'; @@ -35,3 +34,7 @@ export * from './light'; export * from './directional-light'; export * from './sphere-light'; export * from './spot-light'; +export * from './point-light'; +export * from './ranged-directional-light'; +export * from './reflection-probe'; +export * from './lod-group'; diff --git a/cocos/render-scene/scene/light.ts b/cocos/render-scene/scene/light.ts index 30b47b96f6f..1fdabf24e39 100644 --- a/cocos/render-scene/scene/light.ts +++ b/cocos/render-scene/scene/light.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../core/math'; +import { Vec3 } from '../../core'; import { TransformBit } from '../../scene-graph/node-enum'; import { RenderScene } from '../core/render-scene'; import { Node } from '../../scene-graph'; +import { CAMERA_DEFAULT_MASK } from '../../rendering/define'; // Color temperature (in Kelvin) to RGB export function ColorTemperatureToRGB (rgb: Vec3, kelvin: number) { @@ -63,6 +63,8 @@ export enum LightType { DIRECTIONAL, SPHERE, SPOT, + POINT, + RANGED_DIRECTIONAL, UNKNOWN, } @@ -91,6 +93,7 @@ export class Light { */ set color (color: Vec3) { this._color.set(color); + if (this._useColorTemperature) { Vec3.multiply(this._finalColor, this._color, this._colorTempRGB); } } get color (): Vec3 { @@ -103,6 +106,7 @@ export class Light { */ set useColorTemperature (enable: boolean) { this._useColorTemperature = enable; + if (enable) { Vec3.multiply(this._finalColor, this._color, this._colorTempRGB); } } get useColorTemperature (): boolean { @@ -116,6 +120,7 @@ export class Light { set colorTemperature (val: number) { this._colorTemp = val; ColorTemperatureToRGB(this._colorTempRGB, this._colorTemp); + if (this._useColorTemperature) { Vec3.multiply(this._finalColor, this._color, this._colorTempRGB); } } get colorTemperature (): number { @@ -130,6 +135,22 @@ export class Light { return this._colorTempRGB; } + get finalColor (): Readonly { + return this._finalColor; + } + + /** + * @en Visibility mask of the light, declaring a set of node layers that will be visible to this light. + * @zh 光照的可见性掩码,声明在当前光照中可见的节点层级集合。 + * @engineInternal + */ + set visibility (vis: number) { + this._visibility = vis; + } + get visibility (): number { + return this._visibility; + } + set node (n) { this._node = n; if (this._node) { @@ -149,7 +170,7 @@ export class Light { * @en The type of the light source, e.g. directional light, spot light, etc * @zh 光源的类型,比如方向光、聚光灯等 */ - get type () : LightType { + get type (): LightType { return this._type; } @@ -181,6 +202,8 @@ export class Light { protected _colorTempRGB: Vec3 = new Vec3(1, 1, 1); + private _finalColor: Vec3 = new Vec3(1, 1, 1); + protected _scene: RenderScene | null = null; protected _node: Node | null = null; @@ -191,6 +214,8 @@ export class Light { protected _type: LightType = LightType.UNKNOWN; + protected _visibility = CAMERA_DEFAULT_MASK; + public initialize () { this.color = new Vec3(1, 1, 1); this.colorTemperature = 6550.0; diff --git a/cocos/render-scene/scene/lod-group.ts b/cocos/render-scene/scene/lod-group.ts new file mode 100644 index 00000000000..5d85721088a --- /dev/null +++ b/cocos/render-scene/scene/lod-group.ts @@ -0,0 +1,209 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { Model } from './model'; +import { Vec3, assertIsTrue } from '../../core'; +import { RenderScene } from '..'; +import { Device, deviceManager } from '../../gfx'; +import { Node } from '../../scene-graph'; +import { Camera, CameraProjection } from './camera'; + +/** + * @engineInternal + */ +export class LODData { + // Range in [0, 1]. + screenUsagePercentage = 1.0; + + private _models: Model[] = []; + + get models (): readonly Model[] { + return this._models; + } + + public addModel (model: Model) { + this._models.splice(0, 0, model); + } + + public eraseModel (model: Model) { + const removeIndex = this._models.indexOf(model); + if (removeIndex >= 0) { + this._models.splice(removeIndex, 1); + } + } + + public clearModels () { + this._models.length = 0; + } +} + +/** + * @engineInternal + */ +export class LODGroup { + public scene?: RenderScene; + + public node: Node = null!; + + protected _device: Device; + + public enabled = true; + + private _localBoundaryCenter: Vec3 = new Vec3(0, 0, 0); + + /** + * @en Object Size in local space, may be auto-calculated value from object bounding box or value from user input. + */ + protected _objectSize = 1; + + /** + *@en The array of LODs + */ + protected _lodDataArray: LODData[] = []; + + /** + * For editor only, users maybe operate several LOD's object + */ + protected _lockedLODLevelVec: number[] = []; + + private _isLockLevelChanged = false; + + constructor () { + this._device = deviceManager.gfxDevice; + } + + set localBoundaryCenter (val: Vec3) { this._localBoundaryCenter.set(val); } + + get localBoundaryCenter (): Readonly { return this._localBoundaryCenter.clone(); } + + get lodCount () { return this._lodDataArray.length; } + + set objectSize (val: number) { + this._objectSize = val; + } + + get objectSize () { return this._objectSize; } + + get lodDataArray (): readonly LODData[] { return this._lodDataArray; } + attachToScene (scene: RenderScene) { + this.scene = scene; + } + + detachFromScene () { + this.scene = null!; + } + + lockLODLevels (lockLev: number[]) { + if (lockLev.length !== this._lockedLODLevelVec.length) { + this._isLockLevelChanged = true; + } else { + const size = lockLev.length; + let index = 0; + for (; index < size; index++) { + if (lockLev[index] !== this._lockedLODLevelVec[index]) { + this._isLockLevelChanged = true; + break; + } + } + } + this._lockedLODLevelVec = lockLev; + } + + isLockLevelChanged (): boolean { + return this._isLockLevelChanged; + } + + resetLockChangeFlag () { + this._isLockLevelChanged = false; + } + + getLockedLODLevels (): readonly number[] { + return this._lockedLODLevelVec; + } + + clearLODs () { + this._lodDataArray.length = 0; + } + + insertLOD (index: number, lod: LODData) { + this._lodDataArray.splice(index, 0, lod); + } + + updateLOD (index: number, lod: LODData) { + this._lodDataArray[index] = lod; + } + + eraseLOD (index: number) { + this._lodDataArray.splice(index, 1); + } + + /** + * + * @param camera current perspective camera + * @returns visible LOD index in lodGroup + */ + getVisibleLODLevel (camera: Camera): number { + const screenUsagePercentage = this.getScreenUsagePercentage(camera); + + let lodIndex = -1; + for (let i = 0; i < this.lodCount; ++i) { + const lod = this.lodDataArray[i]; + if (screenUsagePercentage >= lod.screenUsagePercentage) { + lodIndex = i; + break; + } + } + return lodIndex; + } + + /** + * + * @param camera current perspective camera + * @returns height of current lod group relative to camera position in screen space, aka. relativeHeight + */ + getScreenUsagePercentage (camera: Camera): number { + if (!this.node) return 0; + + let distance: number | undefined; + if (camera.projectionType === CameraProjection.PERSPECTIVE) { + distance = Vec3.len(this.localBoundaryCenter.transformMat4(this.node.worldMatrix).subtract(camera.node.worldPosition)); + } + + return this.distanceToScreenUsagePercentage(camera, distance, this.getWorldSpaceSize()); + } + + private distanceToScreenUsagePercentage (camera: Camera, distance: number | undefined, size: number): number { + if (camera.projectionType === CameraProjection.PERSPECTIVE) { + assertIsTrue(typeof distance === 'number', 'distance must be present for perspective projection'); + return (size * camera.matProj.m05) / (distance * 2.0); // note: matProj.m11 is 1 / tan(fov / 2.0) + } else { + return size * camera.matProj.m05 * 0.5; + } + } + + private getWorldSpaceSize (): number { + const scale = this.node.scale; + const maxScale = Math.max(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)); + return maxScale * this.objectSize; + } +} diff --git a/cocos/render-scene/scene/model.jsb.ts b/cocos/render-scene/scene/model.jsb.ts index 6e7175de6b5..301e36e5106 100644 --- a/cocos/render-scene/scene/model.jsb.ts +++ b/cocos/render-scene/scene/model.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Attribute, deviceManager } from '../../gfx'; -import { Vec3 } from '../../core/math'; +import { Vec3 } from '../../core'; export interface IInstancedAttributeBlock { buffer: Uint8Array; diff --git a/cocos/render-scene/scene/model.ts b/cocos/render-scene/scene/model.ts index 5717e6afa40..8ef1a06e0f3 100644 --- a/cocos/render-scene/scene/model.ts +++ b/cocos/render-scene/scene/model.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,23 +20,27 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +import { EDITOR } from 'internal:constants'; import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; import { Material } from '../../asset/assets/material'; import { RenderingSubMesh } from '../../asset/assets/rendering-sub-mesh'; -import { AABB } from '../../core/geometry/aabb'; import { Node } from '../../scene-graph'; import { Layers } from '../../scene-graph/layers'; import { RenderScene } from '../core/render-scene'; import { Texture2D } from '../../asset/assets/texture-2d'; import { SubModel } from './submodel'; -import { IMacroPatch, BatchingSchemes } from '../core/pass'; -import { Mat4, Vec3, Vec4 } from '../../core/math'; -import { Attribute, DescriptorSet, Device, Buffer, BufferInfo, getTypedArrayConstructor, - BufferUsageBit, FormatInfos, MemoryUsageBit, Filter, Address, Feature, SamplerInfo, deviceManager } from '../../gfx'; -import { INST_MAT_WORLD, UBOLocal, UBOWorldBound, UNIFORM_LIGHTMAP_TEXTURE_BINDING } from '../../rendering/define'; +import { IMacroPatch } from '../core/pass'; +import { Mat4, Vec3, Vec4, geometry, cclegacy, EPSILON } from '../../core'; +import { Attribute, DescriptorSet, Device, Buffer, BufferInfo, + BufferUsageBit, MemoryUsageBit, Filter, Address, SamplerInfo, deviceManager, Texture } from '../../gfx'; +import { UBOLocal, UBOSH, UBOWorldBound, UNIFORM_LIGHTMAP_TEXTURE_BINDING, UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING, UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING, UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING } from '../../rendering/define'; +import { Root } from '../../root'; +import { TextureCube } from '../../asset/assets'; +import { ShadowType } from './shadows'; +import { ProbeType, ReflectionProbe } from './reflection-probe'; const m4_1 = new Mat4(); @@ -45,10 +48,23 @@ const shadowMapPatches: IMacroPatch[] = [ { name: 'CC_RECEIVE_SHADOW', value: true }, ]; -const lightMapPatches: IMacroPatch[] = [ - { name: 'CC_USE_LIGHTMAP', value: true }, +const staticLightMapPatches: IMacroPatch[] = [ + { name: 'CC_USE_LIGHTMAP', value: 1 }, +]; + +const stationaryLightMapPatches: IMacroPatch[] = [ + { name: 'CC_USE_LIGHTMAP', value: 2 }, ]; +const highpLightMapPatches: IMacroPatch[] = [ + { name: 'CC_LIGHT_MAP_VERSION', value: 2 }, +]; + +const lightProbePatches: IMacroPatch[] = [ + { name: 'CC_USE_LIGHT_PROBE', value: true }, +]; +const CC_USE_REFLECTION_PROBE = 'CC_USE_REFLECTION_PROBE'; +const CC_RECEIVE_DIRECTIONAL_LIGHT = 'CC_RECEIVE_DIRECTIONAL_LIGHT'; export enum ModelType { DEFAULT, SKINNING, @@ -129,6 +145,14 @@ export class Model { return this._localBuffer; } + /** + * @en The SH ubo buffer of the model + * @zh 获取模型的球谐 ubo 缓冲 + */ + get localSHBuffer () { + return this._localSHBuffer; + } + /** * @en The world bound ubo buffer * @zh 获取世界包围盒 ubo 缓冲 @@ -145,6 +169,31 @@ export class Model { return this._updateStamp; } + /** + * @en Use LightProbe or not + * @zh 光照探针开关 + */ + get useLightProbe () { + return this._useLightProbe; + } + + set useLightProbe (val) { + this._useLightProbe = val; + this.onMacroPatchesStateChanged(); + } + + /** + * @en located tetrahedron index + * @zh 模型所处的四面体索引 + */ + get tetrahedronIndex () { + return this._tetrahedronIndex; + } + + set tetrahedronIndex (index: number) { + this._tetrahedronIndex = index; + } + /** * @en Model level shadow bias * @zh 阴影偏移值 @@ -194,11 +243,23 @@ export class Model { this._castShadow = val; } + /** + * @en Gets or sets receive direction Light. + * @zh 获取或者设置接收平行光光照。 + */ + get receiveDirLight (): boolean { + return this._receiveDirLight; + } + set receiveDirLight (val) { + this._receiveDirLight = val; + this.onMacroPatchesStateChanged(); + } + /** * @en The node to which the model belongs * @zh 模型所在的节点 */ - get node () : Node { + get node (): Node { return this._node; } @@ -210,7 +271,7 @@ export class Model { * @en Model's transform * @zh 模型的变换 */ - get transform () : Node { + get transform (): Node { return this._transform; } @@ -225,7 +286,7 @@ export class Model { * @zh 模型的可见性标志 * 模型的可见性标志与 [[Node.layer]] 不同,它会在剔除阶段与 [[Camera.visibility]] 进行比较 */ - get visFlags () : number { + get visFlags (): number { return this._visFlags; } @@ -237,7 +298,7 @@ export class Model { * @en Whether the model is enabled in the render scene so that it will be rendered * @zh 模型是否在渲染场景中启用并被渲染 */ - get enabled () : boolean { + get enabled (): boolean { return this._enabled; } @@ -249,7 +310,7 @@ export class Model { * @en Rendering priority in the transparent queue of model. * @zh Model 在透明队列中的渲染排序优先级 */ - get priority () : number { + get priority (): number { return this._priority; } @@ -257,6 +318,47 @@ export class Model { this._priority = val; } + /** + * @en Whether the model can be render by the reflection probe + * @zh 模型是否能被反射探针渲染 + */ + get bakeToReflectionProbe () { + return this._bakeToReflectionProbe; + } + + set bakeToReflectionProbe (val) { + this._bakeToReflectionProbe = val; + } + + /** + * @en Reflection probe type + * @zh 反射探针类型。 + */ + get reflectionProbeType () { + return this._reflectionProbeType; + } + + set reflectionProbeType (val) { + this._reflectionProbeType = val; + const subModels = this._subModels; + for (let i = 0; i < subModels.length; i++) { + subModels[i].useReflectionProbeType = val; + } + this.onMacroPatchesStateChanged(); + } + + /** + * @en sets or gets reflection probe id + * @zh 设置或获取反射探针id。 + */ + get reflectionProbeId () { + return this._reflectionProbeId; + } + + set reflectionProbeId (val) { + this._reflectionProbeId = val; + } + /** * @en The type of the model * @zh 模型类型 @@ -279,13 +381,13 @@ export class Model { * @en The world axis-aligned bounding box * @zh 世界空间包围盒 */ - protected _worldBounds: AABB | null = null; + protected _worldBounds: geometry.AABB | null = null; /** * @en The model axis-aligned bounding box * @zh 模型空间包围盒 */ - protected _modelBounds: AABB | null = null; + protected _modelBounds: geometry.AABB | null = null; /** * @en Sub models @@ -347,9 +449,29 @@ export class Model { */ protected _localBuffer: Buffer | null = null; + /** + * @en Local SH ubo data + * @zh 本地球谐 ubo 数据 + */ + protected _localSHData: Float32Array | null = null; + + /** + * @en Local SH ubo buffer + * @zh 本地球谐 ubo 缓冲 + */ + protected _localSHBuffer: Buffer | null = null; + private _lightmap: Texture2D | null = null; private _lightmapUVParam: Vec4 = new Vec4(); + /** + * @en located tetrahedron index + * @zh 所处的四面体索引 + */ + private _tetrahedronIndex = -1; + private _lastWorldBoundCenter = new Vec3(Infinity, Infinity, Infinity); + private _useLightProbe = false; + /** * @en World AABB buffer * @zh 世界空间包围盒缓冲 @@ -368,6 +490,12 @@ export class Model { */ protected _castShadow = false; + /** + * @en Is received direction Light. + * @zh 是否接收平行光光照。 + */ + protected _receiveDirLight = true; + /** * @en Shadow bias * @zh 阴影偏移 @@ -380,6 +508,12 @@ export class Model { */ protected _shadowNormalBias = 0; + /** + * @en Reflect probe Id + * @zh 使用第几个反射探针 + */ + protected _reflectionProbeId = -1; + /** * @en Whether the model is enabled in the render scene so that it will be rendered * @zh 模型是否在渲染场景中启用并被渲染 @@ -394,6 +528,18 @@ export class Model { protected _priority = 0; + /** + * @en Whether the model can be render by the reflection probe + * @zh 模型是否能被反射探针渲染 + */ + protected _bakeToReflectionProbe = true; + + /** + * @en Reflection probe type. + * @zh 反射探针类型。 + */ + protected _reflectionProbeType = 0; + /** * @internal * @en native object @@ -426,6 +572,8 @@ export class Model { this.enabled = true; this.visFlags = Layers.Enum.NONE; this._inited = true; + this._bakeToReflectionProbe = true; + this._reflectionProbeType = 0; } /** @@ -441,6 +589,10 @@ export class Model { this._localBuffer.destroy(); this._localBuffer = null; } + if (this._localSHBuffer) { + this._localSHBuffer.destroy(); + this._localSHBuffer = null; + } if (this._worldBoundBuffer) { this._worldBoundBuffer.destroy(); this._worldBoundBuffer = null; @@ -521,6 +673,9 @@ export class Model { } this._updateStamp = stamp; + this.updateSHUBOs(); + const forceUpdateUBO = this.node.scene.globals.shadows.enabled && this.node.scene.globals.shadows.type === ShadowType.Planar; + if (!this._localDataUpdated) { return; } this._localDataUpdated = false; @@ -536,7 +691,7 @@ export class Model { hasNonInstancingPass = true; } } - if (hasNonInstancingPass && this._localBuffer) { + if ((hasNonInstancingPass || forceUpdateUBO) && this._localBuffer) { Mat4.toArray(this._localData, worldMatrix, UBOLocal.MAT_WORLD_OFFSET); Mat4.inverseTranspose(m4_1, worldMatrix); @@ -545,6 +700,99 @@ export class Model { } } + public showTetrahedron () { + return this.isLightProbeAvailable(); + } + + private isLightProbeAvailable () { + if (!this._useLightProbe) { + return false; + } + + const lightProbes = (cclegacy.director.root as Root).pipeline.pipelineSceneData.lightProbes; + if (!lightProbes || lightProbes.empty()) { + return false; + } + + if (!this._worldBounds) { + return false; + } + + return true; + } + + private updateSHBuffer () { + if (!this._localSHData) { + return; + } + + const subModels = this._subModels; + let hasNonInstancingPass = false; + for (let i = 0; i < subModels.length; i++) { + const subModel = subModels[i]; + const idx = subModel.instancedSHIndex; + if (idx >= 0) { + subModel.updateInstancedSH(this._localSHData, idx); + } else { + hasNonInstancingPass = true; + } + } + + if (hasNonInstancingPass && this._localSHBuffer) { + this._localSHBuffer.update(this._localSHData); + } + } + + /** + * @en Clear the model's SH ubo + * @zh 清除模型的球谐 ubo + */ + public clearSHUBOs () { + if (!this._localSHData) { + return; + } + + for (let i = 0; i < UBOSH.COUNT; i++) { + this._localSHData[i] = 0.0; + } + + this.updateSHBuffer(); + } + + /** + * @en Update the model's SH ubo + * @zh 更新模型的球谐 ubo + */ + public updateSHUBOs () { + if (!this.isLightProbeAvailable()) { + return; + } + + const center = this._worldBounds!.center; + if (!EDITOR && center.equals(this._lastWorldBoundCenter, EPSILON)) { + return; + } + + const coefficients: Vec3[] = []; + const weights = new Vec4(0.0, 0.0, 0.0, 0.0); + const lightProbes = (cclegacy.director.root as Root).pipeline.pipelineSceneData.lightProbes; + + this._lastWorldBoundCenter.set(center); + this._tetrahedronIndex = lightProbes.data!.getInterpolationWeights(center, this._tetrahedronIndex, weights); + const result = lightProbes.data!.getInterpolationSHCoefficients(this._tetrahedronIndex, weights, coefficients); + if (!result) { + return; + } + + if (!this._localSHData) { + return; + } + + cclegacy.internal.SH.reduceRinging(coefficients, lightProbes.reduceRinging); + cclegacy.internal.SH.updateUBOData(this._localSHData, UBOSH.SH_LINEAR_CONST_R_OFFSET, coefficients); + this.updateSHBuffer(); + } + /** * @en Create the model's AABB * @zh 创建模型的包围盒 @@ -553,8 +801,8 @@ export class Model { */ public createBoundingShape (minPos?: Vec3, maxPos?: Vec3) { if (!minPos || !maxPos) { return; } - this._modelBounds = AABB.fromPoints(AABB.create(), minPos, maxPos); - this._worldBounds = AABB.clone(this._modelBounds); + this._modelBounds = geometry.AABB.fromPoints(geometry.AABB.create(), minPos, maxPos); + this._worldBounds = geometry.AABB.clone(this._modelBounds); } private _createSubModel () { @@ -663,7 +911,7 @@ export class Model { this.onMacroPatchesStateChanged(); - if (texture === null) { + if (!texture) { texture = builtinResMgr.get('empty-texture'); } @@ -680,6 +928,93 @@ export class Model { } } + /** + * @en Update the cube map of the reflection probe + * @zh 更新反射探针的立方体贴图 + * @param texture probe cubemap + */ + public updateReflectionProbeCubemap (texture: TextureCube | null) { + this._localDataUpdated = true; + this.onMacroPatchesStateChanged(); + + if (!texture) { + texture = builtinResMgr.get('default-cube-texture'); + } + + const gfxTexture = texture.getGFXTexture(); + if (gfxTexture) { + const reflectionSampler = this._device.getSampler(texture.getSamplerInfo()); + const subModels = this._subModels; + for (let i = 0; i < subModels.length; i++) { + const { descriptorSet } = subModels[i]; + if (descriptorSet) { + descriptorSet.bindSampler(UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING, reflectionSampler); + descriptorSet.bindTexture(UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING, gfxTexture); + descriptorSet.update(); + } + } + } + } + + /** + * @en Update the planar relflection map of the reflection probe + * @zh 更新反射探针的平面反射贴图 + * @param texture planar relflection map + */ + public updateReflectionProbePlanarMap (texture: Texture | null) { + this._localDataUpdated = true; + this.onMacroPatchesStateChanged(); + + const sampler = this._device.getSampler(new SamplerInfo( + Filter.LINEAR, + Filter.LINEAR, + Filter.NONE, + Address.CLAMP, + Address.CLAMP, + Address.CLAMP, + )); + if (!texture) { + texture = builtinResMgr.get('empty-texture').getGFXTexture()!; + } + if (texture) { + const subModels = this._subModels; + for (let i = 0; i < subModels.length; i++) { + const { descriptorSet } = subModels[i]; + if (descriptorSet) { + descriptorSet.bindTexture(UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING, texture); + descriptorSet.bindSampler(UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING, sampler); + descriptorSet.update(); + } + } + } + } + + /** + * @en Update the data map of the reflection probe + * @zh 更新反射探针的数据贴图 + * @param texture data map + */ + public updateReflectionProbeDataMap (texture: Texture2D | null) { + this._localDataUpdated = true; + this.onMacroPatchesStateChanged(); + + if (!texture) { + texture = builtinResMgr.get('empty-texture'); + } + const gfxTexture = texture.getGFXTexture(); + if (gfxTexture) { + const subModels = this._subModels; + for (let i = 0; i < subModels.length; i++) { + const { descriptorSet } = subModels[i]; + if (descriptorSet) { + descriptorSet.bindTexture(UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING, gfxTexture); + descriptorSet.bindSampler(UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING, texture.getGFXSampler()); + descriptorSet.update(); + } + } + } + } + /** * @en Update the shadow bias * @zh 更新阴影偏移 @@ -688,8 +1023,44 @@ export class Model { const sv = this._localData; sv[UBOLocal.LOCAL_SHADOW_BIAS + 0] = this._shadowBias; sv[UBOLocal.LOCAL_SHADOW_BIAS + 1] = this._shadowNormalBias; - sv[UBOLocal.LOCAL_SHADOW_BIAS + 2] = 0; + this._localDataUpdated = true; + } + + /** + * @en Update the id of reflection probe + * @zh 更新物体使用哪个反射探针 + */ + public updateReflectionProbeId () { + const sv = this._localData; + sv[UBOLocal.LOCAL_SHADOW_BIAS + 2] = this._reflectionProbeId; sv[UBOLocal.LOCAL_SHADOW_BIAS + 3] = 0; + let probe: ReflectionProbe | null = null; + if (cclegacy.internal.reflectionProbeManager) { + probe = cclegacy.internal.reflectionProbeManager.getProbeById(this._reflectionProbeId); + } + if (probe) { + if (probe.probeType === ProbeType.PLANAR) { + sv[UBOLocal.REFLECTION_PROBE_DATA1] = probe.node.up.x; + sv[UBOLocal.REFLECTION_PROBE_DATA1 + 1] = probe.node.up.y; + sv[UBOLocal.REFLECTION_PROBE_DATA1 + 2] = probe.node.up.z; + sv[UBOLocal.REFLECTION_PROBE_DATA1 + 3] = 1.0; + + sv[UBOLocal.REFLECTION_PROBE_DATA2] = 1.0; + sv[UBOLocal.REFLECTION_PROBE_DATA2 + 1] = 0.0; + sv[UBOLocal.REFLECTION_PROBE_DATA2 + 2] = 0.0; + sv[UBOLocal.REFLECTION_PROBE_DATA2 + 3] = 1.0; + } else { + sv[UBOLocal.REFLECTION_PROBE_DATA1] = probe.node.worldPosition.x; + sv[UBOLocal.REFLECTION_PROBE_DATA1 + 1] = probe.node.worldPosition.y; + sv[UBOLocal.REFLECTION_PROBE_DATA1 + 2] = probe.node.worldPosition.z; + sv[UBOLocal.REFLECTION_PROBE_DATA1 + 3] = 0.0; + + sv[UBOLocal.REFLECTION_PROBE_DATA2] = probe.size.x; + sv[UBOLocal.REFLECTION_PROBE_DATA2 + 1] = probe.size.y; + sv[UBOLocal.REFLECTION_PROBE_DATA2 + 2] = probe.size.z; + sv[UBOLocal.REFLECTION_PROBE_DATA2 + 3] = probe.cubemap ? probe.cubemap.mipmapLevel : 1.0; + } + } this._localDataUpdated = true; } @@ -701,8 +1072,31 @@ export class Model { public getMacroPatches (subModelIndex: number): IMacroPatch[] | null { let patches = this.receiveShadow ? shadowMapPatches : null; if (this._lightmap != null) { - patches = patches ? patches.concat(lightMapPatches) : lightMapPatches; + let stationary = false; + if (this.node && this.node.scene) { + stationary = this.node.scene.globals.bakedWithStationaryMainLight; + } + + const lightmapPathes = stationary ? stationaryLightMapPatches : staticLightMapPatches; + patches = patches ? patches.concat(lightmapPathes) : lightmapPathes; + + // use highp lightmap + if (this.node.scene.globals.bakedWithHighpLightmap) { + patches = patches.concat(highpLightMapPatches); + } + } + if (this._useLightProbe) { + patches = patches ? patches.concat(lightProbePatches) : lightProbePatches; } + const reflectionProbePatches: IMacroPatch[] = [ + { name: CC_USE_REFLECTION_PROBE, value: this._reflectionProbeType }, + ]; + patches = patches ? patches.concat(reflectionProbePatches) : reflectionProbePatches; + const receiveDirLightPatches: IMacroPatch[] = [ + { name: CC_RECEIVE_DIRECTIONAL_LIGHT, value: this._receiveDirLight }, + ]; + patches = patches ? patches.concat(receiveDirLightPatches) : receiveDirLightPatches; + return patches; } @@ -713,6 +1107,9 @@ export class Model { this._initLocalDescriptors(subModelIndex); this._updateLocalDescriptors(subModelIndex, subModel.descriptorSet); + this._initLocalSHDescriptors(subModelIndex); + this._updateLocalSHDescriptors(subModelIndex, subModel.descriptorSet); + this._initWorldBoundDescriptors(subModelIndex); if (subModel.worldBoundDescriptorSet) { @@ -742,6 +1139,25 @@ export class Model { } } + protected _initLocalSHDescriptors (subModelIndex: number) { + if (!EDITOR && !this._useLightProbe) { + return; + } + + if (!this._localSHData) { + this._localSHData = new Float32Array(UBOSH.COUNT); + } + + if (!this._localSHBuffer) { + this._localSHBuffer = this._device.createBuffer(new BufferInfo( + BufferUsageBit.UNIFORM | BufferUsageBit.TRANSFER_DST, + MemoryUsageBit.DEVICE, + UBOSH.SIZE, + UBOSH.SIZE, + )); + } + } + protected _initWorldBoundDescriptors (subModelIndex: number) { if (!this._worldBoundBuffer) { this._worldBoundBuffer = this._device.createBuffer(new BufferInfo( @@ -757,6 +1173,10 @@ export class Model { if (this._localBuffer) descriptorSet.bindBuffer(UBOLocal.BINDING, this._localBuffer); } + protected _updateLocalSHDescriptors (subModelIndex: number, descriptorSet: DescriptorSet) { + if (this._localSHBuffer) descriptorSet.bindBuffer(UBOSH.BINDING, this._localSHBuffer); + } + protected _updateWorldBoundDescriptors (subModelIndex: number, descriptorSet: DescriptorSet) { if (this._worldBoundBuffer) descriptorSet.bindBuffer(UBOWorldBound.BINDING, this._worldBoundBuffer); } diff --git a/cocos/render-scene/scene/octree.ts b/cocos/render-scene/scene/octree.ts index f448ebda089..8515e905b4f 100644 --- a/cocos/render-scene/scene/octree.ts +++ b/cocos/render-scene/scene/octree.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Vec3 } from '../../core/math/vec3'; +import { Vec3 } from '../../core'; import { OctreeInfo } from '../../scene-graph/scene-globals'; /** diff --git a/cocos/render-scene/scene/point-light.ts b/cocos/render-scene/scene/point-light.ts new file mode 100644 index 00000000000..b55a82d3119 --- /dev/null +++ b/cocos/render-scene/scene/point-light.ts @@ -0,0 +1,139 @@ +/* + Copyright (c) 2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { cclegacy, Vec3 } from '../../core'; +import { AABB } from '../../core/geometry'; +import { Light, LightType, nt2lm } from './light'; + +/** + * @en The point light representation in the render scene, it will light up a spherical area in the scene. + * It doesn't support shadow generation currently. + * @zh 渲染场景中的点光抽象,可以照亮场景中的一个球形区域,目前还不支持生成阴影。 + */ +export class PointLight extends Light { + /** + * @en The world position of the light source. + * @zh 光源中心点的世界坐标。 + */ + get position (): Readonly { + return this._pos; + } + + /** + * @en The lighting range of the light source. + * @zh 点光源的光照范围。 + */ + set range (range: number) { + this._range = range; + + this._needUpdate = true; + } + + get range (): number { + return this._range; + } + + /** + * @en The luminance of the light source. + * @zh 光源的亮度。 + */ + get luminance (): number { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + return this._luminanceHDR; + } else { + return this._luminanceLDR; + } + } + set luminance (value: number) { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + this.luminanceHDR = value; + } else { + this.luminanceLDR = value; + } + } + + /** + * @en The luminance of the light source in HDR mode. + * @zh HDR 模式下光源的亮度。 + */ + get luminanceHDR () { + return this._luminanceHDR; + } + set luminanceHDR (value: number) { + this._luminanceHDR = value; + } + + /** + * @en The luminance of the light source in LDR mode. + * @zh LDR 模式下光源的亮度。 + */ + set luminanceLDR (value: number) { + this._luminanceLDR = value; + } + + /** + * @en The AABB bounding box of the lighting area. + * @zh 受光源影响范围的 AABB 包围盒。 + */ + get aabb () { + return this._aabb; + } + + private _needUpdate = false; + private _range = 1.0; + private _luminanceHDR = 0; + private _luminanceLDR = 0; + private _pos: Vec3; + private _aabb: AABB; + + constructor () { + super(); + this._aabb = AABB.create(); + this._pos = new Vec3(); + this._type = LightType.POINT; + } + + public initialize () { + super.initialize(); + + this.range = 1.0; + this.luminanceHDR = 1700 / nt2lm(1.0); + this.luminanceLDR = 1.0; + } + + /** + * @en Update the lighting area. + * @zh 更新光源影响范围。 + */ + public update () { + if (this._node && (this._node.hasChangedFlags || this._needUpdate)) { + this._node.getWorldPosition(this._pos); + const range = this._range; + AABB.set(this._aabb, this._pos.x, this._pos.y, this._pos.z, range, range, range); + this._needUpdate = false; + } + } +} diff --git a/cocos/render-scene/scene/ranged-directional-light.ts b/cocos/render-scene/scene/ranged-directional-light.ts new file mode 100644 index 00000000000..890c30154c7 --- /dev/null +++ b/cocos/render-scene/scene/ranged-directional-light.ts @@ -0,0 +1,140 @@ +/* + Copyright (c) 2023 Xiamen Yaji Software Co., Ltd. + https://www.cocos.com/ + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated engine source code (the "Software"), a limited, + worldwide, royalty-free, non-assignable, revocable and non-exclusive license + to use Cocos Creator solely to develop games on your target platforms. You shall + not use Cocos Creator software for developing other software or tools that's + used for developing games. You are not granted to publish, distribute, + sublicense, and/or sell copies of Cocos Creator. + The software or tools in this License Agreement are licensed, not sold. + Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +import { cclegacy } from '../../core'; +import { Vec3 } from '../../core/math/vec3'; +import { Ambient } from './ambient'; +import { Light, LightType } from './light'; + +const _forward = new Vec3(0, 0, -1); + +/** + * @en Render the abstraction of light in the scene, which is a ranged directional light source in the scene. Non main light source, + * each scene is allowed to have multiple ranged directional light sources without shadows. + * @zh 渲染场景中的光的抽象,这是场景中的范围平行光光源。非主光源,每个场景允许有多个范围平行光光源,不包含阴影。 + */ +export class RangedDirectionalLight extends Light { + private _dir: Vec3 = new Vec3(0, 0, -1); + private _pos: Vec3 = new Vec3(0, 0, 0); + private _scale: Vec3 = new Vec3(1, 1, 1); + private _right: Vec3 = new Vec3(1, 0, 0); + private _illuminanceHDR: number = Ambient.SUN_ILLUM; + private _illuminanceLDR = 1.0; + + /** + * @en The direction vector of the light + * @zh 光源的方向 + */ + get direction (): Readonly { + return this._dir; + } + + /** + * @en The right vector of the light + * @zh 光源的右方向 + */ + get right (): Readonly { + return this._right; + } + + /** + * @en The world position of the light source + * @zh 光源的世界坐标 + */ + get position (): Readonly { + return this._pos; + } + + /** + * @en The world scale of the light source + * @zh 光源的世界缩放 + */ + get scale (): Readonly { + return this._scale; + } + + /** + * @en The illuminance of the light in Lux(lx) + * @zh 光源的辐照度,单位是 Lux(lx) + */ + get illuminance (): number { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + return this._illuminanceHDR; + } else { + return this._illuminanceLDR; + } + } + set illuminance (value: number) { + const isHDR = cclegacy.director.root.pipeline.pipelineSceneData.isHDR; + if (isHDR) { + this.illuminanceHDR = value; + } else { + this.illuminanceLDR = value; + } + } + + /** + * @en The illuminance of the light in HDR mode + * @zh HDR 模式下光源的辐照度 + */ + get illuminanceHDR () { + return this._illuminanceHDR; + } + set illuminanceHDR (value: number) { + this._illuminanceHDR = value; + } + + /** + * @en The illuminance of the light in LDR mode + * @zh LDR 模式下光源的辐照度 + */ + get illuminanceLDR () { + return this._illuminanceLDR; + } + set illuminanceLDR (value: number) { + this._illuminanceLDR = value; + } + + constructor () { + super(); + this._type = LightType.RANGED_DIRECTIONAL; + } + + public initialize () { + super.initialize(); + + this.illuminance = Ambient.SUN_ILLUM; + } + + /** + * @en Update + * @zh 更新 + */ + public update () { + if (this._node && this._node.hasChangedFlags) { + this._node.getWorldPosition(this._pos); + this._node.getWorldScale(this._scale); + Vec3.transformQuat(this._dir, _forward, this._node.worldRotation); + Vec3.transformQuat(this._right, Vec3.RIGHT, this._node.worldRotation); + } + } +} diff --git a/cocos/render-scene/scene/reflection-probe.jsb.ts b/cocos/render-scene/scene/reflection-probe.jsb.ts new file mode 100644 index 00000000000..8dde3c081dd --- /dev/null +++ b/cocos/render-scene/scene/reflection-probe.jsb.ts @@ -0,0 +1,42 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { ClearFlagBit } from '../../gfx'; +import { SKYBOX_FLAG } from './camera'; +declare const jsb: any; + +export enum ProbeClearFlag { + SKYBOX = SKYBOX_FLAG | ClearFlagBit.DEPTH_STENCIL, + SOLID_COLOR = ClearFlagBit.ALL, +} + +export enum ProbeType { + CUBE = 0, + PLANAR = 1, +} + +export const ReflectionProbe = jsb.ReflectionProbe; +const reflectionProbeProto: any = jsb.ReflectionProbe.prototype; +reflectionProbeProto._ctor = function (id:number) { + this._probeId = id; +}; diff --git a/cocos/render-scene/scene/reflection-probe.ts b/cocos/render-scene/scene/reflection-probe.ts new file mode 100644 index 00000000000..ac04bbf26b7 --- /dev/null +++ b/cocos/render-scene/scene/reflection-probe.ts @@ -0,0 +1,500 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { EDITOR } from 'internal:constants'; +import { Camera, CameraAperture, CameraFOVAxis, CameraISO, CameraProjection, CameraShutter, CameraType, SKYBOX_FLAG, TrackingType } from './camera'; +import { Node } from '../../scene-graph/node'; +import { Color, Quat, Rect, toRadian, Vec2, Vec3, geometry, cclegacy, Vec4 } from '../../core'; +import { CAMERA_DEFAULT_MASK } from '../../rendering/define'; +import { ClearFlagBit, Framebuffer } from '../../gfx'; +import { TextureCube } from '../../asset/assets/texture-cube'; +import { RenderTexture } from '../../asset/assets/render-texture'; + +export enum ProbeClearFlag { + SKYBOX = SKYBOX_FLAG | ClearFlagBit.DEPTH_STENCIL, + SOLID_COLOR = ClearFlagBit.ALL, +} + +export enum ProbeType { + CUBE = 0, + PLANAR = 1, +} +// right left up down front back +const cameraDir: Vec3[] = [ + new Vec3(0, -90, 0), + new Vec3(0, 90, 0), + + new Vec3(90, 0, 0), + new Vec3(-90, 0, 0), + + new Vec3(0, 0, 0), + new Vec3(0, 180, 0), +]; + +export class ReflectionProbe { + public bakedCubeTextures: RenderTexture[] = []; + + public realtimePlanarTexture: RenderTexture | null = null; + + protected _resolution = 256; + protected _clearFlag: number = ProbeClearFlag.SKYBOX; + protected _backgroundColor = new Color(0, 0, 0, 255); + protected _visibility = CAMERA_DEFAULT_MASK; + protected _probeType = ProbeType.CUBE; + protected _cubemap: TextureCube | null = null; + protected readonly _size = new Vec3(1, 1, 1); + + /** + * @en Render cubemap's camera + * @zh 渲染cubemap的相机 + */ + private _camera: Camera | null = null; + + /** + * @en Unique id of probe. + * @zh probe的唯一id + */ + private _probeId = 0; + + private _needRefresh = false; + + private _needRender = false; + + private _node: Node | null = null; + + private _cameraNode: Node | null = null; + + /** + * @en The AABB bounding box and probe only render the objects inside the bounding box. + * @zh AABB包围盒,probe只渲染包围盒内的物体 + */ + private _boundingBox: geometry.AABB | null = null; + + /** + * @en The position of the camera in world space. + * @zh 世界空间相机的位置 + */ + private _cameraWorldPos = new Vec3(); + + /** + * @en The rotation of the camera in world space. + * @zh 世界空间相机的旋转 + */ + private _cameraWorldRotation = new Quat(); + + /** + * @en The forward direction vertor of the camera in world space. + * @zh 世界空间相机朝前的方向向量 + */ + private _forward = new Vec3(); + /** + * @en The up direction vertor of the camera in world space. + * @zh 世界空间相机朝上的方向向量 + */ + private _up = new Vec3(); + + /** + * @en Reflection probe cube pattern preview sphere + * @zh 反射探针cube模式的预览小球 + */ + protected _previewSphere: Node | null = null; + + protected _previewPlane: Node | null = null; + + /** + * @en Set probe type,cube or planar. + * @zh 设置探针类型,cube或者planar + */ + set probeType (value: number) { + this._probeType = value; + } + get probeType () { + return this._probeType; + } + + get resolution () { + return this._resolution; + } + + /** + * @en set render texture size + * @zh 设置渲染纹理大小 + */ + set resolution (value: number) { + if (value !== this._resolution) { + this.bakedCubeTextures.forEach((rt, idx) => { + rt.resize(value, value); + }); + } + this._resolution = value; + } + + /** + * @en Clearing flags of the camera, specifies which part of the framebuffer will be actually cleared every frame. + * @zh 相机的缓冲清除标志位,指定帧缓冲的哪部分要每帧清除。 + */ + set clearFlag (value: number) { + this._clearFlag = value; + this.camera.clearFlag = this._clearFlag; + } + get clearFlag () { + return this._clearFlag; + } + + /** + * @en Clearing color of the camera. + * @zh 相机的颜色缓冲默认值。 + */ + set backgroundColor (val: Color) { + this._backgroundColor = val; + this.camera.clearColor = this._backgroundColor; + } + get backgroundColor () { + return this._backgroundColor; + } + /** + * @en Visibility mask, declaring a set of node layers that will be visible to this camera. + * @zh 可见性掩码,声明在当前相机中可见的节点层级集合。 + */ + get visibility () { + return this._visibility; + } + set visibility (val) { + this._visibility = val; + this._camera!.visibility = this._visibility; + } + + /** + * @en Gets or sets the size of the box, in local space. + * @zh 获取或设置盒的大小。 + */ + set size (value) { + this._size.set(value); + + const pos = this.node.getWorldPosition(); + geometry.AABB.set(this._boundingBox!, pos.x, pos.y, pos.z, this._size.x, this._size.y, this._size.z); + } + get size () { + return this._size; + } + + set cubemap (val: TextureCube | null) { + this._cubemap = val; + } + + get cubemap () { + return this._cubemap!; + } + + /** + * @en The node of the probe. + * @zh probe绑定的节点 + */ + get node () { + return this._node!; + } + + get camera () { + return this._camera!; + } + + /** + * @en Refresh the objects that use this probe. + * @zh 刷新使用该probe的物体 + */ + set needRefresh (value: boolean) { + this._needRefresh = value; + } + + get needRefresh () { + return this._needRefresh; + } + + set needRender (value: boolean) { + this._needRender = value; + } + get needRender () { + return this._needRender; + } + + get boundingBox () { + return this._boundingBox; + } + + set cameraNode (node: Node) { + this._cameraNode = node; + } + get cameraNode () { + return this._cameraNode!; + } + + /** + * @en Reflection probe cube mode preview sphere + * @zh 反射探针cube模式的预览小球 + * @engineInternal + */ + set previewSphere (val: Node) { + this._previewSphere = val; + } + + get previewSphere () { + return this._previewSphere!; + } + + /** + * @en Reflection probe planar mode preview plane + * @zh 反射探针Planar模式的预览平面 + */ + set previewPlane (val: Node) { + this._previewPlane = val; + } + + get previewPlane () { + return this._previewPlane!; + } + + constructor (id: number) { + this._probeId = id; + } + + public initialize (node: Node, cameraNode: Node) { + this._node = node; + this._cameraNode = cameraNode; + const pos = this.node.getWorldPosition(); + this._boundingBox = geometry.AABB.create(pos.x, pos.y, pos.z, this._size.x, this._size.y, this._size.z); + this._createCamera(cameraNode); + } + + public initBakedTextures () { + if (this.bakedCubeTextures.length === 0) { + for (let i = 0; i < 6; i++) { + const renderTexture = this._createTargetTexture(this._resolution, this._resolution); + this.bakedCubeTextures.push(renderTexture); + } + } + } + + public captureCubemap () { + this.initBakedTextures(); + this._resetCameraParams(); + this._needRender = true; + } + + /** + * @en Render real-time planar reflection textures + * @zh 渲染实时平面反射贴图 + * @param sourceCamera render planar reflection for this camera + */ + public renderPlanarReflection (sourceCamera: Camera) { + if (!sourceCamera) return; + if (!this.realtimePlanarTexture) { + const canvasSize = cclegacy.view.getDesignResolutionSize(); + this.realtimePlanarTexture = this._createTargetTexture(canvasSize.width, canvasSize.height); + cclegacy.internal.reflectionProbeManager.updatePlanarMap(this, this.realtimePlanarTexture.getGFXTexture()); + } + this._syncCameraParams(sourceCamera); + this._transformReflectionCamera(sourceCamera); + this._needRender = true; + } + + public switchProbeType (type: number, sourceCamera: Camera | null) { + if (type === ProbeType.CUBE) { + this._needRender = false; + } else if (sourceCamera !== null) { + this.renderPlanarReflection(sourceCamera); + } + } + + public getProbeId () { + return this._probeId; + } + + public updateProbeId (id) { + this._probeId = id; + } + + public renderArea (): Vec2 { + if (this._probeType === ProbeType.PLANAR) { + return new Vec2(this.realtimePlanarTexture!.width, this.realtimePlanarTexture!.height); + } else { + return new Vec2(this.resolution, this.resolution); + } + } + + public isFinishedRendering () { + return true; + } + + public validate () { + return this.cubemap !== null; + } + + public destroy () { + if (this._camera) { + this._camera.destroy(); + this._camera = null; + } + for (let i = 0; i < this.bakedCubeTextures.length; i++) { + this.bakedCubeTextures[i].destroy(); + } + this.bakedCubeTextures = []; + + if (this.realtimePlanarTexture) { + this.realtimePlanarTexture.destroy(); + this.realtimePlanarTexture = null; + } + } + public enable () { + } + public disable () { + } + + public updateCameraDir (faceIdx: number) { + this.cameraNode.setRotationFromEuler(cameraDir[faceIdx]); + this.camera.update(true); + } + + public updateBoundingBox () { + if (this.node) { + this.node.updateWorldTransform(); + const pos = this.node.getWorldPosition(); + geometry.AABB.set(this._boundingBox!, pos.x, pos.y, pos.z, this._size.x, this._size.y, this._size.z); + } + } + + public hasFrameBuffer (framebuffer: Framebuffer) { + if (this.bakedCubeTextures.length === 0) return false; + for (let i = 0; i < this.bakedCubeTextures.length; i++) { + const rt = this.bakedCubeTextures[i]; + if (rt.window?.framebuffer === framebuffer) { + return true; + } + } + return false; + } + + private _syncCameraParams (camera: Camera) { + this.camera.projectionType = camera.projectionType; + this.camera.orthoHeight = camera.orthoHeight; + this.camera.nearClip = camera.nearClip; + this.camera.farClip = camera.farClip; + this.camera.fov = camera.fov; + this.camera.visibility = camera.visibility; + this.camera.clearFlag = camera.clearFlag; + this.camera.clearColor = camera.clearColor; + this.camera.priority = camera.priority - 1; + this.camera.resize(camera.width, camera.height); + } + + private _createCamera (cameraNode: Node) { + const root = cclegacy.director.root; + if (!this._camera) { + this._camera = (cclegacy.director.root).createCamera(); + if (!this._camera) return null; + this._camera.initialize({ + name: cameraNode.name, + node: cameraNode, + projection: CameraProjection.PERSPECTIVE, + window: EDITOR ? cclegacy.director.root && cclegacy.director.root.mainWindow + : cclegacy.director.root && cclegacy.director.root.tempWindow, + priority: 0, + cameraType: CameraType.DEFAULT, + trackingType: TrackingType.NO_TRACKING, + }); + } + this._camera.setViewportInOrientedSpace(new Rect(0, 0, 1, 1)); + this._camera.fovAxis = CameraFOVAxis.VERTICAL; + this._camera.fov = toRadian(90); + this._camera.orthoHeight = 10; + this._camera.nearClip = 1; + this._camera.farClip = 1000; + this._camera.clearColor = this._backgroundColor; + this._camera.clearDepth = 1.0; + this._camera.clearStencil = 0.0; + this._camera.clearFlag = this._clearFlag; + this._camera.visibility = this._visibility; + this._camera.aperture = CameraAperture.F16_0; + this._camera.shutter = CameraShutter.D125; + this._camera.iso = CameraISO.ISO100; + return this._camera; + } + + private _resetCameraParams () { + this.camera.projectionType = CameraProjection.PERSPECTIVE; + this.camera.orthoHeight = 10; + this.camera.nearClip = 1; + this.camera.farClip = 1000; + this.camera.fov = toRadian(90); + this.camera.priority = 0; + this.camera.resize(this.resolution, this.resolution); + + this.camera.visibility = this._visibility; + this.camera.clearFlag = this._clearFlag; + this.camera.clearColor = this._backgroundColor; + + this.cameraNode.worldPosition = this.node.worldPosition; + this.cameraNode.worldRotation = this.node.worldRotation; + this.camera.update(true); + } + + private _createTargetTexture (width: number, height: number) { + const rt = new RenderTexture(); + rt.reset({ width, height }); + return rt; + } + + private _transformReflectionCamera (sourceCamera: Camera) { + const offset = Vec3.dot(this.node.worldPosition, this.node.up); + this._reflect(this._cameraWorldPos, sourceCamera.node.worldPosition, this.node.up, offset); + this.cameraNode.worldPosition = this._cameraWorldPos; + + Vec3.transformQuat(this._forward, Vec3.FORWARD, sourceCamera.node.worldRotation); + this._reflect(this._forward, this._forward, this.node.up, 0); + this._forward.normalize(); + this._forward.negative(); + + Vec3.transformQuat(this._up, this.node.up, sourceCamera.node.worldRotation); + this._reflect(this._up, this._up, this.node.up, 0); + this._up.normalize(); + + Quat.fromViewUp(this._cameraWorldRotation, this._forward, this._up); + + this.cameraNode.worldRotation = this._cameraWorldRotation; + + this.camera.update(true); + + // Transform the plane from world space to reflection camera space use the inverse transpose matrix + const viewSpaceProbe = new Vec4(this.node.up.x, this.node.up.y, this.node.up.z, -Vec3.dot(this.node.up, this.node.worldPosition)); + viewSpaceProbe.transformMat4(this.camera.matView.clone().invert().transpose()); + this.camera.calculateObliqueMat(viewSpaceProbe); + } + + private _reflect (out: Vec3, point: Vec3, normal: Vec3, offset: number) { + const n = Vec3.clone(normal); + n.normalize(); + const dist = Vec3.dot(n, point) - offset; + n.multiplyScalar(2.0 * dist); + Vec3.subtract(out, point, n); + return out; + } +} diff --git a/cocos/render-scene/scene/shadows.ts b/cocos/render-scene/scene/shadows.ts index ac06d2a47b7..a172103cd30 100644 --- a/cocos/render-scene/scene/shadows.ts +++ b/cocos/render-scene/scene/shadows.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DEBUG } from 'internal:constants'; import { Material } from '../../asset/assets/material'; -import { Sphere } from '../../core/geometry'; -import { Color, Mat4, Vec3, Vec2 } from '../../core/math'; -import { legacyCC } from '../../core/global-exports'; -import { Enum } from '../../core/value-types'; +import { Color, Mat4, Vec3, Vec2, Enum, assert, geometry, cclegacy } from '../../core'; import type { ShadowsInfo } from '../../scene-graph/scene-globals'; import { IMacroPatch } from '../core/pass'; import { Shader } from '../../gfx'; -import { assert } from '../../core/platform/debug'; /** * @zh 阴影贴图分辨率。 @@ -314,7 +309,7 @@ export class Shadows { * @en The bounding sphere of the shadow map. * @zh 用于计算固定区域阴影 Shadow map 的场景包围球. */ - public fixedSphere: Sphere = new Sphere(0.0, 0.0, 0.0, 0.01); + public fixedSphere: geometry.Sphere = new geometry.Sphere(0.0, 0.0, 0.0, 0.01); /** * @en get or set shadow max received. @@ -393,13 +388,13 @@ export class Shadows { if (this.type === ShadowType.Planar) { this._updatePlanarInfo(); } else { - const root = legacyCC.director.root; + const root = cclegacy.director.root; const pipeline = root.pipeline; pipeline.macros.CC_SHADOW_TYPE = 2; root.onGlobalPipelineStateChanged(); } } else { - const root = legacyCC.director.root; + const root = cclegacy.director.root; const pipeline = root.pipeline; pipeline.macros.CC_SHADOW_TYPE = 0; root.onGlobalPipelineStateChanged(); @@ -415,7 +410,7 @@ export class Shadows { this._instancingMaterial = new Material(); this._instancingMaterial.initialize({ effectName: 'pipeline/planar-shadow', defines: { USE_INSTANCING: true } }); } - const root = legacyCC.director.root; + const root = cclegacy.director.root; const pipeline = root.pipeline; pipeline.macros.CC_SHADOW_TYPE = 1; root.onGlobalPipelineStateChanged(); @@ -433,4 +428,4 @@ export class Shadows { } } -legacyCC.Shadows = Shadows; +cclegacy.Shadows = Shadows; diff --git a/cocos/render-scene/scene/skybox.ts b/cocos/render-scene/scene/skybox.ts index 9a79ac3ad40..0133bd008f2 100644 --- a/cocos/render-scene/scene/skybox.ts +++ b/cocos/render-scene/scene/skybox.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; import { Material } from '../../asset/assets/material'; @@ -30,12 +29,11 @@ import { TextureCube } from '../../asset/assets/texture-cube'; import { UNIFORM_ENVIRONMENT_BINDING, UNIFORM_DIFFUSEMAP_BINDING } from '../../rendering/define'; import { MaterialInstance } from '../core/material-instance'; import { Model } from './model'; -import { legacyCC } from '../../core/global-exports'; import type { SkyboxInfo } from '../../scene-graph/scene-globals'; import { Root } from '../../root'; import { GlobalDSManager } from '../../rendering/global-descriptor-set-manager'; import { deviceManager } from '../../gfx'; -import { Enum } from '../../core/value-types'; +import { Enum, cclegacy } from '../../core'; let skybox_mesh: Mesh | null = null; let skybox_material: Material | null = null; @@ -164,7 +162,7 @@ export class Skybox { * @zh 使用的立方体贴图 */ get envmap (): TextureCube | null { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._envmapHDR; } else { @@ -172,7 +170,7 @@ export class Skybox { } } set envmap (val: TextureCube | null) { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; const isHDR = root.pipeline.pipelineSceneData.isHDR; if (isHDR) { this.setEnvMaps(val, this._envmapLDR); @@ -186,7 +184,7 @@ export class Skybox { * @zh 使用的漫反射卷积图 */ get diffuseMap (): TextureCube | null { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._diffuseMapHDR; } else { @@ -194,7 +192,7 @@ export class Skybox { } } set diffuseMap (val: TextureCube | null) { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this.setDiffuseMaps(val, this._diffuseMapLDR); } else { @@ -203,7 +201,7 @@ export class Skybox { } get reflectionMap (): TextureCube | null { - const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._reflectionHDR; } else { @@ -310,12 +308,12 @@ export class Skybox { } public activate () { - const pipeline = legacyCC.director.root.pipeline; + const pipeline = cclegacy.director.root.pipeline; this._globalDSManager = pipeline.globalDSManager; this._default = builtinResMgr.get('default-cube-texture'); if (!this._model) { - this._model = legacyCC.director.root.createModel(legacyCC.renderer.scene.Model) as Model; + this._model = cclegacy.director.root.createModel(cclegacy.renderer.scene.Model) as Model; //The skybox material has added properties of 'environmentMap' that need local ubo //this._model._initLocalDescriptors = () => {}; //this._model._initWorldBoundDescriptors = () => {}; @@ -335,7 +333,7 @@ export class Skybox { if (this.enabled) { if (!skybox_mesh) { - skybox_mesh = legacyCC.utils.createMesh(legacyCC.primitives.box({ width: 2, height: 2, length: 2 })) as Mesh; + skybox_mesh = cclegacy.utils.createMesh(cclegacy.primitives.box({ width: 2, height: 2, length: 2 })) as Mesh; } if (this._editableMaterial) { this._model.initSubModel(0, skybox_mesh.renderingSubMeshes[0], this._editableMaterial); @@ -359,7 +357,7 @@ export class Skybox { } protected _updatePipeline () { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; const pipeline = root.pipeline; const useIBLValue = this.useIBL ? (this.isRGBE ? 2 : 1) : 0; @@ -435,4 +433,4 @@ export class Skybox { } } -legacyCC.Skybox = Skybox; +cclegacy.Skybox = Skybox; diff --git a/cocos/render-scene/scene/sphere-light.ts b/cocos/render-scene/scene/sphere-light.ts index c6c78ea4fc4..41c95e37917 100644 --- a/cocos/render-scene/scene/sphere-light.ts +++ b/cocos/render-scene/scene/sphere-light.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { AABB } from '../../core/geometry'; -import { legacyCC } from '../../core/global-exports'; -import { Vec3 } from '../../core/math'; +import { Vec3, cclegacy, geometry } from '../../core'; import { Light, LightType, nt2lm } from './light'; /** @@ -73,7 +70,7 @@ export class SphereLight extends Light { * @zh 光源的亮度 */ get luminance (): number { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._luminanceHDR; } else { @@ -81,7 +78,7 @@ export class SphereLight extends Light { } } set luminance (value: number) { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this.luminanceHDR = value; } else { @@ -122,11 +119,11 @@ export class SphereLight extends Light { protected _luminanceHDR = 0; protected _luminanceLDR = 0; protected _pos: Vec3; - protected _aabb: AABB; + protected _aabb: geometry.AABB; constructor () { super(); - this._aabb = AABB.create(); + this._aabb = geometry.AABB.create(); this._pos = new Vec3(); this._type = LightType.SPHERE; } @@ -149,7 +146,7 @@ export class SphereLight extends Light { if (this._node && (this._node.hasChangedFlags || this._needUpdate)) { this._node.getWorldPosition(this._pos); const range = this._range; - AABB.set(this._aabb, this._pos.x, this._pos.y, this._pos.z, range, range, range); + geometry.AABB.set(this._aabb, this._pos.x, this._pos.y, this._pos.z, range, range, range); this._needUpdate = false; } } diff --git a/cocos/render-scene/scene/spot-light.ts b/cocos/render-scene/scene/spot-light.ts index 5979a0acac4..1c6b9498dc6 100644 --- a/cocos/render-scene/scene/spot-light.ts +++ b/cocos/render-scene/scene/spot-light.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { AABB, Frustum } from '../../core/geometry'; -import { legacyCC } from '../../core/global-exports'; -import { Mat4, Quat, Vec3 } from '../../core/math'; +import { Mat4, Quat, Vec3, geometry, cclegacy } from '../../core'; import { Light, LightType, nt2lm } from './light'; import { PCFType } from './shadows'; @@ -49,9 +46,9 @@ export class SpotLight extends Light { protected _pos: Vec3; - protected _aabb: AABB; + protected _aabb: geometry.AABB; - protected _frustum: Frustum; + protected _frustum: geometry.Frustum; /** * @en User-specified full-angle radians. @@ -112,7 +109,7 @@ export class SpotLight extends Light { * @zh 光源的亮度 */ get luminance (): number { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { return this._luminanceHDR; } else { @@ -120,7 +117,7 @@ export class SpotLight extends Light { } } set luminance (value: number) { - const isHDR = (legacyCC.director.root).pipeline.pipelineSceneData.isHDR; + const isHDR = (cclegacy.director.root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this.luminanceHDR = value; } else { @@ -242,8 +239,8 @@ export class SpotLight extends Light { constructor () { super(); - this._aabb = AABB.create(); - this._frustum = Frustum.create(); + this._aabb = geometry.AABB.create(); + this._frustum = geometry.Frustum.create(); this._pos = new Vec3(); this._type = LightType.SPOT; } @@ -265,7 +262,7 @@ export class SpotLight extends Light { Vec3.transformQuat(this._dir, _forward, this._node.getWorldRotation(_qt)); Vec3.normalize(this._dir, this._dir); - AABB.set(this._aabb, this._pos.x, this._pos.y, this._pos.z, this._range, this._range, this._range); + geometry.AABB.set(this._aabb, this._pos.x, this._pos.y, this._pos.z, this._range, this._range, this._range); // view matrix this._node.getWorldRT(_matView); diff --git a/cocos/render-scene/scene/submodel.jsb.ts b/cocos/render-scene/scene/submodel.jsb.ts index a6a0c8ca512..dc230d2e92f 100644 --- a/cocos/render-scene/scene/submodel.jsb.ts +++ b/cocos/render-scene/scene/submodel.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,6 +20,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export const SubModel = jsb.SubModel; diff --git a/cocos/render-scene/scene/submodel.ts b/cocos/render-scene/scene/submodel.ts index d8dd0a67b17..2df562def35 100644 --- a/cocos/render-scene/scene/submodel.ts +++ b/cocos/render-scene/scene/submodel.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { RenderingSubMesh } from '../../asset/assets/rendering-sub-mesh'; -import { RenderPriority, UNIFORM_REFLECTION_TEXTURE_BINDING, UNIFORM_REFLECTION_STORAGE_BINDING, INST_MAT_WORLD } from '../../rendering/define'; +import { RenderPriority, UNIFORM_REFLECTION_TEXTURE_BINDING, UNIFORM_REFLECTION_STORAGE_BINDING, + INST_MAT_WORLD, INST_SH, UBOSH, isEnableEffect } from '../../rendering/define'; import { BatchingSchemes, IMacroPatch, Pass } from '../core/pass'; import { DescriptorSet, DescriptorSetInfo, Device, InputAssembler, Texture, TextureType, TextureUsageBit, TextureInfo, - Format, Sampler, Filter, Address, Shader, SamplerInfo, deviceManager, Attribute, Feature, FormatInfos, getTypedArrayConstructor } from '../../gfx'; -import { legacyCC } from '../../core/global-exports'; -import { errorID } from '../../core/platform/debug'; + Format, Sampler, Filter, Address, Shader, SamplerInfo, deviceManager, + Attribute, Feature, FormatInfos, getTypedArrayConstructor } from '../../gfx'; +import { errorID, Mat4, cclegacy } from '../../core'; import { getPhaseID } from '../../rendering/pass-phase'; import { Root } from '../../root'; -import { Mat4 } from '../../core'; const _dsInfo = new DescriptorSetInfo(null!); const MAX_PASS_COUNT = 8; @@ -65,6 +64,8 @@ export class SubModel { protected _reflectionSampler: Sampler | null = null; protected _instancedAttributeBlock: IInstancedAttributeBlock = { buffer: null!, views: [], attributes: [] }; protected _instancedWorldMatrixIndex = -1; + protected _instancedSHIndex = -1; + protected _useReflectionProbeType = 0; /** * @en @@ -196,13 +197,35 @@ export class SubModel { * @en Get or set instance matrix id, access by sub model * @zh 获取或者设置硬件实例化中的矩阵索引,通过子模型访问 */ - set instancedWorldMatrixIndex (val : number) { + set instancedWorldMatrixIndex (val: number) { this._instancedWorldMatrixIndex = val; } get instancedWorldMatrixIndex () { return this._instancedWorldMatrixIndex; } + /** + * @en Get or set instance SH id, access by sub model + * @zh 获取或者设置硬件实例化中的球谐索引,通过子模型访问 + */ + set instancedSHIndex (val: number) { + this._instancedSHIndex = val; + } + get instancedSHIndex () { + return this._instancedSHIndex; + } + + /** + * @en Gets or sets the type of reflection probe, Used to process instance + * @zh 获取或设置使用反射探针的类型,用于处理instance + */ + set useReflectionProbeType (val) { + this._useReflectionProbeType = val; + } + get useReflectionProbeType () { + return this._useReflectionProbeType; + } + /** * @en * init sub model @@ -213,14 +236,14 @@ export class SubModel { * @param patches @en The shader's macro @zh 着色器的宏定义 */ public initialize (subMesh: RenderingSubMesh, passes: Pass[], patches: IMacroPatch[] | null = null): void { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; this._device = deviceManager.gfxDevice; _dsInfo.layout = passes[0].localSetLayout; this._inputAssembler = this._device.createInputAssembler(subMesh.iaInfo); this._descriptorSet = this._device.createDescriptorSet(_dsInfo); - const pipeline = (legacyCC.director.root as Root).pipeline; + const pipeline = (cclegacy.director.root as Root).pipeline; const occlusionPass = pipeline.pipelineSceneData.getOcclusionQueryPass(); if (occlusionPass) { const occlusionDSInfo = new DescriptorSetInfo(null!); @@ -238,9 +261,10 @@ export class SubModel { } this.priority = RenderPriority.DEFAULT; - + const r = cclegacy.rendering; // initialize resources for reflection material - if (passes[0].phase === getPhaseID('reflection')) { + if (((!r || !r.enableEffectImport) && passes[0].phase === getPhaseID('reflection')) + || (isEnableEffect() && passes[0].phaseID === r.getPhaseID(r.getPassID('default'), 'reflection'))) { let texWidth = root.mainWindow!.width; let texHeight = root.mainWindow!.height; const minSize = 512; @@ -283,7 +307,7 @@ export class SubModel { * 平面阴影着色器初始化 */ public initPlanarShadowShader () { - const pipeline = (legacyCC.director.root as Root).pipeline; + const pipeline = (cclegacy.director.root as Root).pipeline; const shadowInfo = pipeline.pipelineSceneData.shadows; this._planarShader = shadowInfo.getPlanarShader(this._patches); } @@ -298,7 +322,7 @@ export class SubModel { * @internal */ public initPlanarShadowInstanceShader () { - const pipeline = (legacyCC.director.root as Root).pipeline; + const pipeline = (cclegacy.director.root as Root).pipeline; const shadowInfo = pipeline.pipelineSceneData.shadows; this._planarInstanceShader = shadowInfo.getPlanarInstanceShader(this._patches); } @@ -398,8 +422,14 @@ export class SubModel { // update draw info const drawInfo = this._subMesh.drawInfo; + + // to invoke getter/setter function for wasm object if (this._inputAssembler && drawInfo) { - Object.assign(this._inputAssembler.drawInfo, drawInfo); + const dirtyDrawInfo = this._inputAssembler.drawInfo; + Object.keys(drawInfo).forEach((key) => { + dirtyDrawInfo[key] = drawInfo[key]; + }); + this._inputAssembler.drawInfo = dirtyDrawInfo; } } @@ -438,6 +468,28 @@ export class SubModel { v2[0] = mat.m04; v2[1] = mat.m05; v2[2] = mat.m06; v2[3] = mat.m13; v3[0] = mat.m08; v3[1] = mat.m09; v3[2] = mat.m10; v3[3] = mat.m14; } + + /** + * @en + * update instancing SH data, invoked by model + * @zh + * 更新硬件实例化球谐数据,一般由model调用 + */ + /** + * @internal + */ + public updateInstancedSH (data: Float32Array, idx: number) { + const attrs = this.instancedAttributeBlock.views; + const count = (UBOSH.SH_QUADRATIC_R_OFFSET - UBOSH.SH_LINEAR_CONST_R_OFFSET) / 4; + let offset = 0; + + for (let i = idx; i < idx + count; i++) { + for (let k = 0; k < 4; k++) { + attrs[i][k] = data[offset++]; + } + } + } + /** * @en * update instancing related data, invoked by model @@ -450,6 +502,7 @@ export class SubModel { public UpdateInstancedAttributes (attributes: Attribute[]) { // initialize subModelWorldMatrixIndex this.instancedWorldMatrixIndex = -1; + this.instancedSHIndex = -1; const pass = this.passes[0]; if (!pass.device.hasFeature(Feature.INSTANCED_ARRAYS)) { return; } @@ -484,6 +537,7 @@ export class SubModel { } if (pass.batchingScheme === BatchingSchemes.INSTANCING) { pass.getInstancedBuffer().destroy(); } // instancing IA changed this.instancedWorldMatrixIndex = this.getInstancedAttributeIndex(INST_MAT_WORLD); + this.instancedSHIndex = this.getInstancedAttributeIndex(INST_SH); } protected _flushPassInfo (): void { diff --git a/cocos/render-scene/utils.ts b/cocos/render-scene/utils.ts index fc8b8de4d0d..8c9b9fd62e9 100644 --- a/cocos/render-scene/utils.ts +++ b/cocos/render-scene/utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Attribute, Buffer, BufferInfo, Device, InputAssemblerInfo, AttributeName, BufferUsageBit, Format, MemoryUsageBit } from '../gfx'; import { IGeometry } from '../primitive/define'; diff --git a/cocos/rendering/batched-buffer.ts b/cocos/rendering/batched-buffer.ts index c71643b1c62..99188d6cb47 100644 --- a/cocos/rendering/batched-buffer.ts +++ b/cocos/rendering/batched-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BufferUsageBit, Format, MemoryUsageBit, Device, DescriptorSet, InputAssembler, InputAssemblerInfo, Attribute, Buffer, BufferInfo, Shader } from '../gfx'; -import { Mat4 } from '../core/math'; +import { Mat4 } from '../core'; import { SubModel } from '../render-scene/scene/submodel'; import { UBOLocalBatched } from './define'; import { Pass } from '../render-scene'; diff --git a/cocos/rendering/custom/archive.ts b/cocos/rendering/custom/archive.ts index a5c0eb2837c..9b513ffc2bd 100644 --- a/cocos/rendering/custom/archive.ts +++ b/cocos/rendering/custom/archive.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/rendering/custom/binary-archive.ts b/cocos/rendering/custom/binary-archive.ts new file mode 100644 index 00000000000..c0d3f328f84 --- /dev/null +++ b/cocos/rendering/custom/binary-archive.ts @@ -0,0 +1,98 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { OutputArchive, InputArchive } from './archive'; + +export class BinaryOutputArchive implements OutputArchive { + constructor () { + this.capacity = 4096; + this.buffer = new Uint8Array(this.capacity); + this.dataView = new DataView(this.buffer.buffer); + } + writeBool (value: boolean): void { + const newSize = this.size + 1; + if (newSize > this.capacity) { + this.reserve(newSize); + } + this.dataView.setUint8(this.size, value ? 1 : 0); + this.size = newSize; + } + writeNumber (value: number): void { + const newSize = this.size + 8; + if (newSize > this.capacity) { + this.reserve(newSize); + } + this.dataView.setFloat64(this.size, value, true); + this.size = newSize; + } + writeString (value: string): void { + this.writeNumber(value.length); + const newSize = this.size + value.length; + if (newSize > this.capacity) { + this.reserve(newSize); + } + for (let i = 0; i < value.length; i++) { + this.dataView.setUint8(this.size + i, value.charCodeAt(i)); + } + this.size = newSize; + } + reserve (requiredSize: number): void { + const newCapacity = Math.max(requiredSize, this.capacity * 2); + const prevBuffer = this.buffer; + this.buffer = new Uint8Array(newCapacity); + this.buffer.set(prevBuffer); + this.dataView = new DataView(this.buffer.buffer); + this.capacity = newCapacity; + } + get data (): ArrayBuffer { + return this.buffer.buffer.slice(0, this.size); + } + capacity = 0; + size = 0; + buffer: Uint8Array; + dataView: DataView; +} + +export class BinaryInputArchive implements InputArchive { + constructor (data: ArrayBuffer) { + this.dataView = new DataView(data); + } + readBool (): boolean { + return this.dataView.getUint8(this.offset++) !== 0; + } + readNumber (): number { + const value = this.dataView.getFloat64(this.offset, true); + this.offset += 8; + return value; + } + readString (): string { + const length = this.readNumber(); + const value = new Uint8Array(this.dataView.buffer, this.offset, length); + this.offset += length; + return this.textDecoder.decode(value); + } + offset = 0; + dataView: DataView; + textDecoder = new TextDecoder('utf-8'); +} diff --git a/cocos/rendering/custom/builtin-pipelines.ts b/cocos/rendering/custom/builtin-pipelines.ts index 3e0800b7d79..b2d12a1ae80 100644 --- a/cocos/rendering/custom/builtin-pipelines.ts +++ b/cocos/rendering/custom/builtin-pipelines.ts @@ -1,6 +1,33 @@ -import { Camera } from '../../render-scene/scene'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { EDITOR } from 'internal:constants'; +import { Camera, CameraUsage } from '../../render-scene/scene'; import { Pipeline, PipelineBuilder } from './pipeline'; -import { buildForwardPass, buildGBufferPass, buildLightingPass, buildPostprocessPass } from './define'; +import { buildForwardPass, buildGBufferPass, buildLightingPass, buildPostprocessPass, + buildReflectionProbePasss, buildUIPass } from './define'; +import { isUICamera } from './utils'; export class ForwardPipelineBuilder implements PipelineBuilder { public setup (cameras: Camera[], ppl: Pipeline): void { @@ -11,6 +38,9 @@ export class ForwardPipelineBuilder implements PipelineBuilder { } // forward pass buildForwardPass(camera, ppl, false); + if (EDITOR) { + buildReflectionProbePasss(camera, ppl, false); + } } } } @@ -22,12 +52,23 @@ export class DeferredPipelineBuilder implements PipelineBuilder { if (!camera.scene) { continue; } + const isGameView = camera.cameraUsage === CameraUsage.GAME + || camera.cameraUsage === CameraUsage.GAME_VIEW; + if (!isGameView) { + buildForwardPass(camera, ppl, false); + continue; + } + if (!isUICamera(camera)) { // GBuffer Pass - const gBufferInfo = buildGBufferPass(camera, ppl); - // Lighting Pass - const lightInfo = buildLightingPass(camera, ppl, gBufferInfo); - // Postprocess - buildPostprocessPass(camera, ppl, lightInfo.rtName); + const gBufferInfo = buildGBufferPass(camera, ppl); + // Lighting Pass + const lightInfo = buildLightingPass(camera, ppl, gBufferInfo); + // Postprocess + buildPostprocessPass(camera, ppl, lightInfo.rtName); + continue; + } + // render ui + buildUIPass(camera, ppl); } } } diff --git a/cocos/rendering/custom/compiler.ts b/cocos/rendering/custom/compiler.ts index 4ef052f4b2d..87554f5d3d8 100644 --- a/cocos/rendering/custom/compiler.ts +++ b/cocos/rendering/custom/compiler.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ THE SOFTWARE. ****************************************************************************/ import { Buffer, Framebuffer, Texture, Viewport } from '../../gfx'; -import { assert } from '../../core/platform/debug'; +import { assert } from '../../core'; import { VectorGraphColorMap } from './effect'; import { DefaultVisitor, depthFirstSearch, ReferenceGraphView } from './graph'; import { LayoutGraphData } from './layout-graph'; @@ -53,7 +52,7 @@ class PassVisitor implements RenderGraphVisitor { protected _isScene (u: number): boolean { return !!this.context.renderGraph.tryGetScene(u); } - protected _isBlit(u: number): boolean { + protected _isBlit (u: number): boolean { return !!this.context.renderGraph.tryGetBlit(u); } private _fetchValidPass () { @@ -166,10 +165,10 @@ class ResourceVisitor implements ResourceGraphVisitor { constructor (context: CompilerContext) { this._context = context; } - managedBuffer(value: ManagedBuffer) { + managedBuffer (value: ManagedBuffer) { // noop } - managedTexture(value: ManagedTexture) { + managedTexture (value: ManagedTexture) { // noop } managed (value: ManagedResource) { diff --git a/cocos/rendering/custom/custom-pipeline.ts b/cocos/rendering/custom/custom-pipeline.ts index 1d7bbd8a954..66605e74fea 100644 --- a/cocos/rendering/custom/custom-pipeline.ts +++ b/cocos/rendering/custom/custom-pipeline.ts @@ -1,6 +1,33 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { Camera, CameraUsage } from '../../render-scene/scene'; -import { buildBloomPass as buildBloomPasses, buildForwardPass, buildPostprocessPass } from './define'; +import { buildFxaaPass, buildBloomPass as buildBloomPasses, buildForwardPass, + buildNativeDeferredPipeline, buildNativeForwardPass, buildPostprocessPass, + AntiAliasing, buildUIPass } from './define'; import { Pipeline, PipelineBuilder } from './pipeline'; +import { isUICamera } from './utils'; export class CustomPipelineBuilder implements PipelineBuilder { public setup (cameras: Camera[], ppl: Pipeline): void { @@ -11,15 +38,42 @@ export class CustomPipelineBuilder implements PipelineBuilder { } const isGameView = camera.cameraUsage === CameraUsage.GAME || camera.cameraUsage === CameraUsage.GAME_VIEW; - // forward pass - const forwardInfo = buildForwardPass(camera, ppl, isGameView); if (!isGameView) { - return; + // forward pass + buildForwardPass(camera, ppl, isGameView); + continue; + } + // TODO: There is currently no effective way to judge the ui camera. Let’s do this first. + if (!isUICamera(camera)) { + // forward pass + const forwardInfo = buildForwardPass(camera, ppl, isGameView); + // fxaa pass + const fxaaInfo = buildFxaaPass(camera, ppl, forwardInfo.rtName); + // bloom passes + const bloomInfo = buildBloomPasses(camera, ppl, fxaaInfo.rtName); + // Present Pass + buildPostprocessPass(camera, ppl, bloomInfo.rtName, AntiAliasing.NONE); + continue; + } + // render ui + buildUIPass(camera, ppl); + } + } +} + +export class NativePipelineBuilder implements PipelineBuilder { + public setup (cameras: Camera[], ppl: Pipeline): void { + for (let i = 0; i < cameras.length; i++) { + const camera = cameras[i]; + if (camera.scene === null) { + continue; + } + if (camera.cameraUsage !== CameraUsage.GAME) { + buildForwardPass(camera, ppl, false); + continue; } - // bloom passes - const bloomInfo = buildBloomPasses(camera, ppl, forwardInfo.rtName); - // Present Pass - buildPostprocessPass(camera, ppl, bloomInfo.rtName); + buildNativeForwardPass(camera, ppl); + // buildNativeDeferredPipeline(camera, ppl); } } } diff --git a/cocos/rendering/custom/debug.ts b/cocos/rendering/custom/debug.ts index 2af3363d0fb..db25637153c 100644 --- a/cocos/rendering/custom/debug.ts +++ b/cocos/rendering/custom/debug.ts @@ -1,8 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + /* eslint-disable max-len */ import { Viewport } from '../../gfx'; -import { assert } from '../../core/platform'; -import { DefaultVisitor, ReferenceGraphView, ED, edge_descriptor, IncidenceGraph } from './graph'; -import { Blit, ClearView, ComputePass, CopyPass, Dispatch, getRenderGraphValueName, MovePass, PresentPass, RasterPass, RaytracePass, RenderGraph, RenderGraphValue, RenderGraphVisitor, RenderQueue, SceneData } from './render-graph'; +import { assert } from '../../core'; +import { DefaultVisitor, ReferenceGraphView, ED} from './graph'; +import { Blit, ClearView, ComputePass, CopyPass, Dispatch, getRenderGraphValueName, MovePass, PresentPass, RasterPass, RaytracePass, RenderGraph, RenderGraphVisitor, RenderQueue, SceneData } from './render-graph'; import { getQueueHintName } from './types'; export const enableDebug = true; diff --git a/cocos/rendering/custom/define.ts b/cocos/rendering/custom/define.ts index 84ee37a35e5..a243ca10867 100644 --- a/cocos/rendering/custom/define.ts +++ b/cocos/rendering/custom/define.ts @@ -1,25 +1,57 @@ -import { ClearFlagBit, Color, Format, LoadOp, Rect, StoreOp, Viewport } from '../../gfx/base/define'; -import { Camera, CSMLevel, DirectionalLight, Light, LightType, ShadowType, SKYBOX_FLAG, SpotLight } from '../../render-scene/scene'; -import { intersect, Sphere } from '../../core/geometry'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { BufferInfo, Buffer, BufferUsageBit, ClearFlagBit, Color, DescriptorSet, LoadOp, + Format, Rect, Sampler, StoreOp, Texture, Viewport, MemoryUsageBit } from '../../gfx'; +import { Camera, CSMLevel, DirectionalLight, Light, LightType, ReflectionProbe, ShadowType, SKYBOX_FLAG, SpotLight } from '../../render-scene/scene'; import { supportsR32FloatTexture } from '../define'; import { Pipeline } from './pipeline'; -import { AccessType, AttachmentType, ComputeView, LightInfo, QueueHint, RasterView, ResourceResidency, SceneFlags } from './types'; -import { Vec4 } from '../../core/math'; +import { AccessType, AttachmentType, ComputeView, LightInfo, QueueHint, RasterView, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; +import { Vec4, macro, geometry, toRadian, cclegacy, assert } from '../../core'; import { Material } from '../../asset/assets'; -import { macro } from '../../core/platform'; -import { SRGBToLinear } from '../pipeline-funcs'; +import { getProfilerCamera, SRGBToLinear } from '../pipeline-funcs'; +import { RenderWindow } from '../../render-scene/core/render-window'; +import { RenderData } from './render-graph'; +import { WebPipeline } from './web-pipeline'; +import { DescriptorSetData } from './layout-graph'; +import { AABB } from '../../core/geometry'; + +const _rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5); +const _tmpBoundingBox = new AABB(); // Anti-aliasing type, other types will be gradually added in the future export enum AntiAliasing { NONE, FXAA, + FXAAHQ, } export function validPunctualLightsCulling (pipeline: Pipeline, camera: Camera) { const sceneData = pipeline.pipelineSceneData; const validPunctualLights = sceneData.validPunctualLights; validPunctualLights.length = 0; - const _sphere = Sphere.create(0, 0, 0, 1); + const _sphere = geometry.Sphere.create(0, 0, 0, 1); const { spotLights } = camera.scene!; for (let i = 0; i < spotLights.length; i++) { const light = spotLights[i]; @@ -27,8 +59,8 @@ export function validPunctualLightsCulling (pipeline: Pipeline, camera: Camera) continue; } - Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); - if (intersect.sphereFrustum(_sphere, camera.frustum)) { + geometry.Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (geometry.intersect.sphereFrustum(_sphere, camera.frustum)) { validPunctualLights.push(light); } } @@ -39,8 +71,29 @@ export function validPunctualLightsCulling (pipeline: Pipeline, camera: Camera) if (light.baked) { continue; } - Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); - if (intersect.sphereFrustum(_sphere, camera.frustum)) { + geometry.Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (geometry.intersect.sphereFrustum(_sphere, camera.frustum)) { + validPunctualLights.push(light); + } + } + + const { pointLights } = camera.scene!; + for (let i = 0; i < pointLights.length; i++) { + const light = pointLights[i]; + if (light.baked) { + continue; + } + geometry.Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (geometry.intersect.sphereFrustum(_sphere, camera.frustum)) { + validPunctualLights.push(light); + } + } + + const { rangedDirLights } = camera.scene!; + for (let i = 0; i < rangedDirLights.length; i++) { + const light = rangedDirLights[i]; + AABB.transform(_tmpBoundingBox, _rangedDirLightBoundingBox, light.node!.getWorldMatrix()); + if (geometry.intersect.aabbFrustum(_tmpBoundingBox, camera.frustum)) { validPunctualLights.push(light); } } @@ -60,7 +113,7 @@ export function getLoadOpOfClearFlag (clearFlag: ClearFlagBit, attachment: Attac if (!(clearFlag & ClearFlagBit.COLOR) && attachment === AttachmentType.RENDER_TARGET) { if (clearFlag & SKYBOX_FLAG) { - loadOp = LoadOp.DISCARD; + loadOp = LoadOp.CLEAR; } else { loadOp = LoadOp.LOAD; } @@ -92,8 +145,13 @@ export function getRenderArea (camera: Camera, width: number, height: number, li out.width = w; out.height = h; } else { + const screenSpaceSignY = cclegacy.director.root.device.capabilities.screenSpaceSignY; out.x = level % 2 * 0.5 * w; - out.y = (1 - Math.floor(level / 2)) * 0.5 * h; + if (screenSpaceSignY) { + out.y = (1 - Math.floor(level / 2)) * 0.5 * h; + } else { + out.y = Math.floor(level / 2) * 0.5 * h; + } out.width = 0.5 * w; out.height = 0.5 * h; } @@ -112,6 +170,87 @@ export function getRenderArea (camera: Camera, width: number, height: number, li return out; } +class FxaaData { + declare fxaaMaterial: Material; + private _updateFxaaPass () { + if (!this.fxaaMaterial) return; + + const combinePass = this.fxaaMaterial.passes[0]; + combinePass.beginChangeStatesSilently(); + combinePass.tryCompile(); + combinePass.endChangeStatesSilently(); + } + private _init () { + if (this.fxaaMaterial) return; + this.fxaaMaterial = new Material(); + this.fxaaMaterial._uuid = 'builtin-fxaa-material'; + this.fxaaMaterial.initialize({ effectName: 'pipeline/fxaa-hq' }); + for (let i = 0; i < this.fxaaMaterial.passes.length; ++i) { + this.fxaaMaterial.passes[i].tryCompile(); + } + this._updateFxaaPass(); + } + constructor () { + this._init(); + } +} + +let fxaaData: FxaaData | null = null; +export function buildFxaaPass (camera: Camera, + ppl: Pipeline, + inputRT: string) { + if (!fxaaData) { + fxaaData = new FxaaData(); + } + const cameraID = getCameraUniqueID(camera); + const cameraName = `Camera${cameraID}`; + let width = camera.window.width; + let height = camera.window.height; + const area = getRenderArea(camera, width, height); + width = area.width; + height = area.height; + // Start + const clearColor = new Color(0, 0, 0, 1); + if (camera.clearFlag & ClearFlagBit.COLOR) { + clearColor.x = camera.clearColor.x; + clearColor.y = camera.clearColor.y; + clearColor.z = camera.clearColor.z; + } + clearColor.w = camera.clearColor.w; + + const fxaaPassRTName = `dsFxaaPassColor${cameraName}`; + const fxaaPassDSName = `dsFxaaPassDS${cameraName}`; + + // ppl.updateRenderWindow(inputRT, camera.window); + if (!ppl.containsResource(fxaaPassRTName)) { + ppl.addRenderTarget(fxaaPassRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); + ppl.addDepthStencil(fxaaPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); + } + ppl.updateRenderTarget(fxaaPassRTName, width, height); + ppl.updateDepthStencil(fxaaPassDSName, width, height); + const fxaaPassIdx = 0; + const fxaaPass = ppl.addRasterPass(width, height, 'fxaa'); + fxaaPass.name = `CameraFxaaPass${cameraID}`; + fxaaPass.setViewport(new Viewport(area.x, area.y, width, height)); + if (ppl.containsResource(inputRT)) { + const computeView = new ComputeView(); + computeView.name = 'sceneColorMap'; + fxaaPass.addComputeView(inputRT, computeView); + } + const fxaaPassView = new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + LoadOp.CLEAR, StoreOp.STORE, + camera.clearFlag, + clearColor); + fxaaPass.addRasterView(fxaaPassRTName, fxaaPassView); + fxaaData.fxaaMaterial.setProperty('texSize', new Vec4(width, height, 1.0 / width, 1.0 / height), fxaaPassIdx); + fxaaPass.addQueue(QueueHint.RENDER_TRANSPARENT).addCameraQuad( + camera, fxaaData.fxaaMaterial, fxaaPassIdx, + SceneFlags.NONE, + ); + return { rtName: fxaaPassRTName, dsName: fxaaPassDSName }; +} + export const MAX_BLOOM_FILTER_PASS_NUM = 6; export const BLOOM_PREFILTERPASS_INDEX = 0; export const BLOOM_DOWNSAMPLEPASS_INDEX = 1; @@ -199,7 +338,10 @@ export function buildBloomPass (camera: Camera, ppl.addRenderTarget(bloomPassPrefilterRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(bloomPassPrefilterDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } - const bloomPrefilterPass = ppl.addRasterPass(width, height, 'Bloom_Prefilter', `CameraBloomPrefilterPass${cameraID}`); + ppl.updateRenderTarget(bloomPassPrefilterRTName, width, height); + ppl.updateDepthStencil(bloomPassPrefilterDSName, width, height); + const bloomPrefilterPass = ppl.addRasterPass(width, height, 'bloom-prefilter'); + bloomPrefilterPass.name = `CameraBloomPrefilterPass${cameraID}`; bloomPrefilterPass.setViewport(new Viewport(area.x, area.y, width, height)); if (ppl.containsResource(inputRT)) { const computeView = new ComputeView(); @@ -228,7 +370,10 @@ export function buildBloomPass (camera: Camera, ppl.addRenderTarget(bloomPassDownSampleRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(bloomPassDownSampleDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } - const bloomDownSamplePass = ppl.addRasterPass(width, height, `Bloom_Downsample${i}`, `CameraBloomDownSamplePass${cameraID}${i}`); + ppl.updateRenderTarget(bloomPassDownSampleRTName, width, height); + ppl.updateDepthStencil(bloomPassDownSampleDSName, width, height); + const bloomDownSamplePass = ppl.addRasterPass(width, height, `bloom-downsample${i}`); + bloomDownSamplePass.name = `CameraBloomDownSamplePass${cameraID}${i}`; bloomDownSamplePass.setViewport(new Viewport(area.x, area.y, width, height)); const computeView = new ComputeView(); computeView.name = 'bloomTexture'; @@ -260,8 +405,10 @@ export function buildBloomPass (camera: Camera, ppl.addRenderTarget(bloomPassUpSampleRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(bloomPassUpSampleDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } - const bloomUpSamplePass = ppl.addRasterPass(width, height, `Bloom_Upsample${i}`, - `CameraBloomUpSamplePass${cameraID}${bloomData.iterations - 1 - i}`); + ppl.updateRenderTarget(bloomPassUpSampleRTName, width, height); + ppl.updateDepthStencil(bloomPassUpSampleDSName, width, height); + const bloomUpSamplePass = ppl.addRasterPass(width, height, `bloom-upsample${i}`); + bloomUpSamplePass.name = `CameraBloomUpSamplePass${cameraID}${bloomData.iterations - 1 - i}`; bloomUpSamplePass.setViewport(new Viewport(area.x, area.y, width, height)); const computeView = new ComputeView(); computeView.name = 'bloomTexture'; @@ -292,7 +439,10 @@ export function buildBloomPass (camera: Camera, ppl.addRenderTarget(bloomPassCombineRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(bloomPassCombineDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } - const bloomCombinePass = ppl.addRasterPass(width, height, 'Bloom_Combine', `CameraBloomCombinePass${cameraID}`); + ppl.updateRenderTarget(bloomPassCombineRTName, width, height); + ppl.updateDepthStencil(bloomPassCombineDSName, width, height); + const bloomCombinePass = ppl.addRasterPass(width, height, 'bloom-combine'); + bloomCombinePass.name = `CameraBloomCombinePass${cameraID}`; bloomCombinePass.setViewport(new Viewport(area.x, area.y, width, height)); const computeViewOut = new ComputeView(); computeViewOut.name = 'outputResultMap'; @@ -356,10 +506,13 @@ export function buildPostprocessPass (camera: Camera, const postprocessPassRTName = `postprocessPassRTName${cameraID}`; const postprocessPassDS = `postprocessPassDS${cameraID}`; if (!ppl.containsResource(postprocessPassRTName)) { - ppl.addRenderTexture(postprocessPassRTName, Format.RGBA8, width, height, camera.window); + ppl.addRenderTexture(postprocessPassRTName, Format.BGRA8, width, height, camera.window); ppl.addDepthStencil(postprocessPassDS, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } - const postprocessPass = ppl.addRasterPass(width, height, 'Postprocess', `CameraPostprocessPass${cameraID}`); + ppl.updateRenderWindow(postprocessPassRTName, camera.window); + ppl.updateDepthStencil(postprocessPassDS, width, height); + const postprocessPass = ppl.addRasterPass(width, height, 'post-process'); + postprocessPass.name = `CameraPostprocessPass${cameraID}`; postprocessPass.setViewport(new Viewport(area.x, area.y, area.width, area.height)); if (ppl.containsResource(inputTex)) { const computeView = new ComputeView(); @@ -390,7 +543,10 @@ export function buildPostprocessPass (camera: Camera, postInfo.postMaterial, 0, SceneFlags.NONE, ); postprocessPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, new LightInfo(), - SceneFlags.UI | SceneFlags.PROFILER); + SceneFlags.UI); + if (getProfilerCamera() === camera) { + postprocessPass.showStatistics = true; + } return { rtName: postprocessPassRTName, dsName: postprocessPassDS }; } @@ -408,23 +564,31 @@ export function buildForwardPass (camera: Camera, const forwardPassDSName = `dsForwardPassDS${cameraName}`; if (!ppl.containsResource(forwardPassRTName)) { if (!isOffScreen) { - ppl.addRenderTexture(forwardPassRTName, Format.RGBA8, width, height, camera.window); + ppl.addRenderTexture(forwardPassRTName, Format.BGRA8, width, height, camera.window); } else { ppl.addRenderTarget(forwardPassRTName, Format.RGBA16F, width, height, ResourceResidency.MANAGED); } ppl.addDepthStencil(forwardPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } - const forwardPass = ppl.addRasterPass(width, height, 'default', `CameraForwardPass${cameraID}`); + if (!isOffScreen) { + ppl.updateRenderWindow(forwardPassRTName, camera.window); + ppl.updateDepthStencil(forwardPassDSName, width, height); + } else { + ppl.updateRenderTarget(forwardPassRTName, width, height); + ppl.updateDepthStencil(forwardPassDSName, width, height); + } + const forwardPass = ppl.addRasterPass(width, height, 'default'); + forwardPass.name = `CameraForwardPass${cameraID}`; forwardPass.setViewport(new Viewport(area.x, area.y, width, height)); for (const dirShadowName of cameraInfo.mainLightShadowNames) { if (ppl.containsResource(dirShadowName)) { - const computeView = new ComputeView(); + const computeView = new ComputeView('cc_shadowMap'); forwardPass.addComputeView(dirShadowName, computeView); } } for (const spotShadowName of cameraInfo.spotLightShadowNames) { if (ppl.containsResource(spotShadowName)) { - const computeView = new ComputeView(); + const computeView = new ComputeView('cc_spotShadowMap'); forwardPass.addComputeView(spotShadowName, computeView); } } @@ -447,14 +611,14 @@ export function buildForwardPass (camera: Camera, .addSceneOfCamera(camera, new LightInfo(), SceneFlags.OPAQUE_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.CUTOUT_OBJECT | SceneFlags.DEFAULT_LIGHTING | SceneFlags.DRAW_INSTANCING); - forwardPass - .addQueue(QueueHint.RENDER_TRANSPARENT) - .addSceneOfCamera(camera, new LightInfo(), SceneFlags.TRANSPARENT_OBJECT | SceneFlags.GEOMETRY); + let sceneFlags = SceneFlags.TRANSPARENT_OBJECT | SceneFlags.GEOMETRY; if (!isOffScreen) { - forwardPass - .addQueue(QueueHint.RENDER_TRANSPARENT) - .addSceneOfCamera(camera, new LightInfo(), SceneFlags.UI | SceneFlags.PROFILER); + sceneFlags |= SceneFlags.UI; + forwardPass.showStatistics = true; } + forwardPass + .addQueue(QueueHint.RENDER_TRANSPARENT) + .addSceneOfCamera(camera, new LightInfo(), sceneFlags); return { rtName: forwardPassRTName, dsName: forwardPassDSName }; } @@ -462,6 +626,8 @@ export function buildShadowPass (passName: Readonly, ppl: Pipeline, camera: Camera, light: Light, level: number, width: Readonly, height: Readonly) { + const fboW = width; + const fboH = height; const area = getRenderArea(camera, width, height, light, level); width = area.width; height = area.height; @@ -469,10 +635,13 @@ export function buildShadowPass (passName: Readonly, const shadowMapName = passName; if (!ppl.containsResource(shadowMapName)) { const format = supportsR32FloatTexture(device) ? Format.R32F : Format.RGBA8; - ppl.addRenderTarget(shadowMapName, format, width, height, ResourceResidency.MANAGED); - ppl.addDepthStencil(`${shadowMapName}Depth`, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); + ppl.addRenderTarget(shadowMapName, format, fboW, fboH, ResourceResidency.MANAGED); + ppl.addDepthStencil(`${shadowMapName}Depth`, Format.DEPTH_STENCIL, fboW, fboH, ResourceResidency.MANAGED); } - const pass = ppl.addRasterPass(width, height, 'default', passName); + ppl.updateRenderTarget(shadowMapName, fboW, fboH); + ppl.updateDepthStencil(`${shadowMapName}Depth`, fboW, fboH); + const pass = ppl.addRasterPass(width, height, 'default'); + pass.name = passName; pass.setViewport(new Viewport(area.x, area.y, area.width, area.height)); pass.addRasterView(shadowMapName, new RasterView('_', AccessType.WRITE, AttachmentType.RENDER_TARGET, @@ -489,6 +658,67 @@ export function buildShadowPass (passName: Readonly, SceneFlags.SHADOW_CASTER); } +export function buildReflectionProbePasss (camera: Camera, + ppl: Pipeline, + isOffScreen: boolean) { + const probes = cclegacy.internal.reflectionProbeManager.getProbes(); + if (probes.length === 0) { + return; + } + for (let i = 0; i < probes.length; i++) { + const probe = probes[i]; + if (probe.needRender) { + for (let faceIdx = 0; faceIdx < probe.bakedCubeTextures.length; faceIdx++) { + buildReflectionProbePass(camera, ppl, probe, probe.bakedCubeTextures[faceIdx].window!, faceIdx); + } + probe.needRender = false; + } + } +} + +export function buildReflectionProbePass (camera: Camera, + ppl: Pipeline, probe: ReflectionProbe, renderWindow: RenderWindow, faceIdx: number) { + const cameraName = `Camera${faceIdx}`; + const area = probe.renderArea(); + const width = area.x; + const height = area.y; + const probeCamera = probe.camera; + + const probePassRTName = `reflectionProbePassColor${cameraName}`; + const probePassDSName = `reflectionProbePassDS${cameraName}`; + + probe.updateCameraDir(faceIdx); + + if (!ppl.containsResource(probePassRTName)) { + ppl.addRenderTexture(probePassRTName, Format.RGBA8, width, height, renderWindow); + ppl.addDepthStencil(probePassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); + } + ppl.updateRenderWindow(probePassRTName, renderWindow); + ppl.updateDepthStencil(probePassDSName, width, height); + + const probePass = ppl.addRasterPass(width, height, 'default'); + probePass.name = `ReflectionProbePass${faceIdx}`; + probePass.setViewport(new Viewport(0, 0, width, height)); + + const passView = new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + getLoadOpOfClearFlag(probeCamera.clearFlag, AttachmentType.RENDER_TARGET), + StoreOp.STORE, + probeCamera.clearFlag, + new Color(probeCamera.clearColor.x, probeCamera.clearColor.y, probeCamera.clearColor.z, probeCamera.clearColor.w)); + const passDSView = new RasterView('_', + AccessType.WRITE, AttachmentType.DEPTH_STENCIL, + getLoadOpOfClearFlag(probeCamera.clearFlag, AttachmentType.DEPTH_STENCIL), + StoreOp.STORE, + probeCamera.clearFlag, + new Color(probeCamera.clearDepth, probeCamera.clearStencil, 0, 0)); + probePass.addRasterView(probePassRTName, passView); + probePass.addRasterView(probePassDSName, passDSView); + const passBuilder = probePass.addQueue(QueueHint.RENDER_OPAQUE); + passBuilder.addSceneOfCamera(camera, new LightInfo(), SceneFlags.REFLECTION_PROBE); + updateCameraUBO(passBuilder as unknown as any, probeCamera, ppl); +} + class CameraInfo { shadowEnabled = false; mainLightShadowNames = new Array(); @@ -572,8 +802,13 @@ export function buildGBufferPass (camera: Camera, ppl.addRenderTarget(gBufferPassEmissive, colFormat, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(gBufferPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } + ppl.updateRenderTarget(gBufferPassRTName, width, height); + ppl.updateRenderTarget(gBufferPassNormal, width, height); + ppl.updateRenderTarget(gBufferPassEmissive, width, height); + ppl.updateDepthStencil(gBufferPassDSName, width, height); // gbuffer pass - const gBufferPass = ppl.addRasterPass(width, height, 'Geometry', `CameraGBufferPass${cameraID}`); + const gBufferPass = ppl.addRasterPass(width, height, 'default'); + gBufferPass.name = `CameraGBufferPass${cameraID}`; gBufferPass.setViewport(new Viewport(area.x, area.y, area.width, area.height)); const rtColor = new Color(0, 0, 0, 0); if (camera.clearFlag & ClearFlagBit.COLOR) { @@ -658,18 +893,21 @@ export function buildLightingPass (camera: Camera, ppl: Pipeline, gBuffer: GBuff ppl.addRenderTarget(deferredLightingPassRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(deferredLightingPassDS, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } + ppl.updateRenderTarget(deferredLightingPassRTName, width, height); + ppl.updateDepthStencil(deferredLightingPassDS, width, height); // lighting pass - const lightingPass = ppl.addRasterPass(width, height, 'Lighting', `CameraLightingPass${cameraID}`); + const lightingPass = ppl.addRasterPass(width, height, 'deferred-lighting'); + lightingPass.name = `CameraLightingPass${cameraID}`; lightingPass.setViewport(new Viewport(area.x, area.y, width, height)); for (const dirShadowName of cameraInfo.mainLightShadowNames) { if (ppl.containsResource(dirShadowName)) { - const computeView = new ComputeView(); + const computeView = new ComputeView('cc_shadowMap'); lightingPass.addComputeView(dirShadowName, computeView); } } for (const spotShadowName of cameraInfo.spotLightShadowNames) { if (ppl.containsResource(spotShadowName)) { - const computeView = new ComputeView(); + const computeView = new ComputeView('cc_spotShadowMap'); lightingPass.addComputeView(spotShadowName, computeView); } } @@ -707,7 +945,375 @@ export function buildLightingPass (camera: Camera, ppl: Pipeline, gBuffer: GBuff camera, lightingInfo.deferredLightingMaterial, 0, SceneFlags.VOLUMETRIC_LIGHTING, ); - lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, new LightInfo(), - SceneFlags.TRANSPARENT_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.GEOMETRY); + // lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, new LightInfo(), + // SceneFlags.TRANSPARENT_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.GEOMETRY); return { rtName: deferredLightingPassRTName, dsName: deferredLightingPassDS }; } + +function getClearFlags (attachment: AttachmentType, clearFlag: ClearFlagBit, loadOp: LoadOp): ClearFlagBit { + switch (attachment) { + case AttachmentType.DEPTH_STENCIL: + if (loadOp === LoadOp.CLEAR) { + if (clearFlag & ClearFlagBit.DEPTH_STENCIL) { + return clearFlag; + } else { + return ClearFlagBit.DEPTH_STENCIL; + } + } else { + return ClearFlagBit.NONE; + } + case AttachmentType.RENDER_TARGET: + default: + if (loadOp === LoadOp.CLEAR) { + return ClearFlagBit.COLOR; + } else { + return ClearFlagBit.NONE; + } + } +} + +export function buildUIPass (camera: Camera, + ppl: Pipeline) { + const cameraID = getCameraUniqueID(camera); + const cameraName = `Camera${cameraID}`; + const area = getRenderArea(camera, camera.window.width, camera.window.height); + const width = area.width; + const height = area.height; + + const dsUIAndProfilerPassRTName = `dsUIAndProfilerPassColor${cameraName}`; + const dsUIAndProfilerPassDSName = `dsUIAndProfilerPassDS${cameraName}`; + if (!ppl.containsResource(dsUIAndProfilerPassRTName)) { + ppl.addRenderTexture(dsUIAndProfilerPassRTName, Format.BGRA8, width, height, camera.window); + ppl.addDepthStencil(dsUIAndProfilerPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); + } + ppl.updateRenderWindow(dsUIAndProfilerPassRTName, camera.window); + ppl.updateDepthStencil(dsUIAndProfilerPassDSName, width, height); + const uIAndProfilerPass = ppl.addRasterPass(width, height, 'default'); + uIAndProfilerPass.name = `CameraUIAndProfilerPass${cameraID}`; + uIAndProfilerPass.setViewport(new Viewport(area.x, area.y, width, height)); + const passView = new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.RENDER_TARGET), + StoreOp.STORE, + camera.clearFlag, + new Color(camera.clearColor.x, camera.clearColor.y, camera.clearColor.z, camera.clearColor.w)); + const passDSView = new RasterView('_', + AccessType.WRITE, AttachmentType.DEPTH_STENCIL, + getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.DEPTH_STENCIL), + StoreOp.STORE, + camera.clearFlag, + new Color(camera.clearDepth, camera.clearStencil, 0, 0)); + uIAndProfilerPass.addRasterView(dsUIAndProfilerPassRTName, passView); + uIAndProfilerPass.addRasterView(dsUIAndProfilerPassDSName, passDSView); + const sceneFlags = SceneFlags.UI; + uIAndProfilerPass + .addQueue(QueueHint.RENDER_TRANSPARENT) + .addSceneOfCamera(camera, new LightInfo(), sceneFlags); + if (getProfilerCamera() === camera) { + uIAndProfilerPass.showStatistics = true; + } +} + +export function buildNativeForwardPass (camera: Camera, ppl: Pipeline) { + const cameraID = getCameraUniqueID(camera); + const cameraName = `Camera${cameraID}`; + const area = getRenderArea(camera, camera.window.width, camera.window.height); + const width = area.width; + const height = area.height; + + // Resources + const forwardPassRTName = `dsForwardPassColor${cameraName}`; + const forwardPassDSName = `dsForwardPassDS${cameraName}`; + if (!ppl.containsResource(forwardPassRTName)) { + ppl.addRenderTexture(forwardPassRTName, Format.BGRA8, width, height, camera.window); + ppl.addDepthStencil(forwardPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); + } + + ppl.updateRenderWindow(forwardPassRTName, camera.window); + ppl.updateDepthStencil(forwardPassDSName, width, height); + // Passes + const forwardPass = ppl.addRasterPass(width, height, 'default'); + forwardPass.name = `CameraForwardPass${cameraID}`; + forwardPass.setViewport(new Viewport(area.x, area.y, width, height)); + + const cameraRenderTargetLoadOp = getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.RENDER_TARGET); + const cameraDepthStencilLoadOp = getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.DEPTH_STENCIL); + + forwardPass.addRasterView(forwardPassRTName, + new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + cameraRenderTargetLoadOp, + StoreOp.STORE, + getClearFlags(AttachmentType.RENDER_TARGET, camera.clearFlag, cameraRenderTargetLoadOp), + new Color(camera.clearColor.x, camera.clearColor.y, camera.clearColor.z, camera.clearColor.w))); + forwardPass.addRasterView(forwardPassDSName, + new RasterView('_', + AccessType.WRITE, AttachmentType.DEPTH_STENCIL, + cameraDepthStencilLoadOp, + StoreOp.STORE, + getClearFlags(AttachmentType.DEPTH_STENCIL, camera.clearFlag, cameraDepthStencilLoadOp), + new Color(camera.clearDepth, camera.clearStencil, 0, 0))); + + forwardPass + .addQueue(QueueHint.RENDER_OPAQUE) + .addSceneOfCamera(camera, new LightInfo(), + SceneFlags.OPAQUE_OBJECT + | SceneFlags.PLANAR_SHADOW + | SceneFlags.CUTOUT_OBJECT + | SceneFlags.DEFAULT_LIGHTING + | SceneFlags.DRAW_INSTANCING); + forwardPass + .addQueue(QueueHint.RENDER_TRANSPARENT) + .addSceneOfCamera(camera, new LightInfo(), + SceneFlags.TRANSPARENT_OBJECT + | SceneFlags.GEOMETRY); + forwardPass + .addQueue(QueueHint.RENDER_TRANSPARENT) + .addSceneOfCamera(camera, new LightInfo(), + SceneFlags.UI); + forwardPass.showStatistics = true; +} + +export function buildNativeDeferredPipeline (camera: Camera, ppl: Pipeline) { + const cameraID = getCameraUniqueID(camera); + const area = getRenderArea(camera, camera.window.width, camera.window.height); + const width = area.width; + const height = area.height; + if (!ppl.containsResource('Albedo')) { + // GBuffers + ppl.addRenderTarget('Albedo', Format.RGBA16F, width, height, ResourceResidency.MANAGED); + ppl.addRenderTarget('Normal', Format.RGBA16F, width, height, ResourceResidency.MANAGED); + ppl.addRenderTarget('Emissive', Format.RGBA16F, width, height, ResourceResidency.MANAGED); + ppl.addDepthStencil('DepthStencil', Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); + // Lighting + ppl.addRenderTexture('Color', Format.BGRA8, width, height, camera.window); + } + if (!lightingInfo) { + lightingInfo = new LightingInfo(); + } + // GeometryPass + { + const gBufferPass = ppl.addRasterPass(width, height, 'default'); + gBufferPass.name = 'GeometryPass'; + gBufferPass.setViewport(new Viewport(area.x, area.y, area.width, area.height)); + + gBufferPass.addRasterView('Albedo', new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + LoadOp.CLEAR, StoreOp.STORE, ClearFlagBit.COLOR)); + gBufferPass.addRasterView('Normal', new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + LoadOp.CLEAR, StoreOp.STORE, ClearFlagBit.COLOR)); + gBufferPass.addRasterView('Emissive', new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + LoadOp.CLEAR, StoreOp.STORE, ClearFlagBit.COLOR)); + gBufferPass.addRasterView('DepthStencil', new RasterView('_', + AccessType.WRITE, AttachmentType.DEPTH_STENCIL, + LoadOp.CLEAR, StoreOp.STORE, + ClearFlagBit.DEPTH_STENCIL, + new Color(1, 0, 0, 0))); + gBufferPass + .addQueue(QueueHint.RENDER_OPAQUE) + .addSceneOfCamera(camera, new LightInfo(), SceneFlags.OPAQUE_OBJECT | SceneFlags.CUTOUT_OBJECT); + } + // LightingPass + { + const lightingPass = ppl.addRasterPass(width, height, 'default'); + lightingPass.name = 'LightingPass'; + lightingPass.setViewport(new Viewport(area.x, area.y, width, height)); + + const lightingClearColor = new Color(0, 0, 0, 0); + if (camera.clearFlag & ClearFlagBit.COLOR) { + lightingClearColor.x = camera.clearColor.x; + lightingClearColor.y = camera.clearColor.y; + lightingClearColor.z = camera.clearColor.z; + } + lightingClearColor.w = 1; + lightingPass.addRasterView('Color', new RasterView('_', + AccessType.WRITE, AttachmentType.RENDER_TARGET, + LoadOp.CLEAR, StoreOp.STORE, + camera.clearFlag, + lightingClearColor)); + + lightingPass.addComputeView('Albedo', new ComputeView('gbuffer_albedoMap')); + lightingPass.addComputeView('Normal', new ComputeView('gbuffer_normalMap')); + lightingPass.addComputeView('Emissive', new ComputeView('gbuffer_emissiveMap')); + lightingPass.addComputeView('DepthStencil', new ComputeView('depth_stencil')); + + lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addCameraQuad( + camera, lightingInfo.deferredLightingMaterial, 0, + SceneFlags.VOLUMETRIC_LIGHTING, + ); + lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, + new LightInfo(), + SceneFlags.TRANSPARENT_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.GEOMETRY); + } +} + +export function updateCameraUBO (setter: any, camera: Readonly, ppl: Readonly) { + const pipeline = cclegacy.director.root.pipeline; + const sceneData = ppl.pipelineSceneData; + const skybox = sceneData.skybox; + setter.addConstant('CCCamera'); + setter.setMat4('cc_matView', camera.matView); + setter.setMat4('cc_matViewInv', camera.node.worldMatrix); + setter.setMat4('cc_matProj', camera.matProj); + setter.setMat4('cc_matProjInv', camera.matProjInv); + setter.setMat4('cc_matViewProj', camera.matViewProj); + setter.setMat4('cc_matViewProjInv', camera.matViewProjInv); + setter.setVec4('cc_cameraPos', new Vec4(camera.position.x, camera.position.y, camera.position.z, pipeline.getCombineSignY())); + // eslint-disable-next-line max-len + setter.setVec4('cc_surfaceTransform', new Vec4(camera.surfaceTransform, 0.0, Math.cos(toRadian(skybox.getRotationAngle())), Math.sin(toRadian(skybox.getRotationAngle())))); + // eslint-disable-next-line max-len + setter.setVec4('cc_screenScale', new Vec4(sceneData.shadingScale, sceneData.shadingScale, 1.0 / sceneData.shadingScale, 1.0 / sceneData.shadingScale)); + setter.setVec4('cc_exposure', new Vec4(camera.exposure, 1.0 / camera.exposure, sceneData.isHDR ? 1.0 : 0.0, 1.0 / Camera.standardExposureValue)); +} + +function bindDescValue (desc: DescriptorSet, binding: number, value) { + if (value instanceof Buffer) { + desc.bindBuffer(binding, value); + } else if (value instanceof Texture) { + desc.bindTexture(binding, value); + } else if (value instanceof Sampler) { + desc.bindSampler(binding, value); + } +} + +function bindGlobalDesc (desc: DescriptorSet, binding: number, value) { + bindDescValue(desc, binding, value); +} + +export function getDescBinding (descId, descData: DescriptorSetData): number { + const layoutData = descData; + // find descriptor binding + for (const block of layoutData.descriptorSetLayoutData.descriptorBlocks) { + for (let i = 0; i !== block.descriptors.length; ++i) { + if (descId === block.descriptors[i].descriptorID) { + return block.offset + i; + } + } + } + return -1; +} + +export function getDescBindingFromName (bindingName: string) { + const pipeline = cclegacy.director.root.pipeline as WebPipeline; + const layoutGraph = pipeline.layoutGraph; + const vertIds = layoutGraph.vertices(); + const descId = layoutGraph.attributeIndex.get(bindingName); + let currDesData; + for (const i of vertIds) { + const layout = layoutGraph.getLayout(i); + for (const [k, descData] of layout.descriptorSets) { + const layoutData = descData.descriptorSetLayoutData; + const blocks = layoutData.descriptorBlocks; + for (const b of blocks) { + for (const ds of b.descriptors) { + if (ds.descriptorID === descId) { + currDesData = descData; + return getDescBinding(descId, currDesData); + } + } + } + } + } + return -1; +} + +function applyGlobalDescBinding (data: RenderData, layout: string, isUpdate = false) { + const constants = data.constants; + const samplers = data.samplers; + const textures = data.textures; + const device = cclegacy.director.root.device; + const descriptorSetData = getDescriptorSetDataFromLayout(layout)!; + const descriptorSet = descriptorSetData.descriptorSet!; + for (const [key, value] of constants) { + const bindId = getDescBinding(key, descriptorSetData); + if (bindId === -1) { continue; } + let buffer = descriptorSet.getBuffer(bindId); + let haveBuff = true; + if (!buffer && !isUpdate) { + buffer = device.createBuffer(new BufferInfo(BufferUsageBit.UNIFORM | BufferUsageBit.TRANSFER_DST, + MemoryUsageBit.HOST | MemoryUsageBit.DEVICE, + value.length * 4, + value.length * 4)); + haveBuff = false; + } + if (isUpdate) buffer.update(new Float32Array(value)); + if (!haveBuff) bindGlobalDesc(descriptorSet, bindId, buffer); + } + for (const [key, value] of textures) { + const bindId = getDescBinding(key, descriptorSetData); + if (bindId === -1) { continue; } + const tex = descriptorSet.getTexture(bindId); + if (!tex || isUpdate) { + bindGlobalDesc(descriptorSet, bindId, value); + } + } + for (const [key, value] of samplers) { + const bindId = getDescBinding(key, descriptorSetData); + if (bindId === -1) { continue; } + const sampler = descriptorSet.getSampler(bindId); + if (!sampler || isUpdate) { + bindGlobalDesc(descriptorSet, bindId, value); + } + } +} +const layouts: Map = new Map(); +export function getDescriptorSetDataFromLayout (layoutName: string) { + const descLayout = layouts.get(layoutName); + if (descLayout) { + return descLayout; + } + const webPip = cclegacy.director.root.pipeline as WebPipeline; + const stageId = webPip.layoutGraph.locateChild(webPip.layoutGraph.nullVertex(), layoutName); + assert(stageId !== 0xFFFFFFFF); + const layout = webPip.layoutGraph.getLayout(stageId); + const layoutData = layout.descriptorSets.get(UpdateFrequency.PER_PASS); + layouts.set(layoutName, layoutData!); + return layoutData; +} + +export function getDescriptorSetDataFromLayoutId (id: number) { + const webPip = cclegacy.director.root.pipeline as WebPipeline; + const layout = webPip.layoutGraph.getLayout(id); + const layoutData = layout.descriptorSets.get(UpdateFrequency.PER_PASS); + return layoutData; +} + +export function initGlobalDescBinding (data: RenderData, layoutName = 'default') { + applyGlobalDescBinding(data, layoutName); +} + +export function updateGlobalDescBinding (data: RenderData, layoutName = 'default') { + applyGlobalDescBinding(data, layoutName, true); +} + +export function mergeSrcToTargetDesc (fromDesc, toDesc, isForce = false) { + fromDesc.update(); + const fromGpuDesc = fromDesc.gpuDescriptorSet; + const toGpuDesc = toDesc.gpuDescriptorSet; + const extResId: number[] = []; + if (isForce) { + toGpuDesc.gpuDescriptors = fromGpuDesc.gpuDescriptors; + toGpuDesc.descriptorIndices = fromGpuDesc.descriptorIndices; + return extResId; + } + for (let i = 0; i < toGpuDesc.gpuDescriptors.length; i++) { + const fromRes = fromGpuDesc.gpuDescriptors[i]; + if (!fromRes) continue; + const currRes = toGpuDesc.gpuDescriptors[i]; + if (!currRes.gpuBuffer && fromRes.gpuBuffer) { + currRes.gpuBuffer = fromRes.gpuBuffer; + extResId.push(i); + } else if ('gpuTextureView' in currRes && !currRes.gpuTextureView) { + currRes.gpuTextureView = fromRes.gpuTextureView; + currRes.gpuSampler = fromRes.gpuSampler; + extResId.push(i); + } else if ('gpuTexture' in currRes && !currRes.gpuTexture) { + currRes.gpuTexture = fromRes.gpuTexture; + currRes.gpuSampler = fromRes.gpuSampler; + extResId.push(i); + } + } + return extResId; +} diff --git a/cocos/rendering/custom/effect.ts b/cocos/rendering/custom/effect.ts index 64284466065..d038ce3e666 100644 --- a/cocos/rendering/custom/effect.ts +++ b/cocos/rendering/custom/effect.ts @@ -1,351 +1,28 @@ -import { legacyCC } from '../../core/global-exports'; -import { EffectAsset } from '../../asset/assets'; -import { CollectVisitor, WebDescriptorHierarchy } from './web-descriptor-hierarchy'; -// eslint-disable-next-line max-len -import { DescriptorDB, LayoutGraph, LayoutGraphValue } from './layout-graph'; -import { LayoutGraphBuilder, Pipeline } from './pipeline'; -import { DescriptorType, ShaderStageFlagBit, Type, UniformBlock } from '../../gfx'; -import { Descriptor, DescriptorBlock, DescriptorBlockFlattened, DescriptorBlockIndex, DescriptorTypeOrder, - ParameterType, UpdateFrequency } from './types'; -import { depthFirstSearch, GraphColor, MutableVertexPropertyMap } from './graph'; -import { SetIndex } from '../define'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. -function descriptorBlock2Flattened (block: DescriptorBlock, flattened: DescriptorBlockFlattened): void { - block.descriptors.forEach((value, key) => { - const name: string = key; - const d: Descriptor = value; - flattened.descriptorNames.push(name); - flattened.descriptors.push(d); - }); - block.uniformBlocks.forEach((value, key) => { - const name: string = key; - const u: UniformBlock = value; - flattened.uniformBlockNames.push(name); - flattened.uniformBlocks.push(u); - }); - flattened.count = block.count; - flattened.capacity = block.capacity; -} - -export function buildLayoutGraphDataImpl (graph: LayoutGraph, lgData: LayoutGraphBuilder) { - for (const v of graph.vertices()) { - const db: DescriptorDB = graph.getDescriptors(v); - let vid = 0; - if (graph.id(v) === LayoutGraphValue.RenderStage) { - vid = lgData.addRenderStage(graph.getName(v)); - } - if (graph.id(v) === LayoutGraphValue.RenderPhase) { - vid = lgData.addRenderPhase(graph.getName(v), graph.getParent(v)); - const phase = graph.getRenderPhase(vid); - for (const shaderName of phase.shaders) { - lgData.addShader(shaderName, vid); - } - } - - db.blocks.forEach((value, key) => { - const index: DescriptorBlockIndex = JSON.parse(key) as DescriptorBlockIndex; - const block: DescriptorBlock = value; - const flattened = new DescriptorBlockFlattened(); - descriptorBlock2Flattened(block, flattened); - if (block.capacity > 0) { - lgData.addDescriptorBlock(vid, index, flattened); - } - for (let i = 0; i < flattened.uniformBlockNames.length; ++i) { - lgData.addUniformBlock(vid, index, flattened.uniformBlockNames[i], flattened.uniformBlocks[i]); - } - }); - } -} - -function rebuildLayoutGraph (): void { - const root = legacyCC.director.root; - if (!root.usesCustomPipeline) { - return; - } - if (EffectAsset.isLayoutValid()) { - return; - } - console.log('rebuildLayoutGraph begin'); - const ppl: Pipeline = root.customPipeline; - const effects = EffectAsset.getAll(); - const lg: WebDescriptorHierarchy = new WebDescriptorHierarchy(); - const lgData = ppl.layoutGraphBuilder; - lgData.clear(); - - const defaultStage: number = lg.addGlobal('default', true, true, true, true, true, true, true, true); - - for (const n in effects) { - const e: EffectAsset = effects[n]; - lg.addEffect(e, defaultStage); - } - - lg.mergeDescriptors(defaultStage); - - buildLayoutGraphDataImpl(lg.layoutGraph, lgData); - - EffectAsset.setLayoutValid(); - console.log('rebuildLayoutGraph end'); -} - -function buildForwardLayoutFromGlobal (ppl: Pipeline, lg: WebDescriptorHierarchy) { - const src = ppl.globalDSManager.descriptorSetLayout; - const passDB: DescriptorDB = new DescriptorDB(); - let count = 0; - for (const b of src.bindings) { - switch (b.descriptorType) { - case DescriptorType.UNIFORM_BUFFER: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.UNIFORM_BUFFER, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.DYNAMIC_UNIFORM_BUFFER: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.STORAGE_BUFFER: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.STORAGE_BUFFER, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.DYNAMIC_STORAGE_BUFFER: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.DYNAMIC_STORAGE_BUFFER, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.SAMPLER_TEXTURE: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.SAMPLER: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.TEXTURE: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.TEXTURE, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.STORAGE_IMAGE: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.STORAGE_IMAGE, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.INPUT_ATTACHMENT: { - const block = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.INPUT_ATTACHMENT, - b.stageFlags, passDB); - block.descriptors.set(`Descriptor${count}`, new Descriptor(Type.UNKNOWN)); - ++block.count; - ++block.capacity; - break; - } - case DescriptorType.UNKNOWN: - default: - break; - } - ++count; - } - const defaultID = lg._layoutGraph.addVertex( - LayoutGraphValue.RenderStage, - LayoutGraphValue.RenderStage, - 'default', passDB, - ); - - lg.mergeDescriptors(defaultID); -} - -enum BloomStage { - PREFILTER, - DOWNSAMPLE, - UPSAMPLE, - COMBINE -} - -function buildBloomDownSample (lg, idx: number) { - const bloomDownsampleID = lg.addRenderStage(`Bloom_Downsample${idx}`, BloomStage.DOWNSAMPLE); - lg.addRenderPhase('Queue', bloomDownsampleID); - const bloomDownsampleDescriptors = lg.layoutGraph.getDescriptors(bloomDownsampleID); - - const bloomDownsampleUniformBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.UNIFORM_BUFFER, - ShaderStageFlagBit.ALL, - bloomDownsampleDescriptors); - const bloomDownsampleUBO: UniformBlock = lg.getUniformBlock(SetIndex.MATERIAL, - 0, 'BloomUBO', bloomDownsampleUniformBlock); - lg.setUniform(bloomDownsampleUBO, 'texSize', Type.FLOAT4, 1); - lg.setDescriptor(bloomDownsampleUniformBlock, 'BloomUBO', Type.UNKNOWN); - - const bloomDownsamplePassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - bloomDownsampleDescriptors); - lg.setDescriptor(bloomDownsamplePassBlock, 'bloomTexture', Type.SAMPLER2D); - lg.merge(bloomDownsampleDescriptors); - lg.mergeDescriptors(bloomDownsampleID); -} - -function buildBloomUpSample (lg, idx: number) { - const bloomUpsampleID = lg.addRenderStage(`Bloom_Upsample${idx}`, BloomStage.UPSAMPLE); - lg.addRenderPhase('Queue', bloomUpsampleID); - const bloomUpsampleDescriptors = lg.layoutGraph.getDescriptors(bloomUpsampleID); - - const bloomUpsampleUniformBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.UNIFORM_BUFFER, - ShaderStageFlagBit.ALL, - bloomUpsampleDescriptors); - const bloomUpsampleUBO: UniformBlock = lg.getUniformBlock(SetIndex.MATERIAL, - 0, 'BloomUBO', bloomUpsampleUniformBlock); - lg.setUniform(bloomUpsampleUBO, 'texSize', Type.FLOAT4, 1); - lg.setDescriptor(bloomUpsampleUniformBlock, 'BloomUBO', Type.UNKNOWN); - - const bloomUpsamplePassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - bloomUpsampleDescriptors); - lg.setDescriptor(bloomUpsamplePassBlock, 'bloomTexture', Type.SAMPLER2D); - lg.merge(bloomUpsampleDescriptors); - lg.mergeDescriptors(bloomUpsampleID); -} - -export function buildForwardLayout (ppl: Pipeline) { - const lg = new WebDescriptorHierarchy(); - const bFromGlobalDescriptorSet = false; + https://www.cocos.com/ - if (bFromGlobalDescriptorSet) { - buildForwardLayoutFromGlobal(ppl, lg); - } else { - const defaultID = lg.addGlobal('default', true, true, true, true, true, true, true, true); - lg.mergeDescriptors(defaultID); - // 1.=== Bloom prefilter === - const bloomPrefilterID = lg.addRenderStage('Bloom_Prefilter', BloomStage.PREFILTER); - lg.addRenderPhase('Queue', bloomPrefilterID); - const bloomPrefilterDescriptors = lg.layoutGraph.getDescriptors(bloomPrefilterID); - // unifom - const bloomPrefilterUniformBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.UNIFORM_BUFFER, - ShaderStageFlagBit.ALL, - bloomPrefilterDescriptors); - const bloomPrefilterUBO: UniformBlock = lg.getUniformBlock(SetIndex.MATERIAL, - 0, 'BloomUBO', bloomPrefilterUniformBlock); - lg.setUniform(bloomPrefilterUBO, 'texSize', Type.FLOAT4, 1); - lg.setDescriptor(bloomPrefilterUniformBlock, 'BloomUBO', Type.UNKNOWN); - // texture - const bloomPrefilterPassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - bloomPrefilterDescriptors); - lg.setDescriptor(bloomPrefilterPassBlock, 'outputResultMap', Type.SAMPLER2D); - lg.merge(bloomPrefilterDescriptors); - lg.mergeDescriptors(bloomPrefilterID); - // 2.=== Bloom downsample === - buildBloomDownSample(lg, 0); - buildBloomDownSample(lg, 1); - // 3.=== Bloom upsample === - buildBloomUpSample(lg, 0); - buildBloomUpSample(lg, 1); - // 4.=== Bloom combine === - const bloomCombineSampleID = lg.addRenderStage('Bloom_Combine', BloomStage.COMBINE); - lg.addRenderPhase('Queue', bloomCombineSampleID); - const bloomCombineSampleDescriptors = lg.layoutGraph.getDescriptors(bloomCombineSampleID); + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - const bloomCombinesampleUniformBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.UNIFORM_BUFFER, - ShaderStageFlagBit.ALL, - bloomCombineSampleDescriptors); - const bloomCombinesampleUBO: UniformBlock = lg.getUniformBlock(SetIndex.MATERIAL, - 0, 'BloomUBO', bloomCombinesampleUniformBlock); - lg.setUniform(bloomCombinesampleUBO, 'texSize', Type.FLOAT4, 1); - lg.setDescriptor(bloomCombinesampleUniformBlock, 'BloomUBO', Type.UNKNOWN); + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. - const bloomCombineSamplePassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - bloomCombineSampleDescriptors); - lg.setDescriptor(bloomCombineSamplePassBlock, 'outputResultMap', Type.SAMPLER2D); - const bloomCombineSamplePassBlock2 = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - bloomCombineSampleDescriptors); - lg.setDescriptor(bloomCombineSamplePassBlock2, 'bloomTexture', Type.SAMPLER2D); - lg.merge(bloomCombineSampleDescriptors); - lg.mergeDescriptors(bloomCombineSampleID); - // 5.=== Postprocess === - const postPassID = lg.addRenderStage('Postprocess', DeferredStage.POST); - const postDescriptors = lg.layoutGraph.getDescriptors(postPassID); - const postPassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - postDescriptors); + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ - lg.setDescriptor(postPassBlock, 'outputResultMap', Type.SAMPLER2D); - lg.merge(postDescriptors); - lg.mergeDescriptors(postPassID); - } - - const builder = ppl.layoutGraphBuilder; - builder.clear(); - buildLayoutGraphDataImpl(lg.layoutGraph, builder); -} - -enum DeferredStage { - GEOMETRY, - LIGHTING, - POST -} +import { GraphColor, MutableVertexPropertyMap } from './graph'; export class VectorGraphColorMap implements MutableVertexPropertyMap { constructor (sz: number) { @@ -359,55 +36,3 @@ export class VectorGraphColorMap implements MutableVertexPropertyMap } readonly colors: Array; } - -export function buildDeferredLayout (ppl: Pipeline) { - const lg = new WebDescriptorHierarchy(); - const defaultID = lg.addGlobal('default', true, true, true, true, true, true, true, true); - lg.mergeDescriptors(defaultID); - const geometryPassID = lg.addRenderStage('Geometry', DeferredStage.GEOMETRY); - const lightingPassID = lg.addRenderStage('Lighting', DeferredStage.LIGHTING); - const postPassID = lg.addRenderStage('Postprocess', DeferredStage.POST); - - const geometryQueueID = lg.addRenderPhase('Queue', geometryPassID); - const lightingQueueID = lg.addRenderPhase('Queue', lightingPassID); - const postQueueID = lg.addRenderPhase('Queue', postPassID); - - const lightingDescriptors = lg.layoutGraph.getDescriptors(lightingQueueID); - - const lightingPassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - lightingDescriptors); - - lg.setDescriptor(lightingPassBlock, 'gbuffer_albedoMap', Type.FLOAT4); - lg.setDescriptor(lightingPassBlock, 'gbuffer_normalMap', Type.FLOAT4); - lg.setDescriptor(lightingPassBlock, 'gbuffer_emissiveMap', Type.FLOAT4); - lg.setDescriptor(lightingPassBlock, 'depth_stencil', Type.FLOAT4); - - const visitor = new CollectVisitor(); - const colorMap = new VectorGraphColorMap(lg.layoutGraph.numVertices()); - depthFirstSearch(lg.layoutGraph, visitor, colorMap); - - lg.mergeDescriptors(lightingPassID); - // Postprocess - const postDescriptors = lg.layoutGraph.getDescriptors(postPassID); - - const postPassBlock = lg.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, - DescriptorTypeOrder.SAMPLER_TEXTURE, - ShaderStageFlagBit.FRAGMENT, - postDescriptors); - - lg.setDescriptor(postPassBlock, 'outputResultMap', Type.FLOAT4); - lg.merge(postDescriptors); - - lg.mergeDescriptors(postPassID); - if (visitor.error) { - console.log(visitor.error); - } - - const builder = ppl.layoutGraphBuilder; - builder.clear(); - buildLayoutGraphDataImpl(lg.layoutGraph, builder); -} diff --git a/cocos/rendering/custom/executor.ts b/cocos/rendering/custom/executor.ts index b7a243330d5..c833b7b05f3 100644 --- a/cocos/rendering/custom/executor.ts +++ b/cocos/rendering/custom/executor.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -30,7 +29,7 @@ */ /* eslint-disable max-len */ import { getPhaseID, InstancedBuffer, PipelineStateManager } from '..'; -import { assert } from '../../core'; +import { assert, cclegacy, geometry } from '../../core'; import intersect from '../../core/geometry/intersect'; import { Sphere } from '../../core/geometry/sphere'; import { AccessFlagBit, Attribute, Buffer, BufferInfo, BufferUsageBit, BufferViewInfo, Color, ColorAttachment, CommandBuffer, DepthStencilAttachment, DescriptorSet, DescriptorSetInfo, Device, deviceManager, Format, Framebuffer, @@ -40,13 +39,11 @@ import { legacyCC } from '../../core/global-exports'; import { Vec3 } from '../../core/math/vec3'; import { Vec4 } from '../../core/math/vec4'; import { BatchingSchemes } from '../../render-scene'; -import { DirectionalLight } from '../../render-scene/scene'; import { Camera } from '../../render-scene/scene/camera'; -import { LightType } from '../../render-scene/scene/light'; -import { CSMLevel, ShadowType } from '../../render-scene/scene/shadows'; +import { ShadowType } from '../../render-scene/scene/shadows'; import { Root } from '../../root'; import { BatchedBuffer } from '../batched-buffer'; -import { SetIndex, UBODeferredLight, UBOForwardLight, UBOLocal } from '../define'; +import { isEnableEffect, SetIndex, UBODeferredLight, UBOForwardLight, UBOLocal } from '../define'; import { PipelineSceneData } from '../pipeline-scene-data'; import { PipelineInputAssemblerData } from '../render-pipeline'; import { LayoutGraphData, PipelineLayoutData, RenderPhaseData, RenderStageData } from './layout-graph'; @@ -61,11 +58,20 @@ import { WebSceneVisitor } from './web-scene-visitor'; import { stringify } from './utils'; import { RenderAdditiveLightQueue } from '../render-additive-light-queue'; import { RenderShadowMapBatchedQueue } from '../render-shadow-map-batched-queue'; -import { renderProfiler } from '../pipeline-funcs'; import { PlanarShadowQueue } from '../planar-shadow-queue'; import { DefaultVisitor, depthFirstSearch, ReferenceGraphView } from './graph'; import { VectorGraphColorMap } from './effect'; -import { getRenderArea } from './define'; +import { getDescBindingFromName, getDescriptorSetDataFromLayout, getDescriptorSetDataFromLayoutId, getRenderArea, mergeSrcToTargetDesc, updateGlobalDescBinding } from './define'; +import { RenderReflectionProbeQueue } from '../render-reflection-probe-queue'; +import { ReflectionProbeManager } from '../reflection-probe-manager'; +import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; +import { Texture2D } from '../../asset/assets/texture-2d'; +import { AABB } from '../../core/geometry/aabb'; +import { LightType } from '../../render-scene/scene/light'; + +const _v3 = new Vec3(); +const _rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5); +const _tmpBoundingBox = new AABB(); class DeviceResource { protected _context: ExecutorContext; @@ -84,6 +90,7 @@ class DeviceTexture extends DeviceResource { protected _desc: ResourceDesc | null = null; protected _trait: ResourceTraits | null = null; get texture () { return this._texture; } + set framebuffer (val: Framebuffer | null) { this._framebuffer = val; } get framebuffer () { return this._framebuffer; } get description () { return this._desc; } get trait () { return this._trait; } @@ -233,7 +240,7 @@ class BlitDesc { inputAssemblerData.quadIA = quadIA; return inputAssemblerData; } - createSreenQuad () { + createScreenQuad () { if (!this._screenQuad) { this._screenQuad = this._createQuadInputAssembler(); } @@ -253,6 +260,8 @@ class BlitDesc { const sphereLights = camera.scene.sphereLights; const spotLights = camera.scene.spotLights; + const pointLights = camera.scene.pointLights; + const rangedDirLights = camera.scene.rangedDirLights; const _sphere = Sphere.create(0, 0, 0, 1); const _vec4Array = new Float32Array(4); const exposure = camera.exposure; @@ -268,16 +277,16 @@ class BlitDesc { if (intersect.sphereFrustum(_sphere, camera.frustum)) { // cc_lightPos Vec3.toArray(_vec4Array, light.position); - _vec4Array[3] = 0; + _vec4Array[3] = LightType.SPHERE; this._lightBufferData.set(_vec4Array, idx * elementLen); // cc_lightColor Vec3.toArray(_vec4Array, light.color); if (light.useColorTemperature) { - const tempRGB = light.colorTemperatureRGB; - _vec4Array[0] *= tempRGB.x; - _vec4Array[1] *= tempRGB.y; - _vec4Array[2] *= tempRGB.z; + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; } if (pipeline.pipelineSceneData.isHDR) { @@ -302,16 +311,16 @@ class BlitDesc { if (intersect.sphereFrustum(_sphere, camera.frustum)) { // cc_lightPos Vec3.toArray(_vec4Array, light.position); - _vec4Array[3] = 1; + _vec4Array[3] = LightType.SPOT; this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 0); // cc_lightColor Vec3.toArray(_vec4Array, light.color); if (light.useColorTemperature) { - const tempRGB = light.colorTemperatureRGB; - _vec4Array[0] *= tempRGB.x; - _vec4Array[1] *= tempRGB.y; - _vec4Array[2] *= tempRGB.z; + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; } if (pipeline.pipelineSceneData.isHDR) { _vec4Array[3] = light.luminance * exposure * this._lightMeterScale; @@ -332,6 +341,81 @@ class BlitDesc { } } + for (let i = 0; i < pointLights.length && idx < maxLights; i++, ++idx) { + const light = pointLights[i]; + Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (intersect.sphereFrustum(_sphere, camera.frustum)) { + // cc_lightPos + Vec3.toArray(_vec4Array, light.position); + _vec4Array[3] = LightType.POINT; + this._lightBufferData.set(_vec4Array, idx * elementLen); + + // cc_lightColor + Vec3.toArray(_vec4Array, light.color); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; + } + + if (pipeline.pipelineSceneData.isHDR) { + _vec4Array[3] = light.luminance * exposure * this._lightMeterScale; + } else { + _vec4Array[3] = light.luminance; + } + + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 1); + + // cc_lightSizeRangeAngle + _vec4Array[0] = 0.0; + _vec4Array[1] = light.range; + _vec4Array[2] = 0.0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 2); + } + } + + for (let i = 0; i < rangedDirLights.length && idx < maxLights; i++, ++idx) { + const light = rangedDirLights[i]; + AABB.transform(_tmpBoundingBox, _rangedDirLightBoundingBox, light.node!.getWorldMatrix()); + if (geometry.intersect.aabbFrustum(_tmpBoundingBox, camera.frustum)) { + // UBOForwardLight + Vec3.toArray(_vec4Array, light.position); + _vec4Array[3] = LightType.RANGED_DIRECTIONAL; + this._lightBufferData.set(_vec4Array, idx * elementLen); + + // cc_lightColor + Vec3.toArray(_vec4Array, light.color); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; + } + if (pipeline.pipelineSceneData.isHDR) { + _vec4Array[3] = light.illuminance * exposure; + } else { + _vec4Array[3] = light.illuminance; + } + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 1); + + Vec3.toArray(_vec4Array, light.right); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 2); + + Vec3.toArray(_vec4Array, light.direction); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 3); + + // eslint-disable-next-line no-case-declarations + const scale = light.scale; + _v3.set(scale.x * 0.5, scale.y * 0.5, scale.z * 0.5); + Vec3.toArray(_vec4Array, _v3); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 4); + } + } + // the count of lights is set to cc_lightDir[0].w const offset = fieldLen * 3 + 3; this._lightBufferData.set([idx], offset); @@ -368,6 +452,7 @@ class BlitDesc { const deferredLitsBufView = device.createBuffer(new BufferViewInfo(this._lightVolumeBuffer, 0, totalSize)); this._lightBufferData = new Float32Array(totalSize / Float32Array.BYTES_PER_ELEMENT); + const binding = isEnableEffect() ? getDescBindingFromName('CCForwardLight') : UBOForwardLight.BINDING; this._stageDesc.bindBuffer(UBOForwardLight.BINDING, deferredLitsBufView); } const _localUBO = device.createBuffer(new BufferInfo( @@ -386,7 +471,7 @@ class DeviceRenderQueue { private _postSceneTasks: DevicePostSceneTask[] = []; private _devicePass: DeviceRenderPass; private _hint: QueueHint = QueueHint.NONE; - private _phaseID = getPhaseID('default'); + private _phaseID: number = getPhaseID('default'); private _renderPhase: RenderPhaseData | null = null; protected _transversal: DeviceSceneTransversal | null = null; get phaseID (): number { return this._phaseID; } @@ -399,6 +484,7 @@ class DeviceRenderQueue { get queueId () { return this._queueId; } constructor (devicePass: DeviceRenderPass) { this._devicePass = devicePass; + if (isEnableEffect()) this._phaseID = cclegacy.rendering.getPhaseID(devicePass.passID, 'default'); this._sceneVisitor = new WebSceneVisitor(this._devicePass.context.commandBuffer, this._devicePass.context.pipeline.pipelineSceneData); } @@ -407,7 +493,7 @@ class DeviceRenderQueue { return; } this._blitDesc = new BlitDesc(blit, this); - this._blitDesc.createSreenQuad(); + this._blitDesc.createScreenQuad(); this._blitDesc.createStageDescriptor(); } addSceneTask (scene: GraphScene): void { @@ -452,13 +538,14 @@ class DeviceRenderQueue { class SubmitInfo { public instances = new Set(); - public renderInstanceQueue : InstancedBuffer[] = []; + public renderInstanceQueue: InstancedBuffer[] = []; public batches = new Set(); public opaqueList: RenderInfo[] = []; public transparentList: RenderInfo[] = []; public planarQueue: PlanarShadowQueue | null = null; public shadowMap: RenderShadowMapBatchedQueue | null = null; public additiveLight: RenderAdditiveLightQueue | null = null; + public reflectionProbe: RenderReflectionProbeQueue | null = null; } class RenderPassLayoutInfo { @@ -475,14 +562,18 @@ class RenderPassLayoutInfo { this._stage = lg.getRenderStage(layoutId); this._context = context; this._layout = lg.getLayout(layoutId); - const layoutData = this._layout.descriptorSets.get(UpdateFrequency.PER_PASS); + const layoutData = this._layout.descriptorSets.get(UpdateFrequency.PER_PASS); + const globalDesc = context.pipeline.descriptorSet; if (layoutData) { // find resource const deviceTex = context.deviceTextures.get(this._inputName); const gfxTex = deviceTex?.texture; + const layoutDesc = layoutData.descriptorSet!; if (!gfxTex) { throw Error(`Could not find texture with resource name ${this._inputName}`); } + const resId = context.resourceGraph.vertex(this._inputName); + const samplerInfo = context.resourceGraph.getSampler(resId); // bind descriptors for (const descriptor of input[1]) { const descriptorName = descriptor.name; @@ -490,11 +581,19 @@ class RenderPassLayoutInfo { // find descriptor binding for (const block of layoutData.descriptorSetLayoutData.descriptorBlocks) { for (let i = 0; i !== block.descriptors.length; ++i) { + // const buffer = layoutDesc.getBuffer(block.offset + i); + // const texture = layoutDesc.getTexture(block.offset + i); if (descriptorID === block.descriptors[i].descriptorID) { - layoutData.descriptorSet!.bindTexture(block.offset + i, gfxTex); - layoutData.descriptorSet!.bindSampler(block.offset + i, context.device.getSampler(new SamplerInfo())); - if (!this._descriptorSet) this._descriptorSet = layoutData.descriptorSet; + layoutDesc.bindTexture(block.offset + i, gfxTex); + layoutDesc.bindSampler(block.offset + i, context.device.getSampler(samplerInfo)); + if (!this._descriptorSet) this._descriptorSet = layoutDesc; + continue; } + // if (!buffer && !texture) { + // layoutDesc.bindBuffer(block.offset + i, globalDesc.getBuffer(block.offset + i)); + // layoutDesc.bindTexture(block.offset + i, globalDesc.getTexture(block.offset + i)); + // layoutDesc.bindSampler(block.offset + i, globalDesc.getSampler(block.offset + i)); + // } } } } @@ -528,15 +627,16 @@ class DeviceRenderPass { protected _deviceQueues: DeviceRenderQueue[] = []; protected _clearDepth = 1; protected _clearStencil = 0; + protected _passID: number; protected _context: ExecutorContext; protected _viewport: Viewport | null = null; private _rasterInfo: RasterPassInfo; private _layout: RenderPassLayoutInfo | null = null; - public submitMap: Map = new Map(); constructor (context: ExecutorContext, passInfo: RasterPassInfo) { this._context = context; this._rasterInfo = passInfo; const device = context.device; + this._passID = cclegacy.rendering.getPassID(this._context.renderGraph.getLayout(passInfo.id)); const depthStencilAttachment = new DepthStencilAttachment(); depthStencilAttachment.format = Format.DEPTH_STENCIL; depthStencilAttachment.depthLoadOp = LoadOp.DISCARD; @@ -564,6 +664,13 @@ class DeviceRenderPass { const resourceVisitor = new ResourceVisitor(resName, context); resourceGraph.visitVertex(resourceVisitor, vertId); resTex = context.deviceTextures.get(resName)!; + } else { + const resGraph = this.context.resourceGraph; + const resId = resGraph.vertex(resName); + const resFbo = resGraph._vertices[resId]._object; + if (resTex.framebuffer && resFbo instanceof Framebuffer && resTex.framebuffer !== resFbo) { + resTex.framebuffer = resFbo; + } } if (!swapchain) swapchain = resTex.swapchain; if (!framebuffer) framebuffer = resTex.framebuffer; @@ -623,6 +730,7 @@ class DeviceRenderPass { swapchain ? [swapchain.colorTexture] : colorTexs, swapchain ? swapchain.depthStencilTexture : depthTex)); } + get passID (): number { return this._passID; } get renderLayout () { return this._layout; } get context () { return this._context; } get renderPass () { return this._renderPass; } @@ -649,7 +757,14 @@ class DeviceRenderPass { } } } - genQuadVertexData (surfaceTransform: SurfaceTransform, renderArea: Rect) : Float32Array { + getGlobalDescData (context: ExecutorContext) { + const stageId = context.layoutGraph.locateChild(context.layoutGraph.nullVertex(), 'default'); + assert(stageId !== 0xFFFFFFFF); + const layout = context.layoutGraph.getLayout(stageId); + const layoutData = layout.descriptorSets.get(UpdateFrequency.PER_PASS)!; + return layoutData; + } + genQuadVertexData (surfaceTransform: SurfaceTransform, renderArea: Rect): Float32Array { const vbData = new Float32Array(4 * 4); const minX = renderArea.x / this._context.width; @@ -701,35 +816,67 @@ class DeviceRenderPass { protected _applyViewport (frameTex: Texture) { this._viewport = null; const viewport = this._rasterInfo.pass.viewport; - if (viewport.left !== 0 || viewport.top !== 0 - || viewport.width !== frameTex.width - || viewport.height !== frameTex.height) { + if (viewport.left !== 0 + || viewport.top !== 0 + || viewport.width !== 0 + || viewport.height !== 0) { this._viewport = viewport; } } + + protected _showProfiler (rect: Rect) { + const profiler = this.context.pipeline.profiler!; + if (!profiler || !profiler.enabled) { + return; + } + const context = this.context; + const renderPass = this._renderPass; + const cmdBuff = this.context.commandBuffer; + const submodel = profiler.subModels[0]; + const pass = submodel.passes[0]; + const ia = submodel.inputAssembler; + const device = this.context.device; + const pso = PipelineStateManager.getOrCreatePipelineState(device, pass, + submodel.shaders[0], renderPass, ia); + const descData = getDescriptorSetDataFromLayoutId(pass.passID)!; + mergeSrcToTargetDesc(descData.descriptorSet, context.pipeline.descriptorSet, true); + const profilerViewport = new Viewport(); + profilerViewport.width = rect.width; + profilerViewport.height = rect.height; + + cmdBuff.setViewport(profilerViewport); + cmdBuff.setScissor(rect); + cmdBuff.bindPipelineState(pso); + cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, pass.descriptorSet); + cmdBuff.bindDescriptorSet(SetIndex.LOCAL, submodel.descriptorSet); + cmdBuff.bindInputAssembler(ia); + cmdBuff.draw(ia); + } + // record common buffer record () { const tex = this.framebuffer.colorTextures[0]!; this._applyViewport(tex); const cmdBuff = this._context.commandBuffer; - const renderArea = this._viewport ? new Rect(this._viewport.left, this._viewport.top, this._viewport.width, this._viewport.height) + const renderArea = this._viewport + ? new Rect(this._viewport.left, this._viewport.top, this._viewport.width, this._viewport.height) : new Rect(0, 0, tex.width, tex.height); cmdBuff.beginRenderPass(this.renderPass, this.framebuffer, renderArea, this.clearColor, this.clearDepth, this.clearStencil); - const stageId = this.context.layoutGraph.locateChild(this.context.layoutGraph.nullVertex(), 'default'); - assert(stageId !== 0xFFFFFFFF); - const layout = this.context.layoutGraph.getLayout(stageId); - const layoutData = layout.descriptorSets.get(UpdateFrequency.PER_PASS); cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, - layoutData!.descriptorSet!); + this._context.pipeline.descriptorSet); for (const queue of this._deviceQueues) { queue.record(); } + if (this._rasterInfo.pass.showStatistics) { + this._showProfiler(renderArea); + } cmdBuff.endRenderPass(); } - private _clearInstance () { - for (const [cam, info] of this.submitMap) { + private _clear () { + for (const [cam, info] of this.context.submitMap) { + info.additiveLight?.clear(); const it = info.instances.values(); let res = it.next(); while (!res.done) { res.value.clear(); @@ -741,15 +888,55 @@ class DeviceRenderPass { } postPass () { - this._clearInstance(); - this.submitMap.clear(); + this._clear(); + // this.submitMap.clear(); for (const queue of this._deviceQueues) { queue.postRecord(); } } - resetQueues (id: number, pass: RasterPass) { + resetResource (id: number, pass: RasterPass) { this._rasterInfo.applyInfo(id, pass); this._deviceQueues.length = 0; + let framebuffer: Framebuffer | null = null; + const colTextures: Texture[] = []; + let depTexture = this._framebuffer.depthStencilTexture; + for (const cv of this._rasterInfo.pass.computeViews) { + this._applyRenderLayout(cv); + } + // update the layout descriptorSet + if (this.renderLayout && this.renderLayout.descriptorSet) { + this.renderLayout.descriptorSet.update(); + } + for (const [resName, rasterV] of this._rasterInfo.pass.rasterViews) { + const deviceTex = this.context.deviceTextures.get(resName)!; + const resGraph = this.context.resourceGraph; + const resId = resGraph.vertex(resName); + const resFbo = resGraph._vertices[resId]._object; + const resDesc = resGraph.getDesc(resId); + if (deviceTex.framebuffer && resFbo instanceof Framebuffer && deviceTex.framebuffer !== resFbo) { + framebuffer = this._framebuffer = deviceTex.framebuffer = resFbo; + } else if (deviceTex.texture + && (deviceTex.texture.width !== resDesc.width || deviceTex.texture.height !== resDesc.height)) { + deviceTex.texture.resize(resDesc.width, resDesc.height); + switch (rasterV.attachmentType) { + case AttachmentType.RENDER_TARGET: + colTextures.push(deviceTex.texture); + break; + case AttachmentType.DEPTH_STENCIL: + depTexture = deviceTex.texture; + break; + default: + } + } + } + if (!framebuffer && colTextures.length) { + this._framebuffer.destroy(); + this._framebuffer = this.context.device.createFramebuffer(new FramebufferInfo( + this._renderPass, + colTextures, + depTexture, + )); + } } } @@ -803,7 +990,9 @@ class DevicePreSceneTask extends WebSceneTask { if (!this.camera) { return; } - const submitMap = this._currentQueue.devicePass.submitMap; + const devicePass = this._currentQueue.devicePass; + const context = devicePass.context; + const submitMap = context.submitMap; if (submitMap.has(this.camera)) { this._submitInfo = submitMap.get(this.camera)!; } else { @@ -813,11 +1002,25 @@ class DevicePreSceneTask extends WebSceneTask { submitMap.set(this.camera, this._submitInfo); } // shadowmap - if (this._isShadowMap() && !this._submitInfo.shadowMap) { + if (this._isShadowMap()) { assert(this.graphScene.scene!.light.light); - this._submitInfo.shadowMap = new RenderShadowMapBatchedQueue(this._currentQueue.devicePass.context.pipeline); + if (!this._submitInfo.shadowMap) { + this._submitInfo.shadowMap = context.shadowMapBatched; + } + this.sceneData.shadowFrameBufferMap.set(this.graphScene.scene!.light.light, devicePass.framebuffer); this._submitInfo.shadowMap.gatherLightPasses(this.camera, this.graphScene.scene!.light.light, this._cmdBuff, this.graphScene.scene!.light.level); - this.sceneData.shadowFrameBufferMap.set(this.graphScene.scene!.light.light, this._currentQueue.devicePass.framebuffer); + return; + } + // reflection probe + if (this.graphScene.scene!.flags & SceneFlags.REFLECTION_PROBE && !this._submitInfo.reflectionProbe) { + this._submitInfo.reflectionProbe = new RenderReflectionProbeQueue(this._currentQueue.devicePass.context.pipeline); + const probes = ReflectionProbeManager.probeManager.getProbes(); + for (let i = 0; i < probes.length; i++) { + if (probes[i].hasFrameBuffer(this._currentQueue.devicePass.framebuffer)) { + this._submitInfo.reflectionProbe.gatherRenderObjects(probes[i], this.camera, this._cmdBuff); + break; + } + } return; } const sceneFlag = this._graphScene.scene!.flags; @@ -832,7 +1035,7 @@ class DevicePreSceneTask extends WebSceneTask { for (const subModel of subModels) { const passes = subModel.passes; for (const p of passes) { - if (p.phase !== this._currentQueue.phaseID) continue; + if (((isEnableEffect()) ? p.phaseID : p.phase) !== this._currentQueue.phaseID) continue; const batchingScheme = p.batchingScheme; if (batchingScheme === BatchingSchemes.INSTANCING) { const instancedBuffer = p.getInstancedBuffer(); @@ -851,9 +1054,9 @@ class DevicePreSceneTask extends WebSceneTask { } this._instancedSort(); } - const pipeline = this._currentQueue.devicePass.context.pipeline; + const pipeline = context.pipeline; if (sceneFlag & SceneFlags.DEFAULT_LIGHTING) { - this._submitInfo.additiveLight = new RenderAdditiveLightQueue(pipeline); + this._submitInfo.additiveLight = context.additiveLight; this._submitInfo.additiveLight.gatherLightPasses(this.camera, this._cmdBuff); } if (sceneFlag & SceneFlags.PLANAR_SHADOW) { @@ -888,8 +1091,10 @@ class DevicePreSceneTask extends WebSceneTask { const pass = subModel.passes[passIdx]; const shader = subModel.shaders[passIdx]; const currTransparent = pass.blendState.targets[0].blend; - const phases = getPhaseID('default') | getPhaseID('planarShadow'); - if (currTransparent !== isTransparent || !(pass.phase & (isTransparent ? phases : this._currentQueue.phaseID))) { + const passId = this._currentQueue.devicePass.passID; + const phase = isEnableEffect() ? cclegacy.rendering.getPhaseID(passId, 'default') | cclegacy.rendering.getPhaseID(passId, 'planarShadow') + : getPhaseID('default') | getPhaseID('planarShadow'); + if (currTransparent !== isTransparent || !(pass.phaseID & (isTransparent ? phase : this._currentQueue.phaseID))) { return; } const hash = (0 << 30) | pass.priority << 16 | subModel.priority << 8 | passIdx; @@ -949,48 +1154,10 @@ class DevicePreSceneTask extends WebSceneTask { && this.graphScene.scene!.flags & SceneFlags.SHADOW_CASTER; } - private _bindDescriptor (context: ExecutorContext, descId: number, value) { - const layoutData = this._getGlobalDescData(context)!; - // find descriptor binding - for (const block of layoutData.descriptorSetLayoutData.descriptorBlocks) { - for (let i = 0; i !== block.descriptors.length; ++i) { - if (descId === block.descriptors[i].descriptorID) { - if (value instanceof Buffer) layoutData.descriptorSet!.bindBuffer(block.offset + i, value); - else if (value instanceof Texture) layoutData.descriptorSet!.bindTexture(block.offset + i, value); - else if (value instanceof Sampler) layoutData.descriptorSet!.bindSampler(block.offset + i, value); - } - } - } - } - - private _getGlobalDescData (context: ExecutorContext) { - const stageId = context.layoutGraph.locateChild(context.layoutGraph.nullVertex(), 'default'); - assert(stageId !== 0xFFFFFFFF); - const layout = context.layoutGraph.getLayout(stageId); - const layoutData = layout.descriptorSets.get(UpdateFrequency.PER_PASS)!; - return layoutData; - } - protected _updateGlobal (context: ExecutorContext, data: RenderData) { - const constants = data.constants; - const samplers = data.samplers; - const textures = data.textures; - const device = context.root.device; - for (const [key, value] of constants) { - const buffer = device.createBuffer(new BufferInfo(BufferUsageBit.UNIFORM | BufferUsageBit.TRANSFER_DST, - MemoryUsageBit.HOST | MemoryUsageBit.DEVICE, - value.length * 4, - value.length * 4)); - buffer.update(new Float32Array(value)); - this._bindDescriptor(context, key, buffer); - } - for (const [key, value] of textures) { - this._bindDescriptor(context, key, value); - } - for (const [key, value] of samplers) { - this._bindDescriptor(context, key, value); - } - this._getGlobalDescData(context).descriptorSet!.update(); + const devicePass = this._currentQueue.devicePass; + updateGlobalDescBinding(data, isEnableEffect() ? context.renderGraph.getLayout(devicePass.rasterPassInfo.id) : 'default'); + if (!isEnableEffect()) context.pipeline.descriptorSet.update(); } protected _setMainLightShadowTex (context: ExecutorContext, data: RenderData) { @@ -999,9 +1166,14 @@ class DevicePreSceneTask extends WebSceneTask { const mainLight = graphScene.scene.camera.scene!.mainLight; const shadowFrameBufferMap = this.sceneData.shadowFrameBufferMap; if (mainLight && shadowFrameBufferMap.has(mainLight)) { + const shadowAttrID = context.layoutGraph.attributeIndex.get('cc_shadowMap'); + const defaultTex = builtinResMgr.get('default-texture').getGFXTexture()!; for (const [key, value] of data.textures) { - if (key === context.layoutGraph.attributeIndex.get('cc_shadowMap')) { - data.textures.set(key, shadowFrameBufferMap.get(mainLight)!.colorTextures[0]!); + if (key === shadowAttrID) { + const tex = data.textures.get(shadowAttrID); + if (tex === defaultTex) { + data.textures.set(key, shadowFrameBufferMap.get(mainLight)!.colorTextures[0]!); + } return; } } @@ -1021,25 +1193,19 @@ class DevicePreSceneTask extends WebSceneTask { const queueRenderData = context.renderGraph.getData(queueId)!; this._setMainLightShadowTex(context, queueRenderData); this._updateGlobal(context, queueRenderData); - } - - protected _updateBlurUbo (camera: Camera) { - const ubo = this._currentQueue.devicePass.context.ubo; - ubo.updateGlobalUBO(camera.window); - ubo.updateCameraUBO(camera); - ubo.updateShadowUBO(camera); + if (isEnableEffect()) { + const layoutName = context.renderGraph.getLayout(rasterId); + const descSetData = getDescriptorSetDataFromLayout(layoutName); + mergeSrcToTargetDesc(descSetData!.descriptorSet, context.pipeline.descriptorSet, true); + } } public submit () { - const context = this._currentQueue.devicePass.context; - const ubo = context.ubo; + this._updateUbo(); if (this.graphScene.blit) { - const blitCam = this.graphScene.blit.camera; - if (blitCam) this._updateBlurUbo(blitCam); this._currentQueue.blitDesc!.update(); return; } - this._updateUbo(); if (this._isShadowMap()) { return; } @@ -1063,7 +1229,7 @@ class DeviceSceneTask extends WebSceneTask { get graphScene () { return this._graphScene; } public start () {} protected _recordRenderList (isTransparent: boolean) { - const submitMap = this._currentQueue.devicePass.submitMap; + const submitMap = this._currentQueue.devicePass.context.submitMap; const renderList = isTransparent ? submitMap.get(this.camera!)!.transparentList : submitMap.get(this.camera!)!.opaqueList; for (let i = 0; i < renderList.length; ++i) { const { subModel, passIdx } = renderList[i]; @@ -1083,7 +1249,7 @@ class DeviceSceneTask extends WebSceneTask { this._recordRenderList(false); } protected _recordInstences () { - const submitMap = this._currentQueue.devicePass.submitMap; + const submitMap = this._currentQueue.devicePass.context.submitMap; const it = submitMap.get(this.camera!)!.renderInstanceQueue.length === 0 ? submitMap.get(this.camera!)!.instances.values() : submitMap.get(this.camera!)!.renderInstanceQueue.values(); @@ -1113,7 +1279,7 @@ class DeviceSceneTask extends WebSceneTask { } } protected _recordBatches () { - const submitMap = this._currentQueue.devicePass.submitMap; + const submitMap = this._currentQueue.devicePass.context.submitMap; const it = submitMap.get(this.camera!)!.batches.values(); let res = it.next(); while (!res.done) { let boundPSO = false; @@ -1150,7 +1316,7 @@ class DeviceSceneTask extends WebSceneTask { const count = batch.shaders.length; for (let j = 0; j < count; j++) { const pass = batch.passes[j]; - if (pass.phase !== this._currentQueue.phaseID) continue; + if (((isEnableEffect()) ? pass.phaseID : pass.phase) !== this._currentQueue.phaseID) continue; const shader = batch.shaders[j]; const inputAssembler: any = batch.inputAssembler!; const pso = PipelineStateManager.getOrCreatePipelineState(deviceManager.gfxDevice, pass, shader, this._renderPass, inputAssembler); @@ -1168,47 +1334,38 @@ class DeviceSceneTask extends WebSceneTask { } protected _recordShadowMap () { const context = this._currentQueue.devicePass.context; - const submitMap = this._currentQueue.devicePass.submitMap; + const submitMap = context.submitMap; submitMap.get(this.camera!)?.shadowMap?.recordCommandBuffer(context.device, this._renderPass, context.commandBuffer); } + protected _recordReflectionProbe () { + const context = this._currentQueue.devicePass.context; + const submitMap = context.submitMap; + submitMap.get(this.camera!)?.reflectionProbe?.recordCommandBuffer(context.device, + this._renderPass, context.commandBuffer); + } private _isShadowMap () { return this.sceneData.shadows.enabled && this.sceneData.shadows.type === ShadowType.ShadowMap && this.graphScene.scene && this.graphScene.scene.flags & SceneFlags.SHADOW_CASTER; } - private _mergeMatToBlitDesc (fromDesc, toDesc) { - fromDesc.update(); - const fromGpuDesc = fromDesc.gpuDescriptorSet; - const toGpuDesc = toDesc.gpuDescriptorSet; - for (let i = 0; i < toGpuDesc.gpuDescriptors.length; i++) { - const currRes = toGpuDesc.gpuDescriptors[i]; - if (!currRes.gpuBuffer) { - currRes.gpuBuffer = fromGpuDesc.gpuDescriptors[i].gpuBuffer; - } else if (!currRes.gpuTextureView) { - currRes.gpuTextureView = fromGpuDesc.gpuDescriptors[i].gpuTextureView; - } else if (!currRes.gpuSampler) { - currRes.gpuSampler = fromGpuDesc.gpuDescriptors[i].gpuSampler; + + private _clearExtBlitDesc (desc, extResId: number[]) { + const toGpuDesc = desc.gpuDescriptorSet; + for (let i = 0; i < extResId.length; i++) { + const currDesc = toGpuDesc.gpuDescriptors[extResId[i]]; + if (currDesc.gpuBuffer) currDesc.gpuBuffer = null; + else if (currDesc.gpuTextureView) { + currDesc.gpuTextureView = null; + currDesc.gpuSampler = null; + } else if (currDesc.gpuTexture) { + currDesc.gpuTexture = null; + currDesc.gpuSampler = null; } } } - // TODO: After the ubo is perfected, it needs to be replaced - private _beginBindBlitUbo (devicePass) { - this.visitor.bindDescriptorSet(SetIndex.GLOBAL, - devicePass.context.pipeline.globalDSManager.globalDescriptorSet); - } - - private _endBindBlitUbo (devicePass) { - const stageId = devicePass.context.layoutGraph.locateChild(devicePass.context.layoutGraph.nullVertex(), 'default'); - assert(stageId !== 0xFFFFFFFF); - const layout = devicePass.context.layoutGraph.getLayout(stageId); - const layoutData = layout.descriptorSets.get(UpdateFrequency.PER_PASS); - this.visitor.bindDescriptorSet(SetIndex.GLOBAL, - layoutData.descriptorSet!); - } - private _recordBlit () { if (!this.graphScene.blit) { return; } @@ -1218,8 +1375,8 @@ class DeviceSceneTask extends WebSceneTask { pass.update(); const shader = pass.getShaderVariant(); const devicePass = this._currentQueue.devicePass; - this._beginBindBlitUbo(devicePass); const screenIa: any = this._currentQueue.blitDesc!.screenQuad!.quadIA; + const globalDesc = devicePass.context.pipeline.descriptorSet; let pso; if (pass !== null && shader !== null && screenIa !== null) { pso = PipelineStateManager.getOrCreatePipelineState(devicePass.context.device, pass, shader, @@ -1228,19 +1385,22 @@ class DeviceSceneTask extends WebSceneTask { if (pso) { this.visitor.bindPipelineState(pso); const layoutStage = devicePass.renderLayout; - this._mergeMatToBlitDesc(pass.descriptorSet, layoutStage!.descriptorSet!); - // TODO: It will be changed to global later - this.visitor.bindDescriptorSet(SetIndex.MATERIAL, layoutStage!.descriptorSet!); + const layoutDesc = layoutStage!.descriptorSet!; + const extResId: number[] = isEnableEffect() ? [] : mergeSrcToTargetDesc(pass.descriptorSet, layoutDesc); + // if (isEnableEffect()) this.visitor.bindDescriptorSet(SetIndex.GLOBAL, layoutDesc); + this.visitor.bindDescriptorSet(SetIndex.MATERIAL, isEnableEffect() ? pass.descriptorSet : layoutDesc); this.visitor.bindDescriptorSet(SetIndex.LOCAL, this._currentQueue.blitDesc!.stageDesc!); this.visitor.bindInputAssembler(screenIa); this.visitor.draw(screenIa); + // The desc data obtained from the outside should be cleaned up so that the data can be modified + this._clearExtBlitDesc(layoutDesc, extResId); + // if (isEnableEffect()) this.visitor.bindDescriptorSet(SetIndex.GLOBAL, globalDesc); } - this._endBindBlitUbo(devicePass); } private _recordAdditiveLights () { const devicePass = this._currentQueue.devicePass; - const submitMap = devicePass.submitMap; const context = devicePass.context; + const submitMap = context.submitMap; submitMap.get(this.camera!)?.additiveLight?.recordCommandBuffer(context.device, this._renderPass, devicePass.context.commandBuffer); @@ -1248,8 +1408,8 @@ class DeviceSceneTask extends WebSceneTask { private _recordPlanarShadows () { const devicePass = this._currentQueue.devicePass; - const submitMap = devicePass.submitMap; const context = devicePass.context; + const submitMap = context.submitMap; submitMap.get(this.camera!)?.planarQueue?.recordCommandBuffer(context.device, this._renderPass, devicePass.context.commandBuffer); @@ -1260,9 +1420,10 @@ class DeviceSceneTask extends WebSceneTask { const context = devicePass.context; if (!this._currentQueue.devicePass.viewport) { const texture = this._currentQueue.devicePass.framebuffer.colorTextures[0]!; - const lightInfo = this.graphScene.scene!.light; - const area = this._isShadowMap() && lightInfo.light - ? getRenderArea(this.camera!, texture.width, texture.height, lightInfo.light, lightInfo.level) + const graphScene = this.graphScene; + const lightInfo = graphScene.scene ? graphScene.scene.light : null; + const area = this._isShadowMap() && graphScene.scene && lightInfo!.light + ? getRenderArea(this.camera!, texture.width, texture.height, lightInfo!.light, lightInfo!.level) : getRenderArea(this.camera!, texture.width, texture.height); this.visitor.setViewport(new Viewport(area.x, area.y, area.width, area.height)); this.visitor.setScissor(area); @@ -1284,10 +1445,12 @@ class DeviceSceneTask extends WebSceneTask { if (graphSceneData.flags & SceneFlags.DRAW_INSTANCING) { this._recordInstences(); } - this._recordBatches(); + // this._recordBatches(); if (graphSceneData.flags & SceneFlags.DEFAULT_LIGHTING) { this._recordAdditiveLights(); } + this.visitor.bindDescriptorSet(SetIndex.GLOBAL, + devicePass.context.pipeline.descriptorSet); if (graphSceneData.flags & SceneFlags.PLANAR_SHADOW) { this._recordPlanarShadows(); } @@ -1301,9 +1464,8 @@ class DeviceSceneTask extends WebSceneTask { if (graphSceneData.flags & SceneFlags.UI) { this._recordUI(); } - if (graphSceneData.flags & SceneFlags.PROFILER) { - renderProfiler(context.device, devicePass.renderPass, - context.commandBuffer, context.pipeline.profiler, this.camera!); + if (graphSceneData.flags & SceneFlags.REFLECTION_PROBE) { + this._recordReflectionProbe(); } } } @@ -1330,6 +1492,8 @@ class ExecutorContext { this.layoutGraph = layoutGraph; this.width = width; this.height = height; + this.additiveLight = new RenderAdditiveLightQueue(pipeline); + this.shadowMapBatched = new RenderShadowMapBatchedQueue(pipeline); } readonly device: Device; readonly pipeline: Pipeline; @@ -1343,6 +1507,9 @@ class ExecutorContext { readonly ubo: PipelineUBO; readonly width: number; readonly height: number; + readonly additiveLight: RenderAdditiveLightQueue; + readonly shadowMapBatched: RenderShadowMapBatchedQueue; + readonly submitMap: Map = new Map(); renderGraph: RenderGraph; } class ResourceVisitor implements ResourceGraphVisitor { @@ -1399,6 +1566,7 @@ export class Executor { execute (rg: RenderGraph) { this._context.renderGraph = rg; + this._context.submitMap.clear(); const cmdBuff = this._context.commandBuffer; cmdBuff.begin(); const visitor = new RenderVisitor(this._context); @@ -1414,7 +1582,7 @@ export class Executor { } this._context.deviceTextures.clear(); } - private readonly _context: ExecutorContext; + readonly _context: ExecutorContext; } class BaseRenderVisitor { @@ -1461,13 +1629,25 @@ class PreRenderVisitor extends BaseRenderVisitor implements RenderGraphVisitor { raster (pass: RasterPass) { if (!this.rg.getValid(this.passID)) return; const devicePasses = this.context.devicePasses; - const passHash = stringify(pass); - this.currPass = devicePasses.get(passHash); - if (!this.currPass) { - this.currPass = new DeviceRenderPass(this.context, new RasterPassInfo(this.passID, pass)); - devicePasses.set(passHash, this.currPass); + if (pass.versionName === '') { + const passHash = stringify(pass); + this.currPass = devicePasses.get(passHash); + if (!this.currPass) { + this.currPass = new DeviceRenderPass(this.context, new RasterPassInfo(this.passID, pass)); + devicePasses.set(passHash, this.currPass); + } else { + this.currPass.resetResource(this.passID, pass); + } } else { - this.currPass.resetQueues(this.passID, pass); + const passHash = pass.versionName; + this.currPass = devicePasses.get(passHash); + const currRasterPass = this.currPass ? this.currPass.rasterPassInfo.pass : null; + if (!this.currPass || currRasterPass.version !== pass.version) { + this.currPass = new DeviceRenderPass(this.context, new RasterPassInfo(this.passID, pass)); + devicePasses.set(passHash, this.currPass); + } else { + this.currPass.resetResource(this.passID, pass); + } } } compute (value: ComputePass) {} @@ -1519,7 +1699,9 @@ class PostRenderVisitor extends BaseRenderVisitor implements RenderGraphVisitor } raster (pass: RasterPass) { const devicePasses = this.context.devicePasses; - const passHash = stringify(pass); + const passHash = pass.versionName === '' + ? stringify(pass) + : pass.versionName; const currPass = devicePasses.get(passHash); if (!currPass) return; this.currPass = currPass; diff --git a/cocos/rendering/custom/graph.ts b/cocos/rendering/custom/graph.ts index 650d89d4e3e..d3113f99111 100644 --- a/cocos/rendering/custom/graph.ts +++ b/cocos/rendering/custom/graph.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -251,7 +250,7 @@ export interface IncidenceGraph extends Graph { export interface BidirectionalGraph extends IncidenceGraph { inEdges (v: vertex_descriptor): in_edge_iterator; inDegree (v: vertex_descriptor): number; - degree (v: vertex_descriptor) : number; + degree (v: vertex_descriptor): number; } //-------------------------------------------------------------------------- @@ -425,7 +424,7 @@ export interface AddressableGraph extends ParentGraph { addressable (absPath: string): boolean; locate (absPath: string): vertex_descriptor | null; locateRelative (path: string, start?: vertex_descriptor | null): vertex_descriptor | null; - path (v: vertex_descriptor) : string; + path (v: vertex_descriptor): string; } //-------------------------------------------------------------------------- diff --git a/cocos/rendering/custom/index.jsb.ts b/cocos/rendering/custom/index.jsb.ts index de3bc6a7241..34364d05474 100644 --- a/cocos/rendering/custom/index.jsb.ts +++ b/cocos/rendering/custom/index.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,28 +20,26 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ declare const render: any; -import { legacyCC } from '../../core/global-exports'; -import { Pipeline, PipelineBuilder } from './pipeline'; -import { buildDeferredLayout, buildForwardLayout } from './effect'; +import { Pipeline, PipelineBuilder, RenderingModule } from './pipeline'; import { DeferredPipelineBuilder, ForwardPipelineBuilder } from './builtin-pipelines'; -import { CustomPipelineBuilder } from './custom-pipeline'; +import { CustomPipelineBuilder, NativePipelineBuilder } from './custom-pipeline'; +import { Device } from '../../gfx'; export * from './types'; export * from './pipeline'; +export * from './archive'; + +export const INVALID_ID = 0xFFFFFFFF; +export const enableEffectImport = true; + +let _renderModule: RenderingModule; export function createCustomPipeline (): Pipeline { - const root = legacyCC.director.root; - const ppl = render.Factory.createPipeline(); - if (root.useDeferredPipeline) { - buildDeferredLayout(ppl); - } else { - buildForwardLayout(ppl); - } - return ppl; + return render.Factory.createPipeline(); } export const customPipelineBuilderMap = new Map(); @@ -63,6 +60,46 @@ function addCustomBuiltinPipelines (map: Map) { map.set('Forward', new ForwardPipelineBuilder()); map.set('Deferred', new DeferredPipelineBuilder()); map.set('Custom', new CustomPipelineBuilder()); + map.set('Native', new NativePipelineBuilder()); } addCustomBuiltinPipelines(customPipelineBuilderMap); + +export function init (device: Device, arrayBuffer: ArrayBuffer | null) { + if (arrayBuffer) { + _renderModule = render.Factory.init(device, arrayBuffer); + } else { + _renderModule = render.Factory.init(device, new ArrayBuffer(0)); + } +} + +export function destroy () { + render.Factory.destroy(_renderModule); +} + +export function getPassID (name: string | undefined): number { + if (name === undefined) { + return _renderModule.getPassID('default'); + } + return _renderModule.getPassID(name); +} + +export function getPhaseID (passID: number, name: string | number | undefined): number { + if (name === undefined) { + return _renderModule.getPhaseID(passID, 'default'); + } + if (typeof(name) === 'number') { + return _renderModule.getPhaseID(passID, name.toString()); + } + return _renderModule.getPhaseID(passID, name); +} + +export function completePhaseName (name: string | number | undefined): string { + if (typeof name === 'number') { + return name.toString(); + } else if (typeof name === 'string') { + return name; + } else { + return 'default'; + } +} diff --git a/cocos/rendering/custom/index.ts b/cocos/rendering/custom/index.ts index 42feb4b16dd..ffea8944989 100644 --- a/cocos/rendering/custom/index.ts +++ b/cocos/rendering/custom/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,29 +20,40 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ +import { EDITOR } from 'internal:constants'; import { Pipeline, PipelineBuilder } from './pipeline'; import { WebPipeline } from './web-pipeline'; -import { buildDeferredLayout, buildForwardLayout } from './effect'; import { macro } from '../../core/platform/macro'; import { DeferredPipelineBuilder, ForwardPipelineBuilder } from './builtin-pipelines'; -import { CustomPipelineBuilder } from './custom-pipeline'; +import { CustomPipelineBuilder, NativePipelineBuilder } from './custom-pipeline'; +import { LayoutGraphData, loadLayoutGraphData } from './layout-graph'; +import { BinaryInputArchive } from './binary-archive'; +import { WebProgramLibrary } from './web-program-library'; +import { Device } from '../../gfx'; +import { initializeLayoutGraphData, terminateLayoutGraphData, getCustomPassID, getCustomPhaseID } from './layout-graph-utils'; +import { ProgramLibrary } from './private'; let _pipeline: WebPipeline | null = null; +export const INVALID_ID = 0xFFFFFFFF; +const defaultLayoutGraph = new LayoutGraphData(); + export * from './types'; export * from './pipeline'; +export * from './archive'; + +export const enableEffectImport = true; +export const programLib: ProgramLibrary = new WebProgramLibrary(defaultLayoutGraph); export function createCustomPipeline (): Pipeline { - const ppl = new WebPipeline(); + const layoutGraph = defaultLayoutGraph; + + const ppl = new WebPipeline(layoutGraph); const pplName = macro.CUSTOM_PIPELINE_NAME; ppl.setCustomPipelineName(pplName); - if (ppl.usesDeferredPipeline) { - buildDeferredLayout(ppl); - } else { - buildForwardLayout(ppl); - } + (programLib as WebProgramLibrary).pipeline = ppl; _pipeline = ppl; return ppl; } @@ -66,6 +76,37 @@ function addCustomBuiltinPipelines (map: Map) { map.set('Forward', new ForwardPipelineBuilder()); map.set('Deferred', new DeferredPipelineBuilder()); map.set('Custom', new CustomPipelineBuilder()); + map.set('Native', new NativePipelineBuilder()); } addCustomBuiltinPipelines(customPipelineBuilderMap); + +export function init (device: Device, arrayBuffer: ArrayBuffer | null) { + if (arrayBuffer) { + const readBinaryData = new BinaryInputArchive(arrayBuffer); + loadLayoutGraphData(readBinaryData, defaultLayoutGraph); + } + initializeLayoutGraphData(device, defaultLayoutGraph); +} + +export function destroy () { + terminateLayoutGraphData(defaultLayoutGraph); +} + +export function getPassID (name: string | undefined): number { + return getCustomPassID(defaultLayoutGraph, name); +} + +export function getPhaseID (passID: number, name: string | number | undefined): number { + return getCustomPhaseID(defaultLayoutGraph, passID, name); +} + +export function completePhaseName (name: string | number | undefined): string { + if (typeof name === 'number') { + return name.toString(); + } else if (typeof name === 'string') { + return name; + } else { + return 'default'; + } +} diff --git a/cocos/rendering/custom/layout-graph-utils.ts b/cocos/rendering/custom/layout-graph-utils.ts new file mode 100644 index 00000000000..6da6ca94b4a --- /dev/null +++ b/cocos/rendering/custom/layout-graph-utils.ts @@ -0,0 +1,1658 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + +/* eslint-disable max-len */ +import { EffectAsset } from '../../asset/assets'; +import { assert } from '../../core'; +import { DescriptorSetInfo, DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorSetLayoutInfo, DescriptorType, Device, PipelineLayout, PipelineLayoutInfo, ShaderStageFlagBit, Type, Uniform, UniformBlock } from '../../gfx'; +import { DefaultVisitor, depthFirstSearch, GraphColor, MutableVertexPropertyMap } from './graph'; +import { DescriptorBlockData, DescriptorData, DescriptorDB, DescriptorSetData, DescriptorSetLayoutData, LayoutGraph, LayoutGraphData, LayoutGraphDataValue, LayoutGraphValue, PipelineLayoutData, RenderPhase, RenderPhaseData, RenderStageData, ShaderProgramData } from './layout-graph'; +import { UpdateFrequency, getUpdateFrequencyName, getDescriptorTypeOrderName, Descriptor, DescriptorBlock, DescriptorBlockFlattened, DescriptorBlockIndex, DescriptorTypeOrder, ParameterType } from './types'; + +export const INVALID_ID = 0xFFFFFFFF; + +// get name of gfx.Type +function getGfxTypeName (type: Type): string { + switch (type) { + case Type.UNKNOWN: return 'Unknown'; + case Type.BOOL: return 'Bool'; + case Type.BOOL2: return 'Bool2'; + case Type.BOOL3: return 'Bool3'; + case Type.BOOL4: return 'Bool4'; + case Type.INT: return 'Int'; + case Type.INT2: return 'Int2'; + case Type.INT3: return 'Int3'; + case Type.INT4: return 'Int4'; + case Type.UINT: return 'Uint'; + case Type.UINT2: return 'Uint2'; + case Type.UINT3: return 'Uint3'; + case Type.UINT4: return 'Uint4'; + case Type.FLOAT: return 'Float'; + case Type.FLOAT2: return 'Float2'; + case Type.FLOAT3: return 'Float3'; + case Type.FLOAT4: return 'Float4'; + case Type.MAT2: return 'Mat2'; + case Type.MAT2X3: return 'Mat2x3'; + case Type.MAT2X4: return 'Mat2x4'; + case Type.MAT3X2: return 'Mat3x2'; + case Type.MAT3: return 'Mat3'; + case Type.MAT3X4: return 'Mat3x4'; + case Type.MAT4X2: return 'Mat4x2'; + case Type.MAT4X3: return 'Mat4x3'; + case Type.MAT4: return 'Mat4'; + case Type.SAMPLER1D: return 'Sampler1D'; + case Type.SAMPLER1D_ARRAY: return 'Sampler1DArray'; + case Type.SAMPLER2D: return 'Sampler2D'; + case Type.SAMPLER2D_ARRAY: return 'Sampler2DArray'; + case Type.SAMPLER3D: return 'Sampler3D'; + case Type.SAMPLER_CUBE: return 'SamplerCube'; + case Type.SAMPLER: return 'Sampler'; + case Type.TEXTURE1D: return 'Texture1D'; + case Type.TEXTURE1D_ARRAY: return 'Texture1DArray'; + case Type.TEXTURE2D: return 'Texture2D'; + case Type.TEXTURE2D_ARRAY: return 'Texture2DArray'; + case Type.TEXTURE3D: return 'Texture3D'; + case Type.TEXTURE_CUBE: return 'TextureCube'; + case Type.IMAGE1D: return 'Image1D'; + case Type.IMAGE1D_ARRAY: return 'Image1DArray'; + case Type.IMAGE2D: return 'Image2D'; + case Type.IMAGE2D_ARRAY: return 'Image2DArray'; + case Type.IMAGE3D: return 'Image3D'; + case Type.IMAGE_CUBE: return 'ImageCube'; + case Type.SUBPASS_INPUT: return 'SubpassInput'; + case Type.COUNT: return 'Count'; + default: return 'Unknown'; + } +} + +// get DescriptorType from DescriptorTypeOrder +export function getGfxDescriptorType (type: DescriptorTypeOrder): DescriptorType { + switch (type) { + case DescriptorTypeOrder.UNIFORM_BUFFER: + return DescriptorType.UNIFORM_BUFFER; + case DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER: + return DescriptorType.DYNAMIC_UNIFORM_BUFFER; + case DescriptorTypeOrder.SAMPLER_TEXTURE: + return DescriptorType.SAMPLER_TEXTURE; + case DescriptorTypeOrder.SAMPLER: + return DescriptorType.SAMPLER; + case DescriptorTypeOrder.TEXTURE: + return DescriptorType.TEXTURE; + case DescriptorTypeOrder.STORAGE_BUFFER: + return DescriptorType.STORAGE_BUFFER; + case DescriptorTypeOrder.DYNAMIC_STORAGE_BUFFER: + return DescriptorType.DYNAMIC_STORAGE_BUFFER; + case DescriptorTypeOrder.STORAGE_IMAGE: + return DescriptorType.STORAGE_IMAGE; + case DescriptorTypeOrder.INPUT_ATTACHMENT: + return DescriptorType.INPUT_ATTACHMENT; + default: + console.error('DescriptorType not found'); + return DescriptorType.INPUT_ATTACHMENT; + } +} + +// get DescriptorTypeOrder from DescriptorType +export function getDescriptorTypeOrder (type: DescriptorType): DescriptorTypeOrder { + switch (type) { + case DescriptorType.UNIFORM_BUFFER: + return DescriptorTypeOrder.UNIFORM_BUFFER; + case DescriptorType.DYNAMIC_UNIFORM_BUFFER: + return DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER; + case DescriptorType.SAMPLER_TEXTURE: + return DescriptorTypeOrder.SAMPLER_TEXTURE; + case DescriptorType.SAMPLER: + return DescriptorTypeOrder.SAMPLER; + case DescriptorType.TEXTURE: + return DescriptorTypeOrder.TEXTURE; + case DescriptorType.STORAGE_BUFFER: + return DescriptorTypeOrder.STORAGE_BUFFER; + case DescriptorType.DYNAMIC_STORAGE_BUFFER: + return DescriptorTypeOrder.DYNAMIC_STORAGE_BUFFER; + case DescriptorType.STORAGE_IMAGE: + return DescriptorTypeOrder.STORAGE_IMAGE; + case DescriptorType.INPUT_ATTACHMENT: + return DescriptorTypeOrder.INPUT_ATTACHMENT; + case DescriptorType.UNKNOWN: + default: + console.error('DescriptorTypeOrder not found'); + return DescriptorTypeOrder.INPUT_ATTACHMENT; + } +} + +// find passID using name +export function getCustomPassID (lg: LayoutGraphData, name: string | undefined): number { + return lg.locateChild(lg.nullVertex(), name || 'default'); +} + +// find phaseID using passID and phase name +export function getCustomPhaseID (lg: LayoutGraphData, passID: number, name: string | number | undefined): number { + if (name === undefined) { + return lg.locateChild(passID, 'default'); + } + if (typeof (name) === 'number') { + return lg.locateChild(passID, name.toString()); + } + return lg.locateChild(passID, name); +} + +// check ShaderStageFlagBit has certain bits +function hasFlag (flags: ShaderStageFlagBit, flagToTest: ShaderStageFlagBit): boolean { + return (flags & flagToTest) !== 0; +} + +// get name of visibility +function getVisibilityName (stage: ShaderStageFlagBit): string { + let count = 0; + let str = ''; + if (hasFlag(stage, ShaderStageFlagBit.VERTEX)) { + if (count++) { + str += ' | '; + } + str += 'Vertex'; + } + if (hasFlag(stage, ShaderStageFlagBit.CONTROL)) { + if (count++) { + str += ' | '; + } + str += 'Control'; + } + if (hasFlag(stage, ShaderStageFlagBit.EVALUATION)) { + if (count++) { + str += ' | '; + } + str += 'Evaluation'; + } + if (hasFlag(stage, ShaderStageFlagBit.GEOMETRY)) { + if (count++) { + str += ' | '; + } + str += 'Geometry'; + } + if (hasFlag(stage, ShaderStageFlagBit.FRAGMENT)) { + if (count++) { + str += ' | '; + } + str += 'Fragment'; + } + if (hasFlag(stage, ShaderStageFlagBit.COMPUTE)) { + if (count++) { + str += ' | '; + } + str += 'Compute'; + } + if (stage === ShaderStageFlagBit.ALL) { + if (count++) { + str += ' | '; + } + str += 'All'; + } + return str; +} + +// print LayoutGraphData +export class PrintVisitor extends DefaultVisitor { + discoverVertex (u: number, g: LayoutGraphData) { + const ppl: PipelineLayoutData = g.getLayout(u); + const name: string = g._names[u]; + const freq: UpdateFrequency = g._updateFrequencies[u]; + this.oss += `${this.space}"${name}": `; + if (g.holds(LayoutGraphDataValue.RenderStage, u)) { + this.oss += `RenderStage {\n`; + } else { + this.oss += `RenderPhase {\n`; + } + this.space = indent(this.space); + + // eslint-disable-next-line no-loop-func + ppl.descriptorSets.forEach((value, key) => { + this.oss += `${this.space}DescriptorSet<${getUpdateFrequencyName(key)}> {\n`; + this.space = indent(this.space); + const uniformBlocks = value.descriptorSetLayoutData.uniformBlocks; + uniformBlocks.forEach((uniformBlock, attrNameID) => { + const name = g.valueNames[attrNameID]; + this.oss += `${this.space}UniformBlock "${name}" {\n`; + for (const u of uniformBlock.members) { + if (u.count > 1) { + this.oss += `${this.space} ${u.name}[${u.count}]: ${getGfxTypeName(u.type)}\n`; + } else { + this.oss += `${this.space} ${u.name}: ${getGfxTypeName(u.type)}\n`; + } + } + this.oss += `${this.space}}\n`; + }); + + const blocks = value.descriptorSetLayoutData.descriptorBlocks; + for (let j = 0; j < blocks.length; ++j) { + const block = blocks[j]; + this.oss += `${this.space}Block<${getDescriptorTypeOrderName(block.type)}, ${getVisibilityName(block.visibility)}> {\n`; + this.oss += `${this.space} offset: ${block.offset}\n`; + this.oss += `${this.space} capacity: ${block.capacity}\n`; + this.oss += `${this.space} count: ${block.descriptors.length}\n`; + if (block.descriptors.length > 0) { + this.oss += `${this.space} Descriptors{ \n`; + const count = 0; + for (let k = 0; k < block.descriptors.length; ++k) { + const d: DescriptorData = block.descriptors[k]; + // if (count++) { + this.oss += this.space; + this.oss += ' '; + const n: string = g.valueNames[d.descriptorID]; + this.oss += `"${n}`; + if (d.count !== 1) { + this.oss += `[${d.count}]`; + } + this.oss += '"'; + // } + this.oss += '\n'; + } + this.oss += `${this.space} }\n`; + } + this.oss += `${this.space}}\n`; + } + this.space = unindent(this.space); + this.oss += `${this.space}}\n`; + }); + } + finishVertex (v: number, g: LayoutGraphData) { + this.space = unindent(this.space); + this.oss += `${this.space}}\n`; + } + space = ''; + oss = ''; +} + +// text tools, indent 4 spaces +function indent (space: string): string { + return `${space} `; +} + +// text tools, unindent 4 spaces +function unindent (space: string): string { + return space.substring(0, space.length > 4 ? space.length - 4 : 0); +} + +// flatten DescriptorBlock to DescriptorBlockFlattened +function convertDescriptorBlock (block: DescriptorBlock): DescriptorBlockFlattened { + const flattened = new DescriptorBlockFlattened(); + + // sort descriptors by name + const descriptors = Array.from(block.descriptors).sort( + (a, b) => String(a[0]).localeCompare(b[0]), + ); + + // flatten descriptors + descriptors.forEach((v: [string, Descriptor]) => { + const name: string = v[0]; + const d = v[1]; + flattened.descriptorNames.push(name); + flattened.descriptors.push(d); + }); + + // sort uniforms by name + const uniformBlocks = Array.from(block.uniformBlocks).sort( + (a, b) => String(a[0]).localeCompare(b[0]), + ); + + // flatten uniforms + uniformBlocks.forEach((v: [string, UniformBlock]) => { + const name = v[0]; + const uniformBlock = v[1]; + flattened.uniformBlockNames.push(name); + flattened.uniformBlocks.push(uniformBlock); + }); + + // calculate count and capacity + flattened.count = block.count; + flattened.capacity = block.capacity; + return flattened; +} + +// cache of descriptor blocks +class DescriptorCounter { + public addDescriptor (key: string, name: string, count: number) { + // key is DescriptorBlockIndex + // name is Descriptor name + // count is Descriptor count + const v = this.counter.get(key); + if (v === undefined) { + this.counter.set(key, count); + this.inspector.set(key, [name]); + return; + } + this.counter.set(key, v + count); + this.inspector.get(key)?.push(name); + } + // counter is the num of descriptors in each block + readonly counter = new Map(); + readonly inspector = new Map>(); +} + +// print LayoutGraph (not LayoutGraphData) +class LayoutGraphPrintVisitor extends DefaultVisitor { + discoverVertex (v: number, g: LayoutGraph) { + const info: DescriptorDB = g.getDescriptors(v); + const name = g.getName(v); + + this.oss += `${this.space}"${name}": `; + switch (g.id(v)) { + case LayoutGraphValue.RenderStage: + this.oss += `RenderStage {\n`; + break; + case LayoutGraphValue.RenderPhase: + this.oss += `RenderPhase {\n`; + break; + default: + this.oss += `unknown LayoutGraphValue {\n`; + break; + } + this.space = indent(this.space); + + const sortedMap: Map = new Map( + Array.from(info.blocks).sort((a, b) => String(a[0]).localeCompare(b[0])), + ); + + sortedMap.forEach((block: DescriptorBlock, key: string) => { + const index: DescriptorBlockIndex = JSON.parse(key); + const flat = convertDescriptorBlock(block); + this.oss += `${this.space}DescriptorBlock {\n`; + this.space = indent(this.space); + this.oss += `${this.space}updateRate: ${getUpdateFrequencyName(index.updateFrequency)}\n`; + this.oss += `${this.space}type: ${getDescriptorTypeOrderName(index.descriptorType)}\n`; + this.oss += `${this.space}visibility: ${getVisibilityName(index.visibility)}\n`; + this.oss += `${this.space}descriptors: [${flat.descriptorNames.join(', ')}]\n`; + this.oss += `${this.space}uniformBlocks: [`; + for (let i = 0; i < flat.uniformBlocks.length; ++i) { + if (i) { + this.oss += ', '; + } + this.oss += `${flat.uniformBlocks[i].name}`; + } + this.oss += `]\n`; + this.oss += `${this.space}count: ${flat.count}\n`; + this.oss += `${this.space}capacity: ${flat.capacity}\n`; + this.space = unindent(this.space); + this.oss += `${this.space}}\n`; + }); + } + finishVertex (v: number, g: LayoutGraphData) { + this.space = unindent(this.space); + this.oss += `${this.space}}\n`; + } + space = ''; + oss = ''; +} + +// get pass name from effect +function getPassName (pass: EffectAsset.IPassInfo): string { + if (pass.pass === undefined) { + return 'default'; + } + return pass.pass; +} + +// get phase name from effect +function getPhaseName (pass: EffectAsset.IPassInfo): string { + if (pass.phase === undefined) { + return 'default'; + } + if (typeof (pass.phase) === 'number') { + return pass.phase.toString(); + } + return pass.phase; +} + +// key of Visibility +export class VisibilityIndex { + constructor ( + updateFrequency = UpdateFrequency.PER_INSTANCE, + parameterType = ParameterType.TABLE, + descriptorType = DescriptorTypeOrder.UNIFORM_BUFFER, + ) { + this.updateFrequency = updateFrequency; + this.parameterType = parameterType; + this.descriptorType = descriptorType; + } + updateFrequency: UpdateFrequency; + parameterType: ParameterType; + descriptorType: DescriptorTypeOrder; +} + +// descriptors of same visibility +export class VisibilityBlock { + public mergeVisibility (name: string, vis: ShaderStageFlagBit) { + // for each descriptor, merge visibility + // rate must >= PER_PHASE + const v0 = this.descriptors.get(name); + if (v0 === undefined) { + this.descriptors.set(name, vis); + } else { + this.descriptors.set(name, v0 | vis); + } + } + public getVisibility (name: string): ShaderStageFlagBit { + const v = this.descriptors.get(name); + if (v === undefined) { + console.error(`Can't find visibility for descriptor: ${name}`); + return ShaderStageFlagBit.NONE; + } + return v; + } + descriptors = new Map(); +} + +// visibility database of phase +export class VisibilityDB { + public getBlock (index: VisibilityIndex): VisibilityBlock { + const key = JSON.stringify(index); + let block = this.blocks.get(key); + if (block === undefined) { + block = new VisibilityBlock(); + this.blocks.set(key, block); + } + return block; + } + blocks = new Map(); +} + +// visibility database of pass +export class VisibilityPass { + public getPhase (phaseName: string): VisibilityDB { + const phase = this.phases.get(phaseName); + if (phase === undefined) { + const newPhase = new VisibilityDB(); + this.phases.set(phaseName, newPhase); + return newPhase; + } + return phase; + } + phases = new Map(); +} + +export class VisibilityGraph { + public getPass (passName: string): VisibilityPass { + const pass = this.passes.get(passName); + if (pass === undefined) { + const newPass = new VisibilityPass(); + this.passes.set(passName, newPass); + return newPass; + } + return pass; + } + private merge ( + rate: UpdateFrequency, + order: DescriptorTypeOrder, + infoArray: EffectAsset.IBlockInfo[] | + EffectAsset.IBufferInfo[] | + EffectAsset.ISamplerInfo[] | + EffectAsset.IInputAttachmentInfo[] | + EffectAsset.IImageInfo[] | + EffectAsset.ISamplerTextureInfo[] | + EffectAsset.ITextureInfo[], + db: VisibilityDB, + ) { + const blockIndex = new VisibilityIndex( + rate, + ParameterType.TABLE, + order, + ); + const block = db.getBlock(blockIndex); + for (const info of infoArray) { + block.mergeVisibility(info.name, info.stageFlags); + } + } + public mergeEffect (asset: EffectAsset) { + for (const tech of asset.techniques) { + for (const pass of tech.passes) { + const programName = pass.program; + let shader: EffectAsset.IShaderInfo | null = null; + for (const shaderInfo of asset.shaders) { + if (shaderInfo.name === programName) { + shader = shaderInfo; + } + } + if (!shader) { + continue; + } + if (shader.descriptors === undefined) { + console.warn(`No descriptors in shader: ${programName}, please reimport ALL effects`); + continue; + } + const passName = getPassName(pass); + const passData = this.getPass(passName); + const phaseName = getPhaseName(pass); + const phaseData = passData.getPhase(phaseName); + for (const list of shader.descriptors) { + if (list.rate < UpdateFrequency.PER_PHASE) { + // do not merger PER_BATCH, PER_INSTANCE descriptors + continue; + } + this.merge(list.rate, DescriptorTypeOrder.UNIFORM_BUFFER, list.blocks, phaseData); + this.merge(list.rate, DescriptorTypeOrder.STORAGE_BUFFER, list.buffers, phaseData); + this.merge(list.rate, DescriptorTypeOrder.TEXTURE, list.textures, phaseData); + this.merge(list.rate, DescriptorTypeOrder.SAMPLER_TEXTURE, list.samplerTextures, phaseData); + this.merge(list.rate, DescriptorTypeOrder.SAMPLER, list.samplers, phaseData); + this.merge(list.rate, DescriptorTypeOrder.STORAGE_IMAGE, list.images, phaseData); + this.merge(list.rate, DescriptorTypeOrder.INPUT_ATTACHMENT, list.subpassInputs, phaseData); + } + } + } + } + passes = new Map(); +} + +// graph coloring help class +class VectorGraphColorMap implements MutableVertexPropertyMap { + constructor (sz: number) { + this.colors = new Array(sz); + } + get (u: number): GraphColor { + return this.colors[u]; + } + put (u: number, value: GraphColor): void { + this.colors[u] = value; + } + readonly colors: Array; +} + +// class to layout all descriptors +export class LayoutGraphInfo { + constructor (visg: VisibilityGraph) { + this.visg = visg; + } + lg = new LayoutGraph(); + visg: VisibilityGraph; + readonly enableDebug = false; + private getPassID (passName: string): number { + const lg = this.lg; + let passID = lg.locateChild(lg.nullVertex(), passName); + if (passID === lg.nullVertex()) { + passID = lg.addVertex( + LayoutGraphValue.RenderStage, 0, + passName, new DescriptorDB(), + lg.nullVertex(), + ); + } + return passID; + } + private getPhaseID (phaseName: string, passID: number): number { + const lg = this.lg; + let phaseID = lg.locateChild(passID, phaseName); + if (phaseID === lg.nullVertex()) { + phaseID = lg.addVertex( + LayoutGraphValue.RenderPhase, new RenderPhase(), + phaseName, new DescriptorDB(), + passID, + ); + } + return phaseID; + } + private getDescriptorBlock (key: string, descriptorDB: DescriptorDB): DescriptorBlock { + const value = descriptorDB.blocks.get(key); + if (value === undefined) { + const uniformBlock: DescriptorBlock = new DescriptorBlock(); + descriptorDB.blocks.set(key, uniformBlock); + return uniformBlock; + } + return value; + } + private checkConsistency (lhs: UniformBlock, rhs: UniformBlock): boolean { + if (lhs.count !== 1) { + return false; + } + if (lhs.members.length !== rhs.members.length) { + return false; + } + for (let i = 0; i < lhs.members.length; ++i) { + if (lhs.members[i].name !== rhs.members[i].name) { + return false; + } + if (lhs.members[i].type !== rhs.members[i].type) { + return false; + } + if (lhs.members[i].count !== rhs.members[i].count) { + return false; + } + } + return true; + } + private makeUniformBlock (info: EffectAsset.IBlockInfo): UniformBlock { + const uniformBlock = new UniformBlock(0, 0, info.name); + uniformBlock.count = 1; + for (const member of info.members) { + uniformBlock.members.push(new Uniform(member.name, member.type, member.count)); + } + return uniformBlock; + } + private addDescriptor (block: DescriptorBlock, name: string, type = Type.UNKNOWN) { + const value = block.descriptors.get(name); + if (value === undefined) { + block.descriptors.set(name, new Descriptor(type)); + ++block.capacity; + ++block.count; + return; + } + if (value.type !== type) { + console.warn(`Type mismatch for descriptor ${name}`); + } + } + private addUniformBlock (block: DescriptorBlock, + name: string, gfxBlock: UniformBlock): void { + const value = block.uniformBlocks.get(name); + if (value === undefined) { + block.uniformBlocks.set(name, gfxBlock); + return; + } + if (!this.checkConsistency(value, gfxBlock)) { + console.warn(`Uniform block ${name} is inconsistent in the same block`); + } + } + private buildBlocks (visDB: VisibilityDB, rate: UpdateFrequency, blocks: EffectAsset.IBlockInfo[], db: DescriptorDB, counter: DescriptorCounter) { + const visBlock = visDB.getBlock({ + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.UNIFORM_BUFFER, + }); + for (const info of blocks) { + const blockIndex = new DescriptorBlockIndex( + rate, + ParameterType.TABLE, + DescriptorTypeOrder.UNIFORM_BUFFER, + rate >= UpdateFrequency.PER_PHASE ? visBlock.getVisibility(info.name) : info.stageFlags, + ); + const key = JSON.stringify(blockIndex); + const block = this.getDescriptorBlock(key, db); + if (blockIndex.updateFrequency > UpdateFrequency.PER_BATCH) { + this.addDescriptor(block, info.name); + this.addUniformBlock(block, info.name, this.makeUniformBlock(info)); + } else { + counter.addDescriptor(key, info.name, 1); + } + } + } + private buildBuffers ( + visDB: VisibilityDB, + rate: UpdateFrequency, + infoArray: EffectAsset.IBufferInfo[], + type: Type, db: DescriptorDB, counter: DescriptorCounter, + ) { + const visBlock = visDB.getBlock({ + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.STORAGE_BUFFER, + }); + for (const info of infoArray) { + const blockIndex = new DescriptorBlockIndex( + rate, + ParameterType.TABLE, + DescriptorTypeOrder.STORAGE_BUFFER, + rate >= UpdateFrequency.PER_PHASE ? visBlock.getVisibility(info.name) : info.stageFlags, + ); + const key = JSON.stringify(blockIndex); + const block = this.getDescriptorBlock(key, db); + if (blockIndex.updateFrequency > UpdateFrequency.PER_BATCH) { + this.addDescriptor(block, info.name, type); + } else { + counter.addDescriptor(key, info.name, 1); + } + } + } + private buildNonTextures ( + visDB: VisibilityDB, + rate: UpdateFrequency, + order: DescriptorTypeOrder, + infoArray: EffectAsset.ISamplerInfo[] | EffectAsset.IInputAttachmentInfo[], + type: Type, db: DescriptorDB, counter: DescriptorCounter, + ) { + const visBlock = visDB.getBlock({ + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: order, + }); + for (const info of infoArray) { + const blockIndex = new DescriptorBlockIndex( + rate, + ParameterType.TABLE, + order, + rate >= UpdateFrequency.PER_PHASE ? visBlock.getVisibility(info.name) : info.stageFlags, + ); + const key = JSON.stringify(blockIndex); + const block = this.getDescriptorBlock(key, db); + if (blockIndex.updateFrequency > UpdateFrequency.PER_BATCH) { + this.addDescriptor(block, info.name, type); + } else { + counter.addDescriptor(key, info.name, info.count); + } + } + } + private buildTextures ( + visDB: VisibilityDB, + rate: UpdateFrequency, + order: DescriptorTypeOrder, + infoArray: EffectAsset.IImageInfo[] | EffectAsset.ISamplerTextureInfo[] | EffectAsset.ITextureInfo[], + db: DescriptorDB, counter: DescriptorCounter, + ) { + const visBlock = visDB.getBlock({ + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: order, + }); + for (const info of infoArray) { + const blockIndex = new DescriptorBlockIndex( + rate, + ParameterType.TABLE, + order, + rate >= UpdateFrequency.PER_PHASE ? visBlock.getVisibility(info.name) : info.stageFlags, + ); + const key = JSON.stringify(blockIndex); + const block = this.getDescriptorBlock(key, db); + if (blockIndex.updateFrequency > UpdateFrequency.PER_BATCH) { + this.addDescriptor(block, info.name, info.type); + } else { + counter.addDescriptor(key, info.name, info.count); + } + } + } + public addEffect (asset: EffectAsset): void { + const lg = this.lg; + for (const tech of asset.techniques) { + for (const pass of tech.passes) { + const programName = pass.program; + let shader: EffectAsset.IShaderInfo | null = null; + for (const shaderInfo of asset.shaders) { + if (shaderInfo.name === programName) { + shader = shaderInfo; + } + } + if (!shader) { + console.warn(`program: ${programName} not found`); + continue; + } + if (shader.descriptors === undefined) { + console.warn(`No descriptors in shader: ${programName}, please reimport ALL effects`); + continue; + } + // get database + const passName = getPassName(pass); + const phaseName = getPhaseName(pass); + const passID = this.getPassID(passName); + const phaseID = this.getPhaseID(phaseName, passID); + const passVis = this.visg.getPass(passName); + const visDB = passVis.getPhase(phaseName); + const db = lg.getDescriptors(phaseID); + const counter = new DescriptorCounter(); + + // merge descriptors and reserve capacity + for (const list of shader.descriptors) { + this.buildBlocks(visDB, list.rate, list.blocks, db, counter); + this.buildBuffers(visDB, list.rate, list.buffers, Type.UNKNOWN, db, counter); + this.buildNonTextures(visDB, list.rate, DescriptorTypeOrder.SAMPLER, list.samplers, Type.SAMPLER, db, counter); + this.buildNonTextures(visDB, list.rate, DescriptorTypeOrder.INPUT_ATTACHMENT, list.subpassInputs, Type.SAMPLER, db, counter); + this.buildTextures(visDB, list.rate, DescriptorTypeOrder.TEXTURE, list.textures, db, counter); + this.buildTextures(visDB, list.rate, DescriptorTypeOrder.SAMPLER_TEXTURE, list.samplerTextures, db, counter); + this.buildTextures(visDB, list.rate, DescriptorTypeOrder.STORAGE_IMAGE, list.images, db, counter); + } + + // update max capacity and debug info + counter.counter.forEach((v: number, key: string) => { + const block = this.getDescriptorBlock(key, db); + if (v > block.capacity) { + block.capacity = Math.max(block.capacity, v); + if (this.enableDebug) { + const names = counter.inspector.get(key); + if (names === undefined) { + return; + } + block.descriptors.clear(); + for (const name of names) { + block.descriptors.set(name, new Descriptor()); + } + } + } + }); + } + } + } + public build (): number { + const lg = this.lg; + const visMap = new Map(); + // merge phase to pass + for (const v of lg.vertices()) { + if (lg.id(v) === LayoutGraphValue.RenderStage) { + // create visibility database + visMap.set(v, new VisibilityDB()); + continue; + } + const phaseID = v; + const parentID = lg.getParent(phaseID); + if (lg.id(parentID) !== LayoutGraphValue.RenderStage) { + console.error(`phase: ${lg.getName(phaseID)} has no parent stage`); + return 1; + } + const phaseDB = lg.getDescriptors(phaseID); + const passVisDB = visMap.get(parentID); + if (!passVisDB) { + console.error(`pass: ${lg.getName(parentID)} has no visibility database`); + return 1; + } + // merge phase visibility to pass visibility + for (const [key, block] of phaseDB.blocks) { + const index: DescriptorBlockIndex = JSON.parse(key); + if (index.updateFrequency <= UpdateFrequency.PER_PHASE) { + continue; + } + const visIndex = new VisibilityIndex(index.updateFrequency, index.parameterType, index.descriptorType); + const passVisBlock = passVisDB.getBlock(visIndex); + for (const [name, d] of block.descriptors) { + passVisBlock.mergeVisibility(name, index.visibility); + } + } + } + for (const v of lg.vertices()) { + if (lg.id(v) === LayoutGraphValue.RenderStage) { + continue; + } + const phaseID = v; + const parentID = lg.getParent(phaseID); + if (lg.id(parentID) !== LayoutGraphValue.RenderStage) { + console.error(`phase: ${lg.getName(phaseID)} has no parent stage`); + return 1; + } + const passDB = lg.getDescriptors(parentID); + const phaseDB = lg.getDescriptors(phaseID); + const passVisDB = visMap.get(parentID); + if (passVisDB === undefined) { + console.error(`pass: ${lg.getName(parentID)} has no visibility database`); + return 1; + } + for (const [key0, block] of phaseDB.blocks) { + const index0: DescriptorBlockIndex = JSON.parse(key0); + if (index0.updateFrequency <= UpdateFrequency.PER_PHASE) { + continue; + } + const visIndex = new VisibilityIndex( + index0.updateFrequency, index0.parameterType, index0.descriptorType, + ); + const passVisBlock = passVisDB.getBlock(visIndex); + + for (const [name, d] of block.descriptors) { + const vis = passVisBlock.getVisibility(name); + let passBlock: DescriptorBlock; + if (vis === index0.visibility) { + passBlock = this.getDescriptorBlock(key0, passDB); + } else { + const index = new DescriptorBlockIndex( + index0.updateFrequency, + index0.parameterType, + index0.descriptorType, + vis, + ); + const key = JSON.stringify(index); + passBlock = this.getDescriptorBlock(key, passDB); + } + this.addDescriptor(passBlock, name, d.type); + if (index0.descriptorType !== DescriptorTypeOrder.UNIFORM_BUFFER) { + continue; + } + const b = block.uniformBlocks.get(name); + if (!b) { + console.error(`uniform block: ${name} not found`); + return 1; + } + this.addUniformBlock(passBlock, name, b); + } + } + } + // update pass + for (const passID of lg.vertices()) { + if (lg.id(passID) !== LayoutGraphValue.RenderStage) { + continue; + } + const passDB = lg.getDescriptors(passID); + // update children phases + for (const e of lg.children(passID)) { + const phaseID = lg.child(e); + const phaseDB = lg.getDescriptors(phaseID); + for (const [key, passBlock] of passDB.blocks) { + const index: DescriptorBlockIndex = JSON.parse(key); + if (index.updateFrequency !== UpdateFrequency.PER_PASS) { + console.error(`phase: ${lg.getName(phaseID)} update frequency is not PER_PASS`); + return 1; + } + if (passBlock.count === 0) { + console.error(`pass: ${lg.getName(passID)} count is 0`); + return 1; + } + if (passBlock.capacity !== passBlock.count) { + console.error(`pass: ${lg.getName(passID)} capacity does not equal count`); + return 1; + } + const phaseBlock = this.getDescriptorBlock(key, phaseDB); + phaseBlock.descriptors.clear(); + phaseBlock.uniformBlocks.clear(); + phaseBlock.capacity = passBlock.capacity; + phaseBlock.count = passBlock.count; + for (const [name, d] of passBlock.descriptors) { + phaseBlock.descriptors.set(name, d); + } + for (const [name, b] of passBlock.uniformBlocks) { + phaseBlock.uniformBlocks.set(name, b); + } + } + } + } + // console.debug(this.print()); + return 0; + } + public print (): string { + const print = new LayoutGraphPrintVisitor(); + const colorMap = new VectorGraphColorMap(this.lg.numVertices()); + depthFirstSearch(this.lg, print, colorMap); + return print.oss; + } +} + +// sort descriptorBlocks using DescriptorBlockIndex +function sortDescriptorBlocks (lhs: [string, T], rhs: [string, T]): number { + const lhsIndex: DescriptorBlockIndex = JSON.parse(lhs[0]); + const rhsIndex: DescriptorBlockIndex = JSON.parse(rhs[0]); + const lhsValue = lhsIndex.updateFrequency * 10000 + + lhsIndex.parameterType * 1000 + + lhsIndex.descriptorType * 100 + + lhsIndex.visibility; + const rhsValue = rhsIndex.updateFrequency * 10000 + + rhsIndex.parameterType * 1000 + + rhsIndex.descriptorType * 100 + + rhsIndex.visibility; + return lhsValue - rhsValue; +} + +// build LayoutGraphData +function buildLayoutGraphDataImpl (graph: LayoutGraph, builder: LayoutGraphBuilder2) { + for (const v of graph.vertices()) { + const db = graph.getDescriptors(v); + let minLevel = UpdateFrequency.PER_INSTANCE; + let maxLevel = UpdateFrequency.PER_PASS; + switch (graph.id(v)) { + case LayoutGraphValue.RenderStage: { + const vertID = builder.addRenderStage(graph.getName(v)); + if (vertID !== v) { + console.error('vertex id mismatch'); + } + minLevel = UpdateFrequency.PER_PASS; + maxLevel = UpdateFrequency.PER_PASS; + break; + } + case LayoutGraphValue.RenderPhase: { + const parentID = graph.getParent(v); + const vertID = builder.addRenderPhase(graph.getName(v), parentID); + if (vertID !== v) { + console.error('vertex id mismatch'); + } + const phase = graph.getRenderPhase(v); + for (const shaderName of phase.shaders) { + builder.addShader(shaderName, v); + } + minLevel = UpdateFrequency.PER_INSTANCE; + maxLevel = UpdateFrequency.PER_PHASE; + break; + } + default: + console.error('unknown vertex type'); + minLevel = UpdateFrequency.PER_INSTANCE; + minLevel = UpdateFrequency.PER_PASS; + break; + } + + const flattenedBlocks = Array.from(db.blocks).sort(sortDescriptorBlocks); + + flattenedBlocks.forEach((value: [string, DescriptorBlock]) => { + const key = value[0]; + const block = value[1]; + const index: DescriptorBlockIndex = JSON.parse(key); + if (index.updateFrequency > maxLevel || index.updateFrequency < minLevel) { + return; + } + const flattened = convertDescriptorBlock(block); + if (block.capacity === 0) { + console.error('block capacity is 0'); + return; + } + if (index.updateFrequency > UpdateFrequency.PER_BATCH) { + builder.addDescriptorBlock(v, index, flattened); + for (let i = 0; i < flattened.uniformBlockNames.length; ++i) { + builder.addUniformBlock(v, index, flattened.uniformBlockNames[i], flattened.uniformBlocks[i]); + } + } else { + builder.reserveDescriptorBlock(v, index, flattened); + } + }); + } +} + +// get descriptor nameID from name +export function getOrCreateDescriptorID (lg: LayoutGraphData, name: string): number { + const nameID = lg.attributeIndex.get(name); + if (nameID === undefined) { + const newID = lg.valueNames.length; + lg.attributeIndex.set(name, newID); + lg.valueNames.push(name); + return newID; + } + return nameID; +} + +export function getOrCreateConstantID (lg: LayoutGraphData, name: string): number { + const nameID = lg.constantIndex.get(name); + if (nameID === undefined) { + const newID = lg.valueNames.length; + lg.constantIndex.set(name, newID); + lg.valueNames.push(name); + return newID; + } + return nameID; +} + +// LayoutGraphData builder +class LayoutGraphBuilder2 { + public constructor (lg: LayoutGraphData) { + this.lg = lg; + } + clear (): void { + this.lg.clear(); + } + addRenderStage (name: string): number { + return this.lg.addVertex( + LayoutGraphDataValue.RenderStage, + new RenderStageData(), name, + UpdateFrequency.PER_PASS, new PipelineLayoutData(), + ); + } + addRenderPhase (name: string, parentID: number): number { + return this.lg.addVertex( + LayoutGraphDataValue.RenderPhase, + new RenderPhaseData(), name, + UpdateFrequency.PER_PHASE, new PipelineLayoutData(), + parentID, + ); + } + addShader (name: string, parentPhaseID: number): void { + const lg = this.lg; + const phaseData = lg.getRenderPhase(parentPhaseID); + // 填充shaderData数据 + const shaderData = new ShaderProgramData(); + const id = phaseData.shaderPrograms.length; + phaseData.shaderPrograms.push(shaderData); + phaseData.shaderIndex.set(name, id); + // 注册shader所在的phase的ID + lg.shaderLayoutIndex.set(name, parentPhaseID); + } + private getDescriptorSetData (ppl: PipelineLayoutData, rate: UpdateFrequency): DescriptorSetData { + const data = ppl.descriptorSets.get(rate); + if (data === undefined) { + const newData = new DescriptorSetData(); + ppl.descriptorSets.set(rate, newData); + return newData; + } + return data; + } + addDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: Readonly): void { + if (block.capacity <= 0) { + console.error('empty block'); + return; + } + if (block.descriptorNames.length !== block.descriptors.length) { + console.error('error descriptor'); + return; + } + if (block.uniformBlockNames.length !== block.uniformBlocks.length) { + console.error('error uniform'); + return; + } + if (!(index.updateFrequency >= UpdateFrequency.PER_INSTANCE + && index.updateFrequency <= UpdateFrequency.PER_PASS)) { + console.error('invalid update frequency'); + return; + } + + const lg = this.lg; + const ppl: PipelineLayoutData = lg.getLayout(nodeID); + const setData = this.getDescriptorSetData(ppl, index.updateFrequency); + const layout = setData.descriptorSetLayoutData; + + const dstBlock = new DescriptorBlockData(index.descriptorType, index.visibility, block.capacity); + dstBlock.offset = layout.capacity; + layout.descriptorBlocks.push(dstBlock); + for (let j = 0; j < block.descriptors.length; ++j) { + const name: string = block.descriptorNames[j]; + const d: Descriptor = block.descriptors[j]; + const nameID = getOrCreateDescriptorID(lg, name); + const data = new DescriptorData(nameID, d.type, d.count); + dstBlock.descriptors.push(data); + } + layout.capacity += block.capacity; + if (index.descriptorType === DescriptorTypeOrder.UNIFORM_BUFFER + || index.descriptorType === DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER) { + layout.uniformBlockCapacity += block.capacity; + } else if (index.descriptorType === DescriptorTypeOrder.SAMPLER_TEXTURE) { + layout.samplerTextureCapacity += block.capacity; + } + } + addUniformBlock (nodeID: number, index: DescriptorBlockIndex, name: string, uniformBlock: UniformBlock): void { + const g: LayoutGraphData = this.lg; + const ppl: PipelineLayoutData = g.getLayout(nodeID); + const setData = this.getDescriptorSetData(ppl, index.updateFrequency); + const layout = setData.descriptorSetLayoutData; + const nameID = getOrCreateDescriptorID(g, name); + layout.uniformBlocks.set(nameID, uniformBlock); + // register constant names + for (const member of uniformBlock.members) { + getOrCreateConstantID(g, member.name); + } + } + reserveDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: DescriptorBlockFlattened): void { + if (block.capacity <= 0) { + console.error('empty block'); + return; + } + const g: LayoutGraphData = this.lg; + const ppl: PipelineLayoutData = g.getLayout(nodeID); + const setData = this.getDescriptorSetData(ppl, index.updateFrequency); + const layout = setData.descriptorSetLayoutData; + + const dstBlock = new DescriptorBlockData(index.descriptorType, index.visibility, block.capacity); + dstBlock.offset = layout.capacity; + layout.descriptorBlocks.push(dstBlock); + layout.capacity += block.capacity; + if (index.descriptorType === DescriptorTypeOrder.UNIFORM_BUFFER + || index.descriptorType === DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER) { + layout.uniformBlockCapacity += block.capacity; + } else if (index.descriptorType === DescriptorTypeOrder.SAMPLER_TEXTURE) { + layout.samplerTextureCapacity += block.capacity; + } + } + compile (): number { + // console.debug(this.print()); + return 0; + } + print (): string { + const g: LayoutGraphData = this.lg; + const visitor = new PrintVisitor(); + const colorMap = new VectorGraphColorMap(g.numVertices()); + depthFirstSearch(g, visitor, colorMap); + return visitor.oss; + } + readonly lg: LayoutGraphData; +} + +export function buildLayoutGraphData (lg: LayoutGraph, lgData: LayoutGraphData) { + const builder = new LayoutGraphBuilder2(lgData); + buildLayoutGraphDataImpl(lg, builder); + builder.compile(); +} + +function createDescriptorInfo (layoutData: DescriptorSetLayoutData, info: DescriptorSetLayoutInfo) { + for (let i = 0; i < layoutData.descriptorBlocks.length; ++i) { + const block = layoutData.descriptorBlocks[i]; + let slot = block.offset; + for (let j = 0; j < block.descriptors.length; ++j) { + const d = block.descriptors[j]; + const binding: DescriptorSetLayoutBinding = new DescriptorSetLayoutBinding(); + binding.binding = slot; + binding.descriptorType = getGfxDescriptorType(block.type); + binding.count = d.count; + binding.stageFlags = block.visibility; + binding.immutableSamplers = []; + info.bindings.push(binding); + slot += d.count; + } + } +} + +function createDescriptorSetLayout (device: Device | null, layoutData: DescriptorSetLayoutData) { + const info: DescriptorSetLayoutInfo = new DescriptorSetLayoutInfo(); + createDescriptorInfo(layoutData, info); + + if (device) { + return device.createDescriptorSetLayout(info); + } else { + return null; + } +} + +export function createGfxDescriptorSetsAndPipelines (device: Device | null, g: LayoutGraphData) { + for (let i = 0; i < g._layouts.length; ++i) { + const ppl: PipelineLayoutData = g.getLayout(i); + ppl.descriptorSets.forEach((value, key) => { + const level = value; + const layoutData = level.descriptorSetLayoutData; + if (device) { + const layout: DescriptorSetLayout | null = createDescriptorSetLayout(device, layoutData); + if (layout) { + level.descriptorSetLayout = (layout); + level.descriptorSet = (device.createDescriptorSet(new DescriptorSetInfo(layout))); + } + } else { + createDescriptorInfo(layoutData, level.descriptorSetLayoutInfo); + } + }); + } +} + +export function printLayoutGraphData (g: LayoutGraphData): string { + const visitor = new PrintVisitor(); + const colorMap = new VectorGraphColorMap(g.numVertices()); + depthFirstSearch(g, visitor, colorMap); + return visitor.oss; +} + +// lookup DescriptorBlockData from Map +function getDescriptorBlockData (map: Map, index: DescriptorBlockIndex): DescriptorBlockData { + const key = JSON.stringify(index); + const block = map.get(key); + if (block) { + return block; + } + const newBlock = new DescriptorBlockData(index.descriptorType, index.visibility, 0); + map.set(key, newBlock); + return newBlock; +} + +// make DescriptorSetLayoutData from effect directly +export function makeDescriptorSetLayoutData (lg: LayoutGraphData, + rate: UpdateFrequency, set: number, + descriptors: EffectAsset.IDescriptorInfo): DescriptorSetLayoutData { + const map = new Map(); + const uniformBlocks: Map = new Map(); + for (let i = 0; i < descriptors.blocks.length; i++) { + const cb = descriptors.blocks[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.UNIFORM_BUFFER, + visibility: cb.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, cb.name); + block.descriptors.push(new DescriptorData(nameID, Type.UNKNOWN, 1)); + // add uniform buffer + uniformBlocks.set(nameID, new UniformBlock(set, 0xFFFFFFFF, cb.name, cb.members, 1)); + } + for (let i = 0; i < descriptors.samplerTextures.length; i++) { + const samplerTexture = descriptors.samplerTextures[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.SAMPLER_TEXTURE, + visibility: samplerTexture.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, samplerTexture.name); + block.descriptors.push(new DescriptorData(nameID, samplerTexture.type, samplerTexture.count)); + } + for (let i = 0; i < descriptors.samplers.length; i++) { + const sampler = descriptors.samplers[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.SAMPLER, + visibility: sampler.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, sampler.name); + block.descriptors.push(new DescriptorData(nameID, Type.SAMPLER, sampler.count)); + } + for (let i = 0; i < descriptors.textures.length; i++) { + const texture = descriptors.textures[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.TEXTURE, + visibility: texture.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, texture.name); + block.descriptors.push(new DescriptorData(nameID, texture.type, texture.count)); + } + for (let i = 0; i < descriptors.buffers.length; i++) { + const buffer = descriptors.buffers[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.STORAGE_BUFFER, + visibility: buffer.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, buffer.name); + block.descriptors.push(new DescriptorData(nameID, Type.UNKNOWN, 1)); + } + for (let i = 0; i < descriptors.images.length; i++) { + const image = descriptors.images[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.STORAGE_IMAGE, + visibility: image.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, image.name); + block.descriptors.push(new DescriptorData(nameID, image.type, image.count)); + } + for (let i = 0; i < descriptors.subpassInputs.length; i++) { + const subpassInput = descriptors.subpassInputs[i]; + const block = getDescriptorBlockData(map, { + updateFrequency: rate, + parameterType: ParameterType.TABLE, + descriptorType: DescriptorTypeOrder.INPUT_ATTACHMENT, + visibility: subpassInput.stageFlags, + }); + const nameID = getOrCreateDescriptorID(lg, subpassInput.name); + block.descriptors.push(new DescriptorData(nameID, Type.UNKNOWN, subpassInput.count)); + } + + // sort blocks + const flattenedBlocks = Array.from(map).sort(sortDescriptorBlocks); + const data = new DescriptorSetLayoutData(set, 0); + // calculate bindings + let capacity = 0; + for (const [key, block] of flattenedBlocks) { + const index = JSON.parse(key) as DescriptorBlockIndex; + block.offset = capacity; + for (const d of block.descriptors) { + if (index.descriptorType === DescriptorTypeOrder.UNIFORM_BUFFER) { + // update uniform buffer binding + const ub = uniformBlocks.get(d.descriptorID); + if (!ub) { + console.error(`Uniform block not found for ${d.descriptorID}`); + continue; + } + assert(ub.binding === 0xFFFFFFFF); + ub.binding = block.capacity; + // add uniform buffer to output + data.uniformBlocks.set(d.descriptorID, ub); + } + // update block capacity + const binding = data.bindingMap.get(d.descriptorID); + if (binding !== undefined) { + console.error(`Duplicated descriptor ${d.descriptorID}`); + } + data.bindingMap.set(d.descriptorID, block.offset + block.capacity); + block.capacity += d.count; + } + // increate total capacity + capacity += block.capacity; + data.capacity += block.capacity; + if (index.descriptorType === DescriptorTypeOrder.UNIFORM_BUFFER + || index.descriptorType === DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER) { + data.uniformBlockCapacity += block.capacity; + } else if (index.descriptorType === DescriptorTypeOrder.SAMPLER_TEXTURE) { + data.samplerTextureCapacity += block.capacity; + } + data.descriptorBlocks.push(block); + } + return data; +} + +// fill DescriptorSetLayoutInfo from DescriptorSetLayoutData +export function initializeDescriptorSetLayoutInfo (layoutData: DescriptorSetLayoutData, + info: DescriptorSetLayoutInfo): void { + for (let i = 0; i < layoutData.descriptorBlocks.length; ++i) { + const block = layoutData.descriptorBlocks[i]; + let slot = block.offset; + for (let j = 0; j < block.descriptors.length; ++j) { + const d = block.descriptors[j]; + const binding = new DescriptorSetLayoutBinding(); + binding.binding = slot; + binding.descriptorType = getGfxDescriptorType(block.type); + binding.count = d.count; + binding.stageFlags = block.visibility; + binding.immutableSamplers = []; + info.bindings.push(binding); + slot += d.count; + } + } +} + +let _emptyDescriptorSetLayout: DescriptorSetLayout; +let _emptyPipelineLayout: PipelineLayout; + +function populatePipelineLayoutInfo (layout: PipelineLayoutData, + rate: UpdateFrequency, info: PipelineLayoutInfo) { + const set = layout.descriptorSets.get(rate); + if (set && set.descriptorSetLayout) { + info.setLayouts.push(set.descriptorSetLayout); + } else { + info.setLayouts.push(_emptyDescriptorSetLayout); + } +} + +// initialize layout graph module +export function initializeLayoutGraphData (device: Device, lg: LayoutGraphData) { + // create descriptor sets + _emptyDescriptorSetLayout = device.createDescriptorSetLayout(new DescriptorSetLayoutInfo()); + _emptyPipelineLayout = device.createPipelineLayout(new PipelineLayoutInfo()); + for (const v of lg.vertices()) { + const layoutData = lg.getLayout(v); + for (const [_, set] of layoutData.descriptorSets) { + if (set.descriptorSetLayout !== null) { + console.warn('descriptor set layout already initialized. It will be overwritten'); + } + initializeDescriptorSetLayoutInfo(set.descriptorSetLayoutData, + set.descriptorSetLayoutInfo); + set.descriptorSetLayout = device.createDescriptorSetLayout(set.descriptorSetLayoutInfo); + } + } + // create pipeline layouts + for (const v of lg.vertices()) { + if (!lg.holds(LayoutGraphDataValue.RenderPhase, v)) { + continue; + } + const passID = lg.getParent(v); + const phaseID = v; + const passLayout = lg.getLayout(passID); + const phaseLayout = lg.getLayout(phaseID); + const info = new PipelineLayoutInfo(); + populatePipelineLayoutInfo(passLayout, UpdateFrequency.PER_PASS, info); + populatePipelineLayoutInfo(phaseLayout, UpdateFrequency.PER_PHASE, info); + populatePipelineLayoutInfo(phaseLayout, UpdateFrequency.PER_BATCH, info); + populatePipelineLayoutInfo(phaseLayout, UpdateFrequency.PER_INSTANCE, info); + const phase = lg.getRenderPhase(phaseID); + phase.pipelineLayout = device.createPipelineLayout(info); + } +} + +// terminate layout graph module +export function terminateLayoutGraphData (lg: LayoutGraphData) { + for (const v of lg.vertices()) { + const layoutData = lg.getLayout(v); + for (const [_, set] of layoutData.descriptorSets) { + if (set.descriptorSetLayout !== null) { + set.descriptorSetLayout.destroy(); + } + } + } + _emptyPipelineLayout.destroy(); + _emptyDescriptorSetLayout.destroy(); +} + +// get empty descriptor set layout +export function getEmptyDescriptorSetLayout (): DescriptorSetLayout { + return _emptyDescriptorSetLayout; +} + +// get empty pipeline layout +export function getEmptyPipelineLayout (): PipelineLayout { + return _emptyPipelineLayout; +} + +// get descriptor set from LayoutGraphData (not from ProgramData) +export function getOrCreateDescriptorSetLayout (lg: LayoutGraphData, + passID: number, phaseID: number, rate: UpdateFrequency): DescriptorSetLayout { + if (rate < UpdateFrequency.PER_PASS) { + const phaseData = lg.getLayout(phaseID); + const data = phaseData.descriptorSets.get(rate); + if (data) { + if (!data.descriptorSetLayout) { + console.error('descriptor set layout not initialized'); + return _emptyDescriptorSetLayout; + } + return data.descriptorSetLayout; + } + return _emptyDescriptorSetLayout; + } + + assert(rate === UpdateFrequency.PER_PASS); + assert(passID === lg.getParent(phaseID)); + + const passData = lg.getLayout(passID); + const data = passData.descriptorSets.get(rate); + if (data) { + if (!data.descriptorSetLayout) { + console.error('descriptor set layout not initialized'); + return _emptyDescriptorSetLayout; + } + return data.descriptorSetLayout; + } + return _emptyDescriptorSetLayout; +} + +// getDescriptorSetLayout from LayoutGraphData +export function getDescriptorSetLayout (lg: LayoutGraphData, + passID: number, phaseID: number, rate: UpdateFrequency): DescriptorSetLayout | null { + if (rate < UpdateFrequency.PER_PASS) { + const phaseData = lg.getLayout(phaseID); + const data = phaseData.descriptorSets.get(rate); + if (data) { + if (!data.descriptorSetLayout) { + console.error('descriptor set layout not initialized'); + return null; + } + return data.descriptorSetLayout; + } + return null; + } + + assert(rate === UpdateFrequency.PER_PASS); + assert(passID === lg.getParent(phaseID)); + + const passData = lg.getLayout(passID); + const data = passData.descriptorSets.get(rate); + if (data) { + if (!data.descriptorSetLayout) { + console.error('descriptor set layout not initialized'); + return null; + } + return data.descriptorSetLayout; + } + return null; +} + +// get or create DescriptorBlockData from DescriptorSetLayoutData +export function getOrCreateDescriptorBlockData (data: DescriptorSetLayoutData, + type: DescriptorType, vis: ShaderStageFlagBit): DescriptorBlockData { + const order = getDescriptorTypeOrder(type); + for (const block of data.descriptorBlocks) { + if (block.type === order && block.visibility === vis) { + return block; + } + } + const block = new DescriptorBlockData(order, vis); + data.descriptorBlocks.push(block); + return block; +} + +export function getProgramID (lg: LayoutGraphData, phaseID: number, programName: string): number { + assert(phaseID !== lg.nullVertex()); + const phase = lg.getRenderPhase(phaseID); + const programID = phase.shaderIndex.get(programName); + if (programID === undefined) { + return INVALID_ID; + } + return programID; +} + +export function getDescriptorNameID (lg: LayoutGraphData, name: string): number { + const nameID = lg.attributeIndex.get(name); + if (nameID === undefined) { + return INVALID_ID; + } + return nameID; +} + +export function getDescriptorName (lg: LayoutGraphData, nameID: number): string { + if (nameID >= lg.valueNames.length) { + return ''; + } + return lg.valueNames[nameID]; +} + +export function getPerPassDescriptorSetLayoutData (lg: LayoutGraphData, + passID: number): DescriptorSetLayoutData | null { + assert(passID !== lg.nullVertex()); + const node = lg.getLayout(passID); + const set = node.descriptorSets.get(UpdateFrequency.PER_PASS); + if (set === undefined) { + return null; + } + return set.descriptorSetLayoutData; +} + +export function getPerPhaseDescriptorSetLayoutData (lg: LayoutGraphData, + phaseID: number): DescriptorSetLayoutData | null { + assert(phaseID !== lg.nullVertex()); + const node = lg.getLayout(phaseID); + const set = node.descriptorSets.get(UpdateFrequency.PER_PHASE); + if (set === undefined) { + return null; + } + return set.descriptorSetLayoutData; +} + +export function getPerBatchDescriptorSetLayoutData (lg: LayoutGraphData, + phaseID: number, programID): DescriptorSetLayoutData | null { + assert(phaseID !== lg.nullVertex()); + const phase = lg.getRenderPhase(phaseID); + assert(programID < phase.shaderPrograms.length); + const program = phase.shaderPrograms[programID]; + const set = program.layout.descriptorSets.get(UpdateFrequency.PER_BATCH); + if (set === undefined) { + return null; + } + return set.descriptorSetLayoutData; +} + +export function getPerInstanceDescriptorSetLayoutData (lg: LayoutGraphData, + phaseID: number, programID): DescriptorSetLayoutData | null { + assert(phaseID !== lg.nullVertex()); + const phase = lg.getRenderPhase(phaseID); + assert(programID < phase.shaderPrograms.length); + const program = phase.shaderPrograms[programID]; + const set = program.layout.descriptorSets.get(UpdateFrequency.PER_INSTANCE); + if (set === undefined) { + return null; + } + return set.descriptorSetLayoutData; +} + +export function getBinding (layout: DescriptorSetLayoutData, nameID: number) { + const binding = layout.bindingMap.get(nameID); + if (binding === undefined) { + return 0xFFFFFFFF; + } + return binding; +} diff --git a/cocos/rendering/custom/layout-graph.ts b/cocos/rendering/custom/layout-graph.ts index 7b90dacc2ec..e7f2edd26f8 100644 --- a/cocos/rendering/custom/layout-graph.ts +++ b/cocos/rendering/custom/layout-graph.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,11 +28,11 @@ * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= */ /* eslint-disable max-len */ -import * as impl from './graph'; -import { DescriptorSet, DescriptorSetLayout, DescriptorSetLayoutInfo, ShaderStageFlagBit, Type, UniformBlock } from '../../gfx'; -import { DescriptorBlock, DescriptorBlockIndex, DescriptorTypeOrder, UpdateFrequency } from './types'; -import { ccclass } from '../../core/data/decorators'; -import { OutputArchive } from './archive'; +import { AddressableGraph, AdjI, AdjacencyGraph, BidirectionalGraph, ComponentGraph, ED, InEI, MutableGraph, MutableReferenceGraph, NamedGraph, OutE, OutEI, PolymorphicGraph, PropertyGraph, PropertyMap, ReferenceGraph, VertexListGraph, directional, findRelative, getPath, parallel, reindexEdgeList, traversal } from './graph'; +import { DescriptorSet, DescriptorSetLayout, DescriptorSetLayoutInfo, PipelineLayout, ShaderStageFlagBit, Type, UniformBlock } from '../../gfx'; +import { DescriptorBlock, saveDescriptorBlock, loadDescriptorBlock, DescriptorBlockIndex, saveDescriptorBlockIndex, loadDescriptorBlockIndex, DescriptorTypeOrder, UpdateFrequency } from './types'; +import { OutputArchive, InputArchive } from './archive'; +import { saveUniformBlock, loadUniformBlock, saveDescriptorSetLayoutInfo, loadDescriptorSetLayoutInfo } from './serialization'; export class DescriptorDB { readonly blocks: Map = new Map(); @@ -60,7 +59,7 @@ export function getLayoutGraphValueName (e: LayoutGraphValue): string { } } -interface LayoutGraphValueType { +export interface LayoutGraphValueType { [LayoutGraphValue.RenderStage]: number [LayoutGraphValue.RenderPhase]: RenderPhase } @@ -70,7 +69,7 @@ export interface LayoutGraphVisitor { renderPhase(value: RenderPhase): unknown; } -type LayoutGraphObject = number | RenderPhase; +export type LayoutGraphObject = number | RenderPhase; //----------------------------------------------------------------- // Graph Concept @@ -82,25 +81,26 @@ export class LayoutGraphVertex { this._id = id; this._object = object; } - readonly _outEdges: impl.OutE[] = []; - readonly _inEdges: impl.OutE[] = []; + readonly _outEdges: OutE[] = []; + readonly _inEdges: OutE[] = []; readonly _id: LayoutGraphValue; - readonly _object: LayoutGraphObject; + _object: LayoutGraphObject; } //----------------------------------------------------------------- // PropertyGraph Concept -export class LayoutGraphNameMap implements impl.PropertyMap { +export class LayoutGraphNameMap implements PropertyMap { constructor (readonly names: string[]) { this._names = names; } get (v: number): string { return this._names[v]; } + // skip set, name is constant in AddressableGraph readonly _names: string[]; } -export class LayoutGraphDescriptorsMap implements impl.PropertyMap { +export class LayoutGraphDescriptorsMap implements PropertyMap { constructor (readonly descriptors: DescriptorDB[]) { this._descriptors = descriptors; } @@ -117,43 +117,43 @@ export const enum LayoutGraphComponent { Descriptors, } -interface LayoutGraphComponentType { +export interface LayoutGraphComponentType { [LayoutGraphComponent.Name]: string; [LayoutGraphComponent.Descriptors]: DescriptorDB; } -interface LayoutGraphComponentPropertyMap { +export interface LayoutGraphComponentPropertyMap { [LayoutGraphComponent.Name]: LayoutGraphNameMap; [LayoutGraphComponent.Descriptors]: LayoutGraphDescriptorsMap; } //----------------------------------------------------------------- // LayoutGraph Implementation -export class LayoutGraph implements impl.BidirectionalGraph -, impl.AdjacencyGraph -, impl.VertexListGraph -, impl.MutableGraph -, impl.PropertyGraph -, impl.NamedGraph -, impl.ComponentGraph -, impl.PolymorphicGraph -, impl.ReferenceGraph -, impl.MutableReferenceGraph -, impl.AddressableGraph { +export class LayoutGraph implements BidirectionalGraph +, AdjacencyGraph +, VertexListGraph +, MutableGraph +, PropertyGraph +, NamedGraph +, ComponentGraph +, PolymorphicGraph +, ReferenceGraph +, MutableReferenceGraph +, AddressableGraph { //----------------------------------------------------------------- // Graph // type vertex_descriptor = number; nullVertex (): number { return 0xFFFFFFFF; } - // type edge_descriptor = impl.ED; - readonly directed_category: impl.directional = impl.directional.bidirectional; - readonly edge_parallel_category: impl.parallel = impl.parallel.allow; - readonly traversal_category: impl.traversal = impl.traversal.incidence - | impl.traversal.bidirectional - | impl.traversal.adjacency - | impl.traversal.vertex_list; + // type edge_descriptor = ED; + readonly directed_category: directional = directional.bidirectional; + readonly edge_parallel_category: parallel = parallel.allow; + readonly traversal_category: traversal = traversal.incidence + | traversal.bidirectional + | traversal.adjacency + | traversal.vertex_list; //----------------------------------------------------------------- // IncidenceGraph - // type out_edge_iterator = impl.OutEI; + // type out_edge_iterator = OutEI; // type degree_size_type = number; edge (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { @@ -163,23 +163,23 @@ export class LayoutGraph implements impl.BidirectionalGraph } return false; } - source (e: impl.ED): number { + source (e: ED): number { return e.source as number; } - target (e: impl.ED): number { + target (e: ED): number { return e.target as number; } - outEdges (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + outEdges (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } outDegree (v: number): number { return this._vertices[v]._outEdges.length; } //----------------------------------------------------------------- // BidirectionalGraph - // type in_edge_iterator = impl.InEI; - inEdges (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + // type in_edge_iterator = InEI; + inEdges (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } inDegree (v: number): number { return this._vertices[v]._inEdges.length; @@ -189,9 +189,9 @@ export class LayoutGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // AdjacencyGraph - // type adjacency_iterator = impl.AdjI; - adjacentVertices (v: number): impl.AdjI { - return new impl.AdjI(this, this.outEdges(v)); + // type adjacency_iterator = AdjI; + adjacentVertices (v: number): AdjI { + return new AdjI(this, this.outEdges(v)); } //----------------------------------------------------------------- // VertexListGraph @@ -202,6 +202,15 @@ export class LayoutGraph implements impl.BidirectionalGraph return this._vertices.length; } //----------------------------------------------------------------- + // EdgeListGraph + numEdges (): number { + let numEdges = 0; + for (const v of this.vertices()) { + numEdges += this.outDegree(v); + } + return numEdges; + } + //----------------------------------------------------------------- // MutableGraph clear (): void { // ComponentGraph @@ -271,15 +280,15 @@ export class LayoutGraph implements impl.BidirectionalGraph for (let v = 0; v !== sz; ++v) { const vert = this._vertices[v]; - impl.reindexEdgeList(vert._outEdges, u); - impl.reindexEdgeList(vert._inEdges, u); + reindexEdgeList(vert._outEdges, u); + reindexEdgeList(vert._inEdges, u); } } - addEdge (u: number, v: number): impl.ED | null { + addEdge (u: number, v: number): ED | null { // update in/out edge list - this._vertices[u]._outEdges.push(new impl.OutE(v)); - this._vertices[v]._inEdges.push(new impl.OutE(u)); - return new impl.ED(u, v); + this._vertices[u]._outEdges.push(new OutE(v)); + this._vertices[v]._inEdges.push(new OutE(u)); + return new ED(u, v); } removeEdges (u: number, v: number): void { const source = this._vertices[u]; @@ -301,7 +310,7 @@ export class LayoutGraph implements impl.BidirectionalGraph } } } - removeEdge (e: impl.ED): void { + removeEdge (e: ED): void { const u = e.source as number; const v = e.target as number; const source = this._vertices[u]; @@ -366,6 +375,7 @@ export class LayoutGraph implements impl.BidirectionalGraph throw Error('component map not found'); } } + // skip setName, Name is constant in AddressableGraph getName (v: number): string { return this._names[v]; } @@ -438,9 +448,9 @@ export class LayoutGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // ReferenceGraph - // type reference_descriptor = impl.ED; - // type child_iterator = impl.OutEI; - // type parent_iterator = impl.InEI; + // type reference_descriptor = ED; + // type child_iterator = OutEI; + // type parent_iterator = InEI; reference (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { if (v === oe.target as number) { @@ -449,17 +459,17 @@ export class LayoutGraph implements impl.BidirectionalGraph } return false; } - parent (e: impl.ED): number { + parent (e: ED): number { return e.source as number; } - child (e: impl.ED): number { + child (e: ED): number { return e.target as number; } - parents (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + parents (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } - children (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + children (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } numParents (v: number): number { return this._vertices[v]._inEdges.length; @@ -502,10 +512,10 @@ export class LayoutGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // MutableReferenceGraph - addReference (u: number, v: number): impl.ED | null { + addReference (u: number, v: number): ED | null { return this.addEdge(u, v); } - removeReference (e: impl.ED): void { + removeReference (e: ED): void { return this.removeEdge(e); } removeReferences (u: number, v: number): void { @@ -534,16 +544,16 @@ export class LayoutGraph implements impl.BidirectionalGraph //----------------------------------------------------------------- // AddressableGraph addressable (absPath: string): boolean { - return impl.findRelative(this, 0xFFFFFFFF, absPath) as number !== 0xFFFFFFFF; + return findRelative(this, 0xFFFFFFFF, absPath) as number !== 0xFFFFFFFF; } locate (absPath: string): number { - return impl.findRelative(this, 0xFFFFFFFF, absPath) as number; + return findRelative(this, 0xFFFFFFFF, absPath) as number; } locateRelative (path: string, start = 0xFFFFFFFF): number { - return impl.findRelative(this, start, path) as number; + return findRelative(this, start, path) as number; } path (v: number): string { - return impl.getPath(this, v); + return getPath(this, v); } readonly components: string[] = ['Name', 'Descriptors']; @@ -570,11 +580,14 @@ export class UniformBlockData { } export class DescriptorData { - constructor (descriptorID = 0) { + constructor (descriptorID = 0, type: Type = Type.UNKNOWN, count = 1) { this.descriptorID = descriptorID; + this.type = type; + this.count = count; } descriptorID: number; - count = 1; + type: Type; + count: number; } export class DescriptorBlockData { @@ -591,18 +604,30 @@ export class DescriptorBlockData { } export class DescriptorSetLayoutData { - constructor (slot = 0xFFFFFFFF, capacity = 0) { + constructor ( + slot = 0xFFFFFFFF, + capacity = 0, + descriptorBlocks: DescriptorBlockData[] = [], + uniformBlocks: Map = new Map(), + bindingMap: Map = new Map(), + ) { this.slot = slot; this.capacity = capacity; + this.descriptorBlocks = descriptorBlocks; + this.uniformBlocks = uniformBlocks; + this.bindingMap = bindingMap; } slot: number; capacity: number; - readonly descriptorBlocks: DescriptorBlockData[] = []; - readonly uniformBlocks: Map = new Map(); + uniformBlockCapacity = 0; + samplerTextureCapacity = 0; + readonly descriptorBlocks: DescriptorBlockData[]; + readonly uniformBlocks: Map; + readonly bindingMap: Map; } export class DescriptorSetData { - constructor (descriptorSetLayoutData: DescriptorSetLayoutData, descriptorSetLayout: DescriptorSetLayout | null, descriptorSet: DescriptorSet | null) { + constructor (descriptorSetLayoutData: DescriptorSetLayoutData = new DescriptorSetLayoutData(), descriptorSetLayout: DescriptorSetLayout | null = null, descriptorSet: DescriptorSet | null = null) { this.descriptorSetLayoutData = descriptorSetLayoutData; this.descriptorSetLayout = descriptorSetLayout; this.descriptorSet = descriptorSet; @@ -617,8 +642,26 @@ export class PipelineLayoutData { readonly descriptorSets: Map = new Map(); } +export class ShaderBindingData { + readonly descriptorBindings: Map = new Map(); +} + +export class ShaderLayoutData { + readonly layoutData: Map = new Map(); + readonly bindingData: Map = new Map(); +} + +export class TechniqueData { + readonly passes: ShaderLayoutData[] = []; +} + +export class EffectData { + readonly techniques: Map = new Map(); +} + export class ShaderProgramData { readonly layout: PipelineLayoutData = new PipelineLayoutData(); + /*refcount*/ pipelineLayout: PipelineLayout | null = null; } export class RenderStageData { @@ -629,6 +672,7 @@ export class RenderPhaseData { rootSignature = ''; readonly shaderPrograms: ShaderProgramData[] = []; readonly shaderIndex: Map = new Map(); + /*refcount*/ pipelineLayout: PipelineLayout | null = null; } //================================================================= @@ -648,7 +692,7 @@ export function getLayoutGraphDataValueName (e: LayoutGraphDataValue): string { } } -interface LayoutGraphDataValueType { +export interface LayoutGraphDataValueType { [LayoutGraphDataValue.RenderStage]: RenderStageData [LayoutGraphDataValue.RenderPhase]: RenderPhaseData } @@ -658,7 +702,7 @@ export interface LayoutGraphDataVisitor { renderPhase(value: RenderPhaseData): unknown; } -type LayoutGraphDataObject = RenderStageData | RenderPhaseData; +export type LayoutGraphDataObject = RenderStageData | RenderPhaseData; //----------------------------------------------------------------- // Graph Concept @@ -670,35 +714,39 @@ export class LayoutGraphDataVertex { this._id = id; this._object = object; } - readonly _outEdges: impl.OutE[] = []; - readonly _inEdges: impl.OutE[] = []; + readonly _outEdges: OutE[] = []; + readonly _inEdges: OutE[] = []; readonly _id: LayoutGraphDataValue; - readonly _object: LayoutGraphDataObject; + _object: LayoutGraphDataObject; } //----------------------------------------------------------------- // PropertyGraph Concept -export class LayoutGraphDataNameMap implements impl.PropertyMap { +export class LayoutGraphDataNameMap implements PropertyMap { constructor (readonly names: string[]) { this._names = names; } get (v: number): string { return this._names[v]; } + // skip set, name is constant in AddressableGraph readonly _names: string[]; } -export class LayoutGraphDataUpdateMap implements impl.PropertyMap { +export class LayoutGraphDataUpdateMap implements PropertyMap { constructor (readonly updateFrequencies: UpdateFrequency[]) { this._updateFrequencies = updateFrequencies; } get (v: number): UpdateFrequency { return this._updateFrequencies[v]; } + set (v: number, updateFrequencies: UpdateFrequency): void { + this._updateFrequencies[v] = updateFrequencies; + } readonly _updateFrequencies: UpdateFrequency[]; } -export class LayoutGraphDataLayoutMap implements impl.PropertyMap { +export class LayoutGraphDataLayoutMap implements PropertyMap { constructor (readonly layouts: PipelineLayoutData[]) { this._layouts = layouts; } @@ -716,13 +764,13 @@ export const enum LayoutGraphDataComponent { Layout, } -interface LayoutGraphDataComponentType { +export interface LayoutGraphDataComponentType { [LayoutGraphDataComponent.Name]: string; [LayoutGraphDataComponent.Update]: UpdateFrequency; [LayoutGraphDataComponent.Layout]: PipelineLayoutData; } -interface LayoutGraphDataComponentPropertyMap { +export interface LayoutGraphDataComponentPropertyMap { [LayoutGraphDataComponent.Name]: LayoutGraphDataNameMap; [LayoutGraphDataComponent.Update]: LayoutGraphDataUpdateMap; [LayoutGraphDataComponent.Layout]: LayoutGraphDataLayoutMap; @@ -730,32 +778,31 @@ interface LayoutGraphDataComponentPropertyMap { //----------------------------------------------------------------- // LayoutGraphData Implementation -@ccclass('cc.LayoutGraphData') -export class LayoutGraphData implements impl.BidirectionalGraph -, impl.AdjacencyGraph -, impl.VertexListGraph -, impl.MutableGraph -, impl.PropertyGraph -, impl.NamedGraph -, impl.ComponentGraph -, impl.PolymorphicGraph -, impl.ReferenceGraph -, impl.MutableReferenceGraph -, impl.AddressableGraph { +export class LayoutGraphData implements BidirectionalGraph +, AdjacencyGraph +, VertexListGraph +, MutableGraph +, PropertyGraph +, NamedGraph +, ComponentGraph +, PolymorphicGraph +, ReferenceGraph +, MutableReferenceGraph +, AddressableGraph { //----------------------------------------------------------------- // Graph // type vertex_descriptor = number; nullVertex (): number { return 0xFFFFFFFF; } - // type edge_descriptor = impl.ED; - readonly directed_category: impl.directional = impl.directional.bidirectional; - readonly edge_parallel_category: impl.parallel = impl.parallel.allow; - readonly traversal_category: impl.traversal = impl.traversal.incidence - | impl.traversal.bidirectional - | impl.traversal.adjacency - | impl.traversal.vertex_list; + // type edge_descriptor = ED; + readonly directed_category: directional = directional.bidirectional; + readonly edge_parallel_category: parallel = parallel.allow; + readonly traversal_category: traversal = traversal.incidence + | traversal.bidirectional + | traversal.adjacency + | traversal.vertex_list; //----------------------------------------------------------------- // IncidenceGraph - // type out_edge_iterator = impl.OutEI; + // type out_edge_iterator = OutEI; // type degree_size_type = number; edge (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { @@ -765,23 +812,23 @@ export class LayoutGraphData implements impl.BidirectionalGraph } return false; } - source (e: impl.ED): number { + source (e: ED): number { return e.source as number; } - target (e: impl.ED): number { + target (e: ED): number { return e.target as number; } - outEdges (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + outEdges (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } outDegree (v: number): number { return this._vertices[v]._outEdges.length; } //----------------------------------------------------------------- // BidirectionalGraph - // type in_edge_iterator = impl.InEI; - inEdges (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + // type in_edge_iterator = InEI; + inEdges (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } inDegree (v: number): number { return this._vertices[v]._inEdges.length; @@ -791,9 +838,9 @@ export class LayoutGraphData implements impl.BidirectionalGraph } //----------------------------------------------------------------- // AdjacencyGraph - // type adjacency_iterator = impl.AdjI; - adjacentVertices (v: number): impl.AdjI { - return new impl.AdjI(this, this.outEdges(v)); + // type adjacency_iterator = AdjI; + adjacentVertices (v: number): AdjI { + return new AdjI(this, this.outEdges(v)); } //----------------------------------------------------------------- // VertexListGraph @@ -804,6 +851,15 @@ export class LayoutGraphData implements impl.BidirectionalGraph return this._vertices.length; } //----------------------------------------------------------------- + // EdgeListGraph + numEdges (): number { + let numEdges = 0; + for (const v of this.vertices()) { + numEdges += this.outDegree(v); + } + return numEdges; + } + //----------------------------------------------------------------- // MutableGraph clear (): void { // Members @@ -811,6 +867,8 @@ export class LayoutGraphData implements impl.BidirectionalGraph this.attributeIndex.clear(); this.constantIndex.clear(); this.shaderLayoutIndex.clear(); + this.effects.clear(); + this.constantMacros = ''; // ComponentGraph this._names.length = 0; this._updateFrequencies.length = 0; @@ -882,15 +940,15 @@ export class LayoutGraphData implements impl.BidirectionalGraph for (let v = 0; v !== sz; ++v) { const vert = this._vertices[v]; - impl.reindexEdgeList(vert._outEdges, u); - impl.reindexEdgeList(vert._inEdges, u); + reindexEdgeList(vert._outEdges, u); + reindexEdgeList(vert._inEdges, u); } } - addEdge (u: number, v: number): impl.ED | null { + addEdge (u: number, v: number): ED | null { // update in/out edge list - this._vertices[u]._outEdges.push(new impl.OutE(v)); - this._vertices[v]._inEdges.push(new impl.OutE(u)); - return new impl.ED(u, v); + this._vertices[u]._outEdges.push(new OutE(v)); + this._vertices[v]._inEdges.push(new OutE(u)); + return new ED(u, v); } removeEdges (u: number, v: number): void { const source = this._vertices[u]; @@ -912,7 +970,7 @@ export class LayoutGraphData implements impl.BidirectionalGraph } } } - removeEdge (e: impl.ED): void { + removeEdge (e: ED): void { const u = e.source as number; const v = e.target as number; const source = this._vertices[u]; @@ -983,6 +1041,7 @@ export class LayoutGraphData implements impl.BidirectionalGraph throw Error('component map not found'); } } + // skip setName, Name is constant in AddressableGraph getName (v: number): string { return this._names[v]; } @@ -1061,9 +1120,9 @@ export class LayoutGraphData implements impl.BidirectionalGraph } //----------------------------------------------------------------- // ReferenceGraph - // type reference_descriptor = impl.ED; - // type child_iterator = impl.OutEI; - // type parent_iterator = impl.InEI; + // type reference_descriptor = ED; + // type child_iterator = OutEI; + // type parent_iterator = InEI; reference (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { if (v === oe.target as number) { @@ -1072,17 +1131,17 @@ export class LayoutGraphData implements impl.BidirectionalGraph } return false; } - parent (e: impl.ED): number { + parent (e: ED): number { return e.source as number; } - child (e: impl.ED): number { + child (e: ED): number { return e.target as number; } - parents (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + parents (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } - children (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + children (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } numParents (v: number): number { return this._vertices[v]._inEdges.length; @@ -1125,10 +1184,10 @@ export class LayoutGraphData implements impl.BidirectionalGraph } //----------------------------------------------------------------- // MutableReferenceGraph - addReference (u: number, v: number): impl.ED | null { + addReference (u: number, v: number): ED | null { return this.addEdge(u, v); } - removeReference (e: impl.ED): void { + removeReference (e: ED): void { return this.removeEdge(e); } removeReferences (u: number, v: number): void { @@ -1157,16 +1216,16 @@ export class LayoutGraphData implements impl.BidirectionalGraph //----------------------------------------------------------------- // AddressableGraph addressable (absPath: string): boolean { - return impl.findRelative(this, 0xFFFFFFFF, absPath) as number !== 0xFFFFFFFF; + return findRelative(this, 0xFFFFFFFF, absPath) as number !== 0xFFFFFFFF; } locate (absPath: string): number { - return impl.findRelative(this, 0xFFFFFFFF, absPath) as number; + return findRelative(this, 0xFFFFFFFF, absPath) as number; } locateRelative (path: string, start = 0xFFFFFFFF): number { - return impl.findRelative(this, start, path) as number; + return findRelative(this, start, path) as number; } path (v: number): string { - return impl.getPath(this, v); + return getPath(this, v); } readonly components: string[] = ['Name', 'Update', 'Layout']; @@ -1178,4 +1237,537 @@ export class LayoutGraphData implements impl.BidirectionalGraph readonly attributeIndex: Map = new Map(); readonly constantIndex: Map = new Map(); readonly shaderLayoutIndex: Map = new Map(); + readonly effects: Map = new Map(); + constantMacros = ''; +} + +export function saveDescriptorDB (ar: OutputArchive, v: DescriptorDB) { + ar.writeNumber(v.blocks.size); // Map + for (const [k1, v1] of v.blocks) { + saveDescriptorBlockIndex(ar, JSON.parse(k1)); + saveDescriptorBlock(ar, v1); + } +} + +export function loadDescriptorDB (ar: InputArchive, v: DescriptorDB) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = new DescriptorBlockIndex(); + loadDescriptorBlockIndex(ar, k1); + const v1 = new DescriptorBlock(); + loadDescriptorBlock(ar, v1); + v.blocks.set(JSON.stringify(k1), v1); + } +} + +export function saveRenderPhase (ar: OutputArchive, v: RenderPhase) { + ar.writeNumber(v.shaders.size); // Set + for (const v1 of v.shaders) { + ar.writeString(v1); + } +} + +export function loadRenderPhase (ar: InputArchive, v: RenderPhase) { + let sz = 0; + sz = ar.readNumber(); // Set + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = ar.readString(); + v.shaders.add(v1); + } +} + +export function saveLayoutGraph (ar: OutputArchive, g: LayoutGraph) { + const numVertices = g.numVertices(); + const numEdges = g.numEdges(); + ar.writeNumber(numVertices); + ar.writeNumber(numEdges); + let numStages = 0; + let numPhases = 0; + for (const v of g.vertices()) { + switch (g.id(v)) { + case LayoutGraphValue.RenderStage: + numStages += 1; + break; + case LayoutGraphValue.RenderPhase: + numPhases += 1; + break; + default: + break; + } + } + ar.writeNumber(numStages); + ar.writeNumber(numPhases); + for (const v of g.vertices()) { + ar.writeNumber(g.id(v)); + ar.writeNumber(g.getParent(v)); + ar.writeString(g.getName(v)); + saveDescriptorDB(ar, g.getDescriptors(v)); + switch (g.id(v)) { + case LayoutGraphValue.RenderStage: + ar.writeNumber(g.getRenderStage(v)); + break; + case LayoutGraphValue.RenderPhase: + saveRenderPhase(ar, g.getRenderPhase(v)); + break; + default: + break; + } + } +} + +export function loadLayoutGraph (ar: InputArchive, g: LayoutGraph) { + const numVertices = ar.readNumber(); + const numEdges = ar.readNumber(); + const numStages = ar.readNumber(); + const numPhases = ar.readNumber(); + for (let v = 0; v !== numVertices; ++v) { + const id = ar.readNumber(); + const u = ar.readNumber(); + const name = ar.readString(); + const descriptors = new DescriptorDB(); + loadDescriptorDB(ar, descriptors); + switch (id) { + case LayoutGraphValue.RenderStage: { + const renderStage = ar.readNumber(); + g.addVertex(LayoutGraphValue.RenderStage, renderStage, name, descriptors, u); + break; + } + case LayoutGraphValue.RenderPhase: { + const renderPhase = new RenderPhase(); + loadRenderPhase(ar, renderPhase); + g.addVertex(LayoutGraphValue.RenderPhase, renderPhase, name, descriptors, u); + break; + } + default: + break; + } + } +} + +export function saveUniformData (ar: OutputArchive, v: UniformData) { + ar.writeNumber(v.uniformID); + ar.writeNumber(v.uniformType); + ar.writeNumber(v.offset); + ar.writeNumber(v.size); +} + +export function loadUniformData (ar: InputArchive, v: UniformData) { + v.uniformID = ar.readNumber(); + v.uniformType = ar.readNumber(); + v.offset = ar.readNumber(); + v.size = ar.readNumber(); +} + +export function saveUniformBlockData (ar: OutputArchive, v: UniformBlockData) { + ar.writeNumber(v.bufferSize); + ar.writeNumber(v.uniforms.length); // UniformData[] + for (const v1 of v.uniforms) { + saveUniformData(ar, v1); + } +} + +export function loadUniformBlockData (ar: InputArchive, v: UniformBlockData) { + v.bufferSize = ar.readNumber(); + let sz = 0; + sz = ar.readNumber(); // UniformData[] + v.uniforms.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new UniformData(); + loadUniformData(ar, v1); + v.uniforms[i1] = v1; + } +} + +export function saveDescriptorData (ar: OutputArchive, v: DescriptorData) { + ar.writeNumber(v.descriptorID); + ar.writeNumber(v.type); + ar.writeNumber(v.count); +} + +export function loadDescriptorData (ar: InputArchive, v: DescriptorData) { + v.descriptorID = ar.readNumber(); + v.type = ar.readNumber(); + v.count = ar.readNumber(); +} + +export function saveDescriptorBlockData (ar: OutputArchive, v: DescriptorBlockData) { + ar.writeNumber(v.type); + ar.writeNumber(v.visibility); + ar.writeNumber(v.offset); + ar.writeNumber(v.capacity); + ar.writeNumber(v.descriptors.length); // DescriptorData[] + for (const v1 of v.descriptors) { + saveDescriptorData(ar, v1); + } +} + +export function loadDescriptorBlockData (ar: InputArchive, v: DescriptorBlockData) { + v.type = ar.readNumber(); + v.visibility = ar.readNumber(); + v.offset = ar.readNumber(); + v.capacity = ar.readNumber(); + let sz = 0; + sz = ar.readNumber(); // DescriptorData[] + v.descriptors.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new DescriptorData(); + loadDescriptorData(ar, v1); + v.descriptors[i1] = v1; + } +} + +export function saveDescriptorSetLayoutData (ar: OutputArchive, v: DescriptorSetLayoutData) { + ar.writeNumber(v.slot); + ar.writeNumber(v.capacity); + ar.writeNumber(v.uniformBlockCapacity); + ar.writeNumber(v.samplerTextureCapacity); + ar.writeNumber(v.descriptorBlocks.length); // DescriptorBlockData[] + for (const v1 of v.descriptorBlocks) { + saveDescriptorBlockData(ar, v1); + } + ar.writeNumber(v.uniformBlocks.size); // Map + for (const [k1, v1] of v.uniformBlocks) { + ar.writeNumber(k1); + saveUniformBlock(ar, v1); + } + ar.writeNumber(v.bindingMap.size); // Map + for (const [k1, v1] of v.bindingMap) { + ar.writeNumber(k1); + ar.writeNumber(v1); + } +} + +export function loadDescriptorSetLayoutData (ar: InputArchive, v: DescriptorSetLayoutData) { + v.slot = ar.readNumber(); + v.capacity = ar.readNumber(); + v.uniformBlockCapacity = ar.readNumber(); + v.samplerTextureCapacity = ar.readNumber(); + let sz = 0; + sz = ar.readNumber(); // DescriptorBlockData[] + v.descriptorBlocks.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new DescriptorBlockData(); + loadDescriptorBlockData(ar, v1); + v.descriptorBlocks[i1] = v1; + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = new UniformBlock(); + loadUniformBlock(ar, v1); + v.uniformBlocks.set(k1, v1); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = ar.readNumber(); + v.bindingMap.set(k1, v1); + } +} + +export function saveDescriptorSetData (ar: OutputArchive, v: DescriptorSetData) { + saveDescriptorSetLayoutData(ar, v.descriptorSetLayoutData); + saveDescriptorSetLayoutInfo(ar, v.descriptorSetLayoutInfo); + // skip, v.descriptorSetLayout: DescriptorSetLayout + // skip, v.descriptorSet: DescriptorSet +} + +export function loadDescriptorSetData (ar: InputArchive, v: DescriptorSetData) { + loadDescriptorSetLayoutData(ar, v.descriptorSetLayoutData); + loadDescriptorSetLayoutInfo(ar, v.descriptorSetLayoutInfo); + // skip, v.descriptorSetLayout: DescriptorSetLayout + // skip, v.descriptorSet: DescriptorSet +} + +export function savePipelineLayoutData (ar: OutputArchive, v: PipelineLayoutData) { + ar.writeNumber(v.descriptorSets.size); // Map + for (const [k1, v1] of v.descriptorSets) { + ar.writeNumber(k1); + saveDescriptorSetData(ar, v1); + } +} + +export function loadPipelineLayoutData (ar: InputArchive, v: PipelineLayoutData) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = new DescriptorSetData(); + loadDescriptorSetData(ar, v1); + v.descriptorSets.set(k1, v1); + } +} + +export function saveShaderBindingData (ar: OutputArchive, v: ShaderBindingData) { + ar.writeNumber(v.descriptorBindings.size); // Map + for (const [k1, v1] of v.descriptorBindings) { + ar.writeNumber(k1); + ar.writeNumber(v1); + } +} + +export function loadShaderBindingData (ar: InputArchive, v: ShaderBindingData) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = ar.readNumber(); + v.descriptorBindings.set(k1, v1); + } +} + +export function saveShaderLayoutData (ar: OutputArchive, v: ShaderLayoutData) { + ar.writeNumber(v.layoutData.size); // Map + for (const [k1, v1] of v.layoutData) { + ar.writeNumber(k1); + saveDescriptorSetLayoutData(ar, v1); + } + ar.writeNumber(v.bindingData.size); // Map + for (const [k1, v1] of v.bindingData) { + ar.writeNumber(k1); + saveShaderBindingData(ar, v1); + } +} + +export function loadShaderLayoutData (ar: InputArchive, v: ShaderLayoutData) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = new DescriptorSetLayoutData(); + loadDescriptorSetLayoutData(ar, v1); + v.layoutData.set(k1, v1); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = new ShaderBindingData(); + loadShaderBindingData(ar, v1); + v.bindingData.set(k1, v1); + } +} + +export function saveTechniqueData (ar: OutputArchive, v: TechniqueData) { + ar.writeNumber(v.passes.length); // ShaderLayoutData[] + for (const v1 of v.passes) { + saveShaderLayoutData(ar, v1); + } +} + +export function loadTechniqueData (ar: InputArchive, v: TechniqueData) { + let sz = 0; + sz = ar.readNumber(); // ShaderLayoutData[] + v.passes.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new ShaderLayoutData(); + loadShaderLayoutData(ar, v1); + v.passes[i1] = v1; + } +} + +export function saveEffectData (ar: OutputArchive, v: EffectData) { + ar.writeNumber(v.techniques.size); // Map + for (const [k1, v1] of v.techniques) { + ar.writeString(k1); + saveTechniqueData(ar, v1); + } +} + +export function loadEffectData (ar: InputArchive, v: EffectData) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = new TechniqueData(); + loadTechniqueData(ar, v1); + v.techniques.set(k1, v1); + } +} + +export function saveShaderProgramData (ar: OutputArchive, v: ShaderProgramData) { + savePipelineLayoutData(ar, v.layout); + // skip, v.pipelineLayout: PipelineLayout +} + +export function loadShaderProgramData (ar: InputArchive, v: ShaderProgramData) { + loadPipelineLayoutData(ar, v.layout); + // skip, v.pipelineLayout: PipelineLayout +} + +export function saveRenderStageData (ar: OutputArchive, v: RenderStageData) { + ar.writeNumber(v.descriptorVisibility.size); // Map + for (const [k1, v1] of v.descriptorVisibility) { + ar.writeNumber(k1); + ar.writeNumber(v1); + } +} + +export function loadRenderStageData (ar: InputArchive, v: RenderStageData) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readNumber(); + const v1 = ar.readNumber(); + v.descriptorVisibility.set(k1, v1); + } +} + +export function saveRenderPhaseData (ar: OutputArchive, v: RenderPhaseData) { + ar.writeString(v.rootSignature); + ar.writeNumber(v.shaderPrograms.length); // ShaderProgramData[] + for (const v1 of v.shaderPrograms) { + saveShaderProgramData(ar, v1); + } + ar.writeNumber(v.shaderIndex.size); // Map + for (const [k1, v1] of v.shaderIndex) { + ar.writeString(k1); + ar.writeNumber(v1); + } + // skip, v.pipelineLayout: PipelineLayout +} + +export function loadRenderPhaseData (ar: InputArchive, v: RenderPhaseData) { + v.rootSignature = ar.readString(); + let sz = 0; + sz = ar.readNumber(); // ShaderProgramData[] + v.shaderPrograms.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new ShaderProgramData(); + loadShaderProgramData(ar, v1); + v.shaderPrograms[i1] = v1; + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = ar.readNumber(); + v.shaderIndex.set(k1, v1); + } + // skip, v.pipelineLayout: PipelineLayout +} + +export function saveLayoutGraphData (ar: OutputArchive, g: LayoutGraphData) { + const numVertices = g.numVertices(); + const numEdges = g.numEdges(); + ar.writeNumber(numVertices); + ar.writeNumber(numEdges); + let numStages = 0; + let numPhases = 0; + for (const v of g.vertices()) { + switch (g.id(v)) { + case LayoutGraphDataValue.RenderStage: + numStages += 1; + break; + case LayoutGraphDataValue.RenderPhase: + numPhases += 1; + break; + default: + break; + } + } + ar.writeNumber(numStages); + ar.writeNumber(numPhases); + for (const v of g.vertices()) { + ar.writeNumber(g.id(v)); + ar.writeNumber(g.getParent(v)); + ar.writeString(g.getName(v)); + ar.writeNumber(g.getUpdate(v)); + savePipelineLayoutData(ar, g.getLayout(v)); + switch (g.id(v)) { + case LayoutGraphDataValue.RenderStage: + saveRenderStageData(ar, g.getRenderStage(v)); + break; + case LayoutGraphDataValue.RenderPhase: + saveRenderPhaseData(ar, g.getRenderPhase(v)); + break; + default: + break; + } + } + ar.writeNumber(g.valueNames.length); // string[] + for (const v1 of g.valueNames) { + ar.writeString(v1); + } + ar.writeNumber(g.attributeIndex.size); // Map + for (const [k1, v1] of g.attributeIndex) { + ar.writeString(k1); + ar.writeNumber(v1); + } + ar.writeNumber(g.constantIndex.size); // Map + for (const [k1, v1] of g.constantIndex) { + ar.writeString(k1); + ar.writeNumber(v1); + } + ar.writeNumber(g.shaderLayoutIndex.size); // Map + for (const [k1, v1] of g.shaderLayoutIndex) { + ar.writeString(k1); + ar.writeNumber(v1); + } + ar.writeNumber(g.effects.size); // Map + for (const [k1, v1] of g.effects) { + ar.writeString(k1); + saveEffectData(ar, v1); + } +} + +export function loadLayoutGraphData (ar: InputArchive, g: LayoutGraphData) { + const numVertices = ar.readNumber(); + const numEdges = ar.readNumber(); + const numStages = ar.readNumber(); + const numPhases = ar.readNumber(); + for (let v = 0; v !== numVertices; ++v) { + const id = ar.readNumber(); + const u = ar.readNumber(); + const name = ar.readString(); + const update = ar.readNumber(); + const layout = new PipelineLayoutData(); + loadPipelineLayoutData(ar, layout); + switch (id) { + case LayoutGraphDataValue.RenderStage: { + const renderStage = new RenderStageData(); + loadRenderStageData(ar, renderStage); + g.addVertex(LayoutGraphDataValue.RenderStage, renderStage, name, update, layout, u); + break; + } + case LayoutGraphDataValue.RenderPhase: { + const renderPhase = new RenderPhaseData(); + loadRenderPhaseData(ar, renderPhase); + g.addVertex(LayoutGraphDataValue.RenderPhase, renderPhase, name, update, layout, u); + break; + } + default: + break; + } + } + let sz = 0; + sz = ar.readNumber(); // string[] + g.valueNames.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + g.valueNames[i1] = ar.readString(); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = ar.readNumber(); + g.attributeIndex.set(k1, v1); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = ar.readNumber(); + g.constantIndex.set(k1, v1); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = ar.readNumber(); + g.shaderLayoutIndex.set(k1, v1); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = new EffectData(); + loadEffectData(ar, v1); + g.effects.set(k1, v1); + } } diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 50bbafcf6f3..f41b06377de 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,12 +31,12 @@ import { Material } from '../../asset/assets'; import { Camera } from '../../render-scene/scene/camera'; import { GeometryRenderer } from '../geometry-renderer'; -import { Buffer, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, DrawInfo, Format, InputAssembler, PipelineState, Rect, Sampler, Swapchain, Texture, UniformBlock, Viewport } from '../../gfx'; +import { Buffer, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, DrawInfo, Format, InputAssembler, PipelineState, Rect, Sampler, Swapchain, Texture, Viewport } from '../../gfx'; import { GlobalDSManager } from '../global-descriptor-set-manager'; import { Mat4, Quat, Vec2, Vec4 } from '../../core/math'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { PipelineSceneData } from '../pipeline-scene-data'; -import { ComputeView, CopyPair, DescriptorBlockFlattened, DescriptorBlockIndex, LightInfo, MovePair, QueueHint, RasterView, ResourceResidency, SceneFlags, TaskType, UpdateFrequency } from './types'; +import { ComputeView, CopyPair, LightInfo, MovePair, QueueHint, RasterView, ResourceResidency, SceneFlags, TaskType, UpdateFrequency } from './types'; import { RenderScene } from '../../render-scene/core/render-scene'; import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; @@ -47,6 +46,7 @@ export interface PipelineRuntime { destroy (): boolean; render (cameras: Camera[]): void; readonly device: Device; + readonly macros: MacroRecord; readonly globalDSManager: GlobalDSManager; readonly descriptorSetLayout: DescriptorSetLayout; readonly descriptorSet: DescriptorSet; @@ -63,11 +63,13 @@ export interface PipelineRuntime { setMacroInt (name: string, value: number): void; setMacroBool (name: string, value: boolean): void; onGlobalPipelineStateChanged (): void; +} - readonly macros: MacroRecord; +export interface RenderNode { + name: string; } -export interface Setter { +export interface Setter extends RenderNode { setMat4 (name: string, mat: Mat4): void; setQuaternion (name: string, quat: Quat): void; setColor (name: string, color: Color): void; @@ -82,47 +84,43 @@ export interface Setter { } export interface RasterQueueBuilder extends Setter { - addSceneOfCamera (camera: Camera, light: LightInfo, sceneFlags: SceneFlags, name: string): void; addSceneOfCamera (camera: Camera, light: LightInfo, sceneFlags: SceneFlags): void; + addSceneOfCamera (camera: Camera, light: LightInfo/*, SceneFlags.NONE*/): void; addScene (name: string, sceneFlags: SceneFlags): void; - addFullscreenQuad (material: Material, passID: number, sceneFlags: SceneFlags, name: string): void; + addScene (name: string/*, SceneFlags.NONE*/): void; addFullscreenQuad (material: Material, passID: number, sceneFlags: SceneFlags): void; - addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags: SceneFlags, name: string): void; + addFullscreenQuad (material: Material, passID: number/*, SceneFlags.NONE*/): void; addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags: SceneFlags): void; + addCameraQuad (camera: Camera, material: Material, passID: number/*, SceneFlags.NONE*/): void; clearRenderTarget (name: string, color: Color): void; + clearRenderTarget (name: string/*, new Color()*/): void; setViewport (viewport: Viewport): void; } export interface RasterPassBuilder extends Setter { addRasterView (name: string, view: RasterView): void; addComputeView (name: string, view: ComputeView): void; - addQueue (hint: QueueHint, name: string): RasterQueueBuilder; addQueue (hint: QueueHint): RasterQueueBuilder; - addFullscreenQuad (material: Material, passID: number, sceneFlags: SceneFlags, name: string): void; - addFullscreenQuad (material: Material, passID: number, sceneFlags: SceneFlags): void; - addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags: SceneFlags, name: string): void; - addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags: SceneFlags): void; + addQueue (/*QueueHint.NONE*/): RasterQueueBuilder; setViewport (viewport: Viewport): void; + setVersion (name: string, version: number): void; + showStatistics: boolean; } export interface ComputeQueueBuilder extends Setter { - addDispatch (shader: string, threadGroupCountX: number, threadGroupCountY: number, threadGroupCountZ: number, name: string): void; addDispatch (shader: string, threadGroupCountX: number, threadGroupCountY: number, threadGroupCountZ: number): void; } export interface ComputePassBuilder extends Setter { addComputeView (name: string, view: ComputeView): void; - addQueue (name: string): ComputeQueueBuilder; addQueue (): ComputeQueueBuilder; - addDispatch (shader: string, threadGroupCountX: number, threadGroupCountY: number, threadGroupCountZ: number, name: string): void; - addDispatch (shader: string, threadGroupCountX: number, threadGroupCountY: number, threadGroupCountZ: number): void; } -export interface MovePassBuilder { +export interface MovePassBuilder extends RenderNode { addPair (pair: MovePair): void; } -export interface CopyPassBuilder { +export interface CopyPassBuilder extends RenderNode { addPair (pair: CopyPair): void; } @@ -149,36 +147,29 @@ export interface SceneTransversal { transverse (visitor: SceneVisitor): SceneTask; } -export interface LayoutGraphBuilder { - clear (): void; - addRenderStage (name: string): number; - addRenderPhase (name: string, parentID: number): number; - addShader (name: string, parentPhaseID: number): void; - addDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: DescriptorBlockFlattened): void; - addUniformBlock (nodeID: number, index: DescriptorBlockIndex, name: string, uniformBlock: UniformBlock): void; - reserveDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: DescriptorBlockFlattened): void; - compile (): number; - print (): string; -} - export interface Pipeline extends PipelineRuntime { beginSetup (): void; endSetup (): void; containsResource (name: string): boolean; addRenderTexture (name: string, format: Format, width: number, height: number, renderWindow: RenderWindow): number; addRenderTarget (name: string, format: Format, width: number, height: number, residency: ResourceResidency): number; + addRenderTarget (name: string, format: Format, width: number, height: number/*, ResourceResidency.MANAGED*/): number; addDepthStencil (name: string, format: Format, width: number, height: number, residency: ResourceResidency): number; + addDepthStencil (name: string, format: Format, width: number, height: number/*, ResourceResidency.MANAGED*/): number; + updateRenderWindow (name: string, renderWindow: RenderWindow): void; + updateRenderTarget (name: string, width: number, height: number, format: Format): void; + updateRenderTarget (name: string, width: number, height: number/*, gfx.Format.UNKNOWN*/): void; + updateDepthStencil (name: string, width: number, height: number, format: Format): void; + updateDepthStencil (name: string, width: number, height: number/*, gfx.Format.UNKNOWN*/): void; beginFrame (): void; endFrame (): void; - addRasterPass (width: number, height: number, layoutName: string, name: string): RasterPassBuilder; addRasterPass (width: number, height: number, layoutName: string): RasterPassBuilder; - addComputePass (layoutName: string, name: string): ComputePassBuilder; + addRasterPass (width: number, height: number/*, 'default'*/): RasterPassBuilder; addComputePass (layoutName: string): ComputePassBuilder; - addMovePass (name: string): MovePassBuilder; - addCopyPass (name: string): CopyPassBuilder; + addMovePass (): MovePassBuilder; + addCopyPass (): CopyPassBuilder; presentAll (): void; createSceneTransversal (camera: Camera, scene: RenderScene): SceneTransversal; - readonly layoutGraphBuilder: LayoutGraphBuilder; getDescriptorSetLayout (shaderName: string, freq: UpdateFrequency): DescriptorSetLayout | null; } @@ -186,5 +177,10 @@ export interface PipelineBuilder { setup (cameras: Camera[], pipeline: Pipeline): void; } +export interface RenderingModule { + getPassID (name: string): number; + getPhaseID (passID: number, name: string): number; +} + export class Factory { } diff --git a/cocos/rendering/custom/private.ts b/cocos/rendering/custom/private.ts new file mode 100644 index 00000000000..74e285938ff --- /dev/null +++ b/cocos/rendering/custom/private.ts @@ -0,0 +1,57 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + +/** + * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= + * The following section is auto-generated. + * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= + */ +/* eslint-disable max-len */ +import { EffectAsset } from '../../asset/assets'; +import { DescriptorSetLayout, Device, PipelineLayout, Shader, ShaderInfo } from '../../gfx'; +import { MacroRecord } from '../../render-scene/core/pass-utils'; +import { IProgramInfo } from '../../render-scene/core/program-lib'; + +export interface ProgramProxy { + readonly name: string; + readonly shader: Shader; +} + +export interface ProgramLibrary { + addEffect (effectAsset: EffectAsset): void; + precompileEffect (device: Device, effectAsset: EffectAsset): void; + getKey (phaseID: number, programName: string, defines: MacroRecord): string; + getPipelineLayout (device: Device, phaseID: number, programName: string): PipelineLayout; + getMaterialDescriptorSetLayout (device: Device, phaseID: number, programName: string): DescriptorSetLayout; + getLocalDescriptorSetLayout (device: Device, phaseID: number, programName: string): DescriptorSetLayout; + getProgramInfo (phaseID: number, programName: string): IProgramInfo; + getShaderInfo (phaseID: number, programName: string): ShaderInfo; + getProgramVariant (device: Device, phaseID: number, name: string, defines: MacroRecord, key: string | null): ProgramProxy | null; + getProgramVariant (device: Device, phaseID: number, name: string, defines: MacroRecord/*, null*/): ProgramProxy | null; + getBlockSizes (phaseID: number, programName: string): number[]; + getHandleMap (phaseID: number, programName: string): Record; + getProgramID (phaseID: number, programName: string): number; + getDescriptorNameID (name: string): number; + getDescriptorName (nameID: number): string; +} diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index c571dcac5b2..8def7abf449 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,10 +28,10 @@ * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= */ /* eslint-disable max-len */ -import * as impl from './graph'; +import { AdjI, AdjacencyGraph, BidirectionalGraph, ComponentGraph, ED, InEI, MutableGraph, MutableReferenceGraph, NamedGraph, OutE, OutEI, PolymorphicGraph, PropertyGraph, PropertyMap, ReferenceGraph, UuidGraph, VertexListGraph, directional, parallel, reindexEdgeList, traversal } from './graph'; import { Material } from '../../asset/assets'; import { Camera } from '../../render-scene/scene/camera'; -import { AccessFlagBit, Buffer, ClearFlagBit, Color, Format, Framebuffer, SampleCount, Sampler, SamplerInfo, Swapchain, Texture, TextureFlagBit, Viewport } from '../../gfx'; +import { AccessFlagBit, Buffer, ClearFlagBit, Color, Format, Framebuffer, RenderPass, SampleCount, Sampler, SamplerInfo, Swapchain, Texture, TextureFlagBit, Viewport } from '../../gfx'; import { ComputeView, CopyPair, LightInfo, MovePair, QueueHint, RasterView, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags } from './types'; export class ResourceDesc { @@ -62,6 +61,7 @@ export class RenderSwapchain { /*pointer*/ swapchain: Swapchain | null; currentID = 0; numBackBuffers = 0; + generation = 0xFFFFFFFF; } export class ResourceStates { @@ -88,180 +88,87 @@ export class ManagedResource { unused = 0; } -//================================================================= -// ResourceGraph -//================================================================= -// PolymorphicGraph Concept -export const enum ResourceGraphValue { - Managed, - ManagedBuffer, - ManagedTexture, - PersistentBuffer, - PersistentTexture, - Framebuffer, - Swapchain, -} - -export function getResourceGraphValueName (e: ResourceGraphValue): string { - switch (e) { - case ResourceGraphValue.Managed: return 'Managed'; - case ResourceGraphValue.ManagedBuffer: return 'ManagedBuffer'; - case ResourceGraphValue.ManagedTexture: return 'ManagedTexture'; - case ResourceGraphValue.PersistentBuffer: return 'PersistentBuffer'; - case ResourceGraphValue.PersistentTexture: return 'PersistentTexture'; - case ResourceGraphValue.Framebuffer: return 'Framebuffer'; - case ResourceGraphValue.Swapchain: return 'Swapchain'; - default: return ''; - } -} - -interface ResourceGraphValueType { - [ResourceGraphValue.Managed]: ManagedResource - [ResourceGraphValue.ManagedBuffer]: ManagedBuffer - [ResourceGraphValue.ManagedTexture]: ManagedTexture - [ResourceGraphValue.PersistentBuffer]: Buffer - [ResourceGraphValue.PersistentTexture]: Texture - [ResourceGraphValue.Framebuffer]: Framebuffer - [ResourceGraphValue.Swapchain]: RenderSwapchain -} - -export interface ResourceGraphVisitor { - managed(value: ManagedResource): unknown; - managedBuffer(value: ManagedBuffer): unknown; - managedTexture(value: ManagedTexture): unknown; - persistentBuffer(value: Buffer): unknown; - persistentTexture(value: Texture): unknown; - framebuffer(value: Framebuffer): unknown; - swapchain(value: RenderSwapchain): unknown; +export class RasterSubpass { + readonly rasterViews: Map = new Map(); + readonly computeViews: Map = new Map(); } -type ResourceGraphObject = ManagedResource -| ManagedBuffer -| ManagedTexture -| Buffer -| Texture -| Framebuffer -| RenderSwapchain; - -//----------------------------------------------------------------- +//================================================================= +// SubpassGraph +//================================================================= // Graph Concept -export class ResourceGraphVertex { - constructor ( - readonly id: ResourceGraphValue, - readonly object: ResourceGraphObject, - ) { - this._id = id; - this._object = object; +export class SubpassGraphVertex { + constructor () { } - readonly _outEdges: impl.OutE[] = []; - readonly _inEdges: impl.OutE[] = []; - readonly _id: ResourceGraphValue; - readonly _object: ResourceGraphObject; + readonly _outEdges: OutE[] = []; + readonly _inEdges: OutE[] = []; } //----------------------------------------------------------------- // PropertyGraph Concept -export class ResourceGraphNameMap implements impl.PropertyMap { +export class SubpassGraphNameMap implements PropertyMap { constructor (readonly names: string[]) { this._names = names; } get (v: number): string { return this._names[v]; } - readonly _names: string[]; -} - -export class ResourceGraphDescMap implements impl.PropertyMap { - constructor (readonly descs: ResourceDesc[]) { - this._descs = descs; - } - get (v: number): ResourceDesc { - return this._descs[v]; - } - readonly _descs: ResourceDesc[]; -} - -export class ResourceGraphTraitsMap implements impl.PropertyMap { - constructor (readonly traits: ResourceTraits[]) { - this._traits = traits; - } - get (v: number): ResourceTraits { - return this._traits[v]; - } - readonly _traits: ResourceTraits[]; -} - -export class ResourceGraphStatesMap implements impl.PropertyMap { - constructor (readonly states: ResourceStates[]) { - this._states = states; - } - get (v: number): ResourceStates { - return this._states[v]; + set (v: number, names: string): void { + this._names[v] = names; } - readonly _states: ResourceStates[]; + readonly _names: string[]; } -export class ResourceGraphSamplerMap implements impl.PropertyMap { - constructor (readonly samplerInfo: SamplerInfo[]) { - this._samplerInfo = samplerInfo; +export class SubpassGraphSubpassMap implements PropertyMap { + constructor (readonly subpasses: RasterSubpass[]) { + this._subpasses = subpasses; } - get (v: number): SamplerInfo { - return this._samplerInfo[v]; + get (v: number): RasterSubpass { + return this._subpasses[v]; } - readonly _samplerInfo: SamplerInfo[]; + readonly _subpasses: RasterSubpass[]; } //----------------------------------------------------------------- // ComponentGraph Concept -export const enum ResourceGraphComponent { +export const enum SubpassGraphComponent { Name, - Desc, - Traits, - States, - Sampler, + Subpass, } -interface ResourceGraphComponentType { - [ResourceGraphComponent.Name]: string; - [ResourceGraphComponent.Desc]: ResourceDesc; - [ResourceGraphComponent.Traits]: ResourceTraits; - [ResourceGraphComponent.States]: ResourceStates; - [ResourceGraphComponent.Sampler]: SamplerInfo; +export interface SubpassGraphComponentType { + [SubpassGraphComponent.Name]: string; + [SubpassGraphComponent.Subpass]: RasterSubpass; } -interface ResourceGraphComponentPropertyMap { - [ResourceGraphComponent.Name]: ResourceGraphNameMap; - [ResourceGraphComponent.Desc]: ResourceGraphDescMap; - [ResourceGraphComponent.Traits]: ResourceGraphTraitsMap; - [ResourceGraphComponent.States]: ResourceGraphStatesMap; - [ResourceGraphComponent.Sampler]: ResourceGraphSamplerMap; +export interface SubpassGraphComponentPropertyMap { + [SubpassGraphComponent.Name]: SubpassGraphNameMap; + [SubpassGraphComponent.Subpass]: SubpassGraphSubpassMap; } //----------------------------------------------------------------- -// ResourceGraph Implementation -export class ResourceGraph implements impl.BidirectionalGraph -, impl.AdjacencyGraph -, impl.VertexListGraph -, impl.MutableGraph -, impl.PropertyGraph -, impl.NamedGraph -, impl.ComponentGraph -, impl.PolymorphicGraph -, impl.UuidGraph { +// SubpassGraph Implementation +export class SubpassGraph implements BidirectionalGraph +, AdjacencyGraph +, VertexListGraph +, MutableGraph +, PropertyGraph +, NamedGraph +, ComponentGraph { //----------------------------------------------------------------- // Graph // type vertex_descriptor = number; nullVertex (): number { return 0xFFFFFFFF; } - // type edge_descriptor = impl.ED; - readonly directed_category: impl.directional = impl.directional.bidirectional; - readonly edge_parallel_category: impl.parallel = impl.parallel.allow; - readonly traversal_category: impl.traversal = impl.traversal.incidence - | impl.traversal.bidirectional - | impl.traversal.adjacency - | impl.traversal.vertex_list; + // type edge_descriptor = ED; + readonly directed_category: directional = directional.bidirectional; + readonly edge_parallel_category: parallel = parallel.allow; + readonly traversal_category: traversal = traversal.incidence + | traversal.bidirectional + | traversal.adjacency + | traversal.vertex_list; //----------------------------------------------------------------- // IncidenceGraph - // type out_edge_iterator = impl.OutEI; + // type out_edge_iterator = OutEI; // type degree_size_type = number; edge (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { @@ -271,23 +178,23 @@ export class ResourceGraph implements impl.BidirectionalGraph } return false; } - source (e: impl.ED): number { + source (e: ED): number { return e.source as number; } - target (e: impl.ED): number { + target (e: ED): number { return e.target as number; } - outEdges (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + outEdges (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } outDegree (v: number): number { return this._vertices[v]._outEdges.length; } //----------------------------------------------------------------- // BidirectionalGraph - // type in_edge_iterator = impl.InEI; - inEdges (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + // type in_edge_iterator = InEI; + inEdges (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } inDegree (v: number): number { return this._vertices[v]._inEdges.length; @@ -297,9 +204,9 @@ export class ResourceGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // AdjacencyGraph - // type adjacency_iterator = impl.AdjI; - adjacentVertices (v: number): impl.AdjI { - return new impl.AdjI(this, this.outEdges(v)); + // type adjacency_iterator = AdjI; + adjacentVertices (v: number): AdjI { + return new AdjI(this, this.outEdges(v)); } //----------------------------------------------------------------- // VertexListGraph @@ -310,40 +217,32 @@ export class ResourceGraph implements impl.BidirectionalGraph return this._vertices.length; } //----------------------------------------------------------------- + // EdgeListGraph + numEdges (): number { + let numEdges = 0; + for (const v of this.vertices()) { + numEdges += this.outDegree(v); + } + return numEdges; + } + //----------------------------------------------------------------- // MutableGraph clear (): void { - // Members - this.nextFenceValue = 1; - // UuidGraph - this._valueIndex.clear(); // ComponentGraph this._names.length = 0; - this._descs.length = 0; - this._traits.length = 0; - this._states.length = 0; - this._samplerInfo.length = 0; + this._subpasses.length = 0; // Graph Vertices this._vertices.length = 0; } - addVertex ( - id: ResourceGraphValue, - object: ResourceGraphValueType[T], + addVertex ( name: string, - desc: ResourceDesc, - traits: ResourceTraits, - states: ResourceStates, - sampler: SamplerInfo, + subpass: RasterSubpass, ): number { - const vert = new ResourceGraphVertex(id, object); + const vert = new SubpassGraphVertex(); const v = this._vertices.length; this._vertices.push(vert); this._names.push(name); - this._descs.push(desc); - this._traits.push(traits); - this._states.push(states); - this._samplerInfo.push(sampler); - // UuidGraph - this._valueIndex.set(name, v); + this._subpasses.push(subpass); return v; } clearVertex (v: number): void { @@ -375,19 +274,9 @@ export class ResourceGraph implements impl.BidirectionalGraph vert._inEdges.length = 0; } removeVertex (u: number): void { - { // UuidGraph - const key = this._names[u]; - this._valueIndex.delete(key); - this._valueIndex.forEach((v) => { - if (v > u) { --v; } - }); - } this._vertices.splice(u, 1); this._names.splice(u, 1); - this._descs.splice(u, 1); - this._traits.splice(u, 1); - this._states.splice(u, 1); - this._samplerInfo.splice(u, 1); + this._subpasses.splice(u, 1); const sz = this._vertices.length; if (u === sz) { @@ -396,15 +285,15 @@ export class ResourceGraph implements impl.BidirectionalGraph for (let v = 0; v !== sz; ++v) { const vert = this._vertices[v]; - impl.reindexEdgeList(vert._outEdges, u); - impl.reindexEdgeList(vert._inEdges, u); + reindexEdgeList(vert._outEdges, u); + reindexEdgeList(vert._inEdges, u); } } - addEdge (u: number, v: number): impl.ED | null { + addEdge (u: number, v: number): ED | null { // update in/out edge list - this._vertices[u]._outEdges.push(new impl.OutE(v)); - this._vertices[v]._inEdges.push(new impl.OutE(u)); - return new impl.ED(u, v); + this._vertices[u]._outEdges.push(new OutE(v)); + this._vertices[v]._inEdges.push(new OutE(u)); + return new ED(u, v); } removeEdges (u: number, v: number): void { const source = this._vertices[u]; @@ -426,7 +315,7 @@ export class ResourceGraph implements impl.BidirectionalGraph } } } - removeEdge (e: impl.ED): void { + removeEdge (e: ED): void { const u = e.source as number; const v = e.target as number; const source = this._vertices[u]; @@ -453,58 +342,40 @@ export class ResourceGraph implements impl.BidirectionalGraph vertexName (v: number): string { return this._names[v]; } - vertexNameMap (): ResourceGraphNameMap { - return new ResourceGraphNameMap(this._names); + vertexNameMap (): SubpassGraphNameMap { + return new SubpassGraphNameMap(this._names); } //----------------------------------------------------------------- // PropertyGraph - get (tag: string): ResourceGraphNameMap | ResourceGraphDescMap | ResourceGraphTraitsMap | ResourceGraphStatesMap | ResourceGraphSamplerMap { + get (tag: string): SubpassGraphNameMap | SubpassGraphSubpassMap { switch (tag) { // Components case 'Name': - return new ResourceGraphNameMap(this._names); - case 'Desc': - return new ResourceGraphDescMap(this._descs); - case 'Traits': - return new ResourceGraphTraitsMap(this._traits); - case 'States': - return new ResourceGraphStatesMap(this._states); - case 'Sampler': - return new ResourceGraphSamplerMap(this._samplerInfo); + return new SubpassGraphNameMap(this._names); + case 'Subpass': + return new SubpassGraphSubpassMap(this._subpasses); default: throw Error('property map not found'); } } //----------------------------------------------------------------- // ComponentGraph - component (id: T, v: number): ResourceGraphComponentType[T] { + component (id: T, v: number): SubpassGraphComponentType[T] { switch (id) { - case ResourceGraphComponent.Name: - return this._names[v] as ResourceGraphComponentType[T]; - case ResourceGraphComponent.Desc: - return this._descs[v] as ResourceGraphComponentType[T]; - case ResourceGraphComponent.Traits: - return this._traits[v] as ResourceGraphComponentType[T]; - case ResourceGraphComponent.States: - return this._states[v] as ResourceGraphComponentType[T]; - case ResourceGraphComponent.Sampler: - return this._samplerInfo[v] as ResourceGraphComponentType[T]; + case SubpassGraphComponent.Name: + return this._names[v] as SubpassGraphComponentType[T]; + case SubpassGraphComponent.Subpass: + return this._subpasses[v] as SubpassGraphComponentType[T]; default: throw Error('component not found'); } } - componentMap (id: T): ResourceGraphComponentPropertyMap[T] { + componentMap (id: T): SubpassGraphComponentPropertyMap[T] { switch (id) { - case ResourceGraphComponent.Name: - return new ResourceGraphNameMap(this._names) as ResourceGraphComponentPropertyMap[T]; - case ResourceGraphComponent.Desc: - return new ResourceGraphDescMap(this._descs) as ResourceGraphComponentPropertyMap[T]; - case ResourceGraphComponent.Traits: - return new ResourceGraphTraitsMap(this._traits) as ResourceGraphComponentPropertyMap[T]; - case ResourceGraphComponent.States: - return new ResourceGraphStatesMap(this._states) as ResourceGraphComponentPropertyMap[T]; - case ResourceGraphComponent.Sampler: - return new ResourceGraphSamplerMap(this._samplerInfo) as ResourceGraphComponentPropertyMap[T]; + case SubpassGraphComponent.Name: + return new SubpassGraphNameMap(this._names) as SubpassGraphComponentPropertyMap[T]; + case SubpassGraphComponent.Subpass: + return new SubpassGraphSubpassMap(this._subpasses) as SubpassGraphComponentPropertyMap[T]; default: throw Error('component map not found'); } @@ -512,265 +383,220 @@ export class ResourceGraph implements impl.BidirectionalGraph getName (v: number): string { return this._names[v]; } - getDesc (v: number): ResourceDesc { - return this._descs[v]; - } - getTraits (v: number): ResourceTraits { - return this._traits[v]; - } - getStates (v: number): ResourceStates { - return this._states[v]; - } - getSampler (v: number): SamplerInfo { - return this._samplerInfo[v]; + setName (v: number, value: string) { + this._names[v] = value; } - //----------------------------------------------------------------- - // PolymorphicGraph - holds (id: ResourceGraphValue, v: number): boolean { - return this._vertices[v]._id === id; + getSubpass (v: number): RasterSubpass { + return this._subpasses[v]; } - id (v: number): ResourceGraphValue { - return this._vertices[v]._id; + + readonly components: string[] = ['Name', 'Subpass']; + readonly _vertices: SubpassGraphVertex[] = []; + readonly _names: string[] = []; + readonly _subpasses: RasterSubpass[] = []; +} + +export class RasterPass { + readonly rasterViews: Map = new Map(); + readonly computeViews: Map = new Map(); + readonly subpassGraph: SubpassGraph = new SubpassGraph(); + width = 0; + height = 0; + readonly viewport: Viewport = new Viewport(); + versionName = ''; + version = 0; + showStatistics = false; +} + +export class PersistentRenderPassAndFramebuffer { + constructor (renderPass: RenderPass, framebuffer: Framebuffer) { + this.renderPass = renderPass; + this.framebuffer = framebuffer; } - object (v: number): ResourceGraphObject { - return this._vertices[v]._object; - } - value (id: T, v: number): ResourceGraphValueType[T] { - if (this._vertices[v]._id === id) { - return this._vertices[v]._object as ResourceGraphValueType[T]; - } else { - throw Error('value id not match'); - } - } - tryValue (id: T, v: number): ResourceGraphValueType[T] | null { - if (this._vertices[v]._id === id) { - return this._vertices[v]._object as ResourceGraphValueType[T]; - } else { - return null; - } - } - visitVertex (visitor: ResourceGraphVisitor, v: number): unknown { - const vert = this._vertices[v]; - switch (vert._id) { - case ResourceGraphValue.Managed: - return visitor.managed(vert._object as ManagedResource); - case ResourceGraphValue.ManagedBuffer: - return visitor.managedBuffer(vert._object as ManagedBuffer); - case ResourceGraphValue.ManagedTexture: - return visitor.managedTexture(vert._object as ManagedTexture); - case ResourceGraphValue.PersistentBuffer: - return visitor.persistentBuffer(vert._object as Buffer); - case ResourceGraphValue.PersistentTexture: - return visitor.persistentTexture(vert._object as Texture); - case ResourceGraphValue.Framebuffer: - return visitor.framebuffer(vert._object as Framebuffer); - case ResourceGraphValue.Swapchain: - return visitor.swapchain(vert._object as RenderSwapchain); - default: - throw Error('polymorphic type not found'); - } - } - getManaged (v: number): ManagedResource { - if (this._vertices[v]._id === ResourceGraphValue.Managed) { - return this._vertices[v]._object as ManagedResource; - } else { - throw Error('value id not match'); - } - } - getManagedBuffer (v: number): ManagedBuffer { - if (this._vertices[v]._id === ResourceGraphValue.ManagedBuffer) { - return this._vertices[v]._object as ManagedBuffer; - } else { - throw Error('value id not match'); - } - } - getManagedTexture (v: number): ManagedTexture { - if (this._vertices[v]._id === ResourceGraphValue.ManagedTexture) { - return this._vertices[v]._object as ManagedTexture; - } else { - throw Error('value id not match'); - } - } - getPersistentBuffer (v: number): Buffer { - if (this._vertices[v]._id === ResourceGraphValue.PersistentBuffer) { - return this._vertices[v]._object as Buffer; - } else { - throw Error('value id not match'); - } - } - getPersistentTexture (v: number): Texture { - if (this._vertices[v]._id === ResourceGraphValue.PersistentTexture) { - return this._vertices[v]._object as Texture; - } else { - throw Error('value id not match'); - } - } - getFramebuffer (v: number): Framebuffer { - if (this._vertices[v]._id === ResourceGraphValue.Framebuffer) { - return this._vertices[v]._object as Framebuffer; - } else { - throw Error('value id not match'); - } - } - getSwapchain (v: number): RenderSwapchain { - if (this._vertices[v]._id === ResourceGraphValue.Swapchain) { - return this._vertices[v]._object as RenderSwapchain; - } else { - throw Error('value id not match'); - } - } - tryGetManaged (v: number): ManagedResource | null { - if (this._vertices[v]._id === ResourceGraphValue.Managed) { - return this._vertices[v]._object as ManagedResource; - } else { - return null; - } - } - tryGetManagedBuffer (v: number): ManagedBuffer | null { - if (this._vertices[v]._id === ResourceGraphValue.ManagedBuffer) { - return this._vertices[v]._object as ManagedBuffer; - } else { - return null; - } - } - tryGetManagedTexture (v: number): ManagedTexture | null { - if (this._vertices[v]._id === ResourceGraphValue.ManagedTexture) { - return this._vertices[v]._object as ManagedTexture; - } else { - return null; - } - } - tryGetPersistentBuffer (v: number): Buffer | null { - if (this._vertices[v]._id === ResourceGraphValue.PersistentBuffer) { - return this._vertices[v]._object as Buffer; - } else { - return null; - } - } - tryGetPersistentTexture (v: number): Texture | null { - if (this._vertices[v]._id === ResourceGraphValue.PersistentTexture) { - return this._vertices[v]._object as Texture; - } else { - return null; - } - } - tryGetFramebuffer (v: number): Framebuffer | null { - if (this._vertices[v]._id === ResourceGraphValue.Framebuffer) { - return this._vertices[v]._object as Framebuffer; - } else { - return null; - } - } - tryGetSwapchain (v: number): RenderSwapchain | null { - if (this._vertices[v]._id === ResourceGraphValue.Swapchain) { - return this._vertices[v]._object as RenderSwapchain; - } else { - return null; - } - } - //----------------------------------------------------------------- - // UuidGraph - contains (key: string): boolean { - return this._valueIndex.has(key); - } - vertex (key: string): number { - return this._valueIndex.get(key)!; - } - find (key: string): number { - const v = this._valueIndex.get(key); - if (v === undefined) return 0xFFFFFFFF; - return v; + /*refcount*/ renderPass: RenderPass; + /*refcount*/ framebuffer: Framebuffer; + readonly clearColors: Color[] = []; + clearDepth = 0; + clearStencil = 0; +} + +//================================================================= +// ResourceGraph +//================================================================= +// PolymorphicGraph Concept +export const enum ResourceGraphValue { + Managed, + ManagedBuffer, + ManagedTexture, + PersistentBuffer, + PersistentTexture, + Framebuffer, + Swapchain, +} + +export function getResourceGraphValueName (e: ResourceGraphValue): string { + switch (e) { + case ResourceGraphValue.Managed: return 'Managed'; + case ResourceGraphValue.ManagedBuffer: return 'ManagedBuffer'; + case ResourceGraphValue.ManagedTexture: return 'ManagedTexture'; + case ResourceGraphValue.PersistentBuffer: return 'PersistentBuffer'; + case ResourceGraphValue.PersistentTexture: return 'PersistentTexture'; + case ResourceGraphValue.Framebuffer: return 'Framebuffer'; + case ResourceGraphValue.Swapchain: return 'Swapchain'; + default: return ''; } +} - readonly components: string[] = ['Name', 'Desc', 'Traits', 'States', 'Sampler']; - readonly _vertices: ResourceGraphVertex[] = []; - readonly _names: string[] = []; - readonly _descs: ResourceDesc[] = []; - readonly _traits: ResourceTraits[] = []; - readonly _states: ResourceStates[] = []; - readonly _samplerInfo: SamplerInfo[] = []; - readonly _valueIndex: Map = new Map(); - nextFenceValue = 1; +export interface ResourceGraphValueType { + [ResourceGraphValue.Managed]: ManagedResource + [ResourceGraphValue.ManagedBuffer]: ManagedBuffer + [ResourceGraphValue.ManagedTexture]: ManagedTexture + [ResourceGraphValue.PersistentBuffer]: Buffer + [ResourceGraphValue.PersistentTexture]: Texture + [ResourceGraphValue.Framebuffer]: Framebuffer + [ResourceGraphValue.Swapchain]: RenderSwapchain } -export class RasterSubpass { - readonly rasterViews: Map = new Map(); - readonly computeViews: Map = new Map(); +export interface ResourceGraphVisitor { + managed(value: ManagedResource): unknown; + managedBuffer(value: ManagedBuffer): unknown; + managedTexture(value: ManagedTexture): unknown; + persistentBuffer(value: Buffer): unknown; + persistentTexture(value: Texture): unknown; + framebuffer(value: Framebuffer): unknown; + swapchain(value: RenderSwapchain): unknown; } -//================================================================= -// SubpassGraph -//================================================================= +export type ResourceGraphObject = ManagedResource +| ManagedBuffer +| ManagedTexture +| Buffer +| Texture +| Framebuffer +| RenderSwapchain; + +//----------------------------------------------------------------- // Graph Concept -export class SubpassGraphVertex { - constructor () { +export class ResourceGraphVertex { + constructor ( + readonly id: ResourceGraphValue, + readonly object: ResourceGraphObject, + ) { + this._id = id; + this._object = object; } - readonly _outEdges: impl.OutE[] = []; - readonly _inEdges: impl.OutE[] = []; + readonly _outEdges: OutE[] = []; + readonly _inEdges: OutE[] = []; + readonly _id: ResourceGraphValue; + _object: ResourceGraphObject; } //----------------------------------------------------------------- // PropertyGraph Concept -export class SubpassGraphNameMap implements impl.PropertyMap { +export class ResourceGraphNameMap implements PropertyMap { constructor (readonly names: string[]) { this._names = names; } get (v: number): string { return this._names[v]; } + set (v: number, names: string): void { + this._names[v] = names; + } readonly _names: string[]; } -export class SubpassGraphSubpassMap implements impl.PropertyMap { - constructor (readonly subpasses: RasterSubpass[]) { - this._subpasses = subpasses; +export class ResourceGraphDescMap implements PropertyMap { + constructor (readonly descs: ResourceDesc[]) { + this._descs = descs; } - get (v: number): RasterSubpass { - return this._subpasses[v]; + get (v: number): ResourceDesc { + return this._descs[v]; } - readonly _subpasses: RasterSubpass[]; + readonly _descs: ResourceDesc[]; +} + +export class ResourceGraphTraitsMap implements PropertyMap { + constructor (readonly traits: ResourceTraits[]) { + this._traits = traits; + } + get (v: number): ResourceTraits { + return this._traits[v]; + } + readonly _traits: ResourceTraits[]; +} + +export class ResourceGraphStatesMap implements PropertyMap { + constructor (readonly states: ResourceStates[]) { + this._states = states; + } + get (v: number): ResourceStates { + return this._states[v]; + } + readonly _states: ResourceStates[]; +} + +export class ResourceGraphSamplerMap implements PropertyMap { + constructor (readonly samplerInfo: SamplerInfo[]) { + this._samplerInfo = samplerInfo; + } + get (v: number): SamplerInfo { + return this._samplerInfo[v]; + } + readonly _samplerInfo: SamplerInfo[]; } //----------------------------------------------------------------- // ComponentGraph Concept -export const enum SubpassGraphComponent { +export const enum ResourceGraphComponent { Name, - Subpass, + Desc, + Traits, + States, + Sampler, } -interface SubpassGraphComponentType { - [SubpassGraphComponent.Name]: string; - [SubpassGraphComponent.Subpass]: RasterSubpass; +export interface ResourceGraphComponentType { + [ResourceGraphComponent.Name]: string; + [ResourceGraphComponent.Desc]: ResourceDesc; + [ResourceGraphComponent.Traits]: ResourceTraits; + [ResourceGraphComponent.States]: ResourceStates; + [ResourceGraphComponent.Sampler]: SamplerInfo; } -interface SubpassGraphComponentPropertyMap { - [SubpassGraphComponent.Name]: SubpassGraphNameMap; - [SubpassGraphComponent.Subpass]: SubpassGraphSubpassMap; +export interface ResourceGraphComponentPropertyMap { + [ResourceGraphComponent.Name]: ResourceGraphNameMap; + [ResourceGraphComponent.Desc]: ResourceGraphDescMap; + [ResourceGraphComponent.Traits]: ResourceGraphTraitsMap; + [ResourceGraphComponent.States]: ResourceGraphStatesMap; + [ResourceGraphComponent.Sampler]: ResourceGraphSamplerMap; } //----------------------------------------------------------------- -// SubpassGraph Implementation -export class SubpassGraph implements impl.BidirectionalGraph -, impl.AdjacencyGraph -, impl.VertexListGraph -, impl.MutableGraph -, impl.PropertyGraph -, impl.NamedGraph -, impl.ComponentGraph { +// ResourceGraph Implementation +export class ResourceGraph implements BidirectionalGraph +, AdjacencyGraph +, VertexListGraph +, MutableGraph +, PropertyGraph +, NamedGraph +, ComponentGraph +, PolymorphicGraph +, UuidGraph { //----------------------------------------------------------------- // Graph // type vertex_descriptor = number; nullVertex (): number { return 0xFFFFFFFF; } - // type edge_descriptor = impl.ED; - readonly directed_category: impl.directional = impl.directional.bidirectional; - readonly edge_parallel_category: impl.parallel = impl.parallel.allow; - readonly traversal_category: impl.traversal = impl.traversal.incidence - | impl.traversal.bidirectional - | impl.traversal.adjacency - | impl.traversal.vertex_list; + // type edge_descriptor = ED; + readonly directed_category: directional = directional.bidirectional; + readonly edge_parallel_category: parallel = parallel.allow; + readonly traversal_category: traversal = traversal.incidence + | traversal.bidirectional + | traversal.adjacency + | traversal.vertex_list; //----------------------------------------------------------------- // IncidenceGraph - // type out_edge_iterator = impl.OutEI; + // type out_edge_iterator = OutEI; // type degree_size_type = number; edge (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { @@ -780,23 +606,23 @@ export class SubpassGraph implements impl.BidirectionalGraph } return false; } - source (e: impl.ED): number { + source (e: ED): number { return e.source as number; } - target (e: impl.ED): number { + target (e: ED): number { return e.target as number; } - outEdges (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + outEdges (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } outDegree (v: number): number { return this._vertices[v]._outEdges.length; } //----------------------------------------------------------------- // BidirectionalGraph - // type in_edge_iterator = impl.InEI; - inEdges (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + // type in_edge_iterator = InEI; + inEdges (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } inDegree (v: number): number { return this._vertices[v]._inEdges.length; @@ -806,9 +632,9 @@ export class SubpassGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // AdjacencyGraph - // type adjacency_iterator = impl.AdjI; - adjacentVertices (v: number): impl.AdjI { - return new impl.AdjI(this, this.outEdges(v)); + // type adjacency_iterator = AdjI; + adjacentVertices (v: number): AdjI { + return new AdjI(this, this.outEdges(v)); } //----------------------------------------------------------------- // VertexListGraph @@ -819,23 +645,51 @@ export class SubpassGraph implements impl.BidirectionalGraph return this._vertices.length; } //----------------------------------------------------------------- + // EdgeListGraph + numEdges (): number { + let numEdges = 0; + for (const v of this.vertices()) { + numEdges += this.outDegree(v); + } + return numEdges; + } + //----------------------------------------------------------------- // MutableGraph clear (): void { + // Members + this.renderPasses.clear(); + this.nextFenceValue = 0; + this.version = 0; + // UuidGraph + this._valueIndex.clear(); // ComponentGraph this._names.length = 0; - this._subpasses.length = 0; + this._descs.length = 0; + this._traits.length = 0; + this._states.length = 0; + this._samplerInfo.length = 0; // Graph Vertices this._vertices.length = 0; } - addVertex ( + addVertex ( + id: ResourceGraphValue, + object: ResourceGraphValueType[T], name: string, - subpass: RasterSubpass, + desc: ResourceDesc, + traits: ResourceTraits, + states: ResourceStates, + sampler: SamplerInfo, ): number { - const vert = new SubpassGraphVertex(); + const vert = new ResourceGraphVertex(id, object); const v = this._vertices.length; this._vertices.push(vert); this._names.push(name); - this._subpasses.push(subpass); + this._descs.push(desc); + this._traits.push(traits); + this._states.push(states); + this._samplerInfo.push(sampler); + // UuidGraph + this._valueIndex.set(name, v); return v; } clearVertex (v: number): void { @@ -864,12 +718,22 @@ export class SubpassGraph implements impl.BidirectionalGraph } } } - vert._inEdges.length = 0; - } - removeVertex (u: number): void { + vert._inEdges.length = 0; + } + removeVertex (u: number): void { + { // UuidGraph + const key = this._names[u]; + this._valueIndex.delete(key); + this._valueIndex.forEach((v) => { + if (v > u) { --v; } + }); + } this._vertices.splice(u, 1); this._names.splice(u, 1); - this._subpasses.splice(u, 1); + this._descs.splice(u, 1); + this._traits.splice(u, 1); + this._states.splice(u, 1); + this._samplerInfo.splice(u, 1); const sz = this._vertices.length; if (u === sz) { @@ -878,15 +742,15 @@ export class SubpassGraph implements impl.BidirectionalGraph for (let v = 0; v !== sz; ++v) { const vert = this._vertices[v]; - impl.reindexEdgeList(vert._outEdges, u); - impl.reindexEdgeList(vert._inEdges, u); + reindexEdgeList(vert._outEdges, u); + reindexEdgeList(vert._inEdges, u); } } - addEdge (u: number, v: number): impl.ED | null { + addEdge (u: number, v: number): ED | null { // update in/out edge list - this._vertices[u]._outEdges.push(new impl.OutE(v)); - this._vertices[v]._inEdges.push(new impl.OutE(u)); - return new impl.ED(u, v); + this._vertices[u]._outEdges.push(new OutE(v)); + this._vertices[v]._inEdges.push(new OutE(u)); + return new ED(u, v); } removeEdges (u: number, v: number): void { const source = this._vertices[u]; @@ -908,7 +772,7 @@ export class SubpassGraph implements impl.BidirectionalGraph } } } - removeEdge (e: impl.ED): void { + removeEdge (e: ED): void { const u = e.source as number; const v = e.target as number; const source = this._vertices[u]; @@ -935,40 +799,58 @@ export class SubpassGraph implements impl.BidirectionalGraph vertexName (v: number): string { return this._names[v]; } - vertexNameMap (): SubpassGraphNameMap { - return new SubpassGraphNameMap(this._names); + vertexNameMap (): ResourceGraphNameMap { + return new ResourceGraphNameMap(this._names); } //----------------------------------------------------------------- // PropertyGraph - get (tag: string): SubpassGraphNameMap | SubpassGraphSubpassMap { + get (tag: string): ResourceGraphNameMap | ResourceGraphDescMap | ResourceGraphTraitsMap | ResourceGraphStatesMap | ResourceGraphSamplerMap { switch (tag) { // Components case 'Name': - return new SubpassGraphNameMap(this._names); - case 'Subpass': - return new SubpassGraphSubpassMap(this._subpasses); + return new ResourceGraphNameMap(this._names); + case 'Desc': + return new ResourceGraphDescMap(this._descs); + case 'Traits': + return new ResourceGraphTraitsMap(this._traits); + case 'States': + return new ResourceGraphStatesMap(this._states); + case 'Sampler': + return new ResourceGraphSamplerMap(this._samplerInfo); default: throw Error('property map not found'); } } //----------------------------------------------------------------- // ComponentGraph - component (id: T, v: number): SubpassGraphComponentType[T] { + component (id: T, v: number): ResourceGraphComponentType[T] { switch (id) { - case SubpassGraphComponent.Name: - return this._names[v] as SubpassGraphComponentType[T]; - case SubpassGraphComponent.Subpass: - return this._subpasses[v] as SubpassGraphComponentType[T]; + case ResourceGraphComponent.Name: + return this._names[v] as ResourceGraphComponentType[T]; + case ResourceGraphComponent.Desc: + return this._descs[v] as ResourceGraphComponentType[T]; + case ResourceGraphComponent.Traits: + return this._traits[v] as ResourceGraphComponentType[T]; + case ResourceGraphComponent.States: + return this._states[v] as ResourceGraphComponentType[T]; + case ResourceGraphComponent.Sampler: + return this._samplerInfo[v] as ResourceGraphComponentType[T]; default: throw Error('component not found'); } } - componentMap (id: T): SubpassGraphComponentPropertyMap[T] { + componentMap (id: T): ResourceGraphComponentPropertyMap[T] { switch (id) { - case SubpassGraphComponent.Name: - return new SubpassGraphNameMap(this._names) as SubpassGraphComponentPropertyMap[T]; - case SubpassGraphComponent.Subpass: - return new SubpassGraphSubpassMap(this._subpasses) as SubpassGraphComponentPropertyMap[T]; + case ResourceGraphComponent.Name: + return new ResourceGraphNameMap(this._names) as ResourceGraphComponentPropertyMap[T]; + case ResourceGraphComponent.Desc: + return new ResourceGraphDescMap(this._descs) as ResourceGraphComponentPropertyMap[T]; + case ResourceGraphComponent.Traits: + return new ResourceGraphTraitsMap(this._traits) as ResourceGraphComponentPropertyMap[T]; + case ResourceGraphComponent.States: + return new ResourceGraphStatesMap(this._states) as ResourceGraphComponentPropertyMap[T]; + case ResourceGraphComponent.Sampler: + return new ResourceGraphSamplerMap(this._samplerInfo) as ResourceGraphComponentPropertyMap[T]; default: throw Error('component map not found'); } @@ -976,23 +858,190 @@ export class SubpassGraph implements impl.BidirectionalGraph getName (v: number): string { return this._names[v]; } - getSubpass (v: number): RasterSubpass { - return this._subpasses[v]; + setName (v: number, value: string) { + this._names[v] = value; + } + getDesc (v: number): ResourceDesc { + return this._descs[v]; + } + getTraits (v: number): ResourceTraits { + return this._traits[v]; + } + getStates (v: number): ResourceStates { + return this._states[v]; + } + getSampler (v: number): SamplerInfo { + return this._samplerInfo[v]; + } + //----------------------------------------------------------------- + // PolymorphicGraph + holds (id: ResourceGraphValue, v: number): boolean { + return this._vertices[v]._id === id; + } + id (v: number): ResourceGraphValue { + return this._vertices[v]._id; + } + object (v: number): ResourceGraphObject { + return this._vertices[v]._object; + } + value (id: T, v: number): ResourceGraphValueType[T] { + if (this._vertices[v]._id === id) { + return this._vertices[v]._object as ResourceGraphValueType[T]; + } else { + throw Error('value id not match'); + } + } + tryValue (id: T, v: number): ResourceGraphValueType[T] | null { + if (this._vertices[v]._id === id) { + return this._vertices[v]._object as ResourceGraphValueType[T]; + } else { + return null; + } + } + visitVertex (visitor: ResourceGraphVisitor, v: number): unknown { + const vert = this._vertices[v]; + switch (vert._id) { + case ResourceGraphValue.Managed: + return visitor.managed(vert._object as ManagedResource); + case ResourceGraphValue.ManagedBuffer: + return visitor.managedBuffer(vert._object as ManagedBuffer); + case ResourceGraphValue.ManagedTexture: + return visitor.managedTexture(vert._object as ManagedTexture); + case ResourceGraphValue.PersistentBuffer: + return visitor.persistentBuffer(vert._object as Buffer); + case ResourceGraphValue.PersistentTexture: + return visitor.persistentTexture(vert._object as Texture); + case ResourceGraphValue.Framebuffer: + return visitor.framebuffer(vert._object as Framebuffer); + case ResourceGraphValue.Swapchain: + return visitor.swapchain(vert._object as RenderSwapchain); + default: + throw Error('polymorphic type not found'); + } + } + getManaged (v: number): ManagedResource { + if (this._vertices[v]._id === ResourceGraphValue.Managed) { + return this._vertices[v]._object as ManagedResource; + } else { + throw Error('value id not match'); + } + } + getManagedBuffer (v: number): ManagedBuffer { + if (this._vertices[v]._id === ResourceGraphValue.ManagedBuffer) { + return this._vertices[v]._object as ManagedBuffer; + } else { + throw Error('value id not match'); + } + } + getManagedTexture (v: number): ManagedTexture { + if (this._vertices[v]._id === ResourceGraphValue.ManagedTexture) { + return this._vertices[v]._object as ManagedTexture; + } else { + throw Error('value id not match'); + } + } + getPersistentBuffer (v: number): Buffer { + if (this._vertices[v]._id === ResourceGraphValue.PersistentBuffer) { + return this._vertices[v]._object as Buffer; + } else { + throw Error('value id not match'); + } + } + getPersistentTexture (v: number): Texture { + if (this._vertices[v]._id === ResourceGraphValue.PersistentTexture) { + return this._vertices[v]._object as Texture; + } else { + throw Error('value id not match'); + } + } + getFramebuffer (v: number): Framebuffer { + if (this._vertices[v]._id === ResourceGraphValue.Framebuffer) { + return this._vertices[v]._object as Framebuffer; + } else { + throw Error('value id not match'); + } + } + getSwapchain (v: number): RenderSwapchain { + if (this._vertices[v]._id === ResourceGraphValue.Swapchain) { + return this._vertices[v]._object as RenderSwapchain; + } else { + throw Error('value id not match'); + } + } + tryGetManaged (v: number): ManagedResource | null { + if (this._vertices[v]._id === ResourceGraphValue.Managed) { + return this._vertices[v]._object as ManagedResource; + } else { + return null; + } + } + tryGetManagedBuffer (v: number): ManagedBuffer | null { + if (this._vertices[v]._id === ResourceGraphValue.ManagedBuffer) { + return this._vertices[v]._object as ManagedBuffer; + } else { + return null; + } + } + tryGetManagedTexture (v: number): ManagedTexture | null { + if (this._vertices[v]._id === ResourceGraphValue.ManagedTexture) { + return this._vertices[v]._object as ManagedTexture; + } else { + return null; + } + } + tryGetPersistentBuffer (v: number): Buffer | null { + if (this._vertices[v]._id === ResourceGraphValue.PersistentBuffer) { + return this._vertices[v]._object as Buffer; + } else { + return null; + } + } + tryGetPersistentTexture (v: number): Texture | null { + if (this._vertices[v]._id === ResourceGraphValue.PersistentTexture) { + return this._vertices[v]._object as Texture; + } else { + return null; + } + } + tryGetFramebuffer (v: number): Framebuffer | null { + if (this._vertices[v]._id === ResourceGraphValue.Framebuffer) { + return this._vertices[v]._object as Framebuffer; + } else { + return null; + } + } + tryGetSwapchain (v: number): RenderSwapchain | null { + if (this._vertices[v]._id === ResourceGraphValue.Swapchain) { + return this._vertices[v]._object as RenderSwapchain; + } else { + return null; + } + } + //----------------------------------------------------------------- + // UuidGraph + contains (key: string): boolean { + return this._valueIndex.has(key); + } + vertex (key: string): number { + return this._valueIndex.get(key)!; + } + find (key: string): number { + const v = this._valueIndex.get(key); + if (v === undefined) return 0xFFFFFFFF; + return v; } - readonly components: string[] = ['Name', 'Subpass']; - readonly _vertices: SubpassGraphVertex[] = []; + readonly components: string[] = ['Name', 'Desc', 'Traits', 'States', 'Sampler']; + readonly _vertices: ResourceGraphVertex[] = []; readonly _names: string[] = []; - readonly _subpasses: RasterSubpass[] = []; -} - -export class RasterPass { - readonly rasterViews: Map = new Map(); - readonly computeViews: Map = new Map(); - readonly subpassGraph: SubpassGraph = new SubpassGraph(); - width = 0; - height = 0; - readonly viewport: Viewport = new Viewport(); + readonly _descs: ResourceDesc[] = []; + readonly _traits: ResourceTraits[] = []; + readonly _states: ResourceStates[] = []; + readonly _samplerInfo: SamplerInfo[] = []; + readonly _valueIndex: Map = new Map(); + readonly renderPasses: Map = new Map(); + nextFenceValue = 0; + version = 0; } export class ComputePass { @@ -1125,7 +1174,7 @@ export function getRenderGraphValueName (e: RenderGraphValue): string { } } -interface RenderGraphValueType { +export interface RenderGraphValueType { [RenderGraphValue.Raster]: RasterPass [RenderGraphValue.Compute]: ComputePass [RenderGraphValue.Copy]: CopyPass @@ -1155,7 +1204,7 @@ export interface RenderGraphVisitor { viewport(value: Viewport): unknown; } -type RenderGraphObject = RasterPass +export type RenderGraphObject = RasterPass | ComputePass | CopyPass | MovePass @@ -1178,37 +1227,43 @@ export class RenderGraphVertex { this._id = id; this._object = object; } - readonly _outEdges: impl.OutE[] = []; - readonly _inEdges: impl.OutE[] = []; - readonly _children: impl.OutE[] = []; - readonly _parents: impl.OutE[] = []; + readonly _outEdges: OutE[] = []; + readonly _inEdges: OutE[] = []; + readonly _children: OutE[] = []; + readonly _parents: OutE[] = []; readonly _id: RenderGraphValue; - readonly _object: RenderGraphObject; + _object: RenderGraphObject; } //----------------------------------------------------------------- // PropertyGraph Concept -export class RenderGraphNameMap implements impl.PropertyMap { +export class RenderGraphNameMap implements PropertyMap { constructor (readonly names: string[]) { this._names = names; } get (v: number): string { return this._names[v]; } + set (v: number, names: string): void { + this._names[v] = names; + } readonly _names: string[]; } -export class RenderGraphLayoutMap implements impl.PropertyMap { +export class RenderGraphLayoutMap implements PropertyMap { constructor (readonly layoutNodes: string[]) { this._layoutNodes = layoutNodes; } get (v: number): string { return this._layoutNodes[v]; } + set (v: number, layoutNodes: string): void { + this._layoutNodes[v] = layoutNodes; + } readonly _layoutNodes: string[]; } -export class RenderGraphDataMap implements impl.PropertyMap { +export class RenderGraphDataMap implements PropertyMap { constructor (readonly data: RenderData[]) { this._data = data; } @@ -1218,13 +1273,16 @@ export class RenderGraphDataMap implements impl.PropertyMap { readonly _data: RenderData[]; } -export class RenderGraphValidMap implements impl.PropertyMap { +export class RenderGraphValidMap implements PropertyMap { constructor (readonly valid: boolean[]) { this._valid = valid; } get (v: number): boolean { return this._valid[v]; } + set (v: number, valid: boolean): void { + this._valid[v] = valid; + } readonly _valid: boolean[]; } @@ -1237,14 +1295,14 @@ export const enum RenderGraphComponent { Valid, } -interface RenderGraphComponentType { +export interface RenderGraphComponentType { [RenderGraphComponent.Name]: string; [RenderGraphComponent.Layout]: string; [RenderGraphComponent.Data]: RenderData; [RenderGraphComponent.Valid]: boolean; } -interface RenderGraphComponentPropertyMap { +export interface RenderGraphComponentPropertyMap { [RenderGraphComponent.Name]: RenderGraphNameMap; [RenderGraphComponent.Layout]: RenderGraphLayoutMap; [RenderGraphComponent.Data]: RenderGraphDataMap; @@ -1253,30 +1311,30 @@ interface RenderGraphComponentPropertyMap { //----------------------------------------------------------------- // RenderGraph Implementation -export class RenderGraph implements impl.BidirectionalGraph -, impl.AdjacencyGraph -, impl.VertexListGraph -, impl.MutableGraph -, impl.PropertyGraph -, impl.NamedGraph -, impl.ComponentGraph -, impl.PolymorphicGraph -, impl.ReferenceGraph -, impl.MutableReferenceGraph { +export class RenderGraph implements BidirectionalGraph +, AdjacencyGraph +, VertexListGraph +, MutableGraph +, PropertyGraph +, NamedGraph +, ComponentGraph +, PolymorphicGraph +, ReferenceGraph +, MutableReferenceGraph { //----------------------------------------------------------------- // Graph // type vertex_descriptor = number; nullVertex (): number { return 0xFFFFFFFF; } - // type edge_descriptor = impl.ED; - readonly directed_category: impl.directional = impl.directional.bidirectional; - readonly edge_parallel_category: impl.parallel = impl.parallel.allow; - readonly traversal_category: impl.traversal = impl.traversal.incidence - | impl.traversal.bidirectional - | impl.traversal.adjacency - | impl.traversal.vertex_list; + // type edge_descriptor = ED; + readonly directed_category: directional = directional.bidirectional; + readonly edge_parallel_category: parallel = parallel.allow; + readonly traversal_category: traversal = traversal.incidence + | traversal.bidirectional + | traversal.adjacency + | traversal.vertex_list; //----------------------------------------------------------------- // IncidenceGraph - // type out_edge_iterator = impl.OutEI; + // type out_edge_iterator = OutEI; // type degree_size_type = number; edge (u: number, v: number): boolean { for (const oe of this._vertices[u]._outEdges) { @@ -1286,23 +1344,23 @@ export class RenderGraph implements impl.BidirectionalGraph } return false; } - source (e: impl.ED): number { + source (e: ED): number { return e.source as number; } - target (e: impl.ED): number { + target (e: ED): number { return e.target as number; } - outEdges (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._outEdges.values(), v); + outEdges (v: number): OutEI { + return new OutEI(this._vertices[v]._outEdges.values(), v); } outDegree (v: number): number { return this._vertices[v]._outEdges.length; } //----------------------------------------------------------------- // BidirectionalGraph - // type in_edge_iterator = impl.InEI; - inEdges (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._inEdges.values(), v); + // type in_edge_iterator = InEI; + inEdges (v: number): InEI { + return new InEI(this._vertices[v]._inEdges.values(), v); } inDegree (v: number): number { return this._vertices[v]._inEdges.length; @@ -1312,9 +1370,9 @@ export class RenderGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // AdjacencyGraph - // type adjacency_iterator = impl.AdjI; - adjacentVertices (v: number): impl.AdjI { - return new impl.AdjI(this, this.outEdges(v)); + // type adjacency_iterator = AdjI; + adjacentVertices (v: number): AdjI { + return new AdjI(this, this.outEdges(v)); } //----------------------------------------------------------------- // VertexListGraph @@ -1325,6 +1383,15 @@ export class RenderGraph implements impl.BidirectionalGraph return this._vertices.length; } //----------------------------------------------------------------- + // EdgeListGraph + numEdges (): number { + let numEdges = 0; + for (const v of this.vertices()) { + numEdges += this.outDegree(v); + } + return numEdges; + } + //----------------------------------------------------------------- // MutableGraph clear (): void { // Members @@ -1356,8 +1423,8 @@ export class RenderGraph implements impl.BidirectionalGraph // ReferenceGraph if (u !== 0xFFFFFFFF) { - this._vertices[u]._children.push(new impl.OutE(v)); - vert._parents.push(new impl.OutE(u)); + this._vertices[u]._children.push(new OutE(v)); + vert._parents.push(new OutE(u)); } return v; @@ -1431,18 +1498,18 @@ export class RenderGraph implements impl.BidirectionalGraph for (let v = 0; v !== sz; ++v) { const vert = this._vertices[v]; - impl.reindexEdgeList(vert._outEdges, u); - impl.reindexEdgeList(vert._inEdges, u); + reindexEdgeList(vert._outEdges, u); + reindexEdgeList(vert._inEdges, u); // ReferenceGraph (Separated) - impl.reindexEdgeList(vert._children, u); - impl.reindexEdgeList(vert._parents, u); + reindexEdgeList(vert._children, u); + reindexEdgeList(vert._parents, u); } } - addEdge (u: number, v: number): impl.ED | null { + addEdge (u: number, v: number): ED | null { // update in/out edge list - this._vertices[u]._outEdges.push(new impl.OutE(v)); - this._vertices[v]._inEdges.push(new impl.OutE(u)); - return new impl.ED(u, v); + this._vertices[u]._outEdges.push(new OutE(v)); + this._vertices[v]._inEdges.push(new OutE(u)); + return new ED(u, v); } removeEdges (u: number, v: number): void { const source = this._vertices[u]; @@ -1464,7 +1531,7 @@ export class RenderGraph implements impl.BidirectionalGraph } } } - removeEdge (e: impl.ED): void { + removeEdge (e: ED): void { const u = e.source as number; const v = e.target as number; const source = this._vertices[u]; @@ -1544,6 +1611,9 @@ export class RenderGraph implements impl.BidirectionalGraph getName (v: number): string { return this._names[v]; } + setName (v: number, value: string) { + this._names[v] = value; + } getLayout (v: number): string { return this._layoutNodes[v]; } @@ -1785,9 +1855,9 @@ export class RenderGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // ReferenceGraph - // type reference_descriptor = impl.ED; - // type child_iterator = impl.OutEI; - // type parent_iterator = impl.InEI; + // type reference_descriptor = ED; + // type child_iterator = OutEI; + // type parent_iterator = InEI; reference (u: number, v: number): boolean { for (const oe of this._vertices[u]._children) { if (v === oe.target as number) { @@ -1796,17 +1866,17 @@ export class RenderGraph implements impl.BidirectionalGraph } return false; } - parent (e: impl.ED): number { + parent (e: ED): number { return e.source as number; } - child (e: impl.ED): number { + child (e: ED): number { return e.target as number; } - parents (v: number): impl.InEI { - return new impl.InEI(this._vertices[v]._parents.values(), v); + parents (v: number): InEI { + return new InEI(this._vertices[v]._parents.values(), v); } - children (v: number): impl.OutEI { - return new impl.OutEI(this._vertices[v]._children.values(), v); + children (v: number): OutEI { + return new OutEI(this._vertices[v]._children.values(), v); } numParents (v: number): number { return this._vertices[v]._parents.length; @@ -1849,13 +1919,13 @@ export class RenderGraph implements impl.BidirectionalGraph } //----------------------------------------------------------------- // MutableReferenceGraph - addReference (u: number, v: number): impl.ED | null { + addReference (u: number, v: number): ED | null { // update in/out edge list - this._vertices[u]._children.push(new impl.OutE(v)); - this._vertices[v]._parents.push(new impl.OutE(u)); - return new impl.ED(u, v); + this._vertices[u]._children.push(new OutE(v)); + this._vertices[v]._parents.push(new OutE(u)); + return new ED(u, v); } - removeReference (e: impl.ED): void { + removeReference (e: ED): void { const u = e.source as number; const v = e.target as number; const source = this._vertices[u]; diff --git a/cocos/rendering/custom/serialization.ts b/cocos/rendering/custom/serialization.ts new file mode 100644 index 00000000000..3fc092ed126 --- /dev/null +++ b/cocos/rendering/custom/serialization.ts @@ -0,0 +1,111 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { OutputArchive, InputArchive } from './archive'; +import { Color, DescriptorSetLayoutBinding, DescriptorSetLayoutInfo, Uniform, UniformBlock } from '../../gfx'; + +export function saveColor (ar: OutputArchive, v: Color) { + ar.writeNumber(v.x); + ar.writeNumber(v.y); + ar.writeNumber(v.z); + ar.writeNumber(v.w); +} + +export function loadColor (ar: InputArchive, v: Color) { + v.x = ar.readNumber(); + v.y = ar.readNumber(); + v.z = ar.readNumber(); + v.w = ar.readNumber(); +} + +export function saveUniform (ar: OutputArchive, v: Uniform) { + ar.writeString(v.name); + ar.writeNumber(v.type); + ar.writeNumber(v.count); +} + +export function loadUniform (ar: InputArchive, v: Uniform) { + v.name = ar.readString(); + v.type = ar.readNumber(); + v.count = ar.readNumber(); +} + +export function saveUniformBlock (ar: OutputArchive, v: UniformBlock) { + ar.writeNumber(v.set); + ar.writeNumber(v.binding); + ar.writeString(v.name); + ar.writeNumber(v.members.length); + for (const v1 of v.members) { + saveUniform(ar, v1); + } + ar.writeNumber(v.count); +} + +export function loadUniformBlock (ar: InputArchive, v: UniformBlock) { + v.set = ar.readNumber(); + v.binding = ar.readNumber(); + v.name = ar.readString(); + let sz = 0; + sz = ar.readNumber(); + v.members.length = sz; + for (let i = 0; i !== sz; ++i) { + const v1 = new Uniform(); + loadUniform(ar, v1); + v.members[i] = v1; + } + v.count = ar.readNumber(); +} + +export function saveDescriptorSetLayoutBinding (ar: OutputArchive, v: DescriptorSetLayoutBinding) { + ar.writeNumber(v.binding); + ar.writeNumber(v.descriptorType); + ar.writeNumber(v.count); + ar.writeNumber(v.stageFlags); + // skip immutableSamplers; +} + +export function loadDescriptorSetLayoutBinding (ar: InputArchive, v: DescriptorSetLayoutBinding) { + v.binding = ar.readNumber(); + v.descriptorType = ar.readNumber(); + v.count = ar.readNumber(); + v.stageFlags = ar.readNumber(); + // skip immutableSamplers; +} + +export function saveDescriptorSetLayoutInfo (ar: OutputArchive, v: DescriptorSetLayoutInfo) { + ar.writeNumber(v.bindings.length); + for (const v1 of v.bindings) { + saveDescriptorSetLayoutBinding(ar, v1); + } +} + +export function loadDescriptorSetLayoutInfo (ar: InputArchive, v: DescriptorSetLayoutInfo) { + const sz = ar.readNumber(); + v.bindings.length = sz; + for (let i = 0; i !== sz; ++i) { + const v1 = new DescriptorSetLayoutBinding(); + loadDescriptorSetLayoutBinding(ar, v1); + v.bindings[i] = v1; + } +} diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index 13c82c69167..56607505fae 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -31,6 +30,8 @@ /* eslint-disable max-len */ import { ClearFlagBit, Color, LoadOp, ShaderStageFlagBit, StoreOp, Type, UniformBlock } from '../../gfx'; import { Light } from '../../render-scene/scene'; +import { OutputArchive, InputArchive } from './archive'; +import { saveColor, loadColor, saveUniformBlock, loadUniformBlock } from './serialization'; export enum UpdateFrequency { PER_INSTANCE, @@ -196,6 +197,7 @@ export enum SceneFlags { PROFILER = 0x400, DRAW_INSTANCING = 0x800, DRAW_NON_INSTANCING = 0x1000, + REFLECTION_PROBE = 0x2000, ALL = 0xFFFFFFFF, } @@ -278,6 +280,7 @@ export class RasterView { storeOp: StoreOp; clearFlags: ClearFlagBit; readonly clearColor: Color; + slotID = 0; } export enum ClearValueType { @@ -297,11 +300,24 @@ export function getClearValueTypeName (e: ClearValueType): string { } export class ComputeView { - name = ''; - accessType: AccessType = AccessType.READ; - clearFlags: ClearFlagBit = ClearFlagBit.NONE; - readonly clearColor: Color = new Color(); - clearValueType: ClearValueType = ClearValueType.FLOAT_TYPE; + constructor ( + name = '', + accessType: AccessType = AccessType.READ, + clearFlags: ClearFlagBit = ClearFlagBit.NONE, + clearColor: Color = new Color(), + clearValueType: ClearValueType = ClearValueType.FLOAT_TYPE, + ) { + this.name = name; + this.accessType = accessType; + this.clearFlags = clearFlags; + this.clearColor = clearColor; + this.clearValueType = clearValueType; + } + name: string; + accessType: AccessType; + clearFlags: ClearFlagBit; + readonly clearColor: Color; + clearValueType: ClearValueType; } export class LightInfo { @@ -449,3 +465,249 @@ export class MovePair { targetFirstSlice: number; targetPlaneSlice: number; } + +export class PipelineStatistics { + numRenderPasses = 0; + numManagedTextures = 0; + totalManagedTextures = 0; + numUploadBuffers = 0; + numUploadBufferViews = 0; + numFreeUploadBuffers = 0; + numFreeUploadBufferViews = 0; + numDescriptorSets = 0; + numFreeDescriptorSets = 0; + numInstancingBuffers = 0; + numInstancingUniformBlocks = 0; +} + +export function saveRasterView (ar: OutputArchive, v: RasterView) { + ar.writeString(v.slotName); + ar.writeNumber(v.accessType); + ar.writeNumber(v.attachmentType); + ar.writeNumber(v.loadOp); + ar.writeNumber(v.storeOp); + ar.writeNumber(v.clearFlags); + saveColor(ar, v.clearColor); + ar.writeNumber(v.slotID); +} + +export function loadRasterView (ar: InputArchive, v: RasterView) { + v.slotName = ar.readString(); + v.accessType = ar.readNumber(); + v.attachmentType = ar.readNumber(); + v.loadOp = ar.readNumber(); + v.storeOp = ar.readNumber(); + v.clearFlags = ar.readNumber(); + loadColor(ar, v.clearColor); + v.slotID = ar.readNumber(); +} + +export function saveComputeView (ar: OutputArchive, v: ComputeView) { + ar.writeString(v.name); + ar.writeNumber(v.accessType); + ar.writeNumber(v.clearFlags); + saveColor(ar, v.clearColor); + ar.writeNumber(v.clearValueType); +} + +export function loadComputeView (ar: InputArchive, v: ComputeView) { + v.name = ar.readString(); + v.accessType = ar.readNumber(); + v.clearFlags = ar.readNumber(); + loadColor(ar, v.clearColor); + v.clearValueType = ar.readNumber(); +} + +export function saveLightInfo (ar: OutputArchive, v: LightInfo) { + // skip, v.light: Light + ar.writeNumber(v.level); +} + +export function loadLightInfo (ar: InputArchive, v: LightInfo) { + // skip, v.light: Light + v.level = ar.readNumber(); +} + +export function saveDescriptor (ar: OutputArchive, v: Descriptor) { + ar.writeNumber(v.type); + ar.writeNumber(v.count); +} + +export function loadDescriptor (ar: InputArchive, v: Descriptor) { + v.type = ar.readNumber(); + v.count = ar.readNumber(); +} + +export function saveDescriptorBlock (ar: OutputArchive, v: DescriptorBlock) { + ar.writeNumber(v.descriptors.size); // Map + for (const [k1, v1] of v.descriptors) { + ar.writeString(k1); + saveDescriptor(ar, v1); + } + ar.writeNumber(v.uniformBlocks.size); // Map + for (const [k1, v1] of v.uniformBlocks) { + ar.writeString(k1); + saveUniformBlock(ar, v1); + } + ar.writeNumber(v.capacity); + ar.writeNumber(v.count); +} + +export function loadDescriptorBlock (ar: InputArchive, v: DescriptorBlock) { + let sz = 0; + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = new Descriptor(); + loadDescriptor(ar, v1); + v.descriptors.set(k1, v1); + } + sz = ar.readNumber(); // Map + for (let i1 = 0; i1 !== sz; ++i1) { + const k1 = ar.readString(); + const v1 = new UniformBlock(); + loadUniformBlock(ar, v1); + v.uniformBlocks.set(k1, v1); + } + v.capacity = ar.readNumber(); + v.count = ar.readNumber(); +} + +export function saveDescriptorBlockFlattened (ar: OutputArchive, v: DescriptorBlockFlattened) { + ar.writeNumber(v.descriptorNames.length); // string[] + for (const v1 of v.descriptorNames) { + ar.writeString(v1); + } + ar.writeNumber(v.uniformBlockNames.length); // string[] + for (const v1 of v.uniformBlockNames) { + ar.writeString(v1); + } + ar.writeNumber(v.descriptors.length); // Descriptor[] + for (const v1 of v.descriptors) { + saveDescriptor(ar, v1); + } + ar.writeNumber(v.uniformBlocks.length); // UniformBlock[] + for (const v1 of v.uniformBlocks) { + saveUniformBlock(ar, v1); + } + ar.writeNumber(v.capacity); + ar.writeNumber(v.count); +} + +export function loadDescriptorBlockFlattened (ar: InputArchive, v: DescriptorBlockFlattened) { + let sz = 0; + sz = ar.readNumber(); // string[] + v.descriptorNames.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + v.descriptorNames[i1] = ar.readString(); + } + sz = ar.readNumber(); // string[] + v.uniformBlockNames.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + v.uniformBlockNames[i1] = ar.readString(); + } + sz = ar.readNumber(); // Descriptor[] + v.descriptors.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new Descriptor(); + loadDescriptor(ar, v1); + v.descriptors[i1] = v1; + } + sz = ar.readNumber(); // UniformBlock[] + v.uniformBlocks.length = sz; + for (let i1 = 0; i1 !== sz; ++i1) { + const v1 = new UniformBlock(); + loadUniformBlock(ar, v1); + v.uniformBlocks[i1] = v1; + } + v.capacity = ar.readNumber(); + v.count = ar.readNumber(); +} + +export function saveDescriptorBlockIndex (ar: OutputArchive, v: DescriptorBlockIndex) { + ar.writeNumber(v.updateFrequency); + ar.writeNumber(v.parameterType); + ar.writeNumber(v.descriptorType); + ar.writeNumber(v.visibility); +} + +export function loadDescriptorBlockIndex (ar: InputArchive, v: DescriptorBlockIndex) { + v.updateFrequency = ar.readNumber(); + v.parameterType = ar.readNumber(); + v.descriptorType = ar.readNumber(); + v.visibility = ar.readNumber(); +} + +export function saveCopyPair (ar: OutputArchive, v: CopyPair) { + ar.writeString(v.source); + ar.writeString(v.target); + ar.writeNumber(v.mipLevels); + ar.writeNumber(v.numSlices); + ar.writeNumber(v.sourceMostDetailedMip); + ar.writeNumber(v.sourceFirstSlice); + ar.writeNumber(v.sourcePlaneSlice); + ar.writeNumber(v.targetMostDetailedMip); + ar.writeNumber(v.targetFirstSlice); + ar.writeNumber(v.targetPlaneSlice); +} + +export function loadCopyPair (ar: InputArchive, v: CopyPair) { + v.source = ar.readString(); + v.target = ar.readString(); + v.mipLevels = ar.readNumber(); + v.numSlices = ar.readNumber(); + v.sourceMostDetailedMip = ar.readNumber(); + v.sourceFirstSlice = ar.readNumber(); + v.sourcePlaneSlice = ar.readNumber(); + v.targetMostDetailedMip = ar.readNumber(); + v.targetFirstSlice = ar.readNumber(); + v.targetPlaneSlice = ar.readNumber(); +} + +export function saveMovePair (ar: OutputArchive, v: MovePair) { + ar.writeString(v.source); + ar.writeString(v.target); + ar.writeNumber(v.mipLevels); + ar.writeNumber(v.numSlices); + ar.writeNumber(v.targetMostDetailedMip); + ar.writeNumber(v.targetFirstSlice); + ar.writeNumber(v.targetPlaneSlice); +} + +export function loadMovePair (ar: InputArchive, v: MovePair) { + v.source = ar.readString(); + v.target = ar.readString(); + v.mipLevels = ar.readNumber(); + v.numSlices = ar.readNumber(); + v.targetMostDetailedMip = ar.readNumber(); + v.targetFirstSlice = ar.readNumber(); + v.targetPlaneSlice = ar.readNumber(); +} + +export function savePipelineStatistics (ar: OutputArchive, v: PipelineStatistics) { + ar.writeNumber(v.numRenderPasses); + ar.writeNumber(v.numManagedTextures); + ar.writeNumber(v.totalManagedTextures); + ar.writeNumber(v.numUploadBuffers); + ar.writeNumber(v.numUploadBufferViews); + ar.writeNumber(v.numFreeUploadBuffers); + ar.writeNumber(v.numFreeUploadBufferViews); + ar.writeNumber(v.numDescriptorSets); + ar.writeNumber(v.numFreeDescriptorSets); + ar.writeNumber(v.numInstancingBuffers); + ar.writeNumber(v.numInstancingUniformBlocks); +} + +export function loadPipelineStatistics (ar: InputArchive, v: PipelineStatistics) { + v.numRenderPasses = ar.readNumber(); + v.numManagedTextures = ar.readNumber(); + v.totalManagedTextures = ar.readNumber(); + v.numUploadBuffers = ar.readNumber(); + v.numUploadBufferViews = ar.readNumber(); + v.numFreeUploadBuffers = ar.readNumber(); + v.numFreeUploadBufferViews = ar.readNumber(); + v.numDescriptorSets = ar.readNumber(); + v.numFreeDescriptorSets = ar.readNumber(); + v.numInstancingBuffers = ar.readNumber(); + v.numInstancingUniformBlocks = ar.readNumber(); +} diff --git a/cocos/rendering/custom/utils.ts b/cocos/rendering/custom/utils.ts index e69a067a154..5489f4a6028 100644 --- a/cocos/rendering/custom/utils.ts +++ b/cocos/rendering/custom/utils.ts @@ -1,6 +1,43 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + // https://stackoverflow.com/questions/56714318/how-to-disable-multiple-rules-for-eslint-nextline?msclkid=5d4c2298ba7911eca34d0ab30591752e -import { Type } from '../../gfx/base/define'; +import { Type } from '../../gfx'; +import { Camera } from '../../render-scene/scene/camera'; + +export function isUICamera (camera: Camera): boolean { + const scene = camera.scene!; + const batches = scene.batches; + for (let i = 0; i < batches.length; i++) { + const batch = batches[i]; + if (camera.visibility & batch.visFlags) { + return true; + } + } + return false; +} // eslint-disable-next-line @typescript-eslint/no-unused-vars export function replacer (key: unknown, value: unknown) { diff --git a/cocos/rendering/custom/web-descriptor-hierarchy.ts b/cocos/rendering/custom/web-descriptor-hierarchy.ts deleted file mode 100644 index 22848ea79ea..00000000000 --- a/cocos/rendering/custom/web-descriptor-hierarchy.ts +++ /dev/null @@ -1,691 +0,0 @@ -/* eslint-disable max-len */ -/**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. - - http://www.cocos.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -****************************************************************************/ - -import { EffectAsset } from '../../asset/assets'; -import { DescriptorDB, LayoutGraph, LayoutGraphValue, RenderPhase } from './layout-graph'; -import { ShaderStageFlagBit, Type, Uniform, UniformBlock } from '../../gfx'; -import { Descriptor, DescriptorBlock, DescriptorBlockIndex, DescriptorTypeOrder, ParameterType, UpdateFrequency } from './types'; -import { JOINT_UNIFORM_CAPACITY, RenderPassStage, SetIndex, UBOCamera, UBOCSM, UBOForwardLight, UBOGlobal, UBOLocal, UBOLocalBatched, UBOMorph, UBOShadow, UBOSkinning, UBOSkinningAnimation, UBOSkinningTexture, UBOUILocal, UBOWorldBound } from '../define'; -import { DefaultVisitor, edge_descriptor } from './graph'; -import { ccclass } from '../../core/data/decorators'; - -@ccclass('cc.WebDescriptorHierarchy') -export class WebDescriptorHierarchy { - public uniformBlockIndex: Map; - public blockMerged: Map>; - public dbsToMerge: Map; - - constructor () { - this._layoutGraph = new LayoutGraph(); - this.uniformBlockIndex = new Map(); - this.blockMerged = new Map>(); - this.dbsToMerge = new Map(); - } - - public getLayoutBlock (freq: UpdateFrequency, paraType: ParameterType, descType: DescriptorTypeOrder, vis: ShaderStageFlagBit, descriptorDB: DescriptorDB): DescriptorBlock { - const blockIndex: DescriptorBlockIndex = new DescriptorBlockIndex(freq, paraType, descType, vis); - const key = JSON.stringify(blockIndex); - if (descriptorDB.blocks.get(key) === undefined) { - const uniformBlock: DescriptorBlock = new DescriptorBlock(); - descriptorDB.blocks.set(key, uniformBlock); - - this.uniformBlockIndex.set(uniformBlock, blockIndex); - } - return descriptorDB.blocks.get(key) as DescriptorBlock; - } - - public getLayoutBlockByKey (key: string, descriptorDB: DescriptorDB): DescriptorBlock { - if (descriptorDB.blocks.get(key) === undefined) { - const uniformBlock: DescriptorBlock = new DescriptorBlock(); - descriptorDB.blocks.set(key, uniformBlock); - - const blockIndedx: DescriptorBlockIndex = JSON.parse(key) as DescriptorBlockIndex; - this.uniformBlockIndex.set(uniformBlock, blockIndedx); - } - return descriptorDB.blocks.get(key) as DescriptorBlock; - } - - public getUniformBlock (set: number, binding: number, blockName: string, targetBlock: DescriptorBlock): UniformBlock { - if (targetBlock.uniformBlocks.get(blockName) === undefined) { - const uniformDB: UniformBlock = new UniformBlock(set, binding, blockName, [], 1); - targetBlock.uniformBlocks.set(blockName, uniformDB); - } - return targetBlock.uniformBlocks.get(blockName) as UniformBlock; - } - - public setUniform (uniformDB: UniformBlock, name: string, type: Type, count: number) { - const uniform: Uniform = new Uniform(name, type, count); - uniformDB.members.push(uniform); - } - - public setDescriptor (targetBlock: DescriptorBlock, name: string, type: Type) { - const descriptor: Descriptor = new Descriptor(type); - targetBlock.descriptors.set(name, descriptor); - } - - public merge (descriptorDB: DescriptorDB) { - for (const entry of descriptorDB.blocks) { - const block: DescriptorBlock = entry[1]; - const typeMap: Map = new Map(); - for (const ee of block.descriptors) { - const descriptor: Descriptor = ee[1]; - const type: Type = descriptor.type; - if (typeMap.get(type) === undefined) { - typeMap.set(type, 1); - } else { - const before: number = typeMap.get(type) as number; - typeMap.set(type, before + 1); - } - block.capacity++; - } - for (const ii of typeMap) { - const type: Type = ii[0]; - const count: number = ii[1]; - if (count > 0) { - const mergedDescriptor: Descriptor = new Descriptor(type); - mergedDescriptor.count = count; - let merged: Map; - if (this.blockMerged.get(block) === undefined) { - merged = new Map(); - this.blockMerged.set(block, merged); - } - this.blockMerged.get(block)?.set(type, mergedDescriptor); - } - } - } - } - - public mergeDBs (descriptorDBs: DescriptorDB[], target: DescriptorDB) { - for (let i = 0; i < descriptorDBs.length; ++i) { - const db: DescriptorDB = descriptorDBs[i]; - for (const e of db.blocks) { - const key: string = e[0]; - const block: DescriptorBlock = e[1]; - - let merged: Map; - if (this.blockMerged.get(block) === undefined) { - merged = new Map(); - this.blockMerged.set(block, merged); - } else { - merged = this.blockMerged.get(block) as Map; - } - if (merged.size > 0) { - const targetBlock: DescriptorBlock = this.getLayoutBlockByKey(key, target); - let targetMerged: Map; - if (this.blockMerged.get(targetBlock) === undefined) { - targetMerged = new Map(); - this.blockMerged.set(targetBlock, targetMerged); - } else { - targetMerged = this.blockMerged.get(targetBlock) as Map; - } - for (const ee of merged) { - const type: Type = ee[0]; - const descriptor: Descriptor = ee[1]; - if (!targetMerged.has(type)) { - const ds: Descriptor = new Descriptor(descriptor.type); - ds.count = descriptor.count; - targetMerged.set(type, ds); - } else { - const ds: Descriptor | undefined = targetMerged.get(type); - if (ds !== undefined) { - ds.count = ds.count > descriptor.count ? ds.count : descriptor.count; - } - } - } - targetBlock.capacity = block.capacity > targetBlock.capacity ? block.capacity : targetBlock.capacity; - } - } - } - } - - public sort (descriptorDB: DescriptorDB) { - const sortedMap: Map = new Map(Array.from(descriptorDB.blocks).sort((a, b) => String(a[0]).localeCompare(b[0]))); - descriptorDB.blocks.clear(); - for (const e of sortedMap) { - descriptorDB.blocks.set(e[0], e[1]); - } - } - - public addEffect (asset: EffectAsset, parent: number): void { - const sz = asset.shaders.length; - - const dbsMap: Map = new Map(); - - for (let i = 0; i !== sz; ++i) { - const shader: EffectAsset.IShaderInfo = asset.shaders[i]; - - const queueDB: DescriptorDB = new DescriptorDB(); - - for (let k = 0; k < shader.blocks.length; ++k) { - const blockInfo: EffectAsset.IBlockInfo = shader.blocks[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_INSTANCE, - ParameterType.TABLE, DescriptorTypeOrder.UNIFORM_BUFFER, blockInfo.stageFlags, queueDB); - const uniformDB: UniformBlock = this.getUniformBlock(SetIndex.MATERIAL, blockInfo.binding, blockInfo.name, targetBlock); - for (let kk = 0; kk < blockInfo.members.length; ++kk) { - const uniform: Uniform = blockInfo.members[kk]; - uniformDB.members.push(uniform); - } - } - - for (let k = 0; k < shader.buffers.length; ++k) { - const bufferInfo: EffectAsset.IBufferInfo = shader.buffers[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.STORAGE_BUFFER, bufferInfo.stageFlags, queueDB); - this.setDescriptor(targetBlock, bufferInfo.name, Type.UNKNOWN); - } - - for (let k = 0; k < shader.images.length; ++k) { - const imageInfo: EffectAsset.IImageInfo = shader.images[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.STORAGE_IMAGE, imageInfo.stageFlags, queueDB); - this.setDescriptor(targetBlock, imageInfo.name, imageInfo.type); - } - - for (let k = 0; k < shader.samplerTextures.length; ++k) { - const samplerTexInfo: EffectAsset.ISamplerTextureInfo = shader.samplerTextures[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.SAMPLER_TEXTURE, samplerTexInfo.stageFlags, queueDB); - this.setDescriptor(targetBlock, samplerTexInfo.name, samplerTexInfo.type); - } - - for (let k = 0; k < shader.samplers.length; ++k) { - const samplerInfo: EffectAsset.ISamplerInfo = shader.samplers[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.SAMPLER, samplerInfo.stageFlags, queueDB); - this.setDescriptor(targetBlock, samplerInfo.name, Type.SAMPLER); - } - - for (let k = 0; k < shader.textures.length; ++k) { - const texInfo: EffectAsset.ITextureInfo = shader.textures[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.TEXTURE, texInfo.stageFlags, queueDB); - this.setDescriptor(targetBlock, texInfo.name, texInfo.type); - } - - for (let k = 0; k < shader.subpassInputs.length; ++k) { - const subpassInfo: EffectAsset.IInputAttachmentInfo = shader.subpassInputs[k]; - const targetBlock: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.INPUT_ATTACHMENT, subpassInfo.stageFlags, queueDB); - this.setDescriptor(targetBlock, subpassInfo.name, Type.SUBPASS_INPUT); - } - - // Add queue layout from define.ts - const localUniformTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_INSTANCE, - ParameterType.TABLE, DescriptorTypeOrder.UNIFORM_BUFFER, ShaderStageFlagBit.VERTEX, queueDB); - const localLightTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER, ShaderStageFlagBit.FRAGMENT, queueDB); - const localUITarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_INSTANCE, - ParameterType.TABLE, DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER, ShaderStageFlagBit.VERTEX, queueDB); - const localModelTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_INSTANCE, - ParameterType.TABLE, DescriptorTypeOrder.UNIFORM_BUFFER, ShaderStageFlagBit.VERTEX | ShaderStageFlagBit.COMPUTE, queueDB); - const localSamplerVertTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.SAMPLER_TEXTURE, ShaderStageFlagBit.VERTEX, queueDB); - const localSamplerFragTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.SAMPLER_TEXTURE, ShaderStageFlagBit.FRAGMENT, queueDB); - const localSamplerCompTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_BATCH, - ParameterType.TABLE, DescriptorTypeOrder.SAMPLER_TEXTURE, ShaderStageFlagBit.COMPUTE, queueDB); - - for (let k = 0; k < shader.builtins.locals.blocks.length; ++k) { - const blockName: string = shader.builtins.locals.blocks[k].name; - if (blockName === 'CCMorph') { - const morphDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOMorph.BINDING, 'CCMorph', localUniformTarget); - this.setUniform(morphDB, 'cc_displacementWeights', Type.FLOAT4, UBOMorph.MAX_MORPH_TARGET_COUNT / 4); - this.setUniform(morphDB, 'cc_displacementTextureInfo', Type.FLOAT4, 1); - } else if (blockName === 'CCSkinningTexture') { - const skinningTexDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOSkinningTexture.BINDING, 'CCSkinningTexture', localUniformTarget); - this.setUniform(skinningTexDB, 'cc_jointTextureInfo', Type.FLOAT4, 1); - } else if (blockName === 'CCSkinningAnimation') { - const skinningAnimDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOSkinningAnimation.BINDING, 'CCSkinningAnimation', localUniformTarget); - this.setUniform(skinningAnimDB, 'cc_jointAnimInfo', Type.FLOAT4, 1); - } else if (blockName === 'CCSkinning') { - const skinningDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOSkinning.BINDING, 'CCSkinning', localUniformTarget); - this.setUniform(skinningDB, 'cc_joints', Type.FLOAT4, JOINT_UNIFORM_CAPACITY * 3); - } else if (blockName === 'CCUILocal') { - const uiDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOUILocal.BINDING, 'CCUILocal', localUITarget); - this.setUniform(uiDB, 'cc_local_data', Type.FLOAT4, 1); - } else if (blockName === 'CCForwardLight') { - const lightDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOForwardLight.BINDING, 'CCForwardLight', localLightTarget); - this.setUniform(lightDB, 'cc_lightPos', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS); - this.setUniform(lightDB, 'cc_lightColor', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS); - this.setUniform(lightDB, 'cc_lightSizeRangeAngle', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS); - this.setUniform(lightDB, 'cc_lightDir', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS); - } else if (blockName === 'CCLocal') { - const localDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOLocal.BINDING, 'CCLocal', localModelTarget); - this.setUniform(localDB, 'cc_matWorld', Type.MAT4, 1); - this.setUniform(localDB, 'cc_matWorldIT', Type.MAT4, 1); - this.setUniform(localDB, 'cc_lightingMapUVParam', Type.FLOAT4, 1); - } else if (blockName === 'CCLocalBatched') { - const batchDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOLocalBatched.BINDING, 'CCLocalBatched', localModelTarget); - this.setUniform(batchDB, 'cc_matWorlds', Type.MAT4, UBOLocalBatched.BATCHING_COUNT); - } else if (blockName === 'CCWorldBound') { - const boundDB: UniformBlock = this.getUniformBlock(SetIndex.LOCAL, UBOWorldBound.BINDING, 'CCWorldBound', localModelTarget); - this.setUniform(boundDB, 'cc_worldBoundCenter', Type.FLOAT4, 1); - this.setUniform(boundDB, 'cc_worldBoundHalfExtents', Type.FLOAT4, 1); - } - } - - for (let k = 0; k < shader.builtins.locals.samplerTextures.length; ++k) { - const samplerName: string = shader.builtins.locals.samplerTextures[k].name; - if (samplerName === 'cc_jointTexture') { - this.setDescriptor(localSamplerVertTarget, 'cc_jointTexture', Type.SAMPLER2D); - } else if (samplerName === 'cc_PositionDisplacements') { - this.setDescriptor(localSamplerVertTarget, 'cc_PositionDisplacements', Type.SAMPLER2D); - } else if (samplerName === 'cc_realtimeJoint') { - this.setDescriptor(localSamplerVertTarget, 'cc_realtimeJoint', Type.SAMPLER2D); - } else if (samplerName === 'cc_NormalDisplacements') { - this.setDescriptor(localSamplerVertTarget, 'cc_NormalDisplacements', Type.SAMPLER2D); - } else if (samplerName === 'cc_TangentDisplacements') { - this.setDescriptor(localSamplerVertTarget, 'cc_TangentDisplacements', Type.SAMPLER2D); - } else if (samplerName === 'cc_lightingMap') { - this.setDescriptor(localSamplerFragTarget, 'cc_lightingMap', Type.SAMPLER2D); - } else if (samplerName === 'cc_spriteTexture') { - this.setDescriptor(localSamplerFragTarget, 'cc_spriteTexture', Type.SAMPLER2D); - } else if (samplerName === 'cc_reflectionTexture') { - this.setDescriptor(localSamplerFragTarget, 'cc_reflectionTexture', Type.SAMPLER2D); - } - } - - for (let k = 0; k < shader.builtins.locals.images.length; ++k) { - const imgName: string = shader.builtins.locals.images[k].name; - if (imgName === 'cc_reflectionStorage') { - this.setDescriptor(localSamplerCompTarget, 'cc_reflectionStorage', Type.IMAGE2D); - } - } - - dbsMap.set(shader.name, queueDB); - - this.merge(queueDB); - this.sort(queueDB); - - const parentDB: DescriptorDB = this._layoutGraph.getDescriptors(parent); - if (this.dbsToMerge.get(parentDB) === undefined) { - this.dbsToMerge.set(parentDB, []); - } - this.dbsToMerge.get(parentDB)?.push(queueDB); - } - - const pName = this._layoutGraph.getName(parent); - - for (let i = 0; i < asset.techniques.length; ++i) { - const tech = asset.techniques[i]; - for (let j = 0; j < tech.passes.length; ++j) { - const pass = tech.passes[j]; - const passPhase = pass.phase; - let phase = ''; - if (passPhase === undefined) { - phase = `${pName}_`; - } else if (typeof passPhase === 'number') { - phase = passPhase.toString(); - } else { - phase = passPhase; - } - const db2add = dbsMap.get(pass.program); - if (db2add) { - const v2add = this._layoutGraph.locate(`/${pName}/${phase}`); - if (v2add === 0xFFFFFFFF) { - const v = this.addRenderPhase(phase, parent); - const dbStored = this._layoutGraph.getDescriptors(v); - for (const ee of db2add.blocks) { - const blockIndex = ee[0]; - const block = ee[1]; - const b2add = new DescriptorBlock(); - for (const dd of block.descriptors) { - b2add.descriptors.set(dd[0], dd[1]); - b2add.count++; - b2add.capacity++; - } - for (const uu of block.uniformBlocks) { - b2add.uniformBlocks.set(uu[0], uu[1]); - b2add.count++; - b2add.capacity++; - } - if (b2add.capacity > 0 || b2add.count > 0) { - dbStored.blocks.set(blockIndex, b2add); - } - } - } else { - const dbStored = this._layoutGraph.getDescriptors(v2add); - for (const ee of db2add.blocks) { - const blockIndex = ee[0]; - const block = ee[1]; - const blockStored = dbStored.blocks.get(blockIndex); - if (blockStored === undefined) { - const b2add = new DescriptorBlock(); - for (const dd of block.descriptors) { - b2add.descriptors.set(dd[0], dd[1]); - b2add.count++; - b2add.capacity++; - } - for (const uu of block.uniformBlocks) { - b2add.uniformBlocks.set(uu[0], uu[1]); - b2add.count++; - b2add.capacity++; - } - if (b2add.capacity > 0 || b2add.count > 0) { - dbStored.blocks.set(blockIndex, b2add); - } - } else { - const index = JSON.parse(blockIndex) as DescriptorBlockIndex; - if (index.descriptorType !== DescriptorTypeOrder.UNIFORM_BUFFER && index.descriptorType !== DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER) { - if (index.updateFrequency <= UpdateFrequency.PER_BATCH) { - let capacityToAdd = 0; - for (const dd of block.descriptors) { - capacityToAdd++; - } - if (capacityToAdd > blockStored.capacity) { - blockStored.capacity = capacityToAdd; - blockStored.count = capacityToAdd; - } - - let capacityStored = 0; - for (const dd of blockStored.descriptors) { - capacityStored++; - } - for (const dd of block.descriptors) { - if (blockStored.descriptors.get(dd[0]) === undefined /*&& capacityStored < capacityToAdd*/) { - blockStored.descriptors.set(dd[0], dd[1]); - capacityStored++; - } - } - } else { - for (const dd of block.descriptors) { - if (blockStored.descriptors.get(dd[0]) === undefined) { - blockStored.descriptors.set(dd[0], dd[1]); - blockStored.count++; - blockStored.capacity++; - } - } - } - } else if (index.descriptorType === DescriptorTypeOrder.UNIFORM_BUFFER || index.descriptorType === DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER) { - if (index.updateFrequency <= UpdateFrequency.PER_BATCH) { - let capacityToAdd = 0; - for (const uu of block.uniformBlocks) { - capacityToAdd++; - } - if (capacityToAdd > blockStored.capacity) { - blockStored.capacity = capacityToAdd; - blockStored.count = capacityToAdd; - } - - let capacityStored = 0; - for (const dd of blockStored.uniformBlocks) { - capacityStored++; - } - for (const uu of block.uniformBlocks) { - if (blockStored.uniformBlocks.get(uu[0]) === undefined /*&& capacityStored < capacityToAdd*/) { - blockStored.uniformBlocks.set(uu[0], uu[1]); - capacityStored++; - } - } - } else { - for (const uu of block.uniformBlocks) { - if (blockStored.uniformBlocks.get(uu[0]) === undefined) { - blockStored.uniformBlocks.set(uu[0], uu[1]); - blockStored.count++; - blockStored.capacity++; - } - } - } - } - } - } - } - } - } - } - } - - public addGlobal (vName: string, hasCCGlobal, hasCCCamera, hasCCShadow, hasCCCSM, hasShadowmap, hasEnv, hasDiffuse, hasSpot): number { - const passDB: DescriptorDB = new DescriptorDB(); - // Add pass layout from define.ts - const globalUniformTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, DescriptorTypeOrder.UNIFORM_BUFFER, ShaderStageFlagBit.ALL, passDB); - const globalSamplerTexTarget: DescriptorBlock = this.getLayoutBlock(UpdateFrequency.PER_PASS, - ParameterType.TABLE, DescriptorTypeOrder.SAMPLER_TEXTURE, ShaderStageFlagBit.FRAGMENT, passDB); - - if (hasCCGlobal) { - const globalDB: UniformBlock = this.getUniformBlock(SetIndex.GLOBAL, - UBOGlobal.BINDING, 'CCGlobal', globalUniformTarget); - this.setUniform(globalDB, 'cc_time', Type.FLOAT4, 1); - this.setUniform(globalDB, 'cc_screenSize', Type.FLOAT4, 1); - this.setUniform(globalDB, 'cc_nativeSize', Type.FLOAT4, 1); - this.setUniform(globalDB, 'cc_debug_view_mode', Type.FLOAT, 4); - this.setUniform(globalDB, 'cc_debug_view_composite_pack_1', Type.FLOAT, 4); - this.setUniform(globalDB, 'cc_debug_view_composite_pack_2', Type.FLOAT, 4); - this.setUniform(globalDB, 'cc_debug_view_composite_pack_3', Type.FLOAT, 4); - this.setDescriptor(globalUniformTarget, 'CCGlobal', Type.UNKNOWN); - } - - if (hasCCCamera) { - const cameraDB: UniformBlock = this.getUniformBlock(SetIndex.GLOBAL, - UBOCamera.BINDING, 'CCCamera', globalUniformTarget); - this.setUniform(cameraDB, 'cc_matView', Type.MAT4, 1); - this.setUniform(cameraDB, 'cc_matViewInv', Type.MAT4, 1); - this.setUniform(cameraDB, 'cc_matProj', Type.MAT4, 1); - this.setUniform(cameraDB, 'cc_matProjInv', Type.MAT4, 1); - this.setUniform(cameraDB, 'cc_matViewProj', Type.MAT4, 1); - this.setUniform(cameraDB, 'cc_matViewProjInv', Type.MAT4, 1); - this.setUniform(cameraDB, 'cc_cameraPos', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_surfaceTransform', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_screenScale', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_exposure', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_mainLitDir', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_mainLitColor', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_ambientSky', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_ambientGround', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_fogColor', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_fogBase', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_fogAdd', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_nearFar', Type.FLOAT4, 1); - this.setUniform(cameraDB, 'cc_viewPort', Type.FLOAT4, 1); - - this.setDescriptor(globalUniformTarget, 'CCCamera', Type.UNKNOWN); - } - - if (hasCCShadow) { - const shadowDB: UniformBlock = this.getUniformBlock(SetIndex.GLOBAL, - UBOShadow.BINDING, 'CCShadow', globalUniformTarget); - this.setUniform(shadowDB, 'cc_matLightView', Type.MAT4, 1); - this.setUniform(shadowDB, 'cc_matLightViewProj', Type.MAT4, 1); - this.setUniform(shadowDB, 'cc_shadowInvProjDepthInfo', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_shadowProjDepthInfo', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_shadowProjInfo', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_shadowNFLSInfo', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_shadowWHPBInfo', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_shadowLPNNInfo', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_shadowColor', Type.FLOAT4, 1); - this.setUniform(shadowDB, 'cc_planarNDInfo', Type.FLOAT4, 1); - - this.setDescriptor(globalUniformTarget, 'CCShadow', Type.UNKNOWN); - } - - if (hasCCCSM) { - const csmDB: UniformBlock = this.getUniformBlock(SetIndex.GLOBAL, - UBOCSM.BINDING, 'CCCSM', globalUniformTarget); - this.setUniform(csmDB, 'cc_csmViewDir0', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_csmViewDir1', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_csmViewDir2', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_csmAtlas', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_matCSMViewProj', Type.MAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_csmProjDepthInfo', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_csmProjInfo', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT); - this.setUniform(csmDB, 'cc_csmSplitsInfo', Type.FLOAT4, 1); - - this.setDescriptor(globalUniformTarget, 'CCCSM', Type.UNKNOWN); - } - - if (hasShadowmap) { - this.setDescriptor(globalSamplerTexTarget, 'cc_shadowMap', Type.SAMPLER2D); - } - if (hasEnv) { - this.setDescriptor(globalSamplerTexTarget, 'cc_environment', Type.SAMPLER_CUBE); - } - if (hasSpot) { - this.setDescriptor(globalSamplerTexTarget, 'cc_spotShadowMap', Type.SAMPLER2D); - } - if (hasDiffuse) { - this.setDescriptor(globalSamplerTexTarget, 'cc_diffuseMap', Type.SAMPLER_CUBE); - } - - this.merge(passDB); - this.sort(passDB); - - const vid = this._layoutGraph.addVertex( - LayoutGraphValue.RenderStage, RenderPassStage.DEFAULT, vName, passDB, - ); - - return vid; - } - - public mergeDescriptors (vid: number) { - const target: DescriptorDB = this._layoutGraph.getDescriptors(vid); - const toMerge = this.dbsToMerge.get(target); - if (toMerge !== undefined) { - this.mergeDBs(toMerge, target); - this.sort(target); - } - } - - public addRenderStage (name: string, stageID: number): number { - const passDB: DescriptorDB = new DescriptorDB(); - return this._layoutGraph.addVertex(LayoutGraphValue.RenderStage, - stageID, name, passDB); - } - - public addRenderPhase (name: string, parentStageID: number): number { - const passDB: DescriptorDB = new DescriptorDB(); - return this._layoutGraph.addVertex(LayoutGraphValue.RenderPhase, - new RenderPhase(), name, passDB, parentStageID); - } - - public _layoutGraph: LayoutGraph; - - public get layoutGraph () { - return this._layoutGraph; - } -} - -function getNumDescriptors (block: DescriptorBlock): number { - let count = 0; - for (const [, d] of block.descriptors) { - count += d.count; - } - return count; -} - -function checkDescriptorConsistency (lhs: Descriptor, rhs: Descriptor): boolean { - if (lhs.type !== rhs.type) { - return false; - } - if (lhs.count !== rhs.count) { - return false; - } - return true; -} - -export class CollectVisitor extends DefaultVisitor { - getFrequency (g: LayoutGraph, v: number): UpdateFrequency { - let freq: UpdateFrequency; - if (g.holds(LayoutGraphValue.RenderStage, v)) { - freq = UpdateFrequency.PER_PASS; - } else { - freq = UpdateFrequency.PER_PHASE; - } - return freq; - } - - mergeDescriptors (srcBlock: DescriptorBlock, dstBlock: DescriptorBlock): string { - for (const [name, src] of srcBlock.descriptors) { - const dst = dstBlock.descriptors.get(name); - if (dst !== undefined) { - if (!checkDescriptorConsistency(src, dst)) { - return `Descriptor ${name} is inconsistent`; - } - } else { - dstBlock.descriptors.set(name, src); - } - } - return ''; - } - - mergeParent (freq: UpdateFrequency, src: DescriptorDB, dst: DescriptorDB): string { - for (const [key, srcBlock] of src.blocks) { - let dstBlock = dst.blocks.get(key); - if (dstBlock === undefined) { - dstBlock = new DescriptorBlock(); - dst.blocks.set(key, dstBlock); - } - const index = JSON.parse(key) as DescriptorBlockIndex; - if (index.updateFrequency > freq) { - const error = this.mergeDescriptors(srcBlock, dstBlock); - if (error) { - return error; - } - } - } - return ''; - } - - updateInfo (freq: UpdateFrequency, db: DescriptorDB) { - db.blocks.forEach((block: DescriptorBlock, key: string) => { - const index = JSON.parse(key) as DescriptorBlockIndex; - if (index.updateFrequency >= freq) { - block.count = getNumDescriptors(block); - block.capacity = block.count; - } - }); - } - - backEdge (e: edge_descriptor, g: LayoutGraph): void { - this._error = 'Cycle detected in graph'; - } - - finishEdge (e: edge_descriptor, g: LayoutGraph): void { - if (this._error !== '') { - return; - } - const parentID = g.source(e); - const v = g.target(e); - const dst = g.getDescriptors(parentID); - const src = g.getDescriptors(v); - const freq = this.getFrequency(g, v); - this.mergeParent(freq, src, dst); - } - - finishVertex (v: number, g: LayoutGraph): void { - if (this._error !== '') { - return; - } - const freq = this.getFrequency(g, v); - const db = g.getDescriptors(v); - this.updateInfo(freq, db); - } - - get error (): string { - return this._error; - } - private _error = ''; -} diff --git a/cocos/rendering/custom/web-layout-exporter.ts b/cocos/rendering/custom/web-layout-exporter.ts new file mode 100644 index 00000000000..28d825631fb --- /dev/null +++ b/cocos/rendering/custom/web-layout-exporter.ts @@ -0,0 +1,362 @@ +/* eslint-disable @typescript-eslint/restrict-plus-operands */ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + +import { EffectAsset } from '../../asset/assets'; +import { ShaderStageFlagBit } from '../../gfx'; +import { EffectData, ShaderBindingData, ShaderLayoutData, TechniqueData } from './layout-graph'; +import { DescriptorTypeOrder, UpdateFrequency } from './types'; + +const isArr = (origin: any): boolean => { + const str = '[object Array]'; + return Object.prototype.toString.call(origin) === str; +}; + +const deepClone = (origin: T, target?: Record | T): T => { + const tar = target || {}; + + for (const key in origin) { + if (Object.prototype.hasOwnProperty.call(origin, key)) { + if (typeof origin[key] === 'object' && origin[key] !== null) { + tar[key] = isArr(origin[key]) ? [] : {}; + deepClone(origin[key], tar[key]); + } else { + tar[key] = origin[key]; + } + } + } + + return tar as T; +}; + +export class WebLayoutExporter { + private layoutGraph; + + constructor (graph) { + this.layoutGraph = graph; + } + + private addBinding (storedMap: Map, freq: UpdateFrequency, flag: ShaderStageFlagBit, type: DescriptorTypeOrder) { + const key = `${freq.toString()}|${flag.toString()}|${type.toString()}`; + let stored = storedMap.get(key); + if (stored === undefined) { + storedMap.set(key, 0); + stored = storedMap.get(key); + } else { + stored += 1; + storedMap.set(key, stored); + } + return stored; + } + + private setBinding (bindingData: ShaderBindingData, name: string, binding: number | undefined) { + const shaderKey = this.layoutGraph.data.attributeIndex.get(name); + if (shaderKey && binding !== undefined) { + bindingData.descriptorBindings.set(shaderKey, binding); + } + } + + public exportEffect (effect: EffectAsset) { + let parent = ''; + if (effect.name.indexOf('bloom') !== -1 + || effect.name.indexOf('post-process') !== -1 + || effect.name.indexOf('smaa') !== -1 + || effect.name.indexOf('toonmap') !== -1) { + parent = 'post'; + } else if (effect.name.indexOf('deferred') !== -1) { + parent = 'deferred'; + } else { + parent = 'default'; + } + + let effectData: EffectData | undefined = this.layoutGraph.data.effects.get(effect.name); + if (effectData === undefined) { + effectData = new EffectData(); + this.layoutGraph.data.effects.set(effect.name, effectData); + } + + for (let i = 0; i < effect.techniques.length; ++i) { + const tech = effect.techniques[i]; + const techName = tech.name ? tech.name : i.toString(); + + let techData: TechniqueData | undefined = effectData.techniques.get(techName); + if (techData === undefined) { + techData = new TechniqueData(); + effectData.techniques.set(techName, techData); + } + + techData.passes.splice(0, techData.passes.length); + for (let j = 0; j < tech.passes.length; ++j) { + const shaderData: ShaderLayoutData = new ShaderLayoutData(); + techData.passes.push(shaderData); + + const pass = tech.passes[j]; + const passPhase = pass.phase; + let phaseName = ''; + if (passPhase) { + phaseName = passPhase.toString(); + } else { + phaseName = `${parent}_`; + } + const shaderName = pass.program; + let passShader; + for (let s = 0; s < effect.shaders.length; ++s) { + const shader = effect.shaders[s]; + const name = shader.name; + if (name === shaderName) { + passShader = {}; + deepClone(shader, passShader); + break; + } + } + if (passShader) { + pass.shader = passShader; + const shader = pass.shader; + if (shader === undefined) { + continue; + } + const storedMap = new Map(); + + const vid = this.layoutGraph.data.locate(`/${parent}/${phaseName}`); + const layout = this.layoutGraph.data.getLayout(vid); + const dss = layout.descriptorSets.get(UpdateFrequency.PER_BATCH); + + if (dss) { + const dsData = dss.descriptorSetLayoutData.descriptorBlocks; + + const bindingData = new ShaderBindingData(); + shaderData.layoutData.set(UpdateFrequency.PER_BATCH, dss.descriptorSetLayoutData); + shaderData.bindingData.set(UpdateFrequency.PER_BATCH, bindingData); + + for (let t = 0; t < shader.samplerTextures.length; ++t) { + const samplerTexInfo: EffectAsset.ISamplerTextureInfo = shader.samplerTextures[t]; + const flag = samplerTexInfo.stageFlags; + const type = DescriptorTypeOrder.SAMPLER_TEXTURE; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + samplerTexInfo.binding = ds.offset + stored; + } else { + samplerTexInfo.binding = ds.offset; + } + + this.setBinding(bindingData, samplerTexInfo.name, samplerTexInfo.binding); + break; + } + } + } + + for (let s = 0; s < shader.samplers.length; ++s) { + const samplerInfo: EffectAsset.ISamplerInfo = shader.samplers[s]; + const flag = samplerInfo.stageFlags; + const type = DescriptorTypeOrder.SAMPLER; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + samplerInfo.binding = ds.offset + stored; + } else { + samplerInfo.binding = ds.offset; + } + + this.setBinding(bindingData, samplerInfo.name, samplerInfo.binding); + break; + } + } + } + + for (let t = 0; t < shader.textures.length; ++t) { + const texInfo: EffectAsset.ITextureInfo = shader.textures[t]; + const flag = texInfo.stageFlags; + const type = DescriptorTypeOrder.TEXTURE; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + texInfo.binding = ds.offset + stored; + } else { + texInfo.binding = ds.offset; + } + + this.setBinding(bindingData, texInfo.name, texInfo.binding); + break; + } + } + } + + for (let b = 0; b < shader.buffers.length; ++b) { + const bufferInfo: EffectAsset.IBufferInfo = shader.buffers[b]; + const flag = bufferInfo.stageFlags; + const type = DescriptorTypeOrder.STORAGE_BUFFER; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + bufferInfo.binding = ds.offset + stored; + } else { + bufferInfo.binding = ds.offset; + } + + this.setBinding(bindingData, bufferInfo.name, bufferInfo.binding); + break; + } + } + } + + for (let m = 0; m < shader.images.length; +m) { + const imageInfo: EffectAsset.IImageInfo = shader.images[m]; + const flag = imageInfo.stageFlags; + const type = DescriptorTypeOrder.STORAGE_IMAGE; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + imageInfo.binding = ds.offset + stored; + } else { + imageInfo.binding = ds.offset; + } + + this.setBinding(bindingData, imageInfo.name, imageInfo.binding); + break; + } + } + } + + for (let si = 0; si < shader.subpassInputs.length; ++si) { + const subpassInfo: EffectAsset.IInputAttachmentInfo = shader.subpassInputs[si]; + const flag = subpassInfo.stageFlags; + const type = DescriptorTypeOrder.INPUT_ATTACHMENT; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + subpassInfo.binding = ds.offset + stored; + } else { + subpassInfo.binding = ds.offset; + } + + this.setBinding(bindingData, subpassInfo.name, subpassInfo.binding); + break; + } + } + } + + // builtin + for (let k = 0; k < shader.builtins.locals.samplerTextures.length; ++k) { + const descriptor = shader.builtins.locals.samplerTextures[k]; + const type = DescriptorTypeOrder.SAMPLER_TEXTURE; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + let flag = ShaderStageFlagBit.VERTEX; + if ((descriptor.name === 'cc_jointTexture' || descriptor.name === 'cc_PositionDisplacements' + || descriptor.name === 'cc_realtimeJoint' || descriptor.name === 'cc_NormalDisplacements' + || descriptor.name === 'cc_TangentDisplacements')) { + flag = ShaderStageFlagBit.VERTEX; + } else { + flag = ShaderStageFlagBit.FRAGMENT; + } + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + descriptor.binding = ds.offset + stored; + } else { + descriptor.binding = ds.offset; + } + + this.setBinding(bindingData, descriptor.name, descriptor.binding); + } + } + } + + for (let k = 0; k < shader.builtins.locals.images.length; ++k) { + const descriptor = shader.builtins.locals.images[k]; + const flag = ShaderStageFlagBit.COMPUTE; + const type = DescriptorTypeOrder.SAMPLER_TEXTURE; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_BATCH, flag, type); + + if (stored !== undefined) { + descriptor.binding = ds.offset + stored; + } else { + descriptor.binding = ds.offset; + } + + this.setBinding(bindingData, descriptor.name, descriptor.binding); + } + } + } + } + + const pid = this.layoutGraph.data.locate(`/${parent}`); + const pLayout = this.layoutGraph.data.getLayout(pid); + const pss = pLayout.descriptorSets.get(UpdateFrequency.PER_PASS); + + if (pss) { + const dsData = pss.descriptorSetLayoutData.descriptorBlocks; + + const bindingData = new ShaderBindingData(); + shaderData.layoutData.set(UpdateFrequency.PER_PASS, pss.descriptorSetLayoutData); + shaderData.bindingData.set(UpdateFrequency.PER_PASS, bindingData); + + for (let g = 0; g < shader.builtins.globals.samplerTextures.length; ++g) { + const descriptor = shader.builtins.globals.samplerTextures[g]; + const flag = ShaderStageFlagBit.FRAGMENT; + const type = DescriptorTypeOrder.SAMPLER_TEXTURE; + for (let d = 0; d < dsData.length; ++d) { + const ds = dsData[d]; + if (ds.visibility === flag && ds.type === type) { + const stored = this.addBinding(storedMap, UpdateFrequency.PER_PASS, flag, type); + + if (stored !== undefined) { + descriptor.binding = ds.offset + stored; + } else { + descriptor.binding = ds.offset; + } + + this.setBinding(bindingData, descriptor.name, descriptor.binding); + } + } + } + } + } + } + } + } +} diff --git a/cocos/rendering/custom/web-layout-graph.ts b/cocos/rendering/custom/web-layout-graph.ts deleted file mode 100644 index abc2f89e72b..00000000000 --- a/cocos/rendering/custom/web-layout-graph.ts +++ /dev/null @@ -1,758 +0,0 @@ -import { DEBUG } from 'internal:constants'; -import { EffectAsset } from '../../asset/assets'; -import { ccclass } from '../../core/data/decorators'; -// eslint-disable-next-line max-len -import { DescriptorSetInfo, DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorSetLayoutInfo, DescriptorType, DESCRIPTOR_BUFFER_TYPE, Device, ShaderStageFlagBit, Type, UniformBlock } from '../../gfx'; -import { VectorGraphColorMap } from './effect'; -import { DefaultVisitor, depthFirstSearch } from './graph'; -// eslint-disable-next-line max-len -import { LayoutGraphData, PipelineLayoutData, LayoutGraphDataValue, RenderStageData, RenderPhaseData, DescriptorSetLayoutData, DescriptorSetData, DescriptorBlockData, DescriptorData } from './layout-graph'; -import { LayoutGraphBuilder } from './pipeline'; -import { getUpdateFrequencyName, DescriptorBlockIndex, DescriptorTypeOrder, - Descriptor, getDescriptorTypeOrderName, DescriptorBlockFlattened, UpdateFrequency } from './types'; - -const isArr = (origin: any): boolean => { - const str = '[object Array]'; - return Object.prototype.toString.call(origin) === str; -}; - -const deepClone = (origin: T, target?: Record | T): T => { - const tar = target || {}; - - for (const key in origin) { - if (Object.prototype.hasOwnProperty.call(origin, key)) { - if (typeof origin[key] === 'object' && origin[key] !== null) { - tar[key] = isArr(origin[key]) ? [] : {}; - deepClone(origin[key], tar[key]); - } else { - tar[key] = origin[key]; - } - } - } - - return tar as T; -}; - -function getName (type: Type): string { - switch (type) { - case Type.UNKNOWN: return 'Unknown'; - case Type.BOOL: return 'Bool'; - case Type.BOOL2: return 'Bool2'; - case Type.BOOL3: return 'Bool3'; - case Type.BOOL4: return 'Bool4'; - case Type.INT: return 'Int'; - case Type.INT2: return 'Int2'; - case Type.INT3: return 'Int3'; - case Type.INT4: return 'Int4'; - case Type.UINT: return 'Uint'; - case Type.UINT2: return 'Uint2'; - case Type.UINT3: return 'Uint3'; - case Type.UINT4: return 'Uint4'; - case Type.FLOAT: return 'Float'; - case Type.FLOAT2: return 'Float2'; - case Type.FLOAT3: return 'Float3'; - case Type.FLOAT4: return 'Float4'; - case Type.MAT2: return 'Mat2'; - case Type.MAT2X3: return 'Mat2x3'; - case Type.MAT2X4: return 'Mat2x4'; - case Type.MAT3X2: return 'Mat3x2'; - case Type.MAT3: return 'Mat3'; - case Type.MAT3X4: return 'Mat3x4'; - case Type.MAT4X2: return 'Mat4x2'; - case Type.MAT4X3: return 'Mat4x3'; - case Type.MAT4: return 'Mat4'; - case Type.SAMPLER1D: return 'Sampler1D'; - case Type.SAMPLER1D_ARRAY: return 'Sampler1DArray'; - case Type.SAMPLER2D: return 'Sampler2D'; - case Type.SAMPLER2D_ARRAY: return 'Sampler2DArray'; - case Type.SAMPLER3D: return 'Sampler3D'; - case Type.SAMPLER_CUBE: return 'SamplerCube'; - case Type.SAMPLER: return 'Sampler'; - case Type.TEXTURE1D: return 'Texture1D'; - case Type.TEXTURE1D_ARRAY: return 'Texture1DArray'; - case Type.TEXTURE2D: return 'Texture2D'; - case Type.TEXTURE2D_ARRAY: return 'Texture2DArray'; - case Type.TEXTURE3D: return 'Texture3D'; - case Type.TEXTURE_CUBE: return 'TextureCube'; - case Type.IMAGE1D: return 'Image1D'; - case Type.IMAGE1D_ARRAY: return 'Image1DArray'; - case Type.IMAGE2D: return 'Image2D'; - case Type.IMAGE2D_ARRAY: return 'Image2DArray'; - case Type.IMAGE3D: return 'Image3D'; - case Type.IMAGE_CUBE: return 'ImageCube'; - case Type.SUBPASS_INPUT: return 'SubpassInput'; - case Type.COUNT: return 'Count'; - default: return 'Unknown'; - } -} - -function hasFlag (flags: ShaderStageFlagBit, flagToTest: ShaderStageFlagBit): boolean { - return (flags & flagToTest) !== 0; -} - -function getVisibilityName (stage: ShaderStageFlagBit): string { - let count = 0; - let str = ''; - if (hasFlag(stage, ShaderStageFlagBit.VERTEX)) { - if (count++) { - str += ' | '; - } - str += 'Vertex'; - } - if (hasFlag(stage, ShaderStageFlagBit.CONTROL)) { - if (count++) { - str += ' | '; - } - str += 'Control'; - } - if (hasFlag(stage, ShaderStageFlagBit.EVALUATION)) { - if (count++) { - str += ' | '; - } - str += 'Evaluation'; - } - if (hasFlag(stage, ShaderStageFlagBit.GEOMETRY)) { - if (count++) { - str += ' | '; - } - str += 'Geometry'; - } - if (hasFlag(stage, ShaderStageFlagBit.FRAGMENT)) { - if (count++) { - str += ' | '; - } - str += 'Fragment'; - } - if (hasFlag(stage, ShaderStageFlagBit.COMPUTE)) { - if (count++) { - str += ' | '; - } - str += 'Compute'; - } - if (stage === ShaderStageFlagBit.ALL) { - if (count++) { - str += ' | '; - } - str += 'All'; - } - return str; -} - -class PrintVisitor extends DefaultVisitor { - discoverVertex (u: number, g: LayoutGraphData) { - const ppl: PipelineLayoutData = g.getLayout(u); - const name: string = g._names[u]; - const freq: UpdateFrequency = g._updateFrequencies[u]; - this.oss += `${this.space}"${name}": `; - if (g.holds(LayoutGraphDataValue.RenderStage, u)) { - this.oss += `RenderStage {\n`; - } else { - this.oss += `RenderPhase {\n`; - } - this.space += ' '; - - // eslint-disable-next-line no-loop-func - ppl.descriptorSets.forEach((value, key) => { - this.oss += `${this.space}DescriptorSet<${getUpdateFrequencyName(key)}> {\n`; - this.space += ' '; - const uniformBlocks = value.descriptorSetLayoutData.uniformBlocks; - uniformBlocks.forEach((uniformBlock, attrNameID) => { - const name = g.valueNames[attrNameID]; - this.oss += `${this.space}UniformBlock "${name}" {\n`; - for (const u of uniformBlock.members) { - if (u.count > 1) { - this.oss += `${this.space} ${u.name}[${u.count}]: ${getName(u.type)}\n`; - } else { - this.oss += `${this.space} ${u.name}: ${getName(u.type)}\n`; - } - } - this.oss += `${this.space}}\n`; - }); - - const blocks = value.descriptorSetLayoutData.descriptorBlocks; - for (let j = 0; j < blocks.length; ++j) { - const block = blocks[j]; - this.oss += `${this.space}Block<${getDescriptorTypeOrderName(block.type)}, ${getVisibilityName(block.visibility)}> {\n`; - this.oss += `${this.space} capacity: ${block.capacity}\n`; - this.oss += `${this.space} count: ${block.descriptors.length}\n`; - if (block.descriptors.length > 0) { - this.oss += `${this.space} Descriptors{ \n`; - const count = 0; - for (let k = 0; k < block.descriptors.length; ++k) { - const d: DescriptorData = block.descriptors[k]; - // if (count++) { - this.oss += this.space; - this.oss += ' '; - const n: string = g.valueNames[d.descriptorID]; - this.oss += `"${n}`; - if (d.count !== 1) { - this.oss += `[${d.count}]`; - } - this.oss += '"'; - // } - this.oss += '\n'; - } - this.oss += `${this.space} }\n`; - } - this.oss += `${this.space}}\n`; - } - this.space = this.space.substring(0, this.space.length - 4); - this.oss += `${this.space}}\n`; - }); - } - finishVertex (v: number, g: LayoutGraphData) { - this.space = this.space.substring(0, this.space.length - 4); - this.oss += `${this.space}}\n`; - } - space = ''; - oss = ''; -} - -@ccclass('cc.WebLayoutGraphBuilder') -export class WebLayoutGraphBuilder implements LayoutGraphBuilder { - private _data: LayoutGraphData; - private _device: Device | null; - - constructor (deviceIn: Device | null, dataIn: LayoutGraphData) { - this._device = deviceIn; - this._data = dataIn; - } - - private getGfxType (type: DescriptorTypeOrder): DescriptorType | null { - switch (type) { - case DescriptorTypeOrder.UNIFORM_BUFFER: - return DescriptorType.UNIFORM_BUFFER; - case DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER: - return DescriptorType.DYNAMIC_UNIFORM_BUFFER; - case DescriptorTypeOrder.SAMPLER_TEXTURE: - return DescriptorType.SAMPLER_TEXTURE; - case DescriptorTypeOrder.SAMPLER: - return DescriptorType.SAMPLER; - case DescriptorTypeOrder.TEXTURE: - return DescriptorType.TEXTURE; - case DescriptorTypeOrder.STORAGE_BUFFER: - return DescriptorType.STORAGE_BUFFER; - case DescriptorTypeOrder.DYNAMIC_STORAGE_BUFFER: - return DescriptorType.DYNAMIC_STORAGE_BUFFER; - case DescriptorTypeOrder.STORAGE_IMAGE: - return DescriptorType.STORAGE_IMAGE; - case DescriptorTypeOrder.INPUT_ATTACHMENT: - return DescriptorType.INPUT_ATTACHMENT; - default: - console.error('DescriptorType not found'); - return null; - } - } - - private createDscriptorInfo (layoutData: DescriptorSetLayoutData, info: DescriptorSetLayoutInfo) { - for (let i = 0; i < layoutData.descriptorBlocks.length; ++i) { - const block = layoutData.descriptorBlocks[i]; - let slot = block.offset; - for (let j = 0; j < block.descriptors.length; ++j) { - const d = block.descriptors[j]; - const binding: DescriptorSetLayoutBinding = new DescriptorSetLayoutBinding(); - binding.binding = slot; - if (this.getGfxType(block.type)) { - binding.descriptorType = this.getGfxType(block.type) as DescriptorType; - } - binding.count = d.count; - binding.stageFlags = block.visibility; - binding.immutableSamplers = []; - info.bindings.push(binding); - slot += d.count; - } - } - } - - private createDescriptorSetLayout (layoutData: DescriptorSetLayoutData) { - const info: DescriptorSetLayoutInfo = new DescriptorSetLayoutInfo(); - this.createDscriptorInfo(layoutData, info); - - if (this._device) { - return this._device.createDescriptorSetLayout(info); - } else { - return null; - } - } - - public clear (): void { - this._data.clear(); - } - - public addRenderStage (name: string): number { - return this._data.addVertex(LayoutGraphDataValue.RenderStage, - new RenderStageData(), name, - UpdateFrequency.PER_PASS, new PipelineLayoutData()); - } - - public addRenderPhase (name: string, parentID: number): number { - return this._data.addVertex(LayoutGraphDataValue.RenderPhase, - new RenderPhaseData(), name, - UpdateFrequency.PER_PHASE, new PipelineLayoutData(), - parentID); - } - - public addShader (name: string, parentPhaseID: number): void { - this._data.shaderLayoutIndex.set(name, parentPhaseID); - } - - public addDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: DescriptorBlockFlattened): void { - const g: LayoutGraphData = this._data; - const ppl: PipelineLayoutData = g.getLayout(nodeID); - if (block.capacity <= 0) { - console.error('empty block'); - return; - } - if (block.descriptorNames.length !== block.descriptors.length) { - console.error('error descriptor'); - return; - } - if (block.uniformBlockNames.length !== block.uniformBlocks.length) { - console.error('error uniform'); - return; - } - let data: DescriptorSetData | undefined = ppl.descriptorSets.get(index.updateFrequency); - if (!data) { - data = new DescriptorSetData(new DescriptorSetLayoutData(), null, null); - ppl.descriptorSets.set(index.updateFrequency, data); - } - const layout = data.descriptorSetLayoutData; - - const dstBlock = new DescriptorBlockData(index.descriptorType, index.visibility, block.capacity); - layout.descriptorBlocks.push(dstBlock); - dstBlock.offset = layout.capacity; - dstBlock.capacity = block.capacity; - for (let j = 0; j < block.descriptors.length; ++j) { - const name: string = block.descriptorNames[j]; - const d: Descriptor = block.descriptors[j]; - let nameID: number | undefined = g.attributeIndex.get(name); - if (nameID === undefined) { - const id = g.valueNames.length; - g.attributeIndex.set(name, id); - g.valueNames.push(name); - } - - nameID = g.attributeIndex.get(name); - const data: DescriptorData = new DescriptorData(nameID); - data.count = d.count; - dstBlock.descriptors.push(data); - } - layout.capacity += block.capacity; - } - - public reorderDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: DescriptorBlockFlattened): void { - const g: LayoutGraphData = this._data; - const ppl: PipelineLayoutData = g.getLayout(nodeID); - if (block.capacity <= 0) { - console.error('empty block'); - return; - } - if (block.descriptorNames.length !== block.descriptors.length) { - console.error('error descriptor'); - return; - } - if (block.uniformBlockNames.length !== block.uniformBlocks.length) { - console.error('error uniform'); - return; - } - let data: DescriptorSetData | undefined = ppl.descriptorSets.get(index.updateFrequency); - if (!data) { - data = new DescriptorSetData(new DescriptorSetLayoutData(), null, null); - ppl.descriptorSets.set(index.updateFrequency, data); - } - const layout = data.descriptorSetLayoutData; - - layout.descriptorBlocks.sort((a, b) => a.type - b.type); - - let cap = 0; - for (let i = 0; i < layout.descriptorBlocks.length; ++i) { - const block = layout.descriptorBlocks[i]; - block.offset = cap; - cap += block.capacity; - } - } - - public addUniformBlock (nodeID: number, index: DescriptorBlockIndex, name: string, uniformBlock: UniformBlock): void { - const g: LayoutGraphData = this._data; - const ppl: PipelineLayoutData = g.getLayout(nodeID); - const layout: DescriptorSetLayoutData | undefined = ppl.descriptorSets.get(index.updateFrequency)?.descriptorSetLayoutData; - if (layout !== undefined) { - let nameID: number | undefined = g.attributeIndex.get(name); - if (nameID === undefined) { - const id = g.valueNames.length; - g.attributeIndex.set(name, id); - g.valueNames.push(name); - } - - nameID = g.attributeIndex.get(name); - layout.uniformBlocks.set(nameID as number, uniformBlock); - } - } - - public reserveDescriptorBlock (nodeID: number, index: DescriptorBlockIndex, block: DescriptorBlockFlattened): void { - const g: LayoutGraphData = this._data; - const ppl: PipelineLayoutData = g.getLayout(nodeID); - if (block.capacity <= 0) { - console.error('empty block'); - return; - } - - const layout: DescriptorSetLayoutData | undefined = ppl.descriptorSets.get(index.updateFrequency)?.descriptorSetLayoutData; - if (layout !== undefined) { - layout.descriptorBlocks.push(new DescriptorBlockData(index.descriptorType, index.visibility, block.capacity)); - const dstBlock = layout.descriptorBlocks[layout.descriptorBlocks.length - 1]; - dstBlock.offset = layout.capacity; - dstBlock.capacity = block.capacity; - layout.capacity += block.capacity; - } else { - console.error('no layout'); - } - } - - public compile (): number { - const g: LayoutGraphData = this._data; - for (let i = 0; i < g._layouts.length; ++i) { - const ppl: PipelineLayoutData = g.getLayout(i); - ppl.descriptorSets.forEach((value, key) => { - const level = value; - const layoutData = level.descriptorSetLayoutData; - if (this._device) { - const layout: DescriptorSetLayout | null = this.createDescriptorSetLayout(layoutData); - if (layout) { - level.descriptorSetLayout = (layout); - level.descriptorSet = (this._device.createDescriptorSet(new DescriptorSetInfo(layout))); - } - } else { - this.createDscriptorInfo(layoutData, level.descriptorSetLayoutInfo); - } - }); - } - if (DEBUG) { - console.log(this.print()); - } - return 0; - } - - public print (): string { - const g: LayoutGraphData = this._data; - const visitor = new PrintVisitor(); - const colorMap = new VectorGraphColorMap(g.numVertices()); - depthFirstSearch(g, visitor, colorMap); - return visitor.oss; - } - - public get data () { - return this._data; - } - - public exportEffect (effect: EffectAsset) { - let parent = ''; - if (effect.name.indexOf('bloom') !== -1 - || effect.name.indexOf('post-process') !== -1 - || effect.name.indexOf('smaa') !== -1 - || effect.name.indexOf('toonmap') !== -1) { - parent = 'post'; - } else if (effect.name.indexOf('deferred') !== -1) { - parent = 'deferred'; - } else { - parent = 'default'; - } - - for (let i = 0; i < effect.techniques.length; ++i) { - const tech = effect.techniques[i]; - for (let j = 0; j < tech.passes.length; ++j) { - const pass = tech.passes[j]; - const passPhase = pass.phase; - let phaseName = ''; - if (passPhase) { - phaseName = passPhase.toString(); - } else { - phaseName = `${parent}_`; - } - const shaderName = pass.program; - let passShader; - for (let s = 0; s < effect.shaders.length; ++s) { - const shader = effect.shaders[s]; - const name = shader.name; - if (name === shaderName) { - passShader = {}; - deepClone(shader, passShader); - break; - } - } - if (passShader) { - pass.shader = passShader; - const shader = pass.shader; - if (shader === undefined) { - continue; - } - const storedMap = new Map(); - - const vid = this.data.locate(`/${parent}/${phaseName}`); - const layout = this.data.getLayout(vid); - const dss = layout.descriptorSets.get(UpdateFrequency.PER_BATCH); - - if (dss) { - const dsData = dss.descriptorSetLayoutData.descriptorBlocks; - - for (let t = 0; t < shader.samplerTextures.length; ++t) { - const samplerTexInfo: EffectAsset.ISamplerTextureInfo = shader.samplerTextures[t]; - const flag = samplerTexInfo.stageFlags; - const type = DescriptorTypeOrder.SAMPLER_TEXTURE; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - samplerTexInfo.binding = ds.offset + stored; - } else { - samplerTexInfo.binding = ds.offset; - } - break; - } - } - } - - for (let s = 0; s < shader.samplers.length; ++s) { - const samplerInfo: EffectAsset.ISamplerInfo = shader.samplers[s]; - const flag = samplerInfo.stageFlags; - const type = DescriptorTypeOrder.SAMPLER; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - samplerInfo.binding = ds.offset + stored; - } else { - samplerInfo.binding = ds.offset; - } - break; - } - } - } - - for (let t = 0; t < shader.textures.length; ++t) { - const texInfo: EffectAsset.ITextureInfo = shader.textures[t]; - const flag = texInfo.stageFlags; - const type = DescriptorTypeOrder.TEXTURE; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - texInfo.binding = ds.offset + stored; - } else { - texInfo.binding = ds.offset; - } - break; - } - } - } - - for (let b = 0; b < shader.buffers.length; ++b) { - const bufferInfo: EffectAsset.IBufferInfo = shader.buffers[b]; - const flag = bufferInfo.stageFlags; - const type = DescriptorTypeOrder.STORAGE_BUFFER; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - bufferInfo.binding = ds.offset + stored; - } else { - bufferInfo.binding = ds.offset; - } - break; - } - } - } - - for (let m = 0; m < shader.images.length; +m) { - const imageInfo: EffectAsset.IImageInfo = shader.images[m]; - const flag = imageInfo.stageFlags; - const type = DescriptorTypeOrder.STORAGE_IMAGE; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - imageInfo.binding = ds.offset + stored; - } else { - imageInfo.binding = ds.offset; - } - break; - } - } - } - - for (let si = 0; si < shader.subpassInputs.length; ++si) { - const subpassInfo: EffectAsset.IInputAttachmentInfo = shader.subpassInputs[si]; - const flag = subpassInfo.stageFlags; - const type = DescriptorTypeOrder.INPUT_ATTACHMENT; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - subpassInfo.binding = ds.offset + stored; - } else { - subpassInfo.binding = ds.offset; - } - break; - } - } - } - - // builtin - for (let k = 0; k < shader.builtins.locals.samplerTextures.length; ++k) { - const descriptor = shader.builtins.locals.samplerTextures[k]; - const type = DescriptorTypeOrder.SAMPLER_TEXTURE; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - let flag = ShaderStageFlagBit.VERTEX; - if ((descriptor.name === 'cc_jointTexture' || descriptor.name === 'cc_PositionDisplacements' - || descriptor.name === 'cc_realtimeJoint' || descriptor.name === 'cc_NormalDisplacements' - || descriptor.name === 'cc_TangentDisplacements')) { - flag = ShaderStageFlagBit.VERTEX; - } else { - flag = ShaderStageFlagBit.FRAGMENT; - } - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - descriptor.binding = ds.offset + stored; - } else { - descriptor.binding = ds.offset; - } - } - } - } - - for (let k = 0; k < shader.builtins.locals.images.length; ++k) { - const descriptor = shader.builtins.locals.images[k]; - const flag = ShaderStageFlagBit.COMPUTE; - const type = DescriptorTypeOrder.SAMPLER_TEXTURE; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_BATCH.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - descriptor.binding = ds.offset + stored; - } else { - descriptor.binding = ds.offset; - } - } - } - } - } - - const pid = this.data.locate(`/${parent}`); - const pLayout = this.data.getLayout(pid); - const pss = pLayout.descriptorSets.get(UpdateFrequency.PER_PASS); - - if (pss) { - const dsData = pss.descriptorSetLayoutData.descriptorBlocks; - - for (let g = 0; g < shader.builtins.globals.samplerTextures.length; ++g) { - const descriptor = shader.builtins.globals.samplerTextures[g]; - const flag = ShaderStageFlagBit.FRAGMENT; - const type = DescriptorTypeOrder.SAMPLER_TEXTURE; - for (let d = 0; d < dsData.length; ++d) { - const ds = dsData[d]; - if (ds.visibility === flag && ds.type === type) { - const key = `${UpdateFrequency.PER_PASS.toString()}|${flag.toString()}|${type.toString()}`; - let stored = storedMap.get(key); - if (stored === undefined) { - storedMap.set(key, 0); - stored = storedMap.get(key); - } else { - stored += 1; - storedMap.set(key, stored); - } - - if (stored !== undefined) { - descriptor.binding = ds.offset + stored; - } else { - descriptor.binding = ds.offset; - } - } - } - } - } - } - } - } - } -} diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index efd185c82d9..f3cf62429e7 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,29 +24,25 @@ /* eslint-disable max-len */ import { systemInfo } from 'pal/system-info'; -import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address } from '../../gfx/index'; -import { Mat4, Quat, Vec2, Vec3, Vec4 } from '../../core/math'; +import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo } from '../../gfx'; +import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy } from '../../core'; import { ComputeView, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, RasterView, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; import { Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedResource, MovePass, RasterPass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData } from './render-graph'; -import { ComputePassBuilder, ComputeQueueBuilder, CopyPassBuilder, LayoutGraphBuilder, MovePassBuilder, Pipeline, PipelineBuilder, RasterPassBuilder, RasterQueueBuilder, SceneTransversal } from './pipeline'; +import { ComputePassBuilder, ComputeQueueBuilder, CopyPassBuilder, MovePassBuilder, Pipeline, PipelineBuilder, RasterPassBuilder, RasterQueueBuilder, SceneTransversal } from './pipeline'; import { PipelineSceneData } from '../pipeline-scene-data'; import { Model, Camera, ShadowType, CSMLevel, DirectionalLight, SpotLight, PCFType, Shadows } from '../../render-scene/scene'; import { Light, LightType } from '../../render-scene/scene/light'; -import { legacyCC } from '../../core/global-exports'; -import { LayoutGraphData } from './layout-graph'; +import { DescriptorSetData, LayoutGraphData } from './layout-graph'; import { Executor } from './executor'; import { RenderWindow } from '../../render-scene/core/render-window'; -import { assert } from '../../core/platform/debug'; -import { macro } from '../../core/platform/macro'; import { MacroRecord, RenderScene } from '../../render-scene'; import { GlobalDSManager } from '../global-descriptor-set-manager'; -import { supportsR32FloatTexture, UBOSkinning } from '../define'; +import { isEnableEffect, supportsR32FloatTexture, UBOSkinning } from '../define'; import { OS } from '../../../pal/system-info/enum-type'; import { Compiler } from './compiler'; import { PipelineUBO } from '../pipeline-ubo'; import { builtinResMgr } from '../../asset/asset-manager'; import { Texture2D } from '../../asset/assets/texture-2d'; -import { WebLayoutGraphBuilder } from './web-layout-graph'; import { GeometryRenderer } from '../geometry-renderer'; import { Material, TextureCube } from '../../asset/assets'; import { DeferredPipelineBuilder, ForwardPipelineBuilder } from './builtin-pipelines'; @@ -55,6 +50,8 @@ import { CustomPipelineBuilder } from './custom-pipeline'; import { decideProfilerCamera } from '../pipeline-funcs'; import { DebugViewCompositeType } from '../debug-view'; import { getUBOTypeCount } from './utils'; +import { initGlobalDescBinding } from './define'; +import { createGfxDescriptorSetsAndPipelines } from './layout-graph-utils'; export class WebSetter { constructor (data: RenderData, lg: LayoutGraphData) { @@ -88,6 +85,7 @@ export class WebSetter { protected _getUniformOffset (name: string, type: Type, idx = 0) { const currBlock = this._getCurrUniformBlock(); + if (!currBlock) return -1; let offset = 0; const typeCount = getUBOTypeCount(type); for (const uniform of currBlock.members) { @@ -113,7 +111,22 @@ export class WebSetter { const ppl = this._lg.getLayout(nodeId); const layout = ppl.descriptorSets.get(UpdateFrequency.PER_PASS)!.descriptorSetLayoutData; const nameID: number = this._lg.attributeIndex.get(block)!; - return layout.uniformBlocks.get(nameID)!; + return layout.uniformBlocks.get(nameID); + } + + protected _getCurrDescriptorBlock (block: string) { + const nodeId = this._lg.locateChild(0xFFFFFFFF, this._currStage); + const ppl = this._lg.getLayout(nodeId); + const layout = ppl.descriptorSets.get(UpdateFrequency.PER_PASS)!.descriptorSetLayoutData; + const nameID: number = this._lg.attributeIndex.get(block)!; + for (const block of layout.descriptorBlocks) { + for (let i = 0; i !== block.descriptors.length; ++i) { + if (nameID === block.descriptors[i].descriptorID) { + return block.offset + i; + } + } + } + return -1; } setCurrConstant (block: string, stage = 'default') { @@ -122,10 +135,12 @@ export class WebSetter { const nameID: number = this._lg.attributeIndex.get(block)!; this._currCount = 0; const currBlock = this._getCurrUniformBlock(); + if (!currBlock) return false; for (const uniform of currBlock.members) { this._currCount += getUBOTypeCount(uniform.type) * uniform.count; } this._currConstant = this._data.constants.get(nameID)!; + return true; } getCurrConstant () { @@ -138,14 +153,17 @@ export class WebSetter { const num = this._lg.attributeIndex.get(block)!; this._currCount = 0; const currBlock = this._getCurrUniformBlock(); + if (!currBlock) return false; for (const uniform of currBlock.members) { this._currCount += getUBOTypeCount(uniform.type) * uniform.count; } if (!this._data.constants.get(num)) { const value = new Array(this._currCount); + value.fill(0); this._data.constants.set(num, value); } this.setCurrConstant(block); + return true; } public setMat4 (name: string, mat: Mat4, idx = 0): void { this._applyCurrConstantBuffer(name, mat, Type.MAT4, idx); @@ -167,15 +185,35 @@ export class WebSetter { } public setBuffer (name: string, buffer: Buffer): void {} public setTexture (name: string, texture: Texture): void { + if (this._getCurrDescriptorBlock(name) === -1) { + return; + } const num = this._lg.attributeIndex.get(name)!; this._data.textures.set(num, texture); } public setReadWriteBuffer (name: string, buffer: Buffer): void {} public setReadWriteTexture (name: string, texture: Texture): void {} public setSampler (name: string, sampler: Sampler): void { + if (this._getCurrDescriptorBlock(name) === -1) { + return; + } const num = this._lg.attributeIndex.get(name)!; this._data.samplers.set(num, sampler); } + public hasSampler (name: string): boolean { + const id = this._lg.attributeIndex.get(name); + if (id === undefined) { + return false; + } + return this._data.samplers.has(id); + } + public hasTexture (name: string): boolean { + const id = this._lg.attributeIndex.get(name); + if (id === undefined) { + return false; + } + return this._data.textures.has(id); + } // protected protected readonly _data: RenderData; @@ -187,9 +225,11 @@ export class WebSetter { } function setShadowUBOLightView (setter: WebSetter, + camera: Camera, light: Light, - level: number) { - const director = legacyCC.director; + level: number, + layout = 'default') { + const director = cclegacy.director; const pipeline = director.root.pipeline; const device = pipeline.device; const sceneData = pipeline.pipelineSceneData; @@ -198,8 +238,17 @@ function setShadowUBOLightView (setter: WebSetter, const packing = supportsR32FloatTexture(device) ? 0.0 : 1.0; const cap = pipeline.device.capabilities; const _vec4ShadowInfo = new Vec4(); + setter.addConstant('CCCSM', layout); // ShadowMap - setter.addConstant('CCShadow'); + if (!setter.addConstant('CCShadow', layout)) return; + if (shadowInfo.enabled) { + if (shadowInfo.type === ShadowType.ShadowMap) { + // update CSM layers + if (light && light.node) { + csmLayers.update(sceneData, camera); + } + } + } switch (light.type) { case LightType.DIRECTIONAL: { const mainLight = light as DirectionalLight; @@ -280,8 +329,8 @@ function setShadowUBOLightView (setter: WebSetter, } default: } - setter.setColor('cc_shadowColor', new Color(shadowInfo.shadowColor.r, shadowInfo.shadowColor.g, - shadowInfo.shadowColor.b, shadowInfo.shadowColor.a)); + setter.setColor('cc_shadowColor', new Color(shadowInfo.shadowColor.x, shadowInfo.shadowColor.y, + shadowInfo.shadowColor.z, shadowInfo.shadowColor.w)); } function getPCFRadius (shadowInfo: Shadows, mainLight: DirectionalLight): number { @@ -300,8 +349,8 @@ function getPCFRadius (shadowInfo: Shadows, mainLight: DirectionalLight): number return 0.0; } -function setShadowUBOView (setter: WebSetter, camera: Camera) { - const director = legacyCC.director; +function setShadowUBOView (setter: WebSetter, camera: Camera, layout = 'default') { + const director = cclegacy.director; const pipeline = director.root.pipeline; const device = pipeline.device; const mainLight = camera.scene!.mainLight; @@ -311,97 +360,107 @@ function setShadowUBOView (setter: WebSetter, camera: Camera) { const csmSupported = sceneData.csmSupported; const packing = supportsR32FloatTexture(device) ? 0.0 : 1.0; const _vec4ShadowInfo = new Vec4(); - setter.addConstant('CCShadow'); - setter.addConstant('CCCSM'); + const hasCCShadow = setter.addConstant('CCShadow', layout); + const hasCCCSM = setter.addConstant('CCCSM', layout); if (mainLight && shadowInfo.enabled) { if (shadowInfo.type === ShadowType.ShadowMap) { if (mainLight.shadowEnabled) { if (mainLight.shadowFixedArea || mainLight.csmLevel === CSMLevel.LEVEL_1 || !csmSupported) { - setter.setCurrConstant('CCShadow'); - const matShadowView = csmLayers.specialLayer.matShadowView; - const matShadowProj = csmLayers.specialLayer.matShadowProj; - const matShadowViewProj = csmLayers.specialLayer.matShadowViewProj; - const near = mainLight.shadowNear; - const far = mainLight.shadowFar; - - setter.setMat4('cc_matLightView', matShadowView); - setter.setVec4('cc_shadowProjDepthInfo', new Vec4(matShadowProj.m10, matShadowProj.m14, - matShadowProj.m11, matShadowProj.m15)); - - setter.setVec4('cc_shadowProjInfo', new Vec4(matShadowProj.m00, matShadowProj.m05, - 1.0 / matShadowProj.m00, 1.0 / matShadowProj.m05)); - setter.setMat4('cc_matLightViewProj', matShadowViewProj); - _vec4ShadowInfo.set(near, far, 0, 1.0 - mainLight.shadowSaturation); - setter.setVec4('cc_shadowNFLSInfo', _vec4ShadowInfo); - _vec4ShadowInfo.set(0.0, packing, mainLight.shadowNormalBias, 0); - setter.setVec4('cc_shadowLPNNInfo', _vec4ShadowInfo); + if (hasCCShadow) { + setter.setCurrConstant('CCShadow', layout); + const matShadowView = csmLayers.specialLayer.matShadowView; + const matShadowProj = csmLayers.specialLayer.matShadowProj; + const matShadowViewProj = csmLayers.specialLayer.matShadowViewProj; + const near = mainLight.shadowNear; + const far = mainLight.shadowFar; + + setter.setMat4('cc_matLightView', matShadowView); + setter.setVec4('cc_shadowProjDepthInfo', new Vec4(matShadowProj.m10, matShadowProj.m14, + matShadowProj.m11, matShadowProj.m15)); + + setter.setVec4('cc_shadowProjInfo', new Vec4(matShadowProj.m00, matShadowProj.m05, + 1.0 / matShadowProj.m00, 1.0 / matShadowProj.m05)); + setter.setMat4('cc_matLightViewProj', matShadowViewProj); + _vec4ShadowInfo.set(near, far, 0, 1.0 - mainLight.shadowSaturation); + setter.setVec4('cc_shadowNFLSInfo', _vec4ShadowInfo); + _vec4ShadowInfo.set(0.0, packing, mainLight.shadowNormalBias, 0); + setter.setVec4('cc_shadowLPNNInfo', _vec4ShadowInfo); + } } else { - const layerThreshold = getPCFRadius(shadowInfo, mainLight); - setter.setCurrConstant('CCCSM'); - for (let i = 0; i < mainLight.csmLevel; i++) { - const matShadowView = csmLayers.layers[i].matShadowView; - _vec4ShadowInfo.set(matShadowView.m00, matShadowView.m04, matShadowView.m08, layerThreshold); - setter.setVec4('cc_csmViewDir0', _vec4ShadowInfo, i); - _vec4ShadowInfo.set(matShadowView.m01, matShadowView.m05, matShadowView.m09, 0.0); - setter.setVec4('cc_csmViewDir1', _vec4ShadowInfo, i); - _vec4ShadowInfo.set(matShadowView.m02, matShadowView.m06, matShadowView.m10, 0.0); - setter.setVec4('cc_csmViewDir2', _vec4ShadowInfo, i); - - const csmAtlas = csmLayers.layers[i].csmAtlas; - setter.setVec4('cc_csmAtlas', csmAtlas, i); - - setter.setFloat('cc_csmSplitsInfo', csmLayers.layers[i].splitCameraFar / mainLight.shadowDistance, i); - const matShadowViewProj = csmLayers.layers[i].matShadowViewProj; - setter.setMat4('cc_matCSMViewProj', matShadowViewProj, i); - - const matShadowProj = csmLayers.layers[i].matShadowProj; - setter.setVec4('cc_csmProjDepthInfo', new Vec4(matShadowProj.m10, - matShadowProj.m14, matShadowProj.m11, matShadowProj.m15), i); - - setter.setVec4('cc_csmProjInfo', new Vec4(matShadowProj.m00, - matShadowProj.m05, 1.0 / matShadowProj.m00, 1.0 / matShadowProj.m05), i); + if (hasCCCSM) { + const layerThreshold = getPCFRadius(shadowInfo, mainLight); + setter.setCurrConstant('CCCSM', layout); + for (let i = 0; i < mainLight.csmLevel; i++) { + const matShadowView = csmLayers.layers[i].matShadowView; + _vec4ShadowInfo.set(matShadowView.m00, matShadowView.m04, matShadowView.m08, layerThreshold); + setter.setVec4('cc_csmViewDir0', _vec4ShadowInfo, i); + _vec4ShadowInfo.set(matShadowView.m01, matShadowView.m05, matShadowView.m09, 0.0); + setter.setVec4('cc_csmViewDir1', _vec4ShadowInfo, i); + _vec4ShadowInfo.set(matShadowView.m02, matShadowView.m06, matShadowView.m10, 0.0); + setter.setVec4('cc_csmViewDir2', _vec4ShadowInfo, i); + + const csmAtlas = csmLayers.layers[i].csmAtlas; + setter.setVec4('cc_csmAtlas', csmAtlas, i); + + setter.setFloat('cc_csmSplitsInfo', csmLayers.layers[i].splitCameraFar / mainLight.shadowDistance, i); + const matShadowViewProj = csmLayers.layers[i].matShadowViewProj; + setter.setMat4('cc_matCSMViewProj', matShadowViewProj, i); + + const matShadowProj = csmLayers.layers[i].matShadowProj; + setter.setVec4('cc_csmProjDepthInfo', new Vec4(matShadowProj.m10, + matShadowProj.m14, matShadowProj.m11, matShadowProj.m15), i); + + setter.setVec4('cc_csmProjInfo', new Vec4(matShadowProj.m00, + matShadowProj.m05, 1.0 / matShadowProj.m00, 1.0 / matShadowProj.m05), i); + } + } + if (hasCCShadow) { + setter.setCurrConstant('CCShadow', layout); + _vec4ShadowInfo.set(0, 0, 0, 1.0 - mainLight.shadowSaturation); + setter.setVec4('cc_shadowNFLSInfo', _vec4ShadowInfo); + _vec4ShadowInfo.set(0.0, packing, mainLight.shadowNormalBias, mainLight.csmLevel); + setter.setVec4('cc_shadowLPNNInfo', _vec4ShadowInfo); } - setter.setCurrConstant('CCShadow'); - _vec4ShadowInfo.set(0, 0, 0, 1.0 - mainLight.shadowSaturation); - setter.setVec4('cc_shadowNFLSInfo', _vec4ShadowInfo); - _vec4ShadowInfo.set(0.0, packing, mainLight.shadowNormalBias, mainLight.csmLevel); - setter.setVec4('cc_shadowLPNNInfo', _vec4ShadowInfo); } - setter.setCurrConstant('CCShadow'); - _vec4ShadowInfo.set(shadowInfo.size.x, shadowInfo.size.y, mainLight.shadowPcf, mainLight.shadowBias); - setter.setVec4('cc_shadowWHPBInfo', _vec4ShadowInfo); + if (hasCCShadow) { + setter.setCurrConstant('CCShadow', layout); + _vec4ShadowInfo.set(shadowInfo.size.x, shadowInfo.size.y, mainLight.shadowPcf, mainLight.shadowBias); + setter.setVec4('cc_shadowWHPBInfo', _vec4ShadowInfo); + } } - } else { - setter.setCurrConstant('CCShadow'); + } else if (hasCCShadow) { + setter.setCurrConstant('CCShadow', layout); const _tempVec3 = new Vec3(); Vec3.normalize(_tempVec3, shadowInfo.normal); setter.setVec4('cc_planarNDInfo', new Vec4(_tempVec3.x, _tempVec3.y, _tempVec3.z, -shadowInfo.distance)); } - setter.setCurrConstant('CCShadow'); - setter.setColor('cc_shadowColor', shadowInfo.shadowColor); + if (hasCCShadow) { + setter.setCurrConstant('CCShadow', layout); + setter.setColor('cc_shadowColor', shadowInfo.shadowColor); + } } } function setCameraUBOValues (setter: WebSetter, camera: Readonly, cfg: Readonly, - scene: Readonly) { - const director = legacyCC.director; + scene: Readonly, + layoutName = 'default') { + const director = cclegacy.director; const root = director.root; const pipeline = root.pipeline as WebPipeline; - const layoutGraph = pipeline.layoutGraph; const shadowInfo = cfg.shadows; const skybox = cfg.skybox; const shadingScale = cfg.shadingScale; // Camera - setter.addConstant('CCCamera'); + if (!setter.addConstant('CCCamera', layoutName)) return; setter.setMat4('cc_matView', camera.matView); setter.setMat4('cc_matViewInv', camera.node.worldMatrix); setter.setMat4('cc_matProj', camera.matProj); setter.setMat4('cc_matProjInv', camera.matProjInv); setter.setMat4('cc_matViewProj', camera.matViewProj); setter.setMat4('cc_matViewProjInv', camera.matViewProjInv); - setter.setVec4('cc_cameraPos', new Vec4(camera.position.x, camera.position.y, camera.position.z, 0.0)); - setter.setVec4('cc_surfaceTransform', new Vec4(camera.surfaceTransform, 0.0, 0.0, 0.0)); + setter.setVec4('cc_cameraPos', new Vec4(camera.position.x, camera.position.y, camera.position.z, pipeline.getCombineSignY())); + setter.setVec4('cc_surfaceTransform', new Vec4(camera.surfaceTransform, 0.0, Math.cos(toRadian(skybox.getRotationAngle())), Math.sin(toRadian(skybox.getRotationAngle())))); setter.setVec4('cc_screenScale', new Vec4(cfg.shadingScale, cfg.shadingScale, 1.0 / cfg.shadingScale, 1.0 / cfg.shadingScale)); setter.setVec4('cc_exposure', new Vec4(camera.exposure, 1.0 / camera.exposure, cfg.isHDR ? 1.0 : 0.0, 1.0 / Camera.standardExposureValue)); @@ -439,16 +498,16 @@ function setCameraUBOValues (setter: WebSetter, const fog = cfg.fog; const colorTempRGB = fog.colorArray; - setter.setVec4('cc_fogColor', new Vec4(colorTempRGB.x, colorTempRGB.y, colorTempRGB.z, colorTempRGB.w)); + setter.setVec4('cc_fogColor', new Vec4(colorTempRGB.x, colorTempRGB.y, colorTempRGB.z, colorTempRGB.z)); setter.setVec4('cc_fogBase', new Vec4(fog.fogStart, fog.fogEnd, fog.fogDensity, 0.0)); setter.setVec4('cc_fogAdd', new Vec4(fog.fogTop, fog.fogRange, fog.fogAtten, 0.0)); setter.setVec4('cc_nearFar', new Vec4(camera.nearClip, camera.farClip, 0.0, 0.0)); setter.setVec4('cc_viewPort', new Vec4(camera.viewport.x, camera.viewport.y, shadingScale * camera.window.width * camera.viewport.z, shadingScale * camera.window.height * camera.viewport.w)); } -function setTextureUBOView (setter: WebSetter, camera: Camera, cfg: Readonly) { +function setTextureUBOView (setter: WebSetter, camera: Camera, cfg: Readonly, layout = 'default') { const skybox = cfg.skybox; - const director = legacyCC.director; + const director = cclegacy.director; const root = director.root; if (skybox.reflectionMap) { const texture = skybox.reflectionMap.getGFXTexture()!; @@ -479,11 +538,20 @@ function setTextureUBOView (setter: WebSetter, camera: Camera, cfg: Readonly('default-texture').getGFXTexture()!); - setter.setSampler('cc_spotShadowMap', pointSampler); - setter.setTexture('cc_spotShadowMap', builtinResMgr.get('default-texture').getGFXTexture()!); + if (!setter.hasSampler('cc_shadowMap')) { + setter.setSampler('cc_shadowMap', pointSampler); + } + if (!setter.hasTexture('cc_shadowMap')) { + setter.setTexture('cc_shadowMap', builtinResMgr.get('default-texture').getGFXTexture()!); + } + if (!setter.hasSampler('cc_spotShadowMap')) { + setter.setSampler('cc_spotShadowMap', pointSampler); + } + if (!setter.hasTexture('cc_spotShadowMap')) { + setter.setTexture('cc_spotShadowMap', builtinResMgr.get('default-texture').getGFXTexture()!); + } } function getFirstChildLayoutName (lg: LayoutGraphData, parentID: number): string { @@ -505,22 +573,38 @@ export class WebRasterQueueBuilder extends WebSetter implements RasterQueueBuild this._queue = queue; this._pipeline = pipeline; } - addSceneOfCamera (camera: Camera, light: LightInfo, sceneFlags: SceneFlags, name = 'Camera'): void { + get name () { + return this._renderGraph.getName(this._vertID); + } + set name (name: string) { + this._renderGraph.setName(this._vertID, name); + } + + getLayoutName () { + const parId = this._renderGraph.getParent(this._vertID); + const layoutName = isEnableEffect() ? this._renderGraph.getLayout(parId) : 'default'; + return layoutName; + } + + addSceneOfCamera (camera: Camera, light: LightInfo, sceneFlags = SceneFlags.NONE, name = 'Camera'): void { const sceneData = new SceneData(name, sceneFlags, light); sceneData.camera = camera; this._renderGraph.addVertex( RenderGraphValue.Scene, sceneData, name, '', new RenderData(), false, this._vertID, ); + const layoutName = this.getLayoutName(); setCameraUBOValues(this, camera, this._pipeline, - camera.scene ? camera.scene : legacyCC.director.getScene().renderScene); + camera.scene ? camera.scene : cclegacy.director.getScene().renderScene, + layoutName); if (sceneFlags & SceneFlags.SHADOW_CASTER) { - setShadowUBOLightView(this, light.light!, light.level); + setShadowUBOLightView(this, camera, light.light!, light.level, layoutName); } else { - setShadowUBOView(this, camera); + setShadowUBOView(this, camera, layoutName); } setTextureUBOView(this, camera, this._pipeline); + initGlobalDescBinding(this._data, layoutName); } - addScene (sceneName: string, sceneFlags: SceneFlags): void { + addScene (sceneName: string, sceneFlags = SceneFlags.NONE): void { const sceneData = new SceneData(sceneName, sceneFlags); this._renderGraph.addVertex( RenderGraphValue.Scene, sceneData, sceneName, '', new RenderData(), false, this._vertID, @@ -532,21 +616,23 @@ export class WebRasterQueueBuilder extends WebSetter implements RasterQueueBuild name, '', new RenderData(), false, this._vertID, ); } - addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags: SceneFlags) { + addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags = SceneFlags.NONE) { this._renderGraph.addVertex( RenderGraphValue.Blit, new Blit(material, passID, sceneFlags, camera), 'CameraQuad', '', new RenderData(), false, this._vertID, ); + const layoutName = this.getLayoutName(); setCameraUBOValues(this, camera, this._pipeline, - camera.scene ? camera.scene : legacyCC.director.getScene().renderScene); + camera.scene ? camera.scene : cclegacy.director.getScene().renderScene, layoutName); if (sceneFlags & SceneFlags.SHADOW_CASTER) { // setShadowUBOLightView(this, light.light!, light.level); } else { - setShadowUBOView(this, camera); + setShadowUBOView(this, camera, layoutName); } setTextureUBOView(this, camera, this._pipeline); + initGlobalDescBinding(this._data, layoutName); } - clearRenderTarget (name: string, color: Color) { + clearRenderTarget (name: string, color: Color = new Color()) { this._renderGraph.addVertex( RenderGraphValue.Clear, [new ClearView(name, ClearFlagBit.COLOR, color)], 'ClearRenderTarget', '', new RenderData(), false, this._vertID, @@ -578,6 +664,16 @@ export class WebRasterPassBuilder extends WebSetter implements RasterPassBuilder ); this._layoutID = layoutGraph.locateChild(layoutGraph.nullVertex(), layoutName); } + setVersion (name: string, version: number): void { + this._pass.versionName = name; + this._pass.version = version; + } + get name () { + return this._renderGraph.getName(this._vertID); + } + set name (name: string) { + this._renderGraph.setName(this._vertID, name); + } addRasterView (name: string, view: RasterView) { this._pass.rasterViews.set(name, view); } @@ -625,6 +721,12 @@ export class WebRasterPassBuilder extends WebSetter implements RasterPassBuilder setViewport (viewport: Viewport): void { this._pass.viewport.copy(viewport); } + get showStatistics (): boolean { + return this._pass.showStatistics; + } + set showStatistics (enable: boolean) { + this._pass.showStatistics = enable; + } private readonly _renderGraph: RenderGraph; private readonly _vertID: number; private readonly _layoutID: number; @@ -641,6 +743,12 @@ export class WebComputeQueueBuilder extends WebSetter implements ComputeQueueBui this._queue = queue; this._pipeline = pipeline; } + get name () { + return this._renderGraph.getName(this._vertID); + } + set name (name: string) { + this._renderGraph.setName(this._vertID, name); + } addDispatch (shader: string, threadGroupCountX: number, threadGroupCountY: number, @@ -672,6 +780,12 @@ export class WebComputePassBuilder extends WebSetter implements ComputePassBuild ); this._layoutID = layoutGraph.locateChild(layoutGraph.nullVertex(), layoutName); } + get name () { + return this._renderGraph.getName(this._vertID); + } + set name (name: string) { + this._renderGraph.setName(this._vertID, name); + } addComputeView (name: string, view: ComputeView) { if (this._pass.computeViews.has(name)) { this._pass.computeViews.get(name)?.push(view); @@ -712,6 +826,12 @@ export class WebMovePassBuilder implements MovePassBuilder { this._vertID = vertID; this._pass = pass; } + get name () { + return this._renderGraph.getName(this._vertID); + } + set name (name: string) { + this._renderGraph.setName(this._vertID, name); + } addPair (pair: MovePair) { this._pass.movePairs.push(pair); } @@ -726,6 +846,12 @@ export class WebCopyPassBuilder implements CopyPassBuilder { this._vertID = vertID; this._pass = pass; } + get name () { + return this._renderGraph.getName(this._vertID); + } + set name (name: string) { + this._renderGraph.setName(this._vertID, name); + } addPair (pair: CopyPair) { this._pass.copyPairs.push(pair); } @@ -740,18 +866,40 @@ function isManaged (residency: ResourceResidency): boolean { } export class WebPipeline implements Pipeline { + constructor (layoutGraph: LayoutGraphData) { + this._layoutGraph = layoutGraph; + } + updateRenderWindow (name: string, renderWindow: RenderWindow): void { + const resId = this.resourceGraph.vertex(name); + const currFbo = this.resourceGraph._vertices[resId]._object; + if (currFbo !== renderWindow.framebuffer) { + this.resourceGraph._vertices[resId]._object = renderWindow.framebuffer; + } + } + updateRenderTarget (name: string, width: number, height: number, format: Format = Format.UNKNOWN): void { + const resId = this.resourceGraph.vertex(name); + const desc = this.resourceGraph.getDesc(resId); + desc.width = width; + desc.height = height; + if (format !== Format.UNKNOWN) desc.format = format; + } + updateDepthStencil (name: string, width: number, height: number, format: Format = Format.UNKNOWN): void { + const resId = this.resourceGraph.vertex(name); + const desc = this.resourceGraph.getDesc(resId); + desc.width = width; + desc.height = height; + if (format !== Format.UNKNOWN) desc.format = format; + } public containsResource (name: string): boolean { return this._resourceGraph.contains(name); } - public addComputePass(layoutName: string, name: string): ComputePassBuilder; - public addComputePass(layoutName: string): ComputePassBuilder; - public addComputePass (layoutName: any, name?: any): ComputePassBuilder { + public addComputePass (layoutName: string): ComputePassBuilder { throw new Error('Method not implemented.'); } - public addMovePass (name: string): MovePassBuilder { + public addMovePass (): MovePassBuilder { throw new Error('Method not implemented.'); } - public addCopyPass (name: string): CopyPassBuilder { + public addCopyPass (): CopyPassBuilder { throw new Error('Method not implemented.'); } public presentAll (): void { @@ -773,6 +921,7 @@ export class WebPipeline implements Pipeline { const jointUniformCapacity = UBOSkinning.JOINT_UNIFORM_CAPACITY; str += `#define CC_JOINT_UNIFORM_CAPACITY ${jointUniformCapacity}\n`; this._constantMacros = str; + this._layoutGraph.constantMacros = this._constantMacros; } public setCustomPipelineName (name: string) { this._customPipelineName = name; @@ -789,16 +938,33 @@ export class WebPipeline implements Pipeline { return layoutData; } + private _initCombineSignY () { + const device = this._device; + this._combineSignY = (device.capabilities.screenSpaceSignY * 0.5 + 0.5) << 1 | (device.capabilities.clipSpaceSignY * 0.5 + 0.5); + } + + public getCombineSignY () { + return this._combineSignY; + } + + get globalDescriptorSetData () { + return this._globalDescSetData; + } + public activate (swapchain: Swapchain): boolean { this._device = deviceManager.gfxDevice; + createGfxDescriptorSetsAndPipelines(this._device, this._layoutGraph); this._globalDSManager = new GlobalDSManager(this._device); - const globalLayoutData = this.getGlobalDescriptorSetData()!; - this._globalDescriptorSetLayout = globalLayoutData.descriptorSetLayout; - this._globalDescriptorSet = globalLayoutData.descriptorSet!; + this._globalDescSetData = this.getGlobalDescriptorSetData()!; + this._globalDescriptorSetLayout = this._globalDescSetData.descriptorSetLayout; + this._globalDescriptorSet = isEnableEffect() ? this._device.createDescriptorSet(new DescriptorSetInfo(this._globalDescriptorSetLayout!)) + : this._globalDescSetData.descriptorSet; + this._globalDSManager.globalDescriptorSet = this.globalDescriptorSet; this.setMacroBool('CC_USE_HDR', this._pipelineSceneData.isHDR); this._generateConstantMacros(false); this._pipelineSceneData.activate(this._device); this._pipelineUBO.activate(this._device, this); + this._initCombineSignY(); const isFloat = supportsR32FloatTexture(this._device) ? 0 : 1; this.setMacroInt('CC_SHADOWMAP_FORMAT', isFloat); // 0: SHADOWMAP_LINER_DEPTH_OFF, 1: SHADOWMAP_LINER_DEPTH_ON. @@ -810,11 +976,22 @@ export class WebPipeline implements Pipeline { >= (WebPipeline.CSM_UNIFORM_VECTORS + WebPipeline.GLOBAL_UNIFORM_VECTORS); this.setMacroBool('CC_SUPPORT_CASCADED_SHADOW_MAP', this.pipelineSceneData.csmSupported); + // 0: CC_SHADOW_NONE, 1: CC_SHADOW_PLANAR, 2: CC_SHADOW_MAP + this.setMacroInt('CC_SHADOW_TYPE', 0); + + // 0: PCFType.HARD, 1: PCFType.SOFT, 2: PCFType.SOFT_2X, 3: PCFType.SOFT_4X + this.setMacroInt('CC_DIR_SHADOW_PCF_TYPE', PCFType.HARD); + + // 0: CC_DIR_LIGHT_SHADOW_NONE, 1: CC_DIR_LIGHT_SHADOW_UNIFORM, 2: CC_DIR_LIGHT_SHADOW_CASCADED, 3: CC_DIR_LIGHT_SHADOW_VARIANCE + this.setMacroInt('CC_DIR_LIGHT_SHADOW_TYPE', 0); + + // 0: CC_CASCADED_LAYERS_TRANSITION_OFF, 1: CC_CASCADED_LAYERS_TRANSITION_ON + this.setMacroBool('CC_CASCADED_LAYERS_TRANSITION', false); + // enable the deferred pipeline if (this.usesDeferredPipeline) { this.setMacroInt('CC_PIPELINE_TYPE', 1); } - this.layoutGraphBuilder.compile(); this._forward = new ForwardPipelineBuilder(); this._deferred = new DeferredPipelineBuilder(); @@ -837,9 +1014,6 @@ export class WebPipeline implements Pipeline { public set lightingMode (mode: LightingMode) { this._lightingMode = mode; } - public get layoutGraphBuilder (): LayoutGraphBuilder { - return new WebLayoutGraphBuilder(this._device, this._layoutGraph); - } public get usesDeferredPipeline (): boolean { return this._usesDeferredPipeline; } @@ -953,7 +1127,7 @@ export class WebPipeline implements Pipeline { ); } } - addRenderTarget (name: string, format: Format, width: number, height: number, residency: ResourceResidency) { + addRenderTarget (name: string, format: Format, width: number, height: number, residency = ResourceResidency.MANAGED) { const desc = new ResourceDesc(); desc.dimension = ResourceDimension.TEXTURE2D; desc.width = width; @@ -963,17 +1137,16 @@ export class WebPipeline implements Pipeline { desc.format = format; desc.flags = ResourceFlags.COLOR_ATTACHMENT | ResourceFlags.SAMPLED; - assert(isManaged(residency)); return this._resourceGraph.addVertex( ResourceGraphValue.Managed, new ManagedResource(), name, desc, new ResourceTraits(residency), new ResourceStates(), - new SamplerInfo(), + new SamplerInfo(Filter.LINEAR, Filter.LINEAR, Filter.NONE, Address.CLAMP, Address.CLAMP, Address.CLAMP), ); } - addDepthStencil (name: string, format: Format, width: number, height: number, residency: ResourceResidency) { + addDepthStencil (name: string, format: Format, width: number, height: number, residency = ResourceResidency.MANAGED) { const desc = new ResourceDesc(); desc.dimension = ResourceDimension.TEXTURE2D; desc.width = width; @@ -1051,7 +1224,8 @@ export class WebPipeline implements Pipeline { this.endFrame(); } - addRasterPass (width: number, height: number, layoutName: string, name = 'Raster'): RasterPassBuilder { + addRasterPass (width: number, height: number, layoutName = 'default'): RasterPassBuilder { + const name = 'Raster'; const pass = new RasterPass(); pass.viewport.width = width; pass.viewport.height = height; @@ -1061,7 +1235,8 @@ export class WebPipeline implements Pipeline { RenderGraphValue.Raster, pass, name, layoutName, data, false, ); const result = new WebRasterPassBuilder(data, this._renderGraph!, this._layoutGraph, vertID, pass, this._pipelineSceneData); - this._updateRasterPassConstants(result, width, height); + this._updateRasterPassConstants(result, width, height, isEnableEffect() ? layoutName : 'default'); + initGlobalDescBinding(data, layoutName); return result; } public getDescriptorSetLayout (shaderName: string, freq: UpdateFrequency): DescriptorSetLayout { @@ -1080,15 +1255,16 @@ export class WebPipeline implements Pipeline { get layoutGraph () { return this._layoutGraph; } - protected _updateRasterPassConstants (setter: WebSetter, width: number, height: number) { - const director = legacyCC.director; + + protected _updateRasterPassConstants (setter: WebSetter, width: number, height: number, layoutName = 'default') { + const director = cclegacy.director; const root = director.root; const shadingWidth = width; const shadingHeight = height; const pipeline = root.pipeline as WebPipeline; const layoutGraph = pipeline.layoutGraph; // Global - setter.addConstant('CCGlobal'); + if (!setter.addConstant('CCGlobal', layoutName)) return; setter.setVec4('cc_time', new Vec4(root.cumulativeTime, root.frameTime, director.getTotalFrames())); setter.setVec4('cc_screenSize', new Vec4(shadingWidth, shadingHeight, 1.0 / shadingWidth, 1.0 / shadingHeight)); setter.setVec4('cc_nativeSize', new Vec4(shadingWidth, shadingHeight, 1.0 / shadingWidth, 1.0 / shadingHeight)); @@ -1137,7 +1313,7 @@ export class WebPipeline implements Pipeline { private _pipelineUBO: PipelineUBO = new PipelineUBO(); private _cameras: Camera[] = []; - private _layoutGraph: LayoutGraphData = new LayoutGraphData(); + private _layoutGraph: LayoutGraphData; private readonly _resourceGraph: ResourceGraph = new ResourceGraph(); private _renderGraph: RenderGraph | null = null; private _compiler: Compiler | null = null; @@ -1145,7 +1321,9 @@ export class WebPipeline implements Pipeline { private _customPipelineName = ''; private _forward!: ForwardPipelineBuilder; private _deferred!: DeferredPipelineBuilder; + private _globalDescSetData!: DescriptorSetData; public builder: PipelineBuilder | null = null; + private _combineSignY = 0; // csm uniform used vectors count public static CSM_UNIFORM_VECTORS = 61; // all global uniform used vectors count diff --git a/cocos/rendering/custom/web-program-library.ts b/cocos/rendering/custom/web-program-library.ts new file mode 100644 index 00000000000..51e720e1418 --- /dev/null +++ b/cocos/rendering/custom/web-program-library.ts @@ -0,0 +1,1005 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + +/* eslint-disable max-len */ +import { EffectAsset } from '../../asset/assets'; +import { Attribute, DescriptorSetLayout, DescriptorType, DESCRIPTOR_BUFFER_TYPE, DESCRIPTOR_SAMPLER_TYPE, Device, MemoryAccessBit, PipelineLayout, PipelineLayoutInfo, Shader, ShaderInfo, ShaderStage, ShaderStageFlagBit, Type, Uniform, UniformBlock, UniformInputAttachment, UniformSampler, UniformSamplerTexture, UniformStorageBuffer, UniformStorageImage, UniformTexture } from '../../gfx'; +import { genHandles, getActiveAttributes, getCombinationDefines, getShaderInstanceName, getSize, getVariantKey, populateMacros, prepareDefines } from '../../render-scene/core/program-utils'; +import { getDeviceShaderVersion, MacroRecord } from '../../render-scene'; +import { IProgramInfo } from '../../render-scene/core/program-lib'; +import { DescriptorBlockData, DescriptorData, DescriptorSetData, DescriptorSetLayoutData, LayoutGraphData, LayoutGraphDataValue, PipelineLayoutData, RenderPhaseData, ShaderProgramData } from './layout-graph'; +import { ProgramLibrary, ProgramProxy } from './private'; +import { DescriptorTypeOrder, UpdateFrequency } from './types'; +import { ProgramGroup, ProgramInfo } from './web-types'; +import { getCustomPassID, getCustomPhaseID, getOrCreateDescriptorSetLayout, getEmptyDescriptorSetLayout, getEmptyPipelineLayout, initializeDescriptorSetLayoutInfo, makeDescriptorSetLayoutData, getDescriptorSetLayout, getOrCreateDescriptorID, getDescriptorTypeOrder, getProgramID, getDescriptorNameID, getDescriptorName, INVALID_ID } from './layout-graph-utils'; +import { assert } from '../../core/platform/debug'; +import { IDescriptorSetLayoutInfo, localDescriptorSetLayout } from '../define'; +import { PipelineRuntime } from './pipeline'; + +const _setIndex = [2, 1, 3, 0]; + +// make IProgramInfo from IShaderInfo +function makeProgramInfo (effectName: string, shader: EffectAsset.IShaderInfo): IProgramInfo { + const programInfo = { ...shader } as IProgramInfo; + programInfo.effectName = effectName; + + populateMacros(programInfo); + + return programInfo; +} + +// overwrite IProgramInfo using gfx.ShaderInfo +function overwriteProgramBlockInfo (shaderInfo: ShaderInfo, programInfo: IProgramInfo) { + const set = _setIndex[UpdateFrequency.PER_BATCH]; + for (const block of programInfo.blocks) { + let found = false; + for (const src of shaderInfo.blocks) { + if (src.set !== set) { + continue; + } + if (src.name === block.name) { + block.binding = src.binding; + found = true; + break; + } + } + if (!found) { + console.error(`Block ${block.name} not found in shader ${shaderInfo.name}`); + } + } +} + +// add descriptor to size-reserved descriptor set +function populateGroupedShaderInfo ( + layout: DescriptorSetLayoutData, + descriptorInfo: EffectAsset.IDescriptorInfo, + set: number, shaderInfo: ShaderInfo, blockSizes: number[], +) { + for (const descriptorBlock of layout.descriptorBlocks) { + const visibility = descriptorBlock.visibility; + let binding = descriptorBlock.offset; + + switch (descriptorBlock.type) { + case DescriptorTypeOrder.UNIFORM_BUFFER: + for (const block of descriptorInfo.blocks) { + if (block.stageFlags !== visibility) { + continue; + } + blockSizes.push(getSize(block.members)); + shaderInfo.blocks.push( + new UniformBlock(set, binding, block.name, + block.members.map((m) => new Uniform(m.name, m.type, m.count)), + 1), // count is always 1 for UniformBlock + ); + ++binding; + } + break; + case DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER: + // not implemented yet + break; + case DescriptorTypeOrder.SAMPLER_TEXTURE: + for (const tex of descriptorInfo.samplerTextures) { + if (tex.stageFlags !== visibility) { + continue; + } + shaderInfo.samplerTextures.push(new UniformSamplerTexture( + set, binding, tex.name, tex.type, tex.count, + )); + ++binding; + } + break; + case DescriptorTypeOrder.SAMPLER: + for (const sampler of descriptorInfo.samplers) { + if (sampler.stageFlags !== visibility) { + continue; + } + shaderInfo.samplers.push(new UniformSampler( + set, binding, sampler.name, sampler.count, + )); + ++binding; + } + break; + case DescriptorTypeOrder.TEXTURE: + for (const texture of descriptorInfo.textures) { + if (texture.stageFlags !== visibility) { + continue; + } + shaderInfo.textures.push(new UniformTexture( + set, binding, texture.name, texture.type, texture.count, + )); + ++binding; + } + break; + case DescriptorTypeOrder.STORAGE_BUFFER: + for (const buffer of descriptorInfo.buffers) { + if (buffer.stageFlags !== visibility) { + continue; + } + shaderInfo.buffers.push(new UniformStorageBuffer( + set, binding, buffer.name, 1, buffer.memoryAccess, + )); // effect compiler guarantees buffer count = 1 + ++binding; + } + break; + case DescriptorTypeOrder.DYNAMIC_STORAGE_BUFFER: + // not implemented yet + break; + case DescriptorTypeOrder.STORAGE_IMAGE: + for (const image of descriptorInfo.images) { + if (image.stageFlags !== visibility) { + continue; + } + shaderInfo.images.push(new UniformStorageImage( + set, binding, image.name, image.type, image.count, image.memoryAccess, + )); + ++binding; + } + break; + case DescriptorTypeOrder.INPUT_ATTACHMENT: + for (const subpassInput of descriptorInfo.subpassInputs) { + if (subpassInput.stageFlags !== visibility) { + continue; + } + shaderInfo.subpassInputs.push(new UniformInputAttachment( + set, subpassInput.binding, subpassInput.name, subpassInput.count, + )); + ++binding; + } + break; + default: + } + } +} + +// add merged descriptor to gfx.ShaderInfo +function populateMergedShaderInfo (valueNames: string[], + layout: DescriptorSetLayoutData, + set: number, shaderInfo: ShaderInfo, blockSizes: number[]) { + for (const descriptorBlock of layout.descriptorBlocks) { + let binding = descriptorBlock.offset; + switch (descriptorBlock.type) { + case DescriptorTypeOrder.UNIFORM_BUFFER: + for (const block of descriptorBlock.descriptors) { + const uniformBlock = layout.uniformBlocks.get(block.descriptorID); + if (uniformBlock === undefined) { + console.error(`Failed to find uniform block ${block.descriptorID} in layout`); + continue; + } + blockSizes.push(getSize(uniformBlock.members)); + shaderInfo.blocks.push( + new UniformBlock(set, binding, valueNames[block.descriptorID], + uniformBlock.members.map((m) => new Uniform(m.name, m.type, m.count)), + 1), // count is always 1 for UniformBlock + ); + ++binding; + } + if (binding !== descriptorBlock.offset + descriptorBlock.capacity) { + console.error(`Uniform buffer binding mismatch for set ${set}`); + } + break; + case DescriptorTypeOrder.DYNAMIC_UNIFORM_BUFFER: + // not implemented yet + break; + case DescriptorTypeOrder.SAMPLER_TEXTURE: + for (const tex of descriptorBlock.descriptors) { + shaderInfo.samplerTextures.push(new UniformSamplerTexture( + set, binding, valueNames[tex.descriptorID], tex.type, tex.count, + )); + ++binding; + } + break; + case DescriptorTypeOrder.SAMPLER: + for (const sampler of descriptorBlock.descriptors) { + shaderInfo.samplers.push(new UniformSampler( + set, binding, valueNames[sampler.descriptorID], sampler.count, + )); + ++binding; + } + break; + case DescriptorTypeOrder.TEXTURE: + for (const texture of descriptorBlock.descriptors) { + shaderInfo.textures.push(new UniformTexture( + set, binding, valueNames[texture.descriptorID], texture.type, texture.count, + )); + ++binding; + } + break; + case DescriptorTypeOrder.STORAGE_BUFFER: + for (const buffer of descriptorBlock.descriptors) { + shaderInfo.buffers.push(new UniformStorageBuffer( + set, binding, valueNames[buffer.descriptorID], 1, + MemoryAccessBit.READ_WRITE/*buffer.memoryAccess*/, + )); // effect compiler guarantees buffer count = 1 + ++binding; + } + break; + case DescriptorTypeOrder.DYNAMIC_STORAGE_BUFFER: + // not implemented yet + break; + case DescriptorTypeOrder.STORAGE_IMAGE: + for (const image of descriptorBlock.descriptors) { + shaderInfo.images.push(new UniformStorageImage( + set, binding, valueNames[image.descriptorID], image.type, image.count, + MemoryAccessBit.READ_WRITE/*image.memoryAccess*/, + )); + ++binding; + } + break; + case DescriptorTypeOrder.INPUT_ATTACHMENT: + for (const subpassInput of descriptorBlock.descriptors) { + shaderInfo.subpassInputs.push(new UniformInputAttachment( + set, binding, valueNames[subpassInput.descriptorID], subpassInput.count, + )); + ++binding; + } + break; + default: + } + } +} + +// add descriptor from effect to gfx.ShaderInfo +function populateShaderInfo ( + descriptorInfo: EffectAsset.IDescriptorInfo, + set: number, shaderInfo: ShaderInfo, blockSizes: number[], +) { + for (let i = 0; i < descriptorInfo.blocks.length; i++) { + const block = descriptorInfo.blocks[i]; + blockSizes.push(getSize(block.members)); + shaderInfo.blocks.push(new UniformBlock(set, block.binding, block.name, + block.members.map((m) => new Uniform(m.name, m.type, m.count)), 1)); // effect compiler guarantees block count = 1 + } + for (let i = 0; i < descriptorInfo.samplerTextures.length; i++) { + const samplerTexture = descriptorInfo.samplerTextures[i]; + shaderInfo.samplerTextures.push(new UniformSamplerTexture( + set, samplerTexture.binding, samplerTexture.name, samplerTexture.type, samplerTexture.count, + )); + } + for (let i = 0; i < descriptorInfo.samplers.length; i++) { + const sampler = descriptorInfo.samplers[i]; + shaderInfo.samplers.push(new UniformSampler( + set, sampler.binding, sampler.name, sampler.count, + )); + } + for (let i = 0; i < descriptorInfo.textures.length; i++) { + const texture = descriptorInfo.textures[i]; + shaderInfo.textures.push(new UniformTexture( + set, texture.binding, texture.name, texture.type, texture.count, + )); + } + for (let i = 0; i < descriptorInfo.buffers.length; i++) { + const buffer = descriptorInfo.buffers[i]; + shaderInfo.buffers.push(new UniformStorageBuffer( + set, buffer.binding, buffer.name, 1, buffer.memoryAccess, + )); // effect compiler guarantees buffer count = 1 + } + for (let i = 0; i < descriptorInfo.images.length; i++) { + const image = descriptorInfo.images[i]; + shaderInfo.images.push(new UniformStorageImage( + set, image.binding, image.name, image.type, image.count, image.memoryAccess, + )); + } + for (let i = 0; i < descriptorInfo.subpassInputs.length; i++) { + const subpassInput = descriptorInfo.subpassInputs[i]; + shaderInfo.subpassInputs.push(new UniformInputAttachment( + set, subpassInput.binding, subpassInput.name, subpassInput.count, + )); + } +} + +// add fixed local descriptors to gfx.ShaderInfo +function populateLocalShaderInfo ( + target: EffectAsset.IDescriptorInfo, + source: IDescriptorSetLayoutInfo, shaderInfo: ShaderInfo, blockSizes: number[], +) { + const set = _setIndex[UpdateFrequency.PER_INSTANCE]; + for (let i = 0; i < target.blocks.length; i++) { + const block = target.blocks[i]; + const info = source.layouts[block.name] as UniformBlock | undefined; + const binding = info && source.bindings.find((bd) => bd.binding === info.binding); + if (!info || !binding || !(binding.descriptorType & DESCRIPTOR_BUFFER_TYPE)) { + console.warn(`builtin UBO '${block.name}' not available!`); + continue; + } + blockSizes.push(getSize(block.members)); + shaderInfo.blocks.push(new UniformBlock(set, binding.binding, block.name, + block.members.map((m) => new Uniform(m.name, m.type, m.count)), 1)); // effect compiler guarantees block count = 1 + } + for (let i = 0; i < target.samplerTextures.length; i++) { + const samplerTexture = target.samplerTextures[i]; + const info = source.layouts[samplerTexture.name] as UniformSamplerTexture; + const binding = info && source.bindings.find((bd) => bd.binding === info.binding); + if (!info || !binding || !(binding.descriptorType & DESCRIPTOR_SAMPLER_TYPE)) { + console.warn(`builtin samplerTexture '${samplerTexture.name}' not available!`); + continue; + } + shaderInfo.samplerTextures.push(new UniformSamplerTexture( + set, binding.binding, samplerTexture.name, samplerTexture.type, samplerTexture.count, + )); + } +} + +function getIDescriptorSetLayoutInfoUniformBlockCapacity (info: IDescriptorSetLayoutInfo): number { + let capacity = 0; + for (const binding of info.bindings) { + if (binding.descriptorType === DescriptorType.UNIFORM_BUFFER + || binding.descriptorType === DescriptorType.DYNAMIC_UNIFORM_BUFFER) { + capacity += binding.count; + } + } + return capacity; +} + +function getIDescriptorSetLayoutInfoSamplerTextureCapacity (info: IDescriptorSetLayoutInfo): number { + let capacity = 0; + for (const binding of info.bindings) { + if (binding.descriptorType !== DescriptorType.UNIFORM_BUFFER + && binding.descriptorType !== DescriptorType.DYNAMIC_UNIFORM_BUFFER) { + capacity += binding.count; + } + } + return capacity; +} + +function setFlattenedUniformBlockBinding (setOffsets: number[], + descriptors: UniformBlock[]) { + for (const d of descriptors) { + d.flattened = setOffsets[d.set] + d.binding; + } +} + +function setFlattenedSamplerTextureBinding (setOffsets: number[], + uniformBlockCapacities: number[], + descriptors: UniformSamplerTexture[] + | UniformSampler[] + | UniformTexture[] + | UniformStorageBuffer[] + | UniformStorageImage[] + | UniformInputAttachment[]) { + for (const d of descriptors) { + d.flattened = setOffsets[d.set] + d.binding - uniformBlockCapacities[d.set]; + } +} + +function calculateFlattenedBinding ( + descriptorSets: (DescriptorSetLayoutData | null)[], + fixedInstanceDescriptorSetLayout: IDescriptorSetLayoutInfo | null, + shaderInfo: ShaderInfo, +) { + // Descriptors of UniformBlock starts from 0, and Descriptors of SamplerTexture starts from the end of UniformBlock. + const uniformBlockCapacities = new Array(4); + { + const passCapacity = descriptorSets[UpdateFrequency.PER_PASS]?.uniformBlockCapacity || 0; + const phaseCapacity = descriptorSets[UpdateFrequency.PER_PHASE]?.uniformBlockCapacity || 0; + const batchCapacity = descriptorSets[UpdateFrequency.PER_BATCH]?.uniformBlockCapacity || 0; // dynamic size + const instanceCapacity = fixedInstanceDescriptorSetLayout + ? getIDescriptorSetLayoutInfoUniformBlockCapacity(fixedInstanceDescriptorSetLayout) + : (descriptorSets[UpdateFrequency.PER_INSTANCE]?.uniformBlockCapacity || 0); + + // update uniform block capacities + uniformBlockCapacities[_setIndex[UpdateFrequency.PER_PASS]] = passCapacity; + uniformBlockCapacities[_setIndex[UpdateFrequency.PER_PHASE]] = phaseCapacity; + uniformBlockCapacities[_setIndex[UpdateFrequency.PER_BATCH]] = batchCapacity; + uniformBlockCapacities[_setIndex[UpdateFrequency.PER_INSTANCE]] = instanceCapacity; + + // calculate uniform block offsets + const passOffset = 0; + const phaseOffset = passOffset + passCapacity; + const instanceOffset = phaseOffset + phaseCapacity; + const batchOffset = instanceOffset + instanceCapacity; + + // save uniform block offsets by set index + const uniformBlockOffsets = new Array(4); + uniformBlockOffsets[_setIndex[UpdateFrequency.PER_PASS]] = passOffset; + uniformBlockOffsets[_setIndex[UpdateFrequency.PER_PHASE]] = phaseOffset; + uniformBlockOffsets[_setIndex[UpdateFrequency.PER_BATCH]] = batchOffset; + uniformBlockOffsets[_setIndex[UpdateFrequency.PER_INSTANCE]] = instanceOffset; + + // update flattened uniform block binding + setFlattenedUniformBlockBinding(uniformBlockOffsets, shaderInfo.blocks); + } + { + // calculate sampler texture capacities + const passCapacity = descriptorSets[UpdateFrequency.PER_PASS]?.samplerTextureCapacity || 0; + const phaseCapacity = descriptorSets[UpdateFrequency.PER_PHASE]?.samplerTextureCapacity || 0; + // const batchCapacity = descriptorSets[UpdateFrequency.PER_BATCH]?.capacity || 0; // dynamic size + const instanceCapacity = fixedInstanceDescriptorSetLayout + ? getIDescriptorSetLayoutInfoSamplerTextureCapacity(fixedInstanceDescriptorSetLayout) + : (descriptorSets[UpdateFrequency.PER_INSTANCE]?.samplerTextureCapacity || 0); + + // calculate sampler texture offsets + const passOffset = 0; + const phaseOffset = passOffset + passCapacity; + const instanceOffset = phaseOffset + phaseCapacity; + const batchOffset = instanceOffset + instanceCapacity; + + // save sampler texture offsets by set index + const samplerTextureOffsets = new Array(4); + samplerTextureOffsets[_setIndex[UpdateFrequency.PER_PASS]] = passOffset; + samplerTextureOffsets[_setIndex[UpdateFrequency.PER_PHASE]] = phaseOffset; + samplerTextureOffsets[_setIndex[UpdateFrequency.PER_BATCH]] = batchOffset; + samplerTextureOffsets[_setIndex[UpdateFrequency.PER_INSTANCE]] = instanceOffset; + + // update flattened sampler texture binding + setFlattenedSamplerTextureBinding(samplerTextureOffsets, uniformBlockCapacities, shaderInfo.samplerTextures); + } +} + +// make gfx.ShaderInfo +function makeShaderInfo ( + lg: LayoutGraphData, + passLayouts: PipelineLayoutData, + phaseLayouts: PipelineLayoutData, + srcShaderInfo: EffectAsset.IShaderInfo, + programData: ShaderProgramData | null, + fixedLocal: boolean, +): [ShaderInfo, Array] { + const descriptorSets: Array = [null, null, null, null]; + let fixedInstanceDescriptorSetLayout: IDescriptorSetLayoutInfo | null = null; + const shaderInfo = new ShaderInfo(); + const blockSizes = new Array(); + { // pass + const passLayout = passLayouts.descriptorSets.get(UpdateFrequency.PER_PASS); + if (passLayout) { + descriptorSets[UpdateFrequency.PER_PASS] = passLayout.descriptorSetLayoutData; + populateMergedShaderInfo(lg.valueNames, passLayout.descriptorSetLayoutData, + _setIndex[UpdateFrequency.PER_PASS], shaderInfo, blockSizes); + } + } + { // phase + const phaseLayout = phaseLayouts.descriptorSets.get(UpdateFrequency.PER_PHASE); + if (phaseLayout) { + descriptorSets[UpdateFrequency.PER_PHASE] = phaseLayout.descriptorSetLayoutData; + populateMergedShaderInfo(lg.valueNames, phaseLayout.descriptorSetLayoutData, + _setIndex[UpdateFrequency.PER_PHASE], shaderInfo, blockSizes); + } + } + { // batch + const batchInfo = srcShaderInfo.descriptors[UpdateFrequency.PER_BATCH]; + if (programData) { + const perBatch = programData.layout.descriptorSets.get(UpdateFrequency.PER_BATCH); + if (perBatch) { + descriptorSets[UpdateFrequency.PER_BATCH] = perBatch.descriptorSetLayoutData; + populateMergedShaderInfo(lg.valueNames, perBatch.descriptorSetLayoutData, + _setIndex[UpdateFrequency.PER_BATCH], shaderInfo, blockSizes); + } + } else { + const batchLayout = phaseLayouts.descriptorSets.get(UpdateFrequency.PER_BATCH); + if (batchLayout) { + descriptorSets[UpdateFrequency.PER_BATCH] = batchLayout.descriptorSetLayoutData; + populateGroupedShaderInfo(batchLayout.descriptorSetLayoutData, + batchInfo, _setIndex[UpdateFrequency.PER_BATCH], + shaderInfo, blockSizes); + } + } + } + { // instance + const instanceInfo = srcShaderInfo.descriptors[UpdateFrequency.PER_INSTANCE]; + if (programData) { + if (fixedLocal) { + fixedInstanceDescriptorSetLayout = localDescriptorSetLayout; + populateLocalShaderInfo(instanceInfo, localDescriptorSetLayout, shaderInfo, blockSizes); + } else { + const perInstance = programData.layout.descriptorSets.get(UpdateFrequency.PER_INSTANCE); + if (perInstance) { + descriptorSets[UpdateFrequency.PER_INSTANCE] = perInstance.descriptorSetLayoutData; + populateMergedShaderInfo(lg.valueNames, perInstance.descriptorSetLayoutData, + _setIndex[UpdateFrequency.PER_INSTANCE], shaderInfo, blockSizes); + } + } + } else { + const instanceLayout = phaseLayouts.descriptorSets.get(UpdateFrequency.PER_INSTANCE); + if (instanceLayout) { + descriptorSets[UpdateFrequency.PER_INSTANCE] = instanceLayout.descriptorSetLayoutData; + populateGroupedShaderInfo(instanceLayout.descriptorSetLayoutData, + instanceInfo, _setIndex[UpdateFrequency.PER_INSTANCE], + shaderInfo, blockSizes); + } + } + } + calculateFlattenedBinding(descriptorSets, fixedInstanceDescriptorSetLayout, shaderInfo); + shaderInfo.stages.push(new ShaderStage(ShaderStageFlagBit.VERTEX, '')); + shaderInfo.stages.push(new ShaderStage(ShaderStageFlagBit.FRAGMENT, '')); + return [shaderInfo, blockSizes]; +} + +class WebProgramProxy implements ProgramProxy { + constructor (shader: Shader) { + this.shader = shader; + } + get name (): string { + return this.shader.name; + } + readonly shader: Shader; +} + +// find name and type from local descriptor set info +function getDescriptorNameAndType (source: IDescriptorSetLayoutInfo, binding: number): [string, Type] { + for (const name in source.layouts) { + const v = source.layouts[name]; + if (v.binding === binding) { + assert(v.name === name); + let type = Type.UNKNOWN; + if (v instanceof UniformSamplerTexture) { + type = v.type; + } else if (v instanceof UniformStorageImage) { + type = v.type; + } + return [v.name, type]; + } + } + console.error('descriptor not found'); + return ['', Type.UNKNOWN]; +} + +// make DescriptorSetLayoutData from local descriptor set info +function makeLocalDescriptorSetLayoutData (lg: LayoutGraphData, + source: IDescriptorSetLayoutInfo): DescriptorSetLayoutData { + const data = new DescriptorSetLayoutData(); + for (const b of source.bindings) { + const [name, type] = getDescriptorNameAndType(source, b.binding); + const nameID = getOrCreateDescriptorID(lg, name); + const order = getDescriptorTypeOrder(b.descriptorType); + const block = new DescriptorBlockData(order, b.stageFlags, b.count); + block.offset = b.binding; + block.descriptors.push(new DescriptorData(nameID, type, b.count)); + data.descriptorBlocks.push(block); + const binding = data.bindingMap.get(nameID); + if (binding !== undefined) { + console.error(`duplicate descriptor name '${name}'`); + } + data.bindingMap.set(nameID, b.binding); + const v = source.layouts[name]; + if (v instanceof UniformBlock) { + data.uniformBlocks.set(nameID, v); + } + } + return data; +} + +// make descriptor sets for ShaderProgramData (PerBatch, PerInstance) +function buildProgramData ( + programName: string, + srcShaderInfo: EffectAsset.IShaderInfo, + lg: LayoutGraphData, phase: RenderPhaseData, programData: ShaderProgramData, + fixedLocal: boolean, +) { + { + const perBatch = makeDescriptorSetLayoutData(lg, + UpdateFrequency.PER_BATCH, + _setIndex[UpdateFrequency.PER_BATCH], + srcShaderInfo.descriptors[UpdateFrequency.PER_BATCH]); + const setData = new DescriptorSetData(perBatch); + initializeDescriptorSetLayoutInfo(setData.descriptorSetLayoutData, + setData.descriptorSetLayoutInfo); + programData.layout.descriptorSets.set(UpdateFrequency.PER_BATCH, setData); + } + if (fixedLocal) { + const perInstance = makeLocalDescriptorSetLayoutData(lg, localDescriptorSetLayout); + const setData = new DescriptorSetData(perInstance); + initializeDescriptorSetLayoutInfo(setData.descriptorSetLayoutData, + setData.descriptorSetLayoutInfo); + if (localDescriptorSetLayout.bindings.length !== setData.descriptorSetLayoutInfo.bindings.length) { + console.error('local descriptor set layout inconsistent'); + } else { + for (let k = 0; k !== localDescriptorSetLayout.bindings.length; ++k) { + const b = localDescriptorSetLayout.bindings[k]; + const b2 = setData.descriptorSetLayoutInfo.bindings[k]; + if (b.binding !== b2.binding + || b.descriptorType !== b2.descriptorType + || b.count !== b2.count + || b.stageFlags !== b2.stageFlags) { + console.error('local descriptor set layout inconsistent'); + } + } + } + programData.layout.descriptorSets.set(UpdateFrequency.PER_INSTANCE, setData); + } else { + const perInstance = makeDescriptorSetLayoutData(lg, + UpdateFrequency.PER_INSTANCE, + _setIndex[UpdateFrequency.PER_INSTANCE], + srcShaderInfo.descriptors[UpdateFrequency.PER_INSTANCE]); + const setData = new DescriptorSetData(perInstance); + initializeDescriptorSetLayoutInfo(setData.descriptorSetLayoutData, + setData.descriptorSetLayoutInfo); + programData.layout.descriptorSets.set(UpdateFrequency.PER_INSTANCE, setData); + } + const shaderID = phase.shaderPrograms.length; + phase.shaderIndex.set(programName, shaderID); + phase.shaderPrograms.push(programData); +} + +// get or create PerProgram gfx.DescriptorSetLayout +function getOrCreateProgramDescriptorSetLayout (device: Device, + lg: LayoutGraphData, phaseID: number, + programName: string, rate: UpdateFrequency): DescriptorSetLayout { + assert(rate < UpdateFrequency.PER_PHASE); + const phase = lg.getRenderPhase(phaseID); + const programID = phase.shaderIndex.get(programName); + if (programID === undefined) { + return getEmptyDescriptorSetLayout(); + } + const programData = phase.shaderPrograms[programID]; + const layout = programData.layout.descriptorSets.get(rate); + if (layout === undefined) { + return getEmptyDescriptorSetLayout(); + } + if (layout.descriptorSetLayout) { + return layout.descriptorSetLayout; + } + layout.descriptorSetLayout = device.createDescriptorSetLayout(layout.descriptorSetLayoutInfo); + + return layout.descriptorSetLayout; +} + +// get PerProgram gfx.DescriptorSetLayout +function getProgramDescriptorSetLayout (device: Device, + lg: LayoutGraphData, phaseID: number, + programName: string, rate: UpdateFrequency): DescriptorSetLayout | null { + assert(rate < UpdateFrequency.PER_PHASE); + const phase = lg.getRenderPhase(phaseID); + const programID = phase.shaderIndex.get(programName); + if (programID === undefined) { + return null; + } + const programData = phase.shaderPrograms[programID]; + const layout = programData.layout.descriptorSets.get(rate); + if (layout === undefined) { + return null; + } + if (layout.descriptorSetLayout) { + return layout.descriptorSetLayout; + } + layout.descriptorSetLayout = device.createDescriptorSetLayout(layout.descriptorSetLayoutInfo); + + return layout.descriptorSetLayout; +} + +// find shader program in LayoutGraphData +function getEffectShader (lg: LayoutGraphData, effect: EffectAsset, + pass: EffectAsset.IPassInfo): [number, number, EffectAsset.IShaderInfo | null, number] { + const programName = pass.program; + const passID = getCustomPassID(lg, pass.pass); + if (passID === INVALID_ID) { + console.error(`Invalid render pass, program: ${programName}`); + return [INVALID_ID, INVALID_ID, null, INVALID_ID]; + } + const phaseID = getCustomPhaseID(lg, passID, pass.phase); + if (phaseID === INVALID_ID) { + console.error(`Invalid render phase, program: ${programName}`); + return [passID, INVALID_ID, null, INVALID_ID]; + } + let srcShaderInfo: EffectAsset.IShaderInfo | null = null; + let shaderID = INVALID_ID; + for (let i = 0; i < effect.shaders.length; ++i) { + const shaderInfo = effect.shaders[i]; + if (shaderInfo.name === programName) { + srcShaderInfo = shaderInfo; + shaderID = i; + break; + } + } + return [passID, phaseID, srcShaderInfo, shaderID]; +} + +// valid IShaderInfo is compatible +function validateShaderInfo (srcShaderInfo: EffectAsset.IShaderInfo): number { + // source shader info + if (srcShaderInfo.descriptors === undefined) { + console.error(`No descriptors in shader: ${srcShaderInfo.name}, please reimport ALL effects`); + return 1; + } + return 0; +} + +export class WebProgramLibrary implements ProgramLibrary { + constructor (lg: LayoutGraphData) { + this.layoutGraph = lg; + for (const v of lg.vertices()) { + if (lg.holds(LayoutGraphDataValue.RenderPhase, v)) { + this.phases.set(v, new ProgramGroup()); + } + } + } + // add effect to database + addEffect (effect: EffectAsset): void { + const lg = this.layoutGraph; + for (const tech of effect.techniques) { + for (const pass of tech.passes) { + const programName = pass.program; + const [passID, phaseID, srcShaderInfo] = getEffectShader(lg, effect, pass); + if (srcShaderInfo === null || validateShaderInfo(srcShaderInfo)) { + console.error(`program: ${programName} not found`); + continue; + } + assert(passID !== INVALID_ID && phaseID !== INVALID_ID); + const passLayout = lg.getLayout(passID); + const phaseLayout = lg.getLayout(phaseID); + + // programs + let group = this.phases.get(phaseID); + if (group === undefined) { + group = new ProgramGroup(); + this.phases.set(phaseID, group); + } + const phasePrograms = group.programInfos; + + // build program + const programInfo = makeProgramInfo(effect.name, srcShaderInfo); + + // collect program descriptors + let programData: ShaderProgramData | null = null; + if (!this.mergeHighFrequency) { + const phase = lg.getRenderPhase(phaseID); + programData = new ShaderProgramData(); + buildProgramData(programName, srcShaderInfo, lg, phase, programData, this.fixedLocal); + } + + // shaderInfo and blockSizes + const [shaderInfo, blockSizes] = makeShaderInfo(lg, passLayout, phaseLayout, + srcShaderInfo, programData, this.fixedLocal); + + // overwrite programInfo + overwriteProgramBlockInfo(shaderInfo, programInfo); + + // handle map + const handleMap = genHandles(shaderInfo); + // attributes + const attributes = new Array(); + for (const attr of programInfo.attributes) { + attributes.push(new Attribute( + attr.name, attr.format, attr.isNormalized, 0, attr.isInstanced, attr.location, + )); + } + // create programInfo + const info = new ProgramInfo(programInfo, shaderInfo, attributes, blockSizes, handleMap); + phasePrograms.set(srcShaderInfo.name, info); + } + } + } + // precompile effect + precompileEffect (device: Device, effect: EffectAsset): void { + const lg = this.layoutGraph; + for (const tech of effect.techniques) { + for (const pass of tech.passes) { + const programName = pass.program; + const [passID, phaseID, srcShaderInfo, shaderID] = getEffectShader(lg, effect, pass); + if (srcShaderInfo === null || validateShaderInfo(srcShaderInfo)) { + console.error(`program: ${programName} not valid`); + continue; + } + assert(passID !== INVALID_ID && phaseID !== INVALID_ID && shaderID !== INVALID_ID); + const combination = effect.combinations[shaderID]; + if (!combination) { + continue; + } + const defines = getCombinationDefines(combination); + defines.forEach( + (defines) => this.getProgramVariant( + device, phaseID, programName, defines, + ), + ); + } + } + } + // get IProgramInfo + getProgramInfo (phaseID: number, programName: string): IProgramInfo { + assert(phaseID !== INVALID_ID); + const group = this.phases.get(phaseID)!; + const info = group.programInfos.get(programName)!; + return info.programInfo; + } + + // get gfx.ShaderInfo + getShaderInfo (phaseID: number, programName: string): ShaderInfo { + assert(phaseID !== INVALID_ID); + const group = this.phases.get(phaseID)!; + const info = group.programInfos.get(programName)!; + return info.shaderInfo; + } + // get shader key + getKey (phaseID: number, programName: string, defines: MacroRecord): string { + assert(phaseID !== INVALID_ID); + // get phase + const group = this.phases.get(phaseID); + if (group === undefined) { + console.error(`Invalid render phase, program: ${programName}`); + return ''; + } + // get info + const info = group.programInfos.get(programName); + if (info === undefined) { + console.error(`Invalid program, program: ${programName}`); + return ''; + } + return getVariantKey(info.programInfo, defines); + } + // get program variant + getProgramVariant (device: Device, phaseID: number, name: string, defines: MacroRecord, key: string | null = null): ProgramProxy | null { + Object.assign(defines, this.pipeline?.macros); + assert(phaseID !== INVALID_ID); + // get phase + const group = this.phases.get(phaseID); + if (group === undefined) { + console.error(`Invalid render phase, program: ${name}`); + return null; + } + // get info + const info = group.programInfos.get(name); + if (info === undefined) { + console.error(`Invalid program, program: ${name}`); + return null; + } + const programInfo = info.programInfo; + if (key === null) { + key = getVariantKey(programInfo, defines); + } + + // try get program + const programHosts = group.programProxies; + const programHost = programHosts.get(key); + if (programHost !== undefined) { + return programHost; + } + + // prepare variant + const macroArray = prepareDefines(defines, programInfo.defines); + const prefix = this.layoutGraph.constantMacros + programInfo.constantMacros + + macroArray.reduce((acc, cur) => `${acc}#define ${cur.name} ${cur.value}\n`, ''); + + let src = programInfo.glsl3; + const deviceShaderVersion = getDeviceShaderVersion(device); + if (deviceShaderVersion) { + src = programInfo[deviceShaderVersion]; + } else { + console.error('Invalid GFX API!'); + } + + // prepare shader info + const shaderInfo = info.shaderInfo; + shaderInfo.stages[0].source = prefix + src.vert; + shaderInfo.stages[1].source = prefix + src.frag; + shaderInfo.attributes = getActiveAttributes(programInfo, info.attributes, defines); + shaderInfo.name = getShaderInstanceName(name, macroArray); + + // create shader + const shader = device.createShader(shaderInfo); + + // create program host and register + const host = new WebProgramProxy(shader); + programHosts.set(key, host); + + // create + return host; + } + // get material descriptor set layout + getMaterialDescriptorSetLayout (device: Device, phaseID: number, programName: string): DescriptorSetLayout { + if (this.mergeHighFrequency) { + assert(phaseID !== INVALID_ID); + const passID = this.layoutGraph.getParent(phaseID); + return getOrCreateDescriptorSetLayout(this.layoutGraph, passID, phaseID, UpdateFrequency.PER_BATCH); + } + return getOrCreateProgramDescriptorSetLayout(device, this.layoutGraph, + phaseID, programName, UpdateFrequency.PER_BATCH); + } + // get local descriptor set layout + getLocalDescriptorSetLayout (device: Device, phaseID: number, programName: string): DescriptorSetLayout { + if (this.mergeHighFrequency) { + assert(phaseID !== INVALID_ID); + const passID = this.layoutGraph.getParent(phaseID); + return getOrCreateDescriptorSetLayout(this.layoutGraph, passID, phaseID, UpdateFrequency.PER_INSTANCE); + } + return getOrCreateProgramDescriptorSetLayout(device, this.layoutGraph, + phaseID, programName, UpdateFrequency.PER_INSTANCE); + } + // get related uniform block sizes + getBlockSizes (phaseID: number, programName: string): number[] { + assert(phaseID !== INVALID_ID); + const group = this.phases.get(phaseID); + if (!group) { + console.error(`Invalid render phase, program: ${programName}`); + return []; + } + const info = group.programInfos.get(programName); + if (!info) { + console.error(`Invalid program, program: ${programName}`); + return []; + } + return info.blockSizes; + } + // get property handle map + getHandleMap (phaseID: number, programName: string): Record { + assert(phaseID !== INVALID_ID); + const group = this.phases.get(phaseID); + if (!group) { + console.error(`Invalid render phase, program: ${programName}`); + return {}; + } + const info = group.programInfos.get(programName); + if (!info) { + console.error(`Invalid program, program: ${programName}`); + return {}; + } + return info.handleMap; + } + // get shader pipeline layout + getPipelineLayout (device: Device, phaseID: number, programName: string): PipelineLayout { + if (this.mergeHighFrequency) { + assert(phaseID !== INVALID_ID); + const layout = this.layoutGraph.getRenderPhase(phaseID); + return layout.pipelineLayout!; + } + const lg = this.layoutGraph; + const phase = lg.getRenderPhase(phaseID); + const programID = phase.shaderIndex.get(programName); + if (programID === undefined) { + return getEmptyPipelineLayout(); + } + const programData = phase.shaderPrograms[programID]; + if (programData.pipelineLayout) { + return programData.pipelineLayout; + } + + // get pass + const passID = lg.getParent(phaseID); + if (passID === lg.nullVertex()) { + return getEmptyPipelineLayout(); + } + + // craete pipeline layout + const info = new PipelineLayoutInfo(); + const passSet = getDescriptorSetLayout(this.layoutGraph, passID, phaseID, UpdateFrequency.PER_PASS); + if (passSet) { + info.setLayouts.push(passSet); + } + const phaseSet = getDescriptorSetLayout(this.layoutGraph, passID, phaseID, UpdateFrequency.PER_PHASE); + if (phaseSet) { + info.setLayouts.push(phaseSet); + } + const batchSet = getProgramDescriptorSetLayout(device, lg, phaseID, programName, UpdateFrequency.PER_BATCH); + if (batchSet) { + info.setLayouts.push(batchSet); + } + const instanceSet = getProgramDescriptorSetLayout(device, lg, phaseID, programName, UpdateFrequency.PER_INSTANCE); + if (instanceSet) { + info.setLayouts.push(instanceSet); + } + programData.pipelineLayout = device.createPipelineLayout(info); + return programData.pipelineLayout; + } + getProgramID (phaseID: number, programName: string): number { + return getProgramID(this.layoutGraph, phaseID, programName); + } + getDescriptorNameID (name: string): number { + return getDescriptorNameID(this.layoutGraph, name); + } + getDescriptorName (nameID: number): string { + return getDescriptorName(this.layoutGraph, nameID); + } + readonly layoutGraph: LayoutGraphData; + readonly phases: Map = new Map(); + mergeHighFrequency = false; + fixedLocal = true; + pipeline: PipelineRuntime | null = null; +} diff --git a/cocos/rendering/custom/web-scene-visitor.ts b/cocos/rendering/custom/web-scene-visitor.ts index cd5c573d2b5..81f3d187c15 100644 --- a/cocos/rendering/custom/web-scene-visitor.ts +++ b/cocos/rendering/custom/web-scene-visitor.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/rendering/custom/web-scene.ts b/cocos/rendering/custom/web-scene.ts index 5b6a1062c06..026c26e51da 100644 --- a/cocos/rendering/custom/web-scene.ts +++ b/cocos/rendering/custom/web-scene.ts @@ -1,18 +1,17 @@ /**************************************************************************** - Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -114,6 +113,10 @@ export class WebSceneTask implements SceneTask { // filter model by view visibility if (model.enabled) { + if (scene && scene.isCulledByLod(camera, model)) { + continue; + } + if (model.castShadow) { castShadowObjects.push(this._getRenderObject(model, camera)); csmLayerObjects.push(this._getRenderObject(model, camera)); diff --git a/cocos/rendering/custom/web-types.ts b/cocos/rendering/custom/web-types.ts new file mode 100644 index 00000000000..b275b9abde9 --- /dev/null +++ b/cocos/rendering/custom/web-types.ts @@ -0,0 +1,59 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + +/** + * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= + * The following section is auto-generated. + * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= + */ +/* eslint-disable max-len */ +import { Attribute, ShaderInfo } from '../../gfx'; +import { ProgramProxy } from './private'; +import { IProgramInfo } from '../../render-scene/core/program-lib'; + +export class ProgramInfo { + constructor ( + programInfo: IProgramInfo, + shaderInfo: ShaderInfo, + attributes: Attribute[], + blockSizes: number[], + handleMap: Record, + ) { + this.programInfo = programInfo; + this.shaderInfo = shaderInfo; + this.attributes = attributes; + this.blockSizes = blockSizes; + this.handleMap = handleMap; + } + readonly programInfo: IProgramInfo; + readonly shaderInfo: ShaderInfo; + readonly attributes: Attribute[]; + readonly blockSizes: number[]; + readonly handleMap: Record; +} + +export class ProgramGroup { + readonly programInfos: Map = new Map(); + readonly programProxies: Map = new Map(); +} diff --git a/cocos/rendering/debug-view.ts b/cocos/rendering/debug-view.ts index b4434339bbb..e2e5fe19c14 100644 --- a/cocos/rendering/debug-view.ts +++ b/cocos/rendering/debug-view.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { JSB } from 'internal:constants'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import { Root } from '../root'; const enum RenderingDebugViewType { @@ -64,6 +63,7 @@ export const enum DebugViewSingleType { METALLIC, ROUGHNESS, SPECULAR_INTENSITY, + IOR, DIRECT_DIFFUSE, DIRECT_SPECULAR, @@ -76,6 +76,16 @@ export const enum DebugViewSingleType { SHADOW, AO, + FRESNEL, + DIRECT_TRANSMIT_DIFFUSE, + DIRECT_TRANSMIT_SPECULAR, + ENV_TRANSMIT_DIFFUSE, + ENV_TRANSMIT_SPECULAR, + TRANSMIT_ALL, + DIRECT_TRT, + ENV_TRT, + TRT_ALL, + FOG, } @@ -101,6 +111,12 @@ export const enum DebugViewCompositeType { TONE_MAPPING, GAMMA_CORRECTION, + + FRESNEL, + TRANSMIT_DIFFUSE, + TRANSMIT_SPECULAR, + TRT, + MAX_BIT_COUNT } @@ -113,63 +129,45 @@ export class DebugView { * @en Toggle rendering single debug mode. * @zh 设置渲染单项调试模式。 */ - public get singleMode () : DebugViewSingleType { + public get singleMode (): DebugViewSingleType { return this._singleMode; } - public set singleMode (val : DebugViewSingleType) { + public set singleMode (val: DebugViewSingleType) { this._singleMode = val; this._updatePipeline(); - - if (JSB && this._nativeConfig) { - this._nativeConfig.singleMode = this._singleMode; - } } /** * @en Toggle normal / pure lighting mode. * @zh 切换正常光照和仅光照模式。 */ - public get lightingWithAlbedo () : boolean { + public get lightingWithAlbedo (): boolean { return this._lightingWithAlbedo; } - public set lightingWithAlbedo (val : boolean) { + public set lightingWithAlbedo (val: boolean) { this._lightingWithAlbedo = val; this._updatePipeline(); - - if (JSB && this._nativeConfig) { - this._nativeConfig.lightingWithAlbedo = this._lightingWithAlbedo; - } } /** * @en Toggle CSM layer coloration mode. * @zh 切换级联阴影染色调试模式。 */ - public get csmLayerColoration () : boolean { + public get csmLayerColoration (): boolean { return this._csmLayerColoration; } - public set csmLayerColoration (val : boolean) { + public set csmLayerColoration (val: boolean) { this._csmLayerColoration = val; this._updatePipeline(); - - if (JSB && this._nativeConfig) { - this._nativeConfig.csmLayerColoration = this._csmLayerColoration; - } } protected _singleMode = DebugViewSingleType.NONE; protected _compositeModeValue = 0; protected _lightingWithAlbedo = true; protected _csmLayerColoration = false; - protected _nativeConfig: any = null; constructor () { this._activate(); - if (JSB && this._nativeConfig === null) { - // @ts-expect-error jsb object access - this._nativeConfig = new jsb.DebugViewConfig(); - this._nativeConfig.compositeModeBitCount = DebugViewCompositeType.MAX_BIT_COUNT; - } } /** @@ -177,7 +175,7 @@ export class DebugView { * @zh 获取指定的渲染组合调试模式是否开启。 * @param Specified composite type. */ - public isCompositeModeEnabled (val : number) : boolean { + public isCompositeModeEnabled (val: number): boolean { const mode = this._compositeModeValue & (1 << val); return mode !== 0; } @@ -225,17 +223,10 @@ export class DebugView { this._enableAllCompositeMode(true); this._lightingWithAlbedo = true; this._csmLayerColoration = false; - - if (JSB && this._nativeConfig) { - this._nativeConfig.singleMode = this._singleMode; - this._nativeConfig.compositeModeValue = this._compositeModeValue; - this._nativeConfig.lightingWithAlbedo = this._lightingWithAlbedo; - this._nativeConfig.csmLayerColoration = this._csmLayerColoration; - } } protected _updatePipeline () { - const root = legacyCC.director.root as Root; + const root = cclegacy.director.root as Root; const pipeline = root.pipeline; const useDebugView = this._getType(); @@ -252,10 +243,6 @@ export class DebugView { } else { this._compositeModeValue &= (~(1 << val)); } - - if (JSB && this._nativeConfig) { - this._nativeConfig.compositeModeValue = this._compositeModeValue; - } } private _enableAllCompositeMode (enable: boolean) { @@ -265,14 +252,10 @@ export class DebugView { } else { this._compositeModeValue &= (~(1 << i)); } - - if (JSB && this._nativeConfig) { - this._nativeConfig.compositeModeValue = this._compositeModeValue; - } } } - private _getType () : RenderingDebugViewType { + private _getType (): RenderingDebugViewType { if (this._singleMode !== DebugViewSingleType.NONE) { return RenderingDebugViewType.SINGLE; } else if (this._lightingWithAlbedo !== true || this._csmLayerColoration !== false) { diff --git a/cocos/rendering/deferred/bloom-stage.ts b/cocos/rendering/deferred/bloom-stage.ts index a7dea9c9be9..76c26acad4d 100644 --- a/cocos/rendering/deferred/bloom-stage.ts +++ b/cocos/rendering/deferred/bloom-stage.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @category pipeline diff --git a/cocos/rendering/deferred/deferred-pipeline-scene-data.ts b/cocos/rendering/deferred/deferred-pipeline-scene-data.ts index fa5505fd3a3..0c995b6b19e 100644 --- a/cocos/rendering/deferred/deferred-pipeline-scene-data.ts +++ b/cocos/rendering/deferred/deferred-pipeline-scene-data.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Device } from '../../gfx'; import { MAX_BLOOM_FILTER_PASS_NUM } from '../render-pipeline'; diff --git a/cocos/rendering/deferred/deferred-pipeline.ts b/cocos/rendering/deferred/deferred-pipeline.ts index ddba0ccef82..6d16109f253 100644 --- a/cocos/rendering/deferred/deferred-pipeline.ts +++ b/cocos/rendering/deferred/deferred-pipeline.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @category pipeline diff --git a/cocos/rendering/deferred/gbuffer-stage.ts b/cocos/rendering/deferred/gbuffer-stage.ts index fd602058b49..c846d652f23 100644 --- a/cocos/rendering/deferred/gbuffer-stage.ts +++ b/cocos/rendering/deferred/gbuffer-stage.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @category pipeline diff --git a/cocos/rendering/deferred/lighting-stage.ts b/cocos/rendering/deferred/lighting-stage.ts index 10aa72c688d..80ac8e96d88 100644 --- a/cocos/rendering/deferred/lighting-stage.ts +++ b/cocos/rendering/deferred/lighting-stage.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,14 +21,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @category pipeline */ import { ccclass, displayOrder, type, serializable } from 'cc.decorator'; -import { Camera } from '../../render-scene/scene'; +import { Camera, LightType } from '../../render-scene/scene'; import { UBODeferredLight, SetIndex, UBOForwardLight, UBOLocal } from '../define'; import { getPhaseID } from '../pass-phase'; import { Color, Rect, Buffer, BufferUsageBit, MemoryUsageBit, BufferInfo, BufferViewInfo, DescriptorSet, @@ -47,7 +47,12 @@ import { renderQueueClearFunc, RenderQueue, convertRenderQueue, renderQueueSortF import { RenderQueueDesc } from '../pipeline-serialization'; import { UIPhase } from '../ui-phase'; import { Pass } from '../../render-scene/core/pass'; +import { AABB } from '../../core/geometry/aabb'; +import { geometry } from '../../core'; +const _v3 = new Vec3(); +const _rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5); +const _tmpBoundingBox = new AABB(); const colors: Color[] = [new Color(0, 0, 0, 1)]; /** @@ -99,6 +104,8 @@ export class LightingStage extends RenderStage { const sphereLights = camera.scene!.sphereLights; const spotLights = camera.scene!.spotLights; + const pointLights = camera.scene!.pointLights; + const rangedDirLights = camera.scene!.rangedDirLights; const _sphere = Sphere.create(0, 0, 0, 1); const _vec4Array = new Float32Array(4); const exposure = camera.exposure; @@ -113,16 +120,16 @@ export class LightingStage extends RenderStage { if (intersect.sphereFrustum(_sphere, camera.frustum)) { // cc_lightPos Vec3.toArray(_vec4Array, light.position); - _vec4Array[3] = 0; + _vec4Array[3] = LightType.SPHERE; this._lightBufferData.set(_vec4Array, idx * elementLen); // cc_lightColor Vec3.toArray(_vec4Array, light.color); if (light.useColorTemperature) { - const tempRGB = light.colorTemperatureRGB; - _vec4Array[0] *= tempRGB.x; - _vec4Array[1] *= tempRGB.y; - _vec4Array[2] *= tempRGB.z; + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; } if (pipeline.pipelineSceneData.isHDR) { @@ -147,16 +154,16 @@ export class LightingStage extends RenderStage { if (intersect.sphereFrustum(_sphere, camera.frustum)) { // cc_lightPos Vec3.toArray(_vec4Array, light.position); - _vec4Array[3] = 1; + _vec4Array[3] = LightType.SPOT; this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 0); // cc_lightColor Vec3.toArray(_vec4Array, light.color); if (light.useColorTemperature) { - const tempRGB = light.colorTemperatureRGB; - _vec4Array[0] *= tempRGB.x; - _vec4Array[1] *= tempRGB.y; - _vec4Array[2] *= tempRGB.z; + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; } if (pipeline.pipelineSceneData.isHDR) { _vec4Array[3] = light.luminance * exposure * this._lightMeterScale; @@ -177,6 +184,81 @@ export class LightingStage extends RenderStage { } } + for (let i = 0; i < pointLights.length && idx < this._maxDeferredLights; i++, ++idx) { + const light = pointLights[i]; + Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (intersect.sphereFrustum(_sphere, camera.frustum)) { + // cc_lightPos + Vec3.toArray(_vec4Array, light.position); + _vec4Array[3] = LightType.POINT; + this._lightBufferData.set(_vec4Array, idx * elementLen); + + // cc_lightColor + Vec3.toArray(_vec4Array, light.color); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; + } + + if (pipeline.pipelineSceneData.isHDR) { + _vec4Array[3] = light.luminance * exposure * this._lightMeterScale; + } else { + _vec4Array[3] = light.luminance; + } + + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 1); + + // cc_lightSizeRangeAngle + _vec4Array[0] = 0.0; + _vec4Array[1] = light.range; + _vec4Array[2] = 0.0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 2); + } + } + + for (let i = 0; i < rangedDirLights.length && idx < this._maxDeferredLights; i++, ++idx) { + const light = rangedDirLights[i]; + AABB.transform(_tmpBoundingBox, _rangedDirLightBoundingBox, light.node!.getWorldMatrix()); + if (geometry.intersect.aabbFrustum(_tmpBoundingBox, camera.frustum)) { + // UBOForwardLight + Vec3.toArray(_vec4Array, light.position); + _vec4Array[3] = LightType.RANGED_DIRECTIONAL; + this._lightBufferData.set(_vec4Array, idx * elementLen); + + // cc_lightColor + Vec3.toArray(_vec4Array, light.color); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; + } + if (pipeline.pipelineSceneData.isHDR) { + _vec4Array[3] = light.illuminance * exposure; + } else { + _vec4Array[3] = light.illuminance; + } + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 1); + + Vec3.toArray(_vec4Array, light.right); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 2); + + Vec3.toArray(_vec4Array, light.direction); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 3); + + // eslint-disable-next-line no-case-declarations + const scale = light.scale; + _v3.set(scale.x * 0.5, scale.y * 0.5, scale.z * 0.5); + Vec3.toArray(_vec4Array, _v3); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, idx * elementLen + fieldLen * 4); + } + } + // the count of lights is set to cc_lightDir[0].w const offset = fieldLen * 3 + 3; this._lightBufferData.set([idx], offset); @@ -280,7 +362,7 @@ export class LightingStage extends RenderStage { cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, pipeline.descriptorSet); const inputAssembler = pipeline.quadIAOffscreen; - let pso:PipelineState|null = null; + let pso: PipelineState|null = null; if (pass != null && shader != null && inputAssembler != null) { pso = PipelineStateManager.getOrCreatePipelineState(device, pass, shader, renderPass, inputAssembler); } diff --git a/cocos/rendering/deferred/main-flow.ts b/cocos/rendering/deferred/main-flow.ts index e91319e8908..2ecdb081274 100644 --- a/cocos/rendering/deferred/main-flow.ts +++ b/cocos/rendering/deferred/main-flow.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @category pipeline.deferred diff --git a/cocos/rendering/deferred/postprocess-stage.ts b/cocos/rendering/deferred/postprocess-stage.ts index 8de2bafb646..db7e20adf7a 100644 --- a/cocos/rendering/deferred/postprocess-stage.ts +++ b/cocos/rendering/deferred/postprocess-stage.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @category pipeline diff --git a/cocos/rendering/define.ts b/cocos/rendering/define.ts index 3e776ff41e7..fae463f3d73 100644 --- a/cocos/rendering/define.ts +++ b/cocos/rendering/define.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Pass } from '../render-scene/core/pass'; import { Model } from '../render-scene/scene/model'; import { SubModel } from '../render-scene/scene/submodel'; import { Layers } from '../scene-graph/layers'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import { BindingMappingInfo, DescriptorType, Type, ShaderStageFlagBit, UniformStorageBuffer, DescriptorSetLayoutBinding, - Uniform, UniformBlock, UniformSamplerTexture, UniformStorageImage, Device, FormatFeatureBit, Format, + Uniform, UniformBlock, UniformSamplerTexture, UniformStorageImage, Device, FormatFeatureBit, Format, API, } from '../gfx'; export const PIPELINE_FLOW_MAIN = 'MainFlow'; @@ -46,7 +45,7 @@ export enum RenderPassStage { DEFAULT = 100, UI = 200, } -legacyCC.RenderPassStage = RenderPassStage; +cclegacy.RenderPassStage = RenderPassStage; /** * @en The predefined render priorities @@ -133,6 +132,7 @@ export enum ModelLocalBindings { UBO_SKINNING_TEXTURE, UBO_MORPH, UBO_UI_LOCAL, + UBO_SH, SAMPLER_JOINTS, SAMPLER_MORPH_POSITION, @@ -144,6 +144,10 @@ export enum ModelLocalBindings { STORAGE_REFLECTION, + SAMPLER_REFLECTION_PROBE_CUBE, + SAMPLER_REFLECTION_PROBE_PLANAR, + SAMPLER_REFLECTION_PROBE_DATA_MAP, + COUNT, } const LOCAL_UBO_COUNT = ModelLocalBindings.SAMPLER_JOINTS; @@ -175,13 +179,15 @@ export class UBOGlobal { public static readonly TIME_OFFSET = 0; public static readonly SCREEN_SIZE_OFFSET = UBOGlobal.TIME_OFFSET + 4; public static readonly NATIVE_SIZE_OFFSET = UBOGlobal.SCREEN_SIZE_OFFSET + 4; + public static readonly PROBE_INFO_OFFSET = UBOGlobal.NATIVE_SIZE_OFFSET + 4; - public static readonly DEBUG_VIEW_MODE_OFFSET = UBOGlobal.NATIVE_SIZE_OFFSET + 4; + public static readonly DEBUG_VIEW_MODE_OFFSET = UBOGlobal.PROBE_INFO_OFFSET + 4; public static readonly DEBUG_VIEW_COMPOSITE_PACK_1_OFFSET = UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 4; public static readonly DEBUG_VIEW_COMPOSITE_PACK_2_OFFSET = UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_1_OFFSET + 4; public static readonly DEBUG_VIEW_COMPOSITE_PACK_3_OFFSET = UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_2_OFFSET + 4; + public static readonly DEBUG_VIEW_COMPOSITE_PACK_4_OFFSET = UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_3_OFFSET + 4; - public static readonly COUNT = UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_3_OFFSET + 4; + public static readonly COUNT = UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_4_OFFSET + 4; public static readonly SIZE = UBOGlobal.COUNT * 4; public static readonly NAME = 'CCGlobal'; @@ -191,11 +197,13 @@ export class UBOGlobal { new Uniform('cc_time', Type.FLOAT4, 1), new Uniform('cc_screenSize', Type.FLOAT4, 1), new Uniform('cc_nativeSize', Type.FLOAT4, 1), + new Uniform('cc_probeInfo', Type.FLOAT4, 1), - new Uniform('cc_debug_view_mode', Type.FLOAT, 4), - new Uniform('cc_debug_view_composite_pack_1', Type.FLOAT, 4), - new Uniform('cc_debug_view_composite_pack_2', Type.FLOAT, 4), - new Uniform('cc_debug_view_composite_pack_3', Type.FLOAT, 4), + new Uniform('cc_debug_view_mode', Type.FLOAT4, 1), + new Uniform('cc_debug_view_composite_pack_1', Type.FLOAT4, 1), + new Uniform('cc_debug_view_composite_pack_2', Type.FLOAT4, 1), + new Uniform('cc_debug_view_composite_pack_3', Type.FLOAT4, 1), + new Uniform('cc_debug_view_composite_pack_4', Type.FLOAT4, 1), ], 1); } globalDescriptorSetLayout.layouts[UBOGlobal.NAME] = UBOGlobal.LAYOUT; @@ -311,7 +319,7 @@ export class UBOCSM { public static readonly NAME = 'CCCSM'; public static readonly BINDING = PipelineGlobalBindings.UBO_CSM; - public static readonly DESCRIPTOR = new DescriptorSetLayoutBinding(UBOCSM.BINDING, DescriptorType.UNIFORM_BUFFER, 1, ShaderStageFlagBit.ALL); + public static readonly DESCRIPTOR = new DescriptorSetLayoutBinding(UBOCSM.BINDING, DescriptorType.UNIFORM_BUFFER, 1, ShaderStageFlagBit.FRAGMENT); public static readonly LAYOUT = new UniformBlock(SetIndex.GLOBAL, UBOCSM.BINDING, UBOCSM.NAME, [ new Uniform('cc_csmViewDir0', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT), new Uniform('cc_csmViewDir1', Type.FLOAT4, UBOCSM.CSM_LEVEL_COUNT), @@ -373,7 +381,9 @@ export class UBOLocal { public static readonly MAT_WORLD_IT_OFFSET = UBOLocal.MAT_WORLD_OFFSET + 16; public static readonly LIGHTINGMAP_UVPARAM = UBOLocal.MAT_WORLD_IT_OFFSET + 16; public static readonly LOCAL_SHADOW_BIAS = UBOLocal.LIGHTINGMAP_UVPARAM + 4; - public static readonly COUNT = UBOLocal.LOCAL_SHADOW_BIAS + 4; + public static readonly REFLECTION_PROBE_DATA1 = UBOLocal.LOCAL_SHADOW_BIAS + 4; + public static readonly REFLECTION_PROBE_DATA2 = UBOLocal.REFLECTION_PROBE_DATA1 + 4; + public static readonly COUNT = UBOLocal.REFLECTION_PROBE_DATA2 + 4; public static readonly SIZE = UBOLocal.COUNT * 4; public static readonly NAME = 'CCLocal'; @@ -384,6 +394,8 @@ export class UBOLocal { new Uniform('cc_matWorldIT', Type.MAT4, 1), new Uniform('cc_lightingMapUVParam', Type.FLOAT4, 1), new Uniform('cc_localShadowBias', Type.FLOAT4, 1), + new Uniform('cc_reflectionProbeData1', Type.FLOAT4, 1), + new Uniform('cc_reflectionProbeData2', Type.FLOAT4, 1), ], 1); } localDescriptorSetLayout.layouts[UBOLocal.NAME] = UBOLocal.LAYOUT; @@ -411,6 +423,7 @@ localDescriptorSetLayout.layouts[UBOWorldBound.NAME] = UBOWorldBound.LAYOUT; localDescriptorSetLayout.bindings[UBOWorldBound.BINDING] = UBOWorldBound.DESCRIPTOR; export const INST_MAT_WORLD = 'a_matWorld0'; +export const INST_SH = 'a_sh_linear_const_r'; export class UBOLocalBatched { public static readonly BATCHING_COUNT = 10; @@ -439,7 +452,8 @@ export class UBOForwardLight { public static readonly LIGHT_COLOR_OFFSET = UBOForwardLight.LIGHT_POS_OFFSET + UBOForwardLight.LIGHTS_PER_PASS * 4; public static readonly LIGHT_SIZE_RANGE_ANGLE_OFFSET = UBOForwardLight.LIGHT_COLOR_OFFSET + UBOForwardLight.LIGHTS_PER_PASS * 4; public static readonly LIGHT_DIR_OFFSET = UBOForwardLight.LIGHT_SIZE_RANGE_ANGLE_OFFSET + UBOForwardLight.LIGHTS_PER_PASS * 4; - public static readonly COUNT = UBOForwardLight.LIGHT_DIR_OFFSET + UBOForwardLight.LIGHTS_PER_PASS * 4; + public static readonly LIGHT_BOUNDING_SIZE_VS_OFFSET = UBOForwardLight.LIGHT_DIR_OFFSET + UBOForwardLight.LIGHTS_PER_PASS * 4; + public static readonly COUNT = UBOForwardLight.LIGHT_BOUNDING_SIZE_VS_OFFSET + UBOForwardLight.LIGHTS_PER_PASS * 4; public static readonly SIZE = UBOForwardLight.COUNT * 4; public static readonly NAME = 'CCForwardLight'; @@ -450,6 +464,7 @@ export class UBOForwardLight { new Uniform('cc_lightColor', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS), new Uniform('cc_lightSizeRangeAngle', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS), new Uniform('cc_lightDir', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS), + new Uniform('cc_lightBoundingSizeVS', Type.FLOAT4, UBOForwardLight.LIGHTS_PER_PASS), ], 1); } localDescriptorSetLayout.layouts[UBOForwardLight.NAME] = UBOForwardLight.LAYOUT; @@ -567,6 +582,37 @@ export class UBOUILocal { // pre one vec4 localDescriptorSetLayout.layouts[UBOUILocal.NAME] = UBOUILocal.LAYOUT; localDescriptorSetLayout.bindings[UBOUILocal.BINDING] = UBOUILocal.DESCRIPTOR; +/** + * @en The SH uniform buffer object + * @zh 球谐 UBO。 + */ +export class UBOSH { + public static readonly SH_LINEAR_CONST_R_OFFSET = 0; + public static readonly SH_LINEAR_CONST_G_OFFSET = UBOSH.SH_LINEAR_CONST_R_OFFSET + 4; + public static readonly SH_LINEAR_CONST_B_OFFSET = UBOSH.SH_LINEAR_CONST_G_OFFSET + 4; + public static readonly SH_QUADRATIC_R_OFFSET = UBOSH.SH_LINEAR_CONST_B_OFFSET + 4; + public static readonly SH_QUADRATIC_G_OFFSET = UBOSH.SH_QUADRATIC_R_OFFSET + 4; + public static readonly SH_QUADRATIC_B_OFFSET = UBOSH.SH_QUADRATIC_G_OFFSET + 4; + public static readonly SH_QUADRATIC_A_OFFSET = UBOSH.SH_QUADRATIC_B_OFFSET + 4; + public static readonly COUNT = UBOSH.SH_QUADRATIC_A_OFFSET + 4; + public static readonly SIZE = UBOSH.COUNT * 4; + + public static readonly NAME = 'CCSH'; + public static readonly BINDING = ModelLocalBindings.UBO_SH; + public static readonly DESCRIPTOR = new DescriptorSetLayoutBinding(UBOSH.BINDING, DescriptorType.UNIFORM_BUFFER, 1, ShaderStageFlagBit.FRAGMENT); + public static readonly LAYOUT = new UniformBlock(SetIndex.LOCAL, UBOSH.BINDING, UBOSH.NAME, [ + new Uniform('cc_sh_linear_const_r', Type.FLOAT4, 1), + new Uniform('cc_sh_linear_const_g', Type.FLOAT4, 1), + new Uniform('cc_sh_linear_const_b', Type.FLOAT4, 1), + new Uniform('cc_sh_quadratic_r', Type.FLOAT4, 1), + new Uniform('cc_sh_quadratic_g', Type.FLOAT4, 1), + new Uniform('cc_sh_quadratic_b', Type.FLOAT4, 1), + new Uniform('cc_sh_quadratic_a', Type.FLOAT4, 1), + ], 1); +} +localDescriptorSetLayout.layouts[UBOSH.NAME] = UBOSH.LAYOUT; +localDescriptorSetLayout.bindings[UBOSH.BINDING] = UBOSH.DESCRIPTOR; + /** * @en The sampler for joint texture * @zh 骨骼纹理采样器。 @@ -669,6 +715,42 @@ const UNIFORM_REFLECTION_STORAGE_LAYOUT = new UniformStorageImage(SetIndex.LOCAL localDescriptorSetLayout.layouts[UNIFORM_REFLECTION_STORAGE_NAME] = UNIFORM_REFLECTION_STORAGE_LAYOUT; localDescriptorSetLayout.bindings[UNIFORM_REFLECTION_STORAGE_BINDING] = UNIFORM_REFLECTION_STORAGE_DESCRIPTOR; +/** + * @en The sampler for reflection probe cubemap + * @zh 反射探针立方体贴图纹理采样器。 + */ +const UNIFORM_REFLECTION_PROBE_CUBEMAP_NAME = 'cc_reflectionProbeCubemap'; +export const UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING = ModelLocalBindings.SAMPLER_REFLECTION_PROBE_CUBE; +const UNIFORM_REFLECTION_PROBE_CUBEMAP_DESCRIPTOR = new DescriptorSetLayoutBinding(UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING, DescriptorType.SAMPLER_TEXTURE, 1, ShaderStageFlagBit.FRAGMENT); +const UNIFORM_REFLECTION_PROBE_CUBEMAP_LAYOUT = new UniformSamplerTexture(SetIndex.LOCAL, UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING, + UNIFORM_REFLECTION_PROBE_CUBEMAP_NAME, Type.SAMPLER_CUBE, 1); +localDescriptorSetLayout.layouts[UNIFORM_REFLECTION_PROBE_CUBEMAP_NAME] = UNIFORM_REFLECTION_PROBE_CUBEMAP_LAYOUT; +localDescriptorSetLayout.bindings[UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING] = UNIFORM_REFLECTION_PROBE_CUBEMAP_DESCRIPTOR; + +/** + * @en The sampler for reflection probe planar reflection + * @zh 反射探针平面反射贴图纹理采样器。 + */ +const UNIFORM_REFLECTION_PROBE_TEXTURE_NAME = 'cc_reflectionProbePlanarMap'; +export const UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING = ModelLocalBindings.SAMPLER_REFLECTION_PROBE_PLANAR; +const UNIFORM_REFLECTION_PROBE_TEXTURE_DESCRIPTOR = new DescriptorSetLayoutBinding(UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING, DescriptorType.SAMPLER_TEXTURE, 1, ShaderStageFlagBit.FRAGMENT); +const UNIFORM_REFLECTION_PROBE_TEXTURE_LAYOUT = new UniformSamplerTexture(SetIndex.LOCAL, UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING, + UNIFORM_REFLECTION_PROBE_TEXTURE_NAME, Type.SAMPLER2D, 1); +localDescriptorSetLayout.layouts[UNIFORM_REFLECTION_PROBE_TEXTURE_NAME] = UNIFORM_REFLECTION_PROBE_TEXTURE_LAYOUT; +localDescriptorSetLayout.bindings[UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING] = UNIFORM_REFLECTION_PROBE_TEXTURE_DESCRIPTOR; + +/** + * @en The sampler for reflection probe data map + * @zh 反射探针数据贴图采样器。 + */ +const UNIFORM_REFLECTION_PROBE_DATA_MAP_NAME = 'cc_reflectionProbeDataMap'; +export const UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING = ModelLocalBindings.SAMPLER_REFLECTION_PROBE_DATA_MAP; +const UNIFORM_REFLECTION_PROBE_DATA_MAP_DESCRIPTOR = new DescriptorSetLayoutBinding(UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING, DescriptorType.SAMPLER_TEXTURE, 1, ShaderStageFlagBit.FRAGMENT); +const UNIFORM_REFLECTION_PROBE_DATA_MAP_LAYOUT = new UniformSamplerTexture(SetIndex.LOCAL, UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING, + UNIFORM_REFLECTION_PROBE_DATA_MAP_NAME, Type.SAMPLER2D, 1); +localDescriptorSetLayout.layouts[UNIFORM_REFLECTION_PROBE_DATA_MAP_NAME] = UNIFORM_REFLECTION_PROBE_DATA_MAP_LAYOUT; +localDescriptorSetLayout.bindings[UNIFORM_REFLECTION_PROBE_DATA_MAP_BINDING] = UNIFORM_REFLECTION_PROBE_DATA_MAP_DESCRIPTOR; + export const CAMERA_DEFAULT_MASK = Layers.makeMaskExclude([Layers.BitMask.UI_2D, Layers.BitMask.GIZMOS, Layers.BitMask.EDITOR, Layers.BitMask.SCENE_GIZMO, Layers.BitMask.PROFILER]); @@ -691,7 +773,12 @@ export function supportsR16HalfFloatTexture (device: Device) { */ export function supportsR32FloatTexture (device: Device) { return (device.getFormatFeatures(Format.R32F) & (FormatFeatureBit.RENDER_TARGET | FormatFeatureBit.SAMPLED_TEXTURE)) - === (FormatFeatureBit.RENDER_TARGET | FormatFeatureBit.SAMPLED_TEXTURE); + === (FormatFeatureBit.RENDER_TARGET | FormatFeatureBit.SAMPLED_TEXTURE) + && !(device.gfxAPI === API.WEBGL); // wegl 1 Single-channel float type is not supported under webgl1, so it is excluded +} + +export function isEnableEffect (): boolean { + return !!(cclegacy.rendering && cclegacy.rendering.enableEffectImport); } /* eslint-enable max-len */ diff --git a/cocos/rendering/deprecated.ts b/cocos/rendering/deprecated.ts index b7a522dfab0..02cc5360644 100644 --- a/cocos/rendering/deprecated.ts +++ b/cocos/rendering/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { markAsWarning } from '../core/utils'; +import { markAsWarning } from '../core'; import { RenderPipeline } from './render-pipeline'; // deprecate RenderPipeline API diff --git a/cocos/rendering/enum.ts b/cocos/rendering/enum.ts index 85267447130..f717efccab7 100644 --- a/cocos/rendering/enum.ts +++ b/cocos/rendering/enum.ts @@ -1,18 +1,18 @@ /* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export enum CommonStagePriority { BLOOM = 18, @@ -34,6 +34,7 @@ export enum CommonStagePriority { * @en The priority of stage in forward rendering */ export enum ForwardStagePriority { + AR = 5, FORWARD = 10, } diff --git a/cocos/rendering/forward/forward-flow.ts b/cocos/rendering/forward/forward-flow.ts index 55a9f3ece69..a31191e40ee 100644 --- a/cocos/rendering/forward/forward-flow.ts +++ b/cocos/rendering/forward/forward-flow.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; import { PIPELINE_FLOW_FORWARD } from '../define'; diff --git a/cocos/rendering/forward/forward-pipeline.ts b/cocos/rendering/forward/forward-pipeline.ts index 7cd79bccf76..2491f05a75a 100644 --- a/cocos/rendering/forward/forward-pipeline.ts +++ b/cocos/rendering/forward/forward-pipeline.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, type, serializable } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; @@ -36,6 +35,7 @@ import { Texture2D } from '../../asset/assets/texture-2d'; import { Camera } from '../../render-scene/scene'; import { errorID } from '../../core/platform/debug'; import { PipelineSceneData } from '../pipeline-scene-data'; +import { ReflectionProbeFlow } from '../reflection-probe/reflection-probe-flow'; const PIPELINE_TYPE = 0; @@ -64,6 +64,10 @@ export class ForwardPipeline extends RenderPipeline { shadowFlow.initialize(ShadowFlow.initInfo); this._flows.push(shadowFlow); + const reflectionFlow = new ReflectionProbeFlow(); + reflectionFlow.initialize(ReflectionProbeFlow.initInfo); + this._flows.push(reflectionFlow); + const forwardFlow = new ForwardFlow(); forwardFlow.initialize(ForwardFlow.initInfo); this._flows.push(forwardFlow); diff --git a/cocos/rendering/forward/forward-stage.ts b/cocos/rendering/forward/forward-stage.ts index 26c8ecfa78e..00da442cc35 100644 --- a/cocos/rendering/forward/forward-stage.ts +++ b/cocos/rendering/forward/forward-stage.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, type, serializable } from 'cc.decorator'; import { SetIndex } from '../define'; diff --git a/cocos/rendering/geometry-renderer.jsb.ts b/cocos/rendering/geometry-renderer.jsb.ts index 25be2f2a690..fd6f2903103 100644 --- a/cocos/rendering/geometry-renderer.jsb.ts +++ b/cocos/rendering/geometry-renderer.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,8 +21,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; export const GeometryRenderer = jsb.GeometryRenderer; -legacyCC.GeometryRenderer = jsb.GeometryRenderer; +cclegacy.GeometryRenderer = jsb.GeometryRenderer; diff --git a/cocos/rendering/geometry-renderer.ts b/cocos/rendering/geometry-renderer.ts index 7401ae6035e..e48ebe40164 100644 --- a/cocos/rendering/geometry-renderer.ts +++ b/cocos/rendering/geometry-renderer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,24 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { AABB } from '../core/geometry/aabb'; -import { Spline } from '../core/geometry/spline'; -import { Color } from '../core/math/color'; -import { Mat4 } from '../core/math/mat4'; -import { Vec3 } from '../core/math/vec3'; -import { Vec4 } from '../core/math/vec4'; +import { Color, Mat4, Vec3, Vec4, geometry, warnID, toRadian, cclegacy } from '../core'; import { SetIndex } from './define'; import { PipelineStateManager } from './pipeline-state-manager'; import { Attribute, AttributeName, Buffer, BufferInfo, BufferUsageBit, CommandBuffer, Device, DrawInfo, Format, InputAssembler, InputAssemblerInfo, MemoryUsageBit, RenderPass } from '../gfx'; -import { warnID } from '../core/platform/debug'; -import { Frustum } from '../core/geometry/frustum'; -import { toRadian } from '../core/math/utils'; + import { PipelineSceneData } from './pipeline-scene-data'; -import { legacyCC } from '../core/global-exports'; const _min = new Vec3(); const _max = new Vec3(); @@ -404,7 +395,7 @@ export class GeometryRenderer { } } - public addBoundingBox (aabb: AABB, color: Color, + public addBoundingBox (aabb: geometry.AABB, color: Color, wireframe = true, depthTest = true, unlit = false, useTransform = false, transform: Mat4 = new Mat4()) { /** * 2---3 @@ -480,7 +471,7 @@ export class GeometryRenderer { this.addLine(v0, v1, color, depthTest); } - public addFrustum (frustum: Frustum, color: Color, depthTest = true) { + public addFrustum (frustum: geometry.Frustum, color: Color, depthTest = true) { const vertices = frustum.vertices; this.addLine(vertices[0], vertices[1], color, depthTest); @@ -908,7 +899,7 @@ export class GeometryRenderer { } } - public addSpline (spline: Spline, color: Color, index = 0xffffffff, knotSize = 0.5, segments = 32, depthTest = true) { + public addSpline (spline: geometry.Spline, color: Color, index = 0xffffffff, knotSize = 0.5, segments = 32, depthTest = true) { const numPoints = segments + 1; const points = spline.getPoints(numPoints, index); @@ -965,4 +956,4 @@ export class GeometryRenderer { } } -legacyCC.internal.GeometryRenderer = GeometryRenderer; +cclegacy.internal.GeometryRenderer = GeometryRenderer; diff --git a/cocos/rendering/global-descriptor-set-manager.ts b/cocos/rendering/global-descriptor-set-manager.ts index 54108039e92..810f4fe2b6e 100644 --- a/cocos/rendering/global-descriptor-set-manager.ts +++ b/cocos/rendering/global-descriptor-set-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ +import { cclegacy } from '../core'; import { Device, BufferUsageBit, MemoryUsageBit, BufferInfo, Filter, Address, Sampler, DescriptorSet, DescriptorSetInfo, Buffer, Texture, DescriptorSetLayoutInfo, DescriptorSetLayout, SamplerInfo } from '../gfx'; import { Light } from '../render-scene/scene'; -import { UBOShadow, globalDescriptorSetLayout, PipelineGlobalBindings } from './define'; +import { getDescBindingFromName, getDescriptorSetDataFromLayout } from './custom/define'; +import { UBOShadow, globalDescriptorSetLayout, PipelineGlobalBindings, isEnableEffect } from './define'; const _samplerLinearInfo = new SamplerInfo( Filter.LINEAR, @@ -72,6 +73,11 @@ export class GlobalDSManager { return this._descriptorSetLayout; } + // apply layoutGraph descriptorSet + set globalDescriptorSet (val: DescriptorSet) { + this._globalDescriptorSet = val; + } + get globalDescriptorSet () { return this._globalDescriptorSet; } @@ -172,8 +178,9 @@ export class GlobalDSManager { // The global descriptorSet is managed by the pipeline and binds the buffer if (!this._descriptorSetMap.has(light)) { - const globalDescriptorSet = this._globalDescriptorSet; - const descriptorSet = device.createDescriptorSet(new DescriptorSetInfo(this._descriptorSetLayout)); + const globalDescriptorSet = isEnableEffect() ? getDescriptorSetDataFromLayout('default')!.descriptorSet! : this._globalDescriptorSet; + const descriptorSet = device.createDescriptorSet(new DescriptorSetInfo(isEnableEffect() + ? getDescriptorSetDataFromLayout('default')!.descriptorSetLayout! : this._descriptorSetLayout)); this._descriptorSetMap.set(light, descriptorSet); // Create & Sync ALL UBO Buffer, Texture, Sampler @@ -189,7 +196,8 @@ export class GlobalDSManager { UBOShadow.SIZE, UBOShadow.SIZE, )); - descriptorSet.bindBuffer(UBOShadow.BINDING, shadowUBO); + const binding = isEnableEffect() ? getDescBindingFromName('CCShadow') : UBOShadow.BINDING; + descriptorSet.bindBuffer(binding, shadowUBO); descriptorSet.update(); } diff --git a/cocos/rendering/index.jsb.ts b/cocos/rendering/index.jsb.ts index 12693de0a82..05f774f2bb5 100644 --- a/cocos/rendering/index.jsb.ts +++ b/cocos/rendering/index.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ declare const nr: any; +declare const jsb: any; import { getPhaseID } from './pass-phase'; -import { setClassName } from '../core/utils/js'; +import { ccenum, CCString, js } from '../core'; import * as pipeline from './define'; +import { ccclass, serializable, editable, type, visible } from '../core/data/class-decorator'; +import { legacyCC } from '../core/global-exports'; export { pipeline }; nr.getPhaseID = getPhaseID; @@ -48,26 +50,46 @@ export const LightingStage = nr.LightingStage; export const PostProcessStage = nr.PostProcessStage; export const GbufferStage = nr.GbufferStage; export const BloomStage = nr.BloomStage; +export const ReflectionProbeFlow = nr.ReflectionProbeFlow; +export const ReflectionProbeStage = nr.ReflectionProbeStage; export { PipelineEventType } from './pipeline-event'; +interface IRenderFlowInfo { + name: string; + priority: number; + stages: any[]; + tag: number; +} + +interface IRenderPipelineInfo { + flows: any[]; + tag: number; +} +interface IRenderStageInfo { + name: string; + priority: number; + tag: number; + renderQueues: RenderQueueDesc[]; +} + let getOrCreatePipelineState = nr.PipelineStateManager.getOrCreatePipelineState; -nr.PipelineStateManager.getOrCreatePipelineState = function(device, pass, shader, renderPass, ia) { +nr.PipelineStateManager.getOrCreatePipelineState = function (device, pass, shader, renderPass, ia) { return getOrCreatePipelineState(pass, shader, renderPass, ia); //cjh TODO: remove hacking. c++ API doesn't access device argument. }; // ForwardPipeline const forwardPipelineProto = ForwardPipeline.prototype; -forwardPipelineProto._ctor = function() { +forwardPipelineProto._ctor = function () { this._tag = 0; this._flows = []; }; forwardPipelineProto.init = function () { - for (let i = 0; i < this._flows.length; i++) { - this._flows[i].init(this); - } - const info = new nr.RenderPipelineInfo(this._tag, this._flows); - this.initialize(info); + for (let i = 0; i < this._flows.length; i++) { + this._flows[i].init(this); + } + const info: IRenderPipelineInfo = { tag: this._tag, flows: this._flows }; + this.initialize(info); }; const oldForwardOnLoaded = forwardPipelineProto.onLoaded; @@ -77,86 +99,143 @@ forwardPipelineProto.onLoaded = function () { for (let i = 0; i < this._flows.length; i++) { this._flows[i].init(this); } - const info = new nr.RenderPipelineInfo(this._tag, this._flows); + const info: IRenderPipelineInfo = { tag: this._tag, flows: this._flows }; this.initialize(info); } const forwardFlowProto = ForwardFlow.prototype; -forwardFlowProto._ctor = function() { +forwardFlowProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this._stages = []; } -forwardFlowProto.init = function(pipeline) { +forwardFlowProto.init = function (pipeline) { for (let i = 0; i < this._stages.length; i++) { this._stages[i].init(pipeline); } - const info = new nr.RenderFlowInfo(this._name, this._priority, this._tag, this._stages); + const info: IRenderFlowInfo = { name: this._name, priority: this._priority, tag: this._tag, stages: this._stages }; this.initialize(info); } const shadowFlowProto = ShadowFlow.prototype; -shadowFlowProto._ctor = function() { - this._name = 0; - this._priority = 0; - this._tag = 0; - this._stages = []; +shadowFlowProto._ctor = function () { + this._name = 0; + this._priority = 0; + this._tag = 0; + this._stages = []; } shadowFlowProto.init = function (pipeline) { for (let i = 0; i < this._stages.length; i++) { - this._stages[i].init(pipeline); + this._stages[i].init(pipeline); + } + const info: IRenderFlowInfo = { name: this._name, priority: this._priority, tag: this._tag, stages: this._stages }; + this.initialize(info); +} + +const reflectionProbeFlowProto = ReflectionProbeFlow.prototype; +reflectionProbeFlowProto._ctor = function () { + this._name = 0; + this._priority = 0; + this._tag = 0; + this._stages = []; +} +reflectionProbeFlowProto.init = function (pipeline) { + for (let i = 0; i < this._stages.length; i++) { + this._stages[i].init(pipeline); } - const info = new nr.RenderFlowInfo(this._name, this._priority, this._tag, this._stages); + const info: IRenderFlowInfo = { name: this._name, priority: this._priority, tag: this._tag, stages: this._stages }; this.initialize(info); } const forwardStageProto = ForwardStage.prototype; -forwardStageProto._ctor = function() { +forwardStageProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this.renderQueues = []; } -forwardStageProto.init = function(pipeline) { +forwardStageProto.init = function (pipeline) { const queues = []; for (let i = 0; i < this.renderQueues.length; i++) { // @ts-ignore queues.push(this.renderQueues[i].init()); } - const info = new nr.RenderStageInfo(this._name, this._priority, this._tag, queues); + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: queues }; this.initialize(info); } const shadowStageProto = ShadowStage.prototype; -shadowStageProto._ctor = function() { +shadowStageProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; } -shadowStageProto.init = function(pipeline) { - const info = new nr.RenderStageInfo(this._name, this._priority, this._tag, []); + +const reflectionProbeStage = ReflectionProbeStage.prototype; +reflectionProbeStage._ctor = function () { + this._name = 0; + this._priority = 0; + this._tag = 0; + this.renderQueues = []; +} +reflectionProbeStage.init = function (pipeline) { + const queues = []; + for (let i = 0; i < this.renderQueues.length; i++) { + // @ts-ignore + queues.push(this.renderQueues[i].init()); + } + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: queues }; + this.initialize(info); +} + + +export enum RenderQueueSortMode { + FRONT_TO_BACK, + BACK_TO_FRONT, +} +ccenum(RenderQueueSortMode); + +shadowStageProto.init = function (pipeline) { + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: [] }; this.initialize(info); } export class RenderQueueDesc { - public isTransparent = false; - public sortMode = 0; - public stages = []; - constructor() { - this.isTransparent = false; - this.sortMode = 0; - this.stages = []; - } + /** + * @en Whether the render queue is a transparent queue + * @zh 当前队列是否是半透明队列 + */ + @serializable + @editable + public isTransparent = false; + + /** + * @en The sort mode of the render queue + * @zh 渲染队列的排序模式 + */ + @type(RenderQueueSortMode) + public sortMode: RenderQueueSortMode = RenderQueueSortMode.FRONT_TO_BACK; + + /** + * @en The stages using this queue + * @zh 使用当前渲染队列的阶段列表 + */ + @type([CCString]) + public stages: string[] = []; + + constructor() { + this.stages = []; + } - public init() { - return new nr.RenderQueueDesc(this.isTransparent, this.sortMode, this.stages); - } + public init() { + return new nr.RenderQueueDesc(this.isTransparent, this.sortMode, this.stages); + } } const deferredPipelineProto = DeferredPipeline.prototype; -deferredPipelineProto._ctor = function() { +deferredPipelineProto._ctor = function () { this._tag = 0; this._flows = []; this.renderTextures = []; @@ -171,110 +250,237 @@ deferredPipelineProto.onLoaded = function () { for (let i = 0; i < this._flows.length; i++) { this._flows[i].init(this); } - let info = new nr.RenderPipelineInfo(this._tag, this._flows); + let info = { tag: this._tag, flows: this._flows }; this.initialize(info); } const mainFlowProto = MainFlow.prototype; -mainFlowProto._ctor = function() { +mainFlowProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this._stages = []; } -mainFlowProto.init = function(pipeline) { +mainFlowProto.init = function (pipeline) { for (let i = 0; i < this._stages.length; i++) { - this._stages[i].init(pipeline); + this._stages[i].init(pipeline); } - let info = new nr.RenderFlowInfo(this._name, this._priority, this._tag, this._stages); + const info: IRenderFlowInfo = { name: this._name, priority: this._priority, tag: this._tag, stages: this._stages }; this.initialize(info); } const gbufferStageProto = GbufferStage.prototype; -gbufferStageProto._ctor = function() { +gbufferStageProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this.renderQueues = []; } -gbufferStageProto.init = function(pipeline) { +gbufferStageProto.init = function (pipeline) { const queues = []; for (let i = 0; i < this.renderQueues.length; i++) { // @ts-ignore queues.push(this.renderQueues[i].init()); } - let info = new nr.RenderStageInfo(this._name, this._priority, this._tag, queues); + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: queues }; this.initialize(info); } const lightingStageProto = LightingStage.prototype; -lightingStageProto._ctor = function() { +lightingStageProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this.renderQueues = []; this._deferredMaterial = null; } -lightingStageProto.init = function(pipeline) { +lightingStageProto.init = function (pipeline) { const queues = []; for (let i = 0; i < this.renderQueues.length; i++) { // @ts-ignore queues.push(this.renderQueues[i].init()); } pipeline.pipelineSceneData.deferredLightingMaterial = this._deferredMaterial; - let info = new nr.RenderStageInfo(this._name, this._priority, this._tag, queues); + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: queues }; this.initialize(info); } const bloomStageProto = BloomStage.prototype; -bloomStageProto._ctor = function() { +bloomStageProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this.renderQueues = []; this._bloomMaterial = null; } -bloomStageProto.init = function(pipeline) { +bloomStageProto.init = function (pipeline) { const queues = []; for (let i = 0; i < this.renderQueues.length; i++) { // @ts-ignore queues.push(this.renderQueues[i].init()); } pipeline.pipelineSceneData.bloomMaterial = this._bloomMaterial; - let info = new nr.RenderStageInfo(this._name, this._priority, this._tag, queues); + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: queues }; this.initialize(info); } const postProcessStageProto = PostProcessStage.prototype; -postProcessStageProto._ctor = function() { +postProcessStageProto._ctor = function () { this._name = 0; this._priority = 0; this._tag = 0; this.renderQueues = []; this._postProcessMaterial = null; } -postProcessStageProto.init = function(pipeline) { +postProcessStageProto.init = function (pipeline) { const queues = []; for (let i = 0; i < this.renderQueues.length; i++) { // @ts-ignore queues.push(this.renderQueues[i].init()); } pipeline.pipelineSceneData.postProcessMaterial = this._postProcessMaterial; - let info = - new nr.RenderStageInfo(this._name, this._priority, this._tag, queues); + const info: IRenderStageInfo = { name: this._name, priority: this._priority, tag: this._tag, renderQueues: queues }; this.initialize(info); } -setClassName('DeferredPipeline', DeferredPipeline); -setClassName('MainFlow', MainFlow); -setClassName('GbufferStage', GbufferStage); -setClassName('LightingStage', LightingStage); -setClassName('BloomStage', BloomStage); -setClassName('PostProcessStage',PostProcessStage); -setClassName('ForwardPipeline', ForwardPipeline); -setClassName('ForwardFlow', ForwardFlow); -setClassName('ShadowFlow', ShadowFlow); -setClassName('ForwardStage', ForwardStage); -setClassName('ShadowStage', ShadowStage); -setClassName('RenderQueueDesc', RenderQueueDesc); + +legacyCC.RenderFlow = RenderFlow; +legacyCC.RenderStage = RenderStage; +legacyCC.RenderPipeline = RenderPipeline; + + +const RenderTexture: any = jsb.RenderTexture; +@ccclass('RenderTextureConfig') +class RenderTextureConfig { + @serializable + @editable + public name = ''; + @type(RenderTexture) + public texture: RenderTexture | null = null; +} + + +function proxyArrayAttributeImpl(proto: any, attr: string) { + const proxyTarget = `_${attr}_target`; + let arrayProxy = (self, targetArrayAttr: string) => { + return new Proxy(self[targetArrayAttr], { + get(targetArray, prop, receiver) { + return Reflect.get(targetArray, prop, receiver); + }, + set(targetArray, prop, receiver) { + const ret = Reflect.set(targetArray, prop, receiver); + self[targetArrayAttr] = targetArray; + return ret; + } + }); + } + + Object.defineProperty(proto, attr, { + configurable: true, + enumerable: true, + get: function () { + this[proxyTarget] ||= []; + return arrayProxy(this, proxyTarget); + }, + set: function (v) { + this[proxyTarget] = v; + } + }); +} + +function declType(proto: any, attrType: any, attr: string, dft: () => any) { + (type(attrType) as any)(proto, attr, dft); +} + + + + + +let proxyArrayAttribute = proxyArrayAttributeImpl; + +editable(RenderStage.prototype, '_name', () => ''); +editable(RenderStage.prototype, '_tag', () => 0); +editable(RenderStage.prototype, '_priority', () => 0); +serializable(RenderStage.prototype, '_tag', () => 0); +serializable(RenderStage.prototype, '_priority', () => 0); + +editable(RenderFlow.prototype, '_name', () => ''); +editable(RenderFlow.prototype, '_priority', () => 0); +editable(RenderFlow.prototype, '_tag', () => 0); +editable(RenderFlow.prototype, '_stages', () => []); +declType(RenderFlow.prototype, [RenderStage], '_stages', () => []); +proxyArrayAttribute(RenderFlow.prototype, '_stages'); +serializable(RenderFlow.prototype, '_name', () => ''); +serializable(RenderFlow.prototype, '_priority', () => 0); +serializable(RenderFlow.prototype, '_tag', () => 0); +serializable(RenderFlow.prototype, '_stages', () => []); + +editable(RenderPipeline.prototype, '_tag', () => 0); +editable(RenderPipeline.prototype, '_name', () => []); +serializable(RenderPipeline.prototype, '_tag', () => 0); +serializable(RenderPipeline.prototype, '_name', () => ''); + +editable(RenderPipeline.prototype, '_flows', () => []); +declType(RenderPipeline.prototype, [RenderFlow], '_flows', () => []); +proxyArrayAttribute(RenderPipeline.prototype, '_flows'); +serializable(RenderPipeline.prototype, '_flows', () => []); + +editable(DeferredPipeline.prototype, 'renderTextures', () => []); +declType(DeferredPipeline.prototype, [RenderTextureConfig], "renderTextures", () => []); +serializable(DeferredPipeline.prototype, 'renderTextures', () => []); +editable(DeferredPipeline.prototype, 'renderTextures', () => []); + + +editable(ForwardPipeline.prototype, 'renderTextures', () => []); +declType(ForwardPipeline.prototype, [RenderTextureConfig], "renderTextures", () => []); +serializable(ForwardPipeline.prototype, 'renderTextures', () => []); + +declType(GbufferStage.prototype, [RenderQueueDesc], 'renderQueues', () => []); +serializable(GbufferStage.prototype, 'renderQueues', () => []); +editable(GbufferStage.prototype, 'renderQueues', () => []); + + +editable(LightingStage.prototype, '_deferredMaterial', () => null); +declType(LightingStage.prototype, jsb.Material, '_deferredMaterial', () => null); +declType(LightingStage.prototype, [RenderQueueDesc], 'renderQueues', () => []); +serializable(LightingStage.prototype, '_deferredMaterial', () => null); +serializable(LightingStage.prototype, 'renderQueue', () => []); +editable(LightingStage.prototype, 'renderQueue', () => []); + +editable(BloomStage.prototype, '_bloomMaterial', () => null); +declType(BloomStage.prototype, jsb.Material, '_bloomMaterial', () => []); +serializable(BloomStage.prototype, '_bloomMaterial', () => null); + + +declType(PostProcessStage.prototype, [RenderQueueDesc], 'renderQueues', () => []); +editable(PostProcessStage.prototype, '_postProcessMaterial', () => null); +declType(PostProcessStage.prototype, jsb.Material, '_postProcessMaterial', () => null); +serializable(PostProcessStage.prototype, 'renderQueues', () => []); +editable(PostProcessStage.prototype, 'renderQueues', () => []); +serializable(PostProcessStage.prototype, '_postProcessMaterial', () => null); + +declType(ForwardStage.prototype, [RenderQueueDesc], 'renderQueues', () => []); +serializable(ForwardStage.prototype, 'renderQueues', () => []); +editable(ForwardStage.prototype, 'renderQueues', () => []); + +//-------------------- register types -------------------- +ccclass('RenderQueueDesc')(RenderQueueDesc); +ccclass('RenderStage')(RenderStage) +ccclass('ReflectionProbeStage')(ReflectionProbeStage); +ccclass('GbufferStage')(GbufferStage); +ccclass('LightingStage')(LightingStage); +ccclass('BloomStage')(BloomStage); +ccclass('PostProcessStage')(PostProcessStage); +ccclass('ForwardStage')(ForwardStage); +ccclass('ShadowStage')(ShadowStage); + +ccclass('RenderFlow')(RenderFlow) +ccclass('MainFlow')(MainFlow); +ccclass('ForwardFlow')(ForwardFlow); +ccclass('ShadowFlow')(ShadowFlow); +ccclass('ReflectionProbeFlow')(ReflectionProbeFlow); + +ccclass('cc.RenderPipeline')(RenderPipeline); +ccclass('ForwardPipeline')(ForwardPipeline); +ccclass('DeferredPipeline')(DeferredPipeline); \ No newline at end of file diff --git a/cocos/rendering/index.ts b/cocos/rendering/index.ts index 63743e5d30a..d261599fb2d 100644 --- a/cocos/rendering/index.ts +++ b/cocos/rendering/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './deprecated'; import * as pipeline from './define'; @@ -54,6 +53,9 @@ export { PipelineStateManager } from './pipeline-state-manager'; export { PipelineEventProcessor, PipelineEventType } from './pipeline-event'; export { DebugView } from './debug-view'; +export { ReflectionProbeFlow } from './reflection-probe/reflection-probe-flow'; +export { ReflectionProbeStage } from './reflection-probe/reflection-probe-stage'; + export function createDefaultPipeline () { const rppl = new ForwardPipeline(); rppl.initialize({ flows: [] }); diff --git a/cocos/rendering/instanced-buffer.ts b/cocos/rendering/instanced-buffer.ts index 193f02732f4..bb758e0730c 100644 --- a/cocos/rendering/instanced-buffer.ts +++ b/cocos/rendering/instanced-buffer.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Pass } from '../render-scene'; import { IInstancedAttributeBlock, SubModel } from '../render-scene/scene'; -import { UNIFORM_LIGHTMAP_TEXTURE_BINDING } from './define'; +import { UNIFORM_LIGHTMAP_TEXTURE_BINDING, UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING, UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING } from './define'; import { BufferUsageBit, MemoryUsageBit, Device, Texture, InputAssembler, InputAssemblerInfo, Attribute, Buffer, BufferInfo, CommandBuffer, Shader, DescriptorSet } from '../gfx'; @@ -39,6 +38,9 @@ export interface IInstancedItem { shader: Shader | null; descriptorSet: DescriptorSet; lightingMap: Texture; + reflectionProbeCubemap: Texture; + reflectionProbePlanarMap: Texture; + useReflectionProbeType: number; } const INITIAL_CAPACITY = 32; @@ -71,6 +73,9 @@ export class InstancedBuffer { if (!stride) { return; } // we assume per-instance attributes are always present const sourceIA = subModel.inputAssembler; const lightingMap = subModel.descriptorSet.getTexture(UNIFORM_LIGHTMAP_TEXTURE_BINDING); + const reflectionProbeCubemap = subModel.descriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING); + const reflectionProbePlanarMap = subModel.descriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING); + const useReflectionProbeType = subModel.useReflectionProbeType; let shader = shaderImplant; if (!shader) { shader = subModel.shaders[passIdx]; @@ -85,6 +90,17 @@ export class InstancedBuffer { continue; } + if (instance.useReflectionProbeType !== useReflectionProbeType) { + continue; + } else { + if (instance.reflectionProbeCubemap.objectID !== reflectionProbeCubemap.objectID) { + continue; + } + if (instance.reflectionProbePlanarMap.objectID !== reflectionProbePlanarMap.objectID) { + continue; + } + } + if (instance.stride !== stride) { // we allow this considering both baked and non-baked // skinning models may be present in the same buffer @@ -127,7 +143,7 @@ export class InstancedBuffer { vertexBuffers.push(vb); const iaInfo = new InputAssemblerInfo(attributes, vertexBuffers, indexBuffer); const ia = this._device.createInputAssembler(iaInfo); - this.instances.push({ count: 1, capacity: INITIAL_CAPACITY, vb, data, ia, stride, shader, descriptorSet, lightingMap }); + this.instances.push({ count: 1, capacity: INITIAL_CAPACITY, vb, data, ia, stride, shader, descriptorSet, lightingMap, reflectionProbeCubemap, reflectionProbePlanarMap, useReflectionProbeType }); this.hasPendingModels = true; } diff --git a/cocos/rendering/lod-group-editor-utility.ts b/cocos/rendering/lod-group-editor-utility.ts new file mode 100644 index 00000000000..78817d85f1b --- /dev/null +++ b/cocos/rendering/lod-group-editor-utility.ts @@ -0,0 +1,97 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { LODGroup } from "../3d/lod/lodgroup-component"; +import { Vec3, assertIsTrue } from '../core'; +import { Camera, CameraProjection } from '../render-scene/scene'; +import { scene } from '../render-scene'; + +export class LODGroupEditorUtility { + /** + * @en Get the lod level used under the current camera, -1 indicates no lod is used. + * @zh 获取当前摄像机下,使用哪一级的LOD,-1 表示没有lod被使用 + * @param lodGroup current LOD Group component. + * @param camera current perspective camera. + * @returns visible LOD index in lodGroup. + */ + static getVisibleLOD (lodGroup: LODGroup, camera: Camera): number { + const screenOccupancyPercentage = this.getRelativeHeight(lodGroup, camera) || 0; + + let lodIndex = -1; + for (let i = 0; i < lodGroup.lodCount; ++i) { + const lod = lodGroup.getLOD(i); + if (lod && screenOccupancyPercentage >= lod.screenUsagePercentage) { + lodIndex = i; + break; + } + } + return lodIndex; + } + + /** + * @en Get the percentage of objects used on the screen under the current camera. + * @zh 获取当前摄像机下,物体在屏幕上的占用比率 + * @param lodGroup current LOD Group component + * @param camera current perspective camera + * @returns height of current lod group relative to camera position in screen space, aka. relativeHeight + */ + static getRelativeHeight (lodGroup: LODGroup, camera: Camera): number|null { + if (!lodGroup.node) return null; + + let distance: number | undefined; + if (camera.projectionType === scene.CameraProjection.PERSPECTIVE) { + distance = Vec3.len(lodGroup.localBoundaryCenter.transformMat4(lodGroup.node.worldMatrix).subtract(camera.node.position)); + } + return this.distanceToRelativeHeight(camera, distance, this.getWorldSpaceSize(lodGroup)); + } + + /** + * @zh 强制使用某几级的LOD + * @en Force multi LOD level to use. + * lodIndexArray @en The LOD level array. Passing [] will return to standard LOD processing. @zh 要使用的LOD层级数组,传[]时将使用标准的处理流程。 + */ + static forceLODs (lodGroup: LODGroup, lodIndexArray: number[]) { + lodGroup.lodGroup.lockLODLevels(lodIndexArray); + } + + private static distanceToRelativeHeight (camera: Camera, distance: number | undefined, size: number): number { + if (camera.projectionType === CameraProjection.PERSPECTIVE) { + assertIsTrue(typeof distance === 'number', 'distance must be present for perspective projection'); + return (size * camera.matProj.m05) / (distance * 2.0); // note: matProj.m05 is 1 / tan(fov / 2.0) + } else { + return size * camera.matProj.m05 * 0.5; + } + } + + private static relativeHeightToDistance (camera: Camera, relativeHeight: number, size: number): number { + assertIsTrue(camera.projectionType === CameraProjection.PERSPECTIVE, 'Camera type must be perspective.'); + return (size * camera.matProj.m05) / (relativeHeight * 2.0); // note: matProj.m05 is 1 / tan(fov / 2.0) + } + + private static getWorldSpaceSize (lodGroup: LODGroup): number { + const scale = lodGroup.node.scale; + const maxScale = Math.max(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)); + return maxScale * lodGroup.objectSize; + } +} diff --git a/cocos/rendering/pass-phase.jsb.ts b/cocos/rendering/pass-phase.jsb.ts index 5851b812532..8af6dcacafb 100644 --- a/cocos/rendering/pass-phase.jsb.ts +++ b/cocos/rendering/pass-phase.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ declare const nr: any; diff --git a/cocos/rendering/pass-phase.ts b/cocos/rendering/pass-phase.ts index 3ff6f54157a..628eac3f23a 100644 --- a/cocos/rendering/pass-phase.ts +++ b/cocos/rendering/pass-phase.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export const getPhaseID = (() => { const phases: Map = new Map(); diff --git a/cocos/rendering/pipeline-event.ts b/cocos/rendering/pipeline-event.ts index 929a47ef8b0..ff2af4d8c13 100644 --- a/cocos/rendering/pipeline-event.ts +++ b/cocos/rendering/pipeline-event.ts @@ -1,4 +1,28 @@ -import { EventTarget } from '../core/event/event-target'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { EventTarget } from '../core'; export enum PipelineEventType { /** diff --git a/cocos/rendering/pipeline-funcs.ts b/cocos/rendering/pipeline-funcs.ts index c30b8f6ac46..b8792cbcebf 100644 --- a/cocos/rendering/pipeline-funcs.ts +++ b/cocos/rendering/pipeline-funcs.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,13 +20,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ +import { EDITOR } from 'internal:constants'; import { CommandBuffer, Device, Rect, RenderPass, Viewport } from '../gfx'; -import { IVec4Like } from '../core/math'; +import { IVec4Like } from '../core'; import { PipelineStateManager } from './pipeline-state-manager'; -import { SetIndex } from './define'; +import { isEnableEffect, SetIndex } from './define'; import { Camera, Model } from '../render-scene/scene'; +import { Layers } from '../scene-graph/layers'; const profilerViewport = new Viewport(); const profilerScissor = new Rect(); @@ -64,6 +65,10 @@ export function LinearToSRGB (out: IVec4Like, linear: IVec4Like) { let profilerCamera: Camera | null = null; +export function getProfilerCamera (): Camera | null { + return profilerCamera; +} + export function decideProfilerCamera (cameras: Camera[]) { for (let i = cameras.length - 1; i >= 0; --i) { const camera = cameras[i]; @@ -76,18 +81,31 @@ export function decideProfilerCamera (cameras: Camera[]) { } export function renderProfiler (device: Device, renderPass: RenderPass, cmdBuff: CommandBuffer, profiler: Model | null, camera: Camera) { - if (profiler && profiler.enabled && camera === profilerCamera) { - const { inputAssembler, passes, shaders, descriptorSet } = profiler.subModels[0]; - profilerViewport.width = profilerScissor.width = camera.window.width; - profilerViewport.height = profilerScissor.height = camera.window.height; - const pso = PipelineStateManager.getOrCreatePipelineState(device, passes[0], shaders[0], renderPass, inputAssembler); + if (isEnableEffect()) { + return; + } + if (!profiler || !profiler.enabled) { + return; + } - cmdBuff.setViewport(profilerViewport); - cmdBuff.setScissor(profilerScissor); - cmdBuff.bindPipelineState(pso); - cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, passes[0].descriptorSet); - cmdBuff.bindDescriptorSet(SetIndex.LOCAL, descriptorSet); - cmdBuff.bindInputAssembler(inputAssembler); - cmdBuff.draw(inputAssembler); + if (EDITOR) { + if (!(camera.visibility & Layers.Enum.PROFILER)) { + return; + } + } else if (camera !== profilerCamera) { + return; } + + const { inputAssembler, passes, shaders, descriptorSet } = profiler.subModels[0]; + profilerViewport.width = profilerScissor.width = camera.window.width; + profilerViewport.height = profilerScissor.height = camera.window.height; + const pso = PipelineStateManager.getOrCreatePipelineState(device, passes[0], shaders[0], renderPass, inputAssembler); + + cmdBuff.setViewport(profilerViewport); + cmdBuff.setScissor(profilerScissor); + cmdBuff.bindPipelineState(pso); + cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, passes[0].descriptorSet); + cmdBuff.bindDescriptorSet(SetIndex.LOCAL, descriptorSet); + cmdBuff.bindInputAssembler(inputAssembler); + cmdBuff.draw(inputAssembler); } diff --git a/cocos/rendering/pipeline-scene-data.ts b/cocos/rendering/pipeline-scene-data.ts index de0e592b50a..41bcc1b9ceb 100644 --- a/cocos/rendering/pipeline-scene-data.ts +++ b/cocos/rendering/pipeline-scene-data.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,7 +18,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Fog } from '../render-scene/scene/fog'; import { Ambient } from '../render-scene/scene/ambient'; @@ -31,6 +32,7 @@ import { Light } from '../render-scene/scene/light'; import { Material } from '../asset/assets'; import { Pass } from '../render-scene/core/pass'; import { CSMLayers } from './shadow/csm-layers'; +import { cclegacy } from '../core'; const GEOMETRY_RENDERER_TECHNIQUE_COUNT = 6; @@ -68,6 +70,7 @@ export class PipelineSceneData { public shadows: Shadows = new Shadows(); public csmLayers: CSMLayers = new CSMLayers(); public octree: Octree = new Octree(); + public lightProbes = cclegacy.internal.LightProbes ? new cclegacy.internal.LightProbes() : null; /** * @en The list for valid punctual Lights, only available after the scene culling of the current frame. @@ -112,7 +115,7 @@ export class PipelineSceneData { for (let tech = 0; tech < GEOMETRY_RENDERER_TECHNIQUE_COUNT; tech++) { this._geometryRendererMaterials[tech] = new Material(); this._geometryRendererMaterials[tech]._uuid = `geometry-renderer-material-${tech}`; - this._geometryRendererMaterials[tech].initialize({ effectName: 'builtin-geometry-renderer', technique: tech }); + this._geometryRendererMaterials[tech].initialize({ effectName: 'internal/builtin-geometry-renderer', technique: tech }); for (let pass = 0; pass < this._geometryRendererMaterials[tech].passes.length; ++pass) { this._geometryRendererPasses[offset] = this._geometryRendererMaterials[tech].passes[pass]; @@ -138,7 +141,7 @@ export class PipelineSceneData { if (!this._occlusionQueryMaterial) { const mat = new Material(); mat._uuid = 'default-occlusion-query-material'; - mat.initialize({ effectName: 'builtin-occlusion-query' }); + mat.initialize({ effectName: 'internal/builtin-occlusion-query' }); this._occlusionQueryMaterial = mat; if (mat.passes.length > 0) { this._occlusionQueryShader = mat.passes[0].getShaderVariant(); diff --git a/cocos/rendering/pipeline-serialization.ts b/cocos/rendering/pipeline-serialization.ts index a97dd977d66..9fcd89a4d06 100644 --- a/cocos/rendering/pipeline-serialization.ts +++ b/cocos/rendering/pipeline-serialization.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, type, serializable, editable } from 'cc.decorator'; -import { CCString } from '../core/data/utils/attribute'; +import { CCString, ccenum } from '../core'; import { AccessFlagBit, Format, LoadOp, StoreOp, TextureType, TextureUsageBit } from '../gfx'; -import { ccenum } from '../core/value-types/enum'; import { RenderTexture } from '../asset/assets/render-texture'; import { Material } from '../asset/assets/material'; @@ -114,9 +112,9 @@ export class ColorDesc { @serializable @editable public sampleCount = 1; - @type([AccessFlagBit]) + @type(AccessFlagBit) public beginAccesses: AccessFlagBit = AccessFlagBit.NONE; - @type([AccessFlagBit]) + @type(AccessFlagBit) public endAccesses: AccessFlagBit = AccessFlagBit.COLOR_ATTACHMENT_WRITE; } diff --git a/cocos/rendering/pipeline-state-manager.ts b/cocos/rendering/pipeline-state-manager.ts index 56c26ac03dc..afd645fbfdc 100644 --- a/cocos/rendering/pipeline-state-manager.ts +++ b/cocos/rendering/pipeline-state-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Shader, RenderPass, InputAssembler, Device, PipelineState, InputState, PipelineStateInfo } from '../gfx'; import { Pass } from '../render-scene/core/pass'; diff --git a/cocos/rendering/pipeline-ubo.ts b/cocos/rendering/pipeline-ubo.ts index 5dd790f18ec..d256c5ec1c7 100644 --- a/cocos/rendering/pipeline-ubo.ts +++ b/cocos/rendering/pipeline-ubo.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,15 +20,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { UBOGlobal, UBOShadow, UBOCamera, UNIFORM_SHADOWMAP_BINDING, - supportsR32FloatTexture, UNIFORM_SPOT_SHADOW_MAP_TEXTURE_BINDING, UBOCSM } from './define'; + supportsR32FloatTexture, UNIFORM_SPOT_SHADOW_MAP_TEXTURE_BINDING, UBOCSM, isEnableEffect } from './define'; import { Device, BufferInfo, BufferUsageBit, MemoryUsageBit, DescriptorSet } from '../gfx'; import { Camera } from '../render-scene/scene/camera'; -import { Mat4, Vec3, Vec4, Color, toRadian } from '../core/math'; +import { Mat4, Vec3, Vec4, Color, toRadian, cclegacy } from '../core'; import { PipelineRuntime } from './custom/pipeline'; -import { legacyCC } from '../core/global-exports'; import { CSMLevel, PCFType, Shadows, ShadowType } from '../render-scene/scene/shadows'; import { Light, LightType } from '../render-scene/scene/light'; import { DirectionalLight, SpotLight } from '../render-scene/scene'; @@ -37,6 +35,8 @@ import { RenderWindow } from '../render-scene/core/render-window'; import { builtinResMgr } from '../asset/asset-manager/builtin-res-mgr'; import { Texture2D } from '../asset/assets'; import { DebugViewCompositeType } from './debug-view'; +import { legacyCC } from '../core/global-exports'; +import { getDescBindingFromName } from './custom/define'; const _matShadowView = new Mat4(); const _matShadowProj = new Mat4(); @@ -47,7 +47,7 @@ const _tempVec3 = new Vec3(); export class PipelineUBO { public static updateGlobalUBOView (window: RenderWindow, bufferView: Float32Array) { - const director = legacyCC.director; + const director = cclegacy.director; const root = director.root; const fv = bufferView; @@ -58,6 +58,7 @@ export class PipelineUBO { fv[UBOGlobal.TIME_OFFSET] = root.cumulativeTime; fv[UBOGlobal.TIME_OFFSET + 1] = root.frameTime; fv[UBOGlobal.TIME_OFFSET + 2] = director.getTotalFrames(); + fv[UBOGlobal.TIME_OFFSET + 3] = root.cumulativeTime - Math.floor(root.frameTime); fv[UBOGlobal.SCREEN_SIZE_OFFSET] = shadingWidth; fv[UBOGlobal.SCREEN_SIZE_OFFSET + 1] = shadingHeight; @@ -69,27 +70,23 @@ export class PipelineUBO { fv[UBOGlobal.NATIVE_SIZE_OFFSET + 2] = 1.0 / fv[UBOGlobal.NATIVE_SIZE_OFFSET]; fv[UBOGlobal.NATIVE_SIZE_OFFSET + 3] = 1.0 / fv[UBOGlobal.NATIVE_SIZE_OFFSET + 1]; + if (cclegacy.internal.reflectionProbeManager) { + // eslint-disable-next-line @typescript-eslint/restrict-plus-operands + fv[UBOGlobal.PROBE_INFO_OFFSET] = cclegacy.internal.reflectionProbeManager.getMaxProbeId() + 1; + } + const debugView = root.debugView; - if (debugView) { - fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET] = debugView.singleMode as number; - fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 1] = debugView.lightingWithAlbedo ? 1.0 : 0.0; - fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 2] = debugView.csmLayerColoration ? 1.0 : 0.0; - for (let i = DebugViewCompositeType.DIRECT_DIFFUSE as number; i < DebugViewCompositeType.MAX_BIT_COUNT; i++) { - fv[UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_1_OFFSET + i] = debugView.isCompositeModeEnabled(i) ? 1.0 : 0.0; - } - } else { - fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET] = 0.0; - fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 1] = 1.0; - fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 2] = 0.0; - for (let i = DebugViewCompositeType.DIRECT_DIFFUSE as number; i < DebugViewCompositeType.MAX_BIT_COUNT; i++) { - fv[UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_1_OFFSET + i] = 1.0; - } + fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET] = debugView.singleMode as number; + fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 1] = debugView.lightingWithAlbedo ? 1.0 : 0.0; + fv[UBOGlobal.DEBUG_VIEW_MODE_OFFSET + 2] = debugView.csmLayerColoration ? 1.0 : 0.0; + for (let i = DebugViewCompositeType.DIRECT_DIFFUSE as number; i < DebugViewCompositeType.MAX_BIT_COUNT; i++) { + fv[UBOGlobal.DEBUG_VIEW_COMPOSITE_PACK_1_OFFSET + i] = debugView.isCompositeModeEnabled(i) ? 1.0 : 0.0; } } public static updateCameraUBOView (pipeline: PipelineRuntime, bufferView: Float32Array, camera: Camera) { - const scene = camera.scene ? camera.scene : legacyCC.director.getScene().renderScene; + const scene = camera.scene ? camera.scene : cclegacy.director.getScene().renderScene; const mainLight = scene.mainLight; const sceneData = pipeline.pipelineSceneData; const ambient = sceneData.ambient; @@ -161,6 +158,7 @@ export class PipelineUBO { cv[UBOCamera.CAMERA_POS_OFFSET + 3] = this.getCombineSignY(); cv[UBOCamera.SURFACE_TRANSFORM_OFFSET] = camera.surfaceTransform; + cv[UBOCamera.SURFACE_TRANSFORM_OFFSET + 1] = camera.cameraUsage; cv[UBOCamera.SURFACE_TRANSFORM_OFFSET + 2] = Math.cos(toRadian(sceneData.skybox.getRotationAngle())); cv[UBOCamera.SURFACE_TRANSFORM_OFFSET + 3] = Math.sin(toRadian(sceneData.skybox.getRotationAngle())); @@ -230,8 +228,17 @@ export class PipelineUBO { const matShadowView = csmLayers.specialLayer.matShadowView; const matShadowProj = csmLayers.specialLayer.matShadowProj; const matShadowViewProj = csmLayers.specialLayer.matShadowViewProj; - const near = mainLight.shadowNear; - const far = mainLight.shadowFar; + let near = 0.1; + let far = 0; + let levelCount = 0; + if (mainLight.shadowFixedArea) { + near = mainLight.shadowNear; + far = mainLight.shadowFar; + levelCount = 0; + } else { + far = csmLayers.specialLayer.shadowCameraFar; + levelCount = 1; + } Mat4.toArray(sv, matShadowView, UBOShadow.MAT_LIGHT_VIEW_OFFSET); @@ -250,28 +257,27 @@ export class PipelineUBO { _vec4ShadowInfo.set(near, far, 0, 1.0 - mainLight.shadowSaturation); Vec4.toArray(sv, _vec4ShadowInfo, UBOShadow.SHADOW_NEAR_FAR_LINEAR_SATURATION_INFO_OFFSET); - _vec4ShadowInfo.set(0, packing, mainLight.shadowNormalBias, 0); + _vec4ShadowInfo.set(0, packing, mainLight.shadowNormalBias, levelCount); Vec4.toArray(sv, _vec4ShadowInfo, UBOShadow.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET); } else { const layerThreshold = this.getPCFRadius(shadowInfo, mainLight); for (let i = 0; i < mainLight.csmLevel; i++) { - const matShadowView = csmLayers.layers[i].matShadowView; + const layer = csmLayers.layers[i]; + const matShadowView = layer.matShadowView; _vec4ShadowInfo.set(matShadowView.m00, matShadowView.m04, matShadowView.m08, layerThreshold); Vec4.toArray(cv, _vec4ShadowInfo, UBOCSM.CSM_VIEW_DIR_0_OFFSET + 4 * i); - _vec4ShadowInfo.set(matShadowView.m01, matShadowView.m05, matShadowView.m09, 0.0); + _vec4ShadowInfo.set(matShadowView.m01, matShadowView.m05, matShadowView.m09, layer.splitCameraNear); Vec4.toArray(cv, _vec4ShadowInfo, UBOCSM.CSM_VIEW_DIR_1_OFFSET + 4 * i); - _vec4ShadowInfo.set(matShadowView.m02, matShadowView.m06, matShadowView.m10, 0.0); + _vec4ShadowInfo.set(matShadowView.m02, matShadowView.m06, matShadowView.m10, layer.splitCameraFar); Vec4.toArray(cv, _vec4ShadowInfo, UBOCSM.CSM_VIEW_DIR_2_OFFSET + 4 * i); - const csmAtlas = csmLayers.layers[i].csmAtlas; + const csmAtlas = layer.csmAtlas; Vec4.toArray(cv, csmAtlas, UBOCSM.CSM_ATLAS_OFFSET + 4 * i); - cv[UBOCSM.CSM_SPLITS_INFO_OFFSET + i] = csmLayers.layers[i].splitCameraFar / mainLight.shadowDistance; - - const matShadowViewProj = csmLayers.layers[i].matShadowViewProj; + const matShadowViewProj = layer.matShadowViewProj; Mat4.toArray(cv, matShadowViewProj, UBOCSM.MAT_CSM_VIEW_PROJ_OFFSET + 16 * i); - const matShadowProj = csmLayers.layers[i].matShadowProj; + const matShadowProj = layer.matShadowProj; cv[UBOCSM.CSM_PROJ_DEPTH_INFO_OFFSET + 0 + 4 * i] = matShadowProj.m10; cv[UBOCSM.CSM_PROJ_DEPTH_INFO_OFFSET + 1 + 4 * i] = matShadowProj.m14; cv[UBOCSM.CSM_PROJ_DEPTH_INFO_OFFSET + 2 + 4 * i] = matShadowProj.m11; @@ -282,8 +288,10 @@ export class PipelineUBO { cv[UBOCSM.CSM_PROJ_INFO_OFFSET + 2 + 4 * i] = 1.0 / matShadowProj.m00; cv[UBOCSM.CSM_PROJ_INFO_OFFSET + 3 + 4 * i] = 1.0 / matShadowProj.m05; } + _vec4ShadowInfo.set(mainLight.csmTransitionRange, 0, 0, 0); + Vec4.toArray(cv, _vec4ShadowInfo, UBOCSM.CSM_SPLITS_INFO_OFFSET); - _vec4ShadowInfo.set(0, 0, 0, 1.0 - mainLight.shadowSaturation); + _vec4ShadowInfo.set(0.1, mainLight.shadowDistance, 0, 1.0 - mainLight.shadowSaturation); Vec4.toArray(sv, _vec4ShadowInfo, UBOShadow.SHADOW_NEAR_FAR_LINEAR_SATURATION_INFO_OFFSET); _vec4ShadowInfo.set(0.0, packing, mainLight.shadowNormalBias, mainLight.csmLevel); @@ -431,6 +439,9 @@ export class PipelineUBO { this._device = device; this._pipeline = pipeline; const ds = this._pipeline.descriptorSet; + if (isEnableEffect()) { + return; + } this._initCombineSignY(); const globalUBO = device.createBuffer(new BufferInfo( @@ -454,14 +465,16 @@ export class PipelineUBO { UBOShadow.SIZE, UBOShadow.SIZE, )); - ds.bindBuffer(UBOShadow.BINDING, shadowUBO); + const binding = isEnableEffect() ? getDescBindingFromName('CCShadow') : UBOShadow.BINDING; + ds.bindBuffer(binding, shadowUBO); const csmUBO = device.createBuffer(new BufferInfo( BufferUsageBit.UNIFORM | BufferUsageBit.TRANSFER_DST, MemoryUsageBit.HOST | MemoryUsageBit.DEVICE, UBOCSM.SIZE, UBOCSM.SIZE, )); - ds.bindBuffer(UBOCSM.BINDING, csmUBO); + const csmBinding = isEnableEffect() ? getDescBindingFromName('CCCSM') : UBOCSM.BINDING; + ds.bindBuffer(csmBinding, csmUBO); } /** @@ -505,8 +518,10 @@ export class PipelineUBO { } PipelineUBO.updateShadowUBOView(this._pipeline, this._shadowUBO, this._csmUBO, camera); ds.update(); - cmdBuffer[0].updateBuffer(ds.getBuffer(UBOShadow.BINDING), this._shadowUBO); - cmdBuffer[0].updateBuffer(ds.getBuffer(UBOCSM.BINDING), this._csmUBO); + const binding = isEnableEffect() ? getDescBindingFromName('CCShadow') : UBOShadow.BINDING; + cmdBuffer[0].updateBuffer(ds.getBuffer(binding), this._shadowUBO); + const csmBinding = isEnableEffect() ? getDescBindingFromName('CCCSM') : UBOCSM.BINDING; + cmdBuffer[0].updateBuffer(ds.getBuffer(csmBinding), this._csmUBO); } public updateShadowUBOLight (globalDS: DescriptorSet, light: Light, level = 0) { @@ -514,7 +529,8 @@ export class PipelineUBO { globalDS.bindTexture(UNIFORM_SHADOWMAP_BINDING, builtinResMgr.get('default-texture').getGFXTexture()!); globalDS.bindTexture(UNIFORM_SPOT_SHADOW_MAP_TEXTURE_BINDING, builtinResMgr.get('default-texture').getGFXTexture()!); globalDS.update(); - this._pipeline.commandBuffers[0].updateBuffer(globalDS.getBuffer(UBOShadow.BINDING), this._shadowUBO); + const binding = isEnableEffect() ? getDescBindingFromName('CCShadow') : UBOShadow.BINDING; + this._pipeline.commandBuffers[0].updateBuffer(globalDS.getBuffer(binding), this._shadowUBO); } public updateShadowUBORange (offset: number, data: Mat4 | Color) { diff --git a/cocos/rendering/planar-shadow-queue.ts b/cocos/rendering/planar-shadow-queue.ts index e26b42c7b4b..110b0991c2e 100644 --- a/cocos/rendering/planar-shadow-queue.ts +++ b/cocos/rendering/planar-shadow-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { AABB, intersect } from '../core/geometry'; +import { geometry } from '../core'; import { SetIndex } from './define'; import { CommandBuffer, Device, RenderPass } from '../gfx'; import { PipelineStateManager } from './pipeline-state-manager'; @@ -34,11 +33,11 @@ import { Layers } from '../scene-graph/layers'; import { PipelineRuntime } from './custom/pipeline'; import { BatchingSchemes } from '../render-scene/core/pass'; -const _ab = new AABB(); +const _ab = new geometry.AABB(); export class PlanarShadowQueue { private _pendingSubModels: SubModel[] = []; - private _castModels:Model[] = []; + private _castModels: Model[] = []; private _instancedQueue = new RenderInstancedQueue(); private _pipeline: PipelineRuntime; @@ -62,16 +61,20 @@ export class PlanarShadowQueue { const models = scene.models; for (let i = 0; i < models.length; i++) { const model = models[i]; + if (scene.isCulledByLod(camera, model)) { + continue; + } if (model.enabled && model.node && model.castShadow) { this._castModels.push(model); } } + const instancedBuffer = shadows.instancingMaterial.passes[0].getInstancedBuffer(); this._instancedQueue.queue.add(instancedBuffer); for (let i = 0; i < this._castModels.length; i++) { const model = this._castModels[i]; if (model.worldBounds) { - AABB.transform(_ab, model.worldBounds, shadows.matLight); - if (!intersect.aabbFrustum(_ab, frustum)) { continue; } + geometry.AABB.transform(_ab, model.worldBounds, shadows.matLight); + if (!geometry.intersect.aabbFrustum(_ab, frustum)) { continue; } } const subModels = model.subModels; diff --git a/cocos/rendering/reflection-probe-manager.ts b/cocos/rendering/reflection-probe-manager.ts new file mode 100644 index 00000000000..a5d9ac31d94 --- /dev/null +++ b/cocos/rendering/reflection-probe-manager.ts @@ -0,0 +1,533 @@ +/* eslint-disable max-len */ +/* + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { MeshRenderer, ReflectionProbeType } from '../3d/framework/mesh-renderer'; +import { ImageAsset, Texture2D } from '../asset/assets'; +import { PixelFormat } from '../asset/assets/asset-enum'; +import { Vec3, geometry, cclegacy } from '../core'; +import { director, Director } from '../game'; +import { Texture } from '../gfx'; +import { Camera, Model } from '../render-scene/scene'; +import { ProbeType, ReflectionProbe } from '../render-scene/scene/reflection-probe'; +import { Layers } from '../scene-graph/layers'; + +const REFLECTION_PROBE_DEFAULT_MASK = Layers.makeMaskExclude([Layers.BitMask.UI_2D, Layers.BitMask.UI_3D, Layers.BitMask.GIZMOS, Layers.BitMask.EDITOR, + Layers.BitMask.SCENE_GIZMO, Layers.BitMask.PROFILER, Layers.Enum.IGNORE_RAYCAST]); +export class ReflectionProbeManager { + public static probeManager: ReflectionProbeManager; + private _probes: ReflectionProbe[] = []; + /** + * @en + * All models in the scene that use cube type reflection probe. + * @zh + * 场景中所有使用cube类型反射探针的模型 + */ + private _useCubeModels = new Map(); + + /** + * @en + * All models in the scene that use planar type reflection probe. + * @zh + * 场景中所有使用planar类型反射探针的模型 + */ + private _usePlanarModels = new Map(); + private _updateForRuntime = true; + private _dataTexture: Texture2D | null = null; + constructor () { + director.on(Director.EVENT_BEFORE_UPDATE, this.onUpdateProbes, this); + } + /** + * @en Set and get whether to detect objects leaving or entering the reflection probe's bounding box at runtime. + * @zh 设置和获取是否在运行时检测物体离开或者进入反射探针的包围盒。 + */ + set updateForRuntime (val: boolean) { + this._updateForRuntime = val; + } + get updateForRuntime () { + return this._updateForRuntime; + } + + /** + * @en refresh all reflection probe + * @zh 刷新所有反射探针 + */ + public onUpdateProbes (forceUpdate = false) { + if (!this._updateForRuntime || this._probes.length === 0) return; + const scene = director.getScene(); + if (!scene || !scene.renderScene) { + return; + } + const models = scene.renderScene.models; + for (let i = 0; i < models.length; i++) { + const model = models[i]; + if (!model.node) continue; + if ((model.node.layer & REFLECTION_PROBE_DEFAULT_MASK) && (model.node.hasChangedFlags || forceUpdate)) { + if (model.reflectionProbeType === ReflectionProbeType.BAKED_CUBEMAP) { + this.updateUseCubeModels(model); + } else if (model.reflectionProbeType === ReflectionProbeType.PLANAR_REFLECTION) { + this.updateUsePlanarModels(model); + } + } + } + } + + public filterModelsForPlanarReflection () { + if (this._probes.length === 0) return; + const scene = director.getScene(); + if (!scene || !scene.renderScene) { + return; + } + const models = scene.renderScene.models; + for (let i = 0; i < models.length; i++) { + const model = models[i]; + if (!model.node) continue; + if ((model.node.layer & REFLECTION_PROBE_DEFAULT_MASK) && model.reflectionProbeType === ReflectionProbeType.PLANAR_REFLECTION) { + this.updateUsePlanarModels(model); + } + } + } + + public clearPlanarReflectionMap (probe: ReflectionProbe) { + for (const entry of this._usePlanarModels.entries()) { + if (entry[1] === probe) { + this._updatePlanarMapOfModel(entry[0], null, null); + } + } + } + + public register (probe: ReflectionProbe) { + const index = this._probes.indexOf(probe); + if (index === -1) { + this._probes.push(probe); + this.updateProbeData(); + } + } + + public unregister (probe: ReflectionProbe) { + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i] === probe) { + const del = this._probes.splice(i, 1); + if (del[0]) { + this._removeDependentModels(del[0]); + } + break; + } + } + this.updateProbeData(); + } + + public exists (probeId: number): boolean { + if (this._probes.length === 0) return false; + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i].getProbeId() === probeId) { + return true; + } + } + return false; + } + + public getNewReflectionProbeId () { + let probeId = 0; + // eslint-disable-next-line no-constant-condition + while (true) { + if (this.exists(probeId)) { + probeId++; + } else { + return probeId; + } + } + } + + public getProbes (): ReflectionProbe[] { + return this._probes; + } + + public getProbeById (probeId: number): ReflectionProbe | null { + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i].getProbeId() === probeId) { + return this._probes[i]; + } + } + return null; + } + + public clearAll () { + this._probes = []; + } + + public getProbeByCamera (camera: Camera) { + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i].camera === camera) { + return this._probes[i]; + } + } + return null; + } + + /** + * @en Update the cubemap captured by the reflection probe. + * @zh 更新反射探针捕获的cubemap + * @param probe update the texture for this probe + */ + public updateBakedCubemap (probe: ReflectionProbe) { + const models = this._getModelsByProbe(probe); + if (!probe.cubemap) return; + for (let i = 0; i < models.length; i++) { + const model = models[i]; + this._updateCubemapOfModel(model, probe); + } + probe.needRefresh = false; + } + + /** + * @en Update the plane reflection map for reflection probe render. + * @zh 更新反射探针渲染的平面反射贴图 + * @param probe update the texture for this probe + */ + public updatePlanarMap (probe: ReflectionProbe, texture: Texture | null) { + if (!probe.node || !probe.node.scene) return; + const models = this._getModelsByProbe(probe); + for (let i = 0; i < models.length; i++) { + this._updatePlanarMapOfModel(models[i], texture, probe); + } + if (probe.previewPlane) { + const meshRender = probe.previewPlane.getComponent(MeshRenderer); + if (meshRender) { + meshRender.updateProbePlanarMap(texture); + } + } + } + + /** + * @en Update objects using reflection probe for planar reflection. + * @zh 更新使用反射探针进行平面反射的物体。 + * @param probe update the model for reflection probe + * @engineInternal + */ + public updateUsePlanarModels (model: Model) { + if (!model.node || !model.worldBounds || model.reflectionProbeType !== ReflectionProbeType.PLANAR_REFLECTION) return; + for (let i = 0; i < this._probes.length; i++) { + const probe = this._probes[i]; + if (probe.probeType !== ProbeType.PLANAR) continue; + if (model.node.layer & REFLECTION_PROBE_DEFAULT_MASK) { + model.updateWorldBound(); + if (geometry.intersect.aabbWithAABB(model.worldBounds, probe.boundingBox!)) { + this._usePlanarModels.set(model, probe); + } else if (this._usePlanarModels.has(model)) { + const old = this._usePlanarModels.get(model); + if (old === probe) { + this._usePlanarModels.delete(model); + this._updatePlanarMapOfModel(model, null, null); + } + } + } + } + + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i].probeType === ProbeType.PLANAR) { + if (!this._probes[i].realtimePlanarTexture) { + this.updatePlanarMap(this._probes[i], null); + } else { + this.updatePlanarMap(this._probes[i], this._probes[i].realtimePlanarTexture!.getGFXTexture()); + } + } + } + } + + /** + * @en Update objects using reflection probe for bake cubemap. + * @zh 更新使用反射探针烘焙cubemap的物体。 + * @param model update the model for reflection probe + * @engineInternal + */ + public updateUseCubeModels (model: Model) { + if (model.node && model.worldBounds && ((model.node.layer & REFLECTION_PROBE_DEFAULT_MASK))) { + model.updateWorldBound(); + const nearest = this._getNearestProbe(model); + if (!nearest) { + //not in the range of any probe,set default texture for the model + this._updateCubemapOfModel(model, null); + this._useCubeModels.delete(model); + } else if (this._useCubeModels.has(model)) { + const old = this._useCubeModels.get(model); + // if used other probe,reset texture + if (old !== nearest) { + this._useCubeModels.set(model, nearest); + nearest.needRefresh = true; + } + } else { + this._useCubeModels.set(model, nearest); + nearest.needRefresh = true; + } + } + + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i].needRefresh && this._probes[i].probeType === ProbeType.CUBE) { + this.updateBakedCubemap(this._probes[i]); + } + } + } + + /** + * @en Update the preview sphere of the Reflection Probe cube mode. + * @zh 更新反射探针cube模式的预览球 + */ + public updatePreviewSphere (probe: ReflectionProbe) { + if (!probe || !probe.previewSphere) return; + const meshRender = probe.previewSphere.getComponent(MeshRenderer); + if (meshRender) { + meshRender.updateProbeCubemap(probe.cubemap, !probe.cubemap); + } + } + + /** + * @en Update the preview plane of the Reflection Probe planar mode. + * @zh 更新反射探针预览平面 + */ + public updatePreviewPlane (probe: ReflectionProbe) { + if (!probe || !probe.previewPlane) return; + const meshRender = probe.previewPlane.getComponent(MeshRenderer); + if (meshRender) { + if (probe.realtimePlanarTexture) { + this.updatePlanarMap(probe, probe.realtimePlanarTexture.getGFXTexture()); + } + } + } + + /** + * @en Update reflection probe data of model bind. + * @zh 更新模型绑定的反射探针数据。 + */ + public updateProbeData () { + if (this._probes.length === 0) return; + const maxId = this.getMaxProbeId(); + const height = maxId + 1; + const dataWidth = 3; + if (this._dataTexture) { + this._dataTexture.destroy(); + } + + const buffer = new Float32Array(4 * dataWidth * height); + let bufferOffset = 0; + for (let i = 0; i <= maxId; i++) { + const probe = this.getProbeById(i); + if (!probe) { + bufferOffset += 4 * dataWidth; + continue; + } + if (probe.probeType === ProbeType.CUBE) { + //world pos + buffer[bufferOffset] = probe.node.worldPosition.x; + buffer[bufferOffset + 1] = probe.node.worldPosition.y; + buffer[bufferOffset + 2] = probe.node.worldPosition.z; + buffer[bufferOffset + 3] = 0.0; + + buffer[bufferOffset + 4] = probe.size.x; + buffer[bufferOffset + 5] = probe.size.y; + buffer[bufferOffset + 6] = probe.size.z; + buffer[bufferOffset + 7] = 0.0; + buffer[bufferOffset + 8] = probe.cubemap ? probe.cubemap.mipmapLevel : 1.0; + } else { + //plane.xyz; + buffer[bufferOffset] = probe.node.up.x; + buffer[bufferOffset + 1] = probe.node.up.y; + buffer[bufferOffset + 2] = probe.node.up.z; + buffer[bufferOffset + 3] = 1.0; + //plane.w; + buffer[bufferOffset + 4] = 1.0; + //planarReflectionDepthScale + buffer[bufferOffset + 5] = 1.0; + buffer[bufferOffset + 6] = 0.0; + buffer[bufferOffset + 7] = 0.0; + //mipCount; + buffer[bufferOffset + 8] = 1.0; + } + bufferOffset += 4 * dataWidth; + } + const updateView = new Uint8Array(buffer.buffer); + const image = new ImageAsset({ + _data: updateView, + _compressed: false, + width: dataWidth * 4, + height, + format: PixelFormat.RGBA8888, + }); + + this._dataTexture = new Texture2D(); + this._dataTexture.setFilters(Texture2D.Filter.NONE, Texture2D.Filter.NONE); + this._dataTexture.setMipFilter(Texture2D.Filter.NONE); + this._dataTexture.setWrapMode(Texture2D.WrapMode.CLAMP_TO_EDGE, Texture2D.WrapMode.CLAMP_TO_EDGE, Texture2D.WrapMode.CLAMP_TO_EDGE); + this._dataTexture.image = image; + + this._dataTexture.uploadData(updateView); + + for (let i = 0; i < this._probes.length; i++) { + const probe = this._probes[i]; + const models = this._getModelsByProbe(probe); + for (let j = 0; j < models.length; j++) { + const meshRender = models[j].node.getComponent(MeshRenderer); + if (meshRender) { + meshRender.updateReflectionProbeDataMap(this._dataTexture); + meshRender.updateReflectionProbeId(probe.getProbeId()); + } + } + } + } + + /** + * @en get max value of probe id. + * @zh 获取反射探针id的最大值。 + */ + public getMaxProbeId () { + if (this._probes.length === 0) { + return -1; + } + if (this._probes.length === 1) { + return this._probes[0].getProbeId(); + } + this._probes.sort((a: ReflectionProbe, b: ReflectionProbe) => a.getProbeId() - b.getProbeId()); + return this._probes[this._probes.length - 1].getProbeId(); + } + /** + * @en Get the reflection probe used by the model. + * @zh 获取模型使用的反射探针。 + */ + public getUsedReflectionProbe (model: Model, probeType: ReflectionProbeType) { + if (probeType === ReflectionProbeType.BAKED_CUBEMAP) { + if (this._useCubeModels.has(model)) { + return this._useCubeModels.get(model); + } + } else if (probeType === ReflectionProbeType.PLANAR_REFLECTION) { + if (this._usePlanarModels.has(model)) { + return this._usePlanarModels.get(model); + } + } + return null; + } + + /** + * @en + * select the probe with the nearest distance. + * @zh + * 选择距离最近的probe。 + * @param model select the probe for this model + */ + private _getNearestProbe (model: Model): ReflectionProbe | null { + if (!model.node || !model.worldBounds || this._probes.length === 0) return null; + + let nearestProbe: ReflectionProbe | null = null; + let minDistance = Infinity; + + for (const probe of this._probes) { + if (probe.probeType !== ProbeType.CUBE || !probe.validate() || !geometry.intersect.aabbWithAABB(model.worldBounds, probe.boundingBox!)) { + continue; + } + + const distance = Vec3.distance(model.node.worldPosition, probe.node.worldPosition); + if (distance < minDistance) { + minDistance = distance; + nearestProbe = probe; + } + } + + return nearestProbe; + } + + private _getBlendProbe (model: Model): ReflectionProbe | null { + if (this._probes.length === 0) return null; + if (!model.node || !model.worldBounds) return null; + const temp: ReflectionProbe[] = []; + for (let i = 0; i < this._probes.length; i++) { + if (this._probes[i].probeType !== ProbeType.CUBE || !this._probes[i].validate() || !geometry.intersect.aabbWithAABB(model.worldBounds, this._probes[i].boundingBox!)) { + continue; + } + temp.push(this._probes[i]); + } + temp.sort((a: ReflectionProbe, b: ReflectionProbe) => { + const aDistance = Vec3.distance(model.node.worldPosition, a.node.worldPosition); + const bDistance = Vec3.distance(model.node.worldPosition, b.node.worldPosition); + return bDistance - aDistance; + }); + return temp.length > 1 ? temp[1] : null; + } + + private _getModelsByProbe (probe: ReflectionProbe) { + const models: Model[] = []; + let useModels = this._useCubeModels; + if (probe.probeType === ProbeType.PLANAR) { + useModels = this._usePlanarModels; + } + for (const entry of useModels.entries()) { + if (entry[1] === probe) { + models.push(entry[0]); + } + } + return models; + } + + private _removeDependentModels (probe: ReflectionProbe) { + for (const key of this._useCubeModels.keys()) { + const p = this._useCubeModels.get(key); + if (p !== undefined && p === probe) { + this._useCubeModels.delete(key); + this.updateUseCubeModels(key); + } + } + for (const key of this._usePlanarModels.keys()) { + const p = this._usePlanarModels.get(key); + if (p !== undefined && p === probe) { + this._usePlanarModels.delete(key); + this.updateUsePlanarModels(key); + } + } + } + + private _updateCubemapOfModel (model: Model, probe: ReflectionProbe | null) { + if (!model.node) { + return; + } + const meshRender = model.node.getComponent(MeshRenderer); + if (meshRender) { + meshRender.updateProbeCubemap(probe ? probe.cubemap : null); + meshRender.updateReflectionProbeId(probe ? probe.getProbeId() : -1); + if (probe) { + meshRender.updateReflectionProbeDataMap(this._dataTexture); + } + } + } + private _updatePlanarMapOfModel (model: Model, texture: Texture | null, probe: ReflectionProbe | null) { + const meshRender = model.node.getComponent(MeshRenderer); + if (meshRender) { + meshRender.updateProbePlanarMap(texture); + meshRender.updateReflectionProbeId(probe ? probe.getProbeId() : -1); + if (probe) { + meshRender.updateReflectionProbeDataMap(this._dataTexture); + } + } + } +} + +ReflectionProbeManager.probeManager = new ReflectionProbeManager(); +cclegacy.internal.reflectionProbeManager = ReflectionProbeManager.probeManager; diff --git a/cocos/rendering/reflection-probe/reflection-probe-flow.ts b/cocos/rendering/reflection-probe/reflection-probe-flow.ts new file mode 100644 index 00000000000..490195b4b8f --- /dev/null +++ b/cocos/rendering/reflection-probe/reflection-probe-flow.ts @@ -0,0 +1,97 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { EDITOR } from 'internal:constants'; +import { ccclass } from 'cc.decorator'; +import { IRenderFlowInfo, RenderFlow } from '../render-flow'; +import { ReflectionProbeStage } from './reflection-probe-stage'; +import { RenderFlowTag } from '../pipeline-serialization'; +import { RenderPipeline } from '..'; +import { Camera, ProbeType, ReflectionProbe } from '../../render-scene/scene'; +import { cclegacy } from '../../core'; + +/** + * @en reflection probe render flow + * @zh 反射探针rendertexture绘制流程 + */ +@ccclass('ReflectionProbeFlow') +export class ReflectionProbeFlow extends RenderFlow { + public static initInfo: IRenderFlowInfo = { + name: 'PIPELINE_FLOW_RELECTION_PROBE', + priority: 0, + tag: RenderFlowTag.SCENE, + stages: [], + }; + + public initialize (info: IRenderFlowInfo): boolean { + super.initialize(info); + if (this._stages.length === 0) { + const probeStage = new ReflectionProbeStage(); + probeStage.initialize(ReflectionProbeStage.initInfo); + this._stages.push(probeStage); + } + return true; + } + + public activate (pipeline: RenderPipeline) { + super.activate(pipeline); + } + + public render (camera: Camera) { + if (!cclegacy.internal.reflectionProbeManager) { + return; + } + const probes = cclegacy.internal.reflectionProbeManager.getProbes(); + for (let i = 0; i < probes.length; i++) { + if (probes[i].needRender) { + if (EDITOR || probes[i].probeType === ProbeType.PLANAR) { + this._renderStage(camera, probes[i]); + } + } + } + } + + public destroy () { + super.destroy(); + } + private _renderStage (camera: Camera, probe: ReflectionProbe) { + for (let i = 0; i < this._stages.length; i++) { + const probeStage = this._stages[i] as ReflectionProbeStage; + if (probe.probeType === ProbeType.PLANAR) { + cclegacy.internal.reflectionProbeManager.updatePlanarMap(probe, null); + probeStage.setUsageInfo(probe, probe.realtimePlanarTexture!.window!.framebuffer); + probeStage.render(camera); + cclegacy.internal.reflectionProbeManager.updatePlanarMap(probe, probe.realtimePlanarTexture!.getGFXTexture()); + } else { + for (let faceIdx = 0; faceIdx < 6; faceIdx++) { + //update camera dirction + probe.updateCameraDir(faceIdx); + const renderTexture = probe.bakedCubeTextures[faceIdx]; + probeStage.setUsageInfo(probe, renderTexture.window!.framebuffer); + probeStage.render(camera); + } + probe.needRender = false; + } + } + } +} diff --git a/cocos/rendering/reflection-probe/reflection-probe-stage.ts b/cocos/rendering/reflection-probe/reflection-probe-stage.ts new file mode 100644 index 00000000000..bd7be75715b --- /dev/null +++ b/cocos/rendering/reflection-probe/reflection-probe-stage.ts @@ -0,0 +1,136 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ccclass } from 'cc.decorator'; +import { Color, Rect, Framebuffer, ClearFlagBit } from '../../gfx'; +import { IRenderStageInfo, RenderStage } from '../render-stage'; +import { ForwardStagePriority } from '../enum'; +import { ForwardPipeline } from '../forward/forward-pipeline'; +import { SetIndex } from '../define'; +import { ReflectionProbeFlow } from './reflection-probe-flow'; +import { Camera, ProbeType, ReflectionProbe } from '../../render-scene/scene'; +import { RenderReflectionProbeQueue } from '../render-reflection-probe-queue'; +import { Vec3 } from '../../core'; +import { packRGBE } from '../../core/math/color'; + +const colors: Color[] = [new Color(1, 1, 1, 1)]; + +/** + * @en reflection probe render stage + * @zh 反射探针渲染阶段。 + */ +@ccclass('ReflectionProbeStage') +export class ReflectionProbeStage extends RenderStage { + /** + * @en A common initialization info for reflection probe render stage + * @zh 一个通用的 reflection probe stage 的初始化信息对象 + */ + public static initInfo: IRenderStageInfo = { + name: 'ReflectionProbeStage', + priority: ForwardStagePriority.FORWARD, + tag: 0, + }; + + private _frameBuffer: Framebuffer | null = null; + private _renderArea = new Rect(); + private _probe: ReflectionProbe | null = null; + private _probeRenderQueue!: RenderReflectionProbeQueue; + private _rgbeColor = new Vec3(); + + /** + * @en Sets the probe info + * @zh 设置probe信息 + * @param probe + * @param frameBuffer + */ + public setUsageInfo (probe: ReflectionProbe, frameBuffer: Framebuffer) { + this._probe = probe; + this._frameBuffer = frameBuffer; + } + + public destroy () { + this._frameBuffer = null; + this._probeRenderQueue?.clear(); + } + + public clearFramebuffer (camera: Camera) { + if (!this._frameBuffer) { return; } + + colors[0].w = camera.clearColor.w; + const pipeline = this._pipeline as ForwardPipeline; + const pipelineSceneData = pipeline.pipelineSceneData; + const shadingScale = pipelineSceneData.shadingScale; + const vp = camera.viewport; + const size = this._probe!.resolution; + this._renderArea.x = vp.x * size; + this._renderArea.y = vp.y * size; + this._renderArea.width = vp.width * size * shadingScale; + this._renderArea.height = vp.height * size * shadingScale; + const cmdBuff = pipeline.commandBuffers[0]; + const renderPass = this._frameBuffer.renderPass; + + cmdBuff.beginRenderPass(renderPass, this._frameBuffer, this._renderArea, + colors, camera.clearDepth, camera.clearStencil); + cmdBuff.endRenderPass(); + } + + public render (camera: Camera) { + const pipeline = this._pipeline; + const cmdBuff = pipeline.commandBuffers[0]; + this._probeRenderQueue.gatherRenderObjects(this._probe!, camera, cmdBuff); + pipeline.pipelineUBO.updateCameraUBO(this._probe!.camera); + + this._renderArea.x = 0; + this._renderArea.y = 0; + this._renderArea.width = this._probe!.renderArea().x; + this._renderArea.height = this._probe!.renderArea().y; + + const renderPass = this._frameBuffer!.renderPass; + + if (this._probe!.camera.clearFlag & ClearFlagBit.COLOR) { + this._rgbeColor.x = this._probe!.camera.clearColor.x; + this._rgbeColor.y = this._probe!.camera.clearColor.y; + this._rgbeColor.z = this._probe!.camera.clearColor.z; + const rgbe = packRGBE(this._rgbeColor); + colors[0].x = rgbe.x; + colors[0].y = rgbe.y; + colors[0].z = rgbe.z; + colors[0].w = rgbe.w; + } + const device = pipeline.device; + cmdBuff.beginRenderPass(renderPass, this._frameBuffer!, this._renderArea, + colors, this._probe!.camera.clearDepth, this._probe!.camera.clearStencil); + cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, pipeline.descriptorSet); + + this._probeRenderQueue.recordCommandBuffer(device, renderPass, cmdBuff); + cmdBuff.endRenderPass(); + + pipeline.pipelineUBO.updateCameraUBO(camera); + } + + public activate (pipeline: ForwardPipeline, flow: ReflectionProbeFlow) { + super.activate(pipeline, flow); + this._probeRenderQueue = new RenderReflectionProbeQueue(pipeline); + } +} diff --git a/cocos/rendering/render-additive-light-queue.ts b/cocos/rendering/render-additive-light-queue.ts index b68b817eda5..657620e0bb3 100644 --- a/cocos/rendering/render-additive-light-queue.ts +++ b/cocos/rendering/render-additive-light-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,29 +20,31 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BatchingSchemes, Pass } from '../render-scene/core/pass'; import { Model } from '../render-scene/scene/model'; import { PipelineStateManager } from './pipeline-state-manager'; -import { Vec3, nextPow2, Mat4, Color } from '../core/math'; -import { intersect } from '../core/geometry'; +import { Vec3, nextPow2, Mat4, Color, Pool, geometry, cclegacy } from '../core'; import { Device, RenderPass, Buffer, BufferUsageBit, MemoryUsageBit, BufferInfo, BufferViewInfo, CommandBuffer } from '../gfx'; -import { Pool } from '../core/memop'; import { RenderBatchedQueue } from './render-batched-queue'; import { RenderInstancedQueue } from './render-instanced-queue'; import { SphereLight } from '../render-scene/scene/sphere-light'; import { SpotLight } from '../render-scene/scene/spot-light'; +import { PointLight } from '../render-scene/scene/point-light'; +import { RangedDirectionalLight } from '../render-scene/scene/ranged-directional-light'; import { SubModel } from '../render-scene/scene/submodel'; import { getPhaseID } from './pass-phase'; import { Light, LightType } from '../render-scene/scene/light'; import { SetIndex, UBOForwardLight, UBOShadow, UNIFORM_SHADOWMAP_BINDING, - UNIFORM_SPOT_SHADOW_MAP_TEXTURE_BINDING, supportsR32FloatTexture } from './define'; + UNIFORM_SPOT_SHADOW_MAP_TEXTURE_BINDING, supportsR32FloatTexture, isEnableEffect } from './define'; import { Camera, ShadowType } from '../render-scene/scene'; import { GlobalDSManager } from './global-descriptor-set-manager'; import { PipelineUBO } from './pipeline-ubo'; import { PipelineRuntime } from './custom/pipeline'; +import { getDescBindingFromName } from './custom/define'; +import { AABB } from '../core/geometry'; interface IAdditiveLightPass { subModel: SubModel; @@ -54,31 +55,50 @@ interface IAdditiveLightPass { const _lightPassPool = new Pool(() => ({ subModel: null!, passIdx: -1, dynamicOffsets: [], lights: [] }), 16); +const _v3 = new Vec3(); const _vec4Array = new Float32Array(4); const _dynamicOffsets: number[] = []; const _lightIndices: number[] = []; const _matShadowView = new Mat4(); const _matShadowViewProj = new Mat4(); +const _rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5); +const _tmpBoundingBox = new AABB(); function cullSphereLight (light: SphereLight, model: Model) { - return !!(model.worldBounds && !intersect.aabbWithAABB(model.worldBounds, light.aabb)); + return !!(model.worldBounds && !geometry.intersect.aabbWithAABB(model.worldBounds, light.aabb)); } function cullSpotLight (light: SpotLight, model: Model) { return !!(model.worldBounds - && (!intersect.aabbWithAABB(model.worldBounds, light.aabb) || !intersect.aabbFrustum(model.worldBounds, light.frustum))); + && (!geometry.intersect.aabbWithAABB(model.worldBounds, light.aabb) || !geometry.intersect.aabbFrustum(model.worldBounds, light.frustum))); +} + +function cullPointLight (light: PointLight, model: Model) { + return !!(model.worldBounds && !geometry.intersect.aabbWithAABB(model.worldBounds, light.aabb)); +} + +function cullRangedDirLight (light: RangedDirectionalLight, model: Model) { + AABB.transform(_tmpBoundingBox, _rangedDirLightBoundingBox, light.node!.getWorldMatrix()); + return !!(model.worldBounds + && (!geometry.intersect.aabbWithAABB(model.worldBounds, _tmpBoundingBox))); } -const _phaseID = getPhaseID('forward-add'); +const phaseName = 'forward-add'; +let _phaseID = getPhaseID(phaseName); const _lightPassIndices: number[] = []; function getLightPassIndices (subModels: SubModel[], lightPassIndices: number[]) { + const r = cclegacy.rendering; + if (isEnableEffect()) { + _phaseID = r.getPhaseID(r.getPassID('default'), phaseName); + } lightPassIndices.length = 0; let hasValidLightPass = false; for (let j = 0; j < subModels.length; j++) { const { passes } = subModels[j]; let lightPassIndex = -1; for (let k = 0; k < passes.length; k++) { - if (passes[k].phase === _phaseID) { + if (((!r || !r.enableEffectImport) && passes[k].phase === _phaseID) + || (isEnableEffect() && passes[k].phaseID === _phaseID)) { lightPassIndex = k; hasValidLightPass = true; break; @@ -89,24 +109,6 @@ function getLightPassIndices (subModels: SubModel[], lightPassIndices: number[]) return hasValidLightPass; } -function isInstancedOrBatched (model: Model) { - const subModels = model.subModels; - for (let m = 0; m < subModels.length; ++m) { - const passes = subModels[m].passes; - for (let p = 0; p < passes.length; ++p) { - const pass = passes[p]; - const batchingScheme = pass.batchingScheme; - if (batchingScheme === BatchingSchemes.INSTANCING) { - return true; - } - if (batchingScheme === BatchingSchemes.VB_MERGING) { - return true; - } - } - } - return false; -} - /** * @zh 叠加光照队列。 */ @@ -123,15 +125,13 @@ export class RenderAdditiveLightQueue { private _lightBuffer: Buffer; private _firstLightBufferView: Buffer; private _lightBufferData: Float32Array; - private _instancedQueue: RenderInstancedQueue; - private _batchedQueue: RenderBatchedQueue; + private _instancedQueues: RenderInstancedQueue[] = []; + private _batchedQueues: RenderBatchedQueue[] = []; private _lightMeterScale = 10000.0; constructor (pipeline: PipelineRuntime) { this._pipeline = pipeline; this._device = pipeline.device; - this._instancedQueue = new RenderInstancedQueue(); - this._batchedQueue = new RenderBatchedQueue(); const alignment = this._device.capabilities.uboOffsetAlignment; this._lightBufferStride = Math.ceil(UBOForwardLight.SIZE / alignment) * alignment; @@ -150,8 +150,14 @@ export class RenderAdditiveLightQueue { } public clear () { - this._instancedQueue.clear(); - this._batchedQueue.clear(); + this._instancedQueues.forEach((instancedQueue) => { + instancedQueue.clear(); + }); + this._instancedQueues.length = 0; + this._batchedQueues.forEach((batchedQueue) => { + batchedQueue.clear(); + }); + this._batchedQueues.length = 0; for (let i = 0; i < this._lightPasses.length; i++) { const lp = this._lightPasses[i]; @@ -175,7 +181,8 @@ export class RenderAdditiveLightQueue { const key = keys[i]; const descriptorSet = descriptorSetMap.get(key)!; if (descriptorSet) { - descriptorSet.getBuffer(UBOShadow.BINDING).destroy(); + const binding = isEnableEffect() ? getDescBindingFromName('CCShadow') : UBOShadow.BINDING; + descriptorSet.getBuffer(binding).destroy(); descriptorSet.getTexture(UNIFORM_SHADOWMAP_BINDING).destroy(); descriptorSet.getTexture(UNIFORM_SPOT_SHADOW_MAP_TEXTURE_BINDING).destroy(); descriptorSet.destroy(); @@ -215,6 +222,7 @@ export class RenderAdditiveLightQueue { if (isTransparent) { continue; } + const binding = isEnableEffect() ? getDescBindingFromName('CCForwardLight') : UBOForwardLight.BINDING; subModel.descriptorSet.bindBuffer(UBOForwardLight.BINDING, this._firstLightBufferView); subModel.descriptorSet.update(); @@ -230,24 +238,29 @@ export class RenderAdditiveLightQueue { this._batchedLightPassPool.lights.push(light); this._batchedLightPassPool.dynamicOffsets.push(this._lightBufferStride * l); } - this._instancedQueue.uploadBuffers(cmdBuff); - this._batchedQueue.uploadBuffers(cmdBuff); + + this._instancedQueues.forEach((instancedQueue) => { + instancedQueue.uploadBuffers(cmdBuff); + }); + this._batchedQueues.forEach((batchedQueue) => { + batchedQueue.uploadBuffers(cmdBuff); + }); } public recordCommandBuffer (device: Device, renderPass: RenderPass, cmdBuff: CommandBuffer) { const globalDSManager: GlobalDSManager = this._pipeline.globalDSManager; - for (let j = 0; j < this._instancedLightPassPool.lights.length; ++j) { + for (let j = 0; j < this._instancedQueues.length; ++j) { const light = this._instancedLightPassPool.lights[j]; _dynamicOffsets[0] = this._instancedLightPassPool.dynamicOffsets[j]; const descriptorSet = globalDSManager.getOrCreateDescriptorSet(light); - this._instancedQueue.recordCommandBuffer(device, renderPass, cmdBuff, descriptorSet, _dynamicOffsets); + this._instancedQueues[j].recordCommandBuffer(device, renderPass, cmdBuff, descriptorSet, _dynamicOffsets); } - for (let j = 0; j < this._batchedLightPassPool.lights.length; ++j) { + for (let j = 0; j < this._batchedQueues.length; ++j) { const light = this._batchedLightPassPool.lights[j]; _dynamicOffsets[0] = this._batchedLightPassPool.dynamicOffsets[j]; const descriptorSet = globalDSManager.getOrCreateDescriptorSet(light); - this._batchedQueue.recordCommandBuffer(device, renderPass, cmdBuff, descriptorSet, _dynamicOffsets); + this._batchedQueues[j].recordCommandBuffer(device, renderPass, cmdBuff, descriptorSet, _dynamicOffsets); } for (let i = 0; i < this._lightPasses.length; i++) { @@ -275,17 +288,22 @@ export class RenderAdditiveLightQueue { } // light culling - protected _lightCulling (model:Model, validPunctualLights: Light[]) { + protected _lightCulling (model: Model, validPunctualLights: Light[]) { let isCulled = false; - const isNeedCulling = !isInstancedOrBatched(model); for (let l = 0; l < validPunctualLights.length; l++) { const light = validPunctualLights[l]; switch (light.type) { case LightType.SPHERE: - if (isNeedCulling) { isCulled = cullSphereLight(light as SphereLight, model); } + isCulled = cullSphereLight(light as SphereLight, model); break; case LightType.SPOT: - if (isNeedCulling) { isCulled = cullSpotLight(light as SpotLight, model); } + isCulled = cullSpotLight(light as SpotLight, model); + break; + case LightType.POINT: + isCulled = cullPointLight(light as PointLight, model); + break; + case LightType.RANGED_DIRECTIONAL: + isCulled = cullRangedDirLight(light as RangedDirectionalLight, model); break; default: } @@ -299,27 +317,43 @@ export class RenderAdditiveLightQueue { protected _addRenderQueue (pass: Pass, subModel: SubModel, model: Model, lightPassIdx: number) { const validPunctualLights = this._pipeline.pipelineSceneData.validPunctualLights; const { batchingScheme } = pass; - if (batchingScheme === BatchingSchemes.INSTANCING) { // instancing - const buffer = pass.getInstancedBuffer(); - buffer.merge(subModel, lightPassIdx); - buffer.dynamicOffsets[0] = this._lightBufferStride; - this._instancedQueue.queue.add(buffer); - } else if (batchingScheme === BatchingSchemes.VB_MERGING) { // vb-merging - const buffer = pass.getBatchedBuffer(); - buffer.merge(subModel, lightPassIdx, model); - buffer.dynamicOffsets[0] = this._lightBufferStride; - this._batchedQueue.queue.add(buffer); - } else { // standard draw - const lp = _lightPassPool.alloc(); + + let lp: IAdditiveLightPass | null = null; + if (batchingScheme === BatchingSchemes.NONE) { + lp = _lightPassPool.alloc(); lp.subModel = subModel; lp.passIdx = lightPassIdx; - for (let l = 0; l < _lightIndices.length; l++) { - const lightIdx = _lightIndices[l]; - const light = validPunctualLights[lightIdx]; - lp.lights.push(light); - lp.dynamicOffsets.push(this._lightBufferStride * lightIdx); + } + + for (let l = 0; l < _lightIndices.length; l++) { + const lightIdx = _lightIndices[l]; + const light = validPunctualLights[lightIdx]; + const visibility = light.visibility; + if (((visibility & model.node.layer) === model.node.layer)) { + switch (batchingScheme) { + case BatchingSchemes.INSTANCING: { + const buffer = pass.getInstancedBuffer(l); + buffer.merge(subModel, lightPassIdx); + buffer.dynamicOffsets[0] = this._lightBufferStride; + if (!this._instancedQueues[l]) { this._instancedQueues[l] = new RenderInstancedQueue(); } + this._instancedQueues[l].queue.add(buffer); + } break; + case BatchingSchemes.VB_MERGING: { + const buffer = pass.getBatchedBuffer(l); + buffer.merge(subModel, lightPassIdx, model); + buffer.dynamicOffsets[0] = this._lightBufferStride; + if (!this._batchedQueues[l]) { this._batchedQueues[l] = new RenderBatchedQueue(); } + this._batchedQueues[l].queue.add(buffer); + } break; + default: + lp!.lights.push(light); + lp!.dynamicOffsets.push(this._lightBufferStride * lightIdx); + } } - this._lightPasses.push(lp); + } + + if (batchingScheme === BatchingSchemes.NONE) { + this._lightPasses.push(lp!); } } @@ -339,8 +373,8 @@ export class RenderAdditiveLightQueue { const light = validPunctualLights[i]; const descriptorSet = globalDSManager.getOrCreateDescriptorSet(light); if (!descriptorSet) { continue; } - let matShadowProj : Mat4; - let matShadowInvProj : Mat4; + let matShadowProj: Mat4; + let matShadowInvProj: Mat4; switch (light.type) { case LightType.SPHERE: { // planar PROJ @@ -426,11 +460,31 @@ export class RenderAdditiveLightQueue { } break; } + case LightType.POINT: { + // planar PROJ + if (mainLight) { + PipelineUBO.updatePlanarNormalAndDistance(shadowInfo, this._shadowUBO); + } + + this._shadowUBO[UBOShadow.SHADOW_WIDTH_HEIGHT_PCF_BIAS_INFO_OFFSET + 0] = shadowInfo.size.x; + this._shadowUBO[UBOShadow.SHADOW_WIDTH_HEIGHT_PCF_BIAS_INFO_OFFSET + 1] = shadowInfo.size.y; + this._shadowUBO[UBOShadow.SHADOW_WIDTH_HEIGHT_PCF_BIAS_INFO_OFFSET + 2] = 1.0; + this._shadowUBO[UBOShadow.SHADOW_WIDTH_HEIGHT_PCF_BIAS_INFO_OFFSET + 3] = 0.0; + + this._shadowUBO[UBOShadow.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 0] = 2.0; + this._shadowUBO[UBOShadow.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 1] = packing; + this._shadowUBO[UBOShadow.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 2] = 0.0; + this._shadowUBO[UBOShadow.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 3] = 0.0; + + // Reserve point light shadow interface + Color.toArray(this._shadowUBO, shadowInfo.shadowColor, UBOShadow.SHADOW_COLOR_OFFSET); + break; + } default: } descriptorSet.update(); - - cmdBuff.updateBuffer(descriptorSet.getBuffer(UBOShadow.BINDING)!, this._shadowUBO); + const binding = isEnableEffect() ? getDescBindingFromName('CCShadow') : UBOShadow.BINDING; + cmdBuff.updateBuffer(descriptorSet.getBuffer(binding)!, this._shadowUBO); } } @@ -458,7 +512,7 @@ export class RenderAdditiveLightQueue { case LightType.SPHERE: // UBOForwardLight Vec3.toArray(_vec4Array, (light as SphereLight).position); - _vec4Array[3] = 0; + _vec4Array[3] = LightType.SPHERE; this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_POS_OFFSET); _vec4Array[0] = (light as SphereLight).size; @@ -467,12 +521,13 @@ export class RenderAdditiveLightQueue { _vec4Array[3] = 0.0; this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_SIZE_RANGE_ANGLE_OFFSET); + // cc_lightColor Vec3.toArray(_vec4Array, light.color); if (light.useColorTemperature) { - const tempRGB = light.colorTemperatureRGB; - _vec4Array[0] *= tempRGB.x; - _vec4Array[1] *= tempRGB.y; - _vec4Array[2] *= tempRGB.z; + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; } if (isHDR) { _vec4Array[3] = (light as SphereLight).luminance * exposure * this._lightMeterScale; @@ -484,7 +539,7 @@ export class RenderAdditiveLightQueue { case LightType.SPOT: // UBOForwardLight Vec3.toArray(_vec4Array, (light as SpotLight).position); - _vec4Array[3] = 1; + _vec4Array[3] = LightType.SPOT; this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_POS_OFFSET); _vec4Array[0] = (light as SpotLight).size; @@ -496,12 +551,13 @@ export class RenderAdditiveLightQueue { Vec3.toArray(_vec4Array, (light as SpotLight).direction); this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_DIR_OFFSET); + // cc_lightColor Vec3.toArray(_vec4Array, light.color); if (light.useColorTemperature) { - const tempRGB = light.colorTemperatureRGB; - _vec4Array[0] *= tempRGB.x; - _vec4Array[1] *= tempRGB.y; - _vec4Array[2] *= tempRGB.z; + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; } if (isHDR) { _vec4Array[3] = (light as SpotLight).luminance * exposure * this._lightMeterScale; @@ -510,6 +566,69 @@ export class RenderAdditiveLightQueue { } this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_COLOR_OFFSET); break; + case LightType.POINT: + // UBOForwardLight + Vec3.toArray(_vec4Array, (light as PointLight).position); + _vec4Array[3] = LightType.POINT; + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_POS_OFFSET); + + _vec4Array[0] = 0.0; + _vec4Array[1] = (light as PointLight).range; + _vec4Array[2] = 0.0; + _vec4Array[3] = 0.0; + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_SIZE_RANGE_ANGLE_OFFSET); + + // cc_lightColor + Vec3.toArray(_vec4Array, light.color); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; + } + if (isHDR) { + _vec4Array[3] = (light as PointLight).luminance * exposure * this._lightMeterScale; + } else { + _vec4Array[3] = (light as PointLight).luminance; + } + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_COLOR_OFFSET); + break; + case LightType.RANGED_DIRECTIONAL: + // UBOForwardLight + Vec3.toArray(_vec4Array, (light as RangedDirectionalLight).position); + _vec4Array[3] = LightType.RANGED_DIRECTIONAL; + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_POS_OFFSET); + + Vec3.toArray(_vec4Array, (light as RangedDirectionalLight).right); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_SIZE_RANGE_ANGLE_OFFSET); + + Vec3.toArray(_vec4Array, (light as RangedDirectionalLight).direction); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_DIR_OFFSET); + + // eslint-disable-next-line no-case-declarations + const scale = (light as RangedDirectionalLight).scale; + _v3.set(scale.x * 0.5, scale.y * 0.5, scale.z * 0.5); + Vec3.toArray(_vec4Array, _v3); + _vec4Array[3] = 0; + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_BOUNDING_SIZE_VS_OFFSET); + + // cc_lightColor + Vec3.toArray(_vec4Array, light.color); + if (light.useColorTemperature) { + const finalColor = light.finalColor; + _vec4Array[0] = finalColor.x; + _vec4Array[1] = finalColor.y; + _vec4Array[2] = finalColor.z; + } + if (isHDR) { + _vec4Array[3] = (light as RangedDirectionalLight).illuminance * exposure; + } else { + _vec4Array[3] = (light as RangedDirectionalLight).illuminance; + } + this._lightBufferData.set(_vec4Array, offset + UBOForwardLight.LIGHT_COLOR_OFFSET); + break; default: } } diff --git a/cocos/rendering/render-batched-queue.ts b/cocos/rendering/render-batched-queue.ts index 3393077192f..96aa9e671b9 100644 --- a/cocos/rendering/render-batched-queue.ts +++ b/cocos/rendering/render-batched-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { BatchedBuffer } from './batched-buffer'; import { PipelineStateManager } from './pipeline-state-manager'; diff --git a/cocos/rendering/render-flow.ts b/cocos/rendering/render-flow.ts index 58e4e396022..84b50048155 100644 --- a/cocos/rendering/render-flow.ts +++ b/cocos/rendering/render-flow.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, serializable, type } from 'cc.decorator'; import { RenderStage } from './render-stage'; import { RenderPipeline } from './render-pipeline'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import { Camera } from '../render-scene/scene'; /** @@ -156,4 +155,4 @@ export abstract class RenderFlow { } } -legacyCC.RenderFlow = RenderFlow; +cclegacy.RenderFlow = RenderFlow; diff --git a/cocos/rendering/render-instanced-queue.ts b/cocos/rendering/render-instanced-queue.ts index 414b0fe780d..9be4e7e7531 100644 --- a/cocos/rendering/render-instanced-queue.ts +++ b/cocos/rendering/render-instanced-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { InstancedBuffer } from './instanced-buffer'; import { Device, RenderPass, PipelineState, CommandBuffer, DescriptorSet } from '../gfx'; @@ -51,7 +50,7 @@ export class RenderInstancedQueue { res.value.clear(); res = it.next(); } - this._renderQueue = []; + this._renderQueue.length = 0; this.queue.clear(); } diff --git a/cocos/rendering/render-pipeline.jsb.ts b/cocos/rendering/render-pipeline.jsb.ts index e4dd60c72db..ef548dafca6 100644 --- a/cocos/rendering/render-pipeline.jsb.ts +++ b/cocos/rendering/render-pipeline.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; export const RenderPipeline = nr.RenderPipeline; // Do not delete, for the class detection of editor -legacyCC.RenderPipeline = RenderPipeline; +cclegacy.RenderPipeline = RenderPipeline; diff --git a/cocos/rendering/render-pipeline.ts b/cocos/rendering/render-pipeline.ts index 3bc91e218dd..76e721d174d 100644 --- a/cocos/rendering/render-pipeline.ts +++ b/cocos/rendering/render-pipeline.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, serializable, type } from 'cc.decorator'; import { systemInfo } from 'pal/system-info'; @@ -32,7 +31,6 @@ import { AccessFlagBit, Attribute, Buffer, BufferInfo, BufferUsageBit, ClearFlag InputAssemblerInfo, LoadOp, MemoryUsageBit, Rect, RenderPass, RenderPassInfo, Sampler, StoreOp, SurfaceTransform, Swapchain, Texture, TextureInfo, TextureType, TextureUsageBit, Viewport, GeneralBarrierInfo, deviceManager, } from '../gfx'; -import { legacyCC } from '../core/global-exports'; import { MacroRecord } from '../render-scene/core/pass-utils'; import { RenderWindow } from '../render-scene/core/render-window'; import { Camera, SKYBOX_FLAG } from '../render-scene/scene/camera'; @@ -45,10 +43,9 @@ import { RenderFlow } from './render-flow'; import { IPipelineEvent, PipelineEventProcessor, PipelineEventType } from './pipeline-event'; import { decideProfilerCamera } from './pipeline-funcs'; import { OS } from '../../pal/system-info/enum-type'; -import { macro } from '../core/platform/macro'; +import { macro, murmurhash2_32_gc, cclegacy } from '../core'; import { UBOSkinning } from './define'; import { PipelineRuntime } from './custom/pipeline'; -import { murmurhash2_32_gc } from '../core/algorithm/murmurhash2_gc'; /** * @en Render pipeline information descriptor @@ -305,7 +302,7 @@ export abstract class RenderPipeline extends Asset implements IPipelineEvent, Pi if (!(clearFlags & ClearFlagBit.COLOR)) { if (clearFlags & SKYBOX_FLAG) { - colorAttachment.loadOp = LoadOp.DISCARD; + colorAttachment.loadOp = LoadOp.CLEAR; } else { colorAttachment.loadOp = LoadOp.LOAD; colorAttachment.barrier = device.getGeneralBarrier(new GeneralBarrierInfo( @@ -566,7 +563,7 @@ export abstract class RenderPipeline extends Asset implements IPipelineEvent, Pi this._pipelineRenderData!.bloom = null; } - private _genQuadVertexData (surfaceTransform: SurfaceTransform, renderArea: Rect) : Float32Array { + private _genQuadVertexData (surfaceTransform: SurfaceTransform, renderArea: Rect): Float32Array { const vbData = new Float32Array(4 * 4); const minX = renderArea.x / this._width; @@ -916,4 +913,4 @@ export abstract class RenderPipeline extends Asset implements IPipelineEvent, Pi } // Do not delete, for the class detection of editor -legacyCC.RenderPipeline = RenderPipeline; +cclegacy.RenderPipeline = RenderPipeline; diff --git a/cocos/rendering/render-queue.ts b/cocos/rendering/render-queue.ts index e6f78368b17..41002f03b5f 100644 --- a/cocos/rendering/render-queue.ts +++ b/cocos/rendering/render-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { RecyclePool } from '../core/memop'; -import { CachedArray } from '../core/memop/cached-array'; +import { RecyclePool, CachedArray } from '../core'; import { IRenderObject, IRenderPass, IRenderQueueDesc, SetIndex } from './define'; import { PipelineStateManager } from './pipeline-state-manager'; import { RenderPass, Device, CommandBuffer } from '../gfx'; diff --git a/cocos/rendering/render-reflection-probe-queue.ts b/cocos/rendering/render-reflection-probe-queue.ts new file mode 100644 index 00000000000..ada6fe9c958 --- /dev/null +++ b/cocos/rendering/render-reflection-probe-queue.ts @@ -0,0 +1,221 @@ +/* + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { SubModel } from '../render-scene/scene/submodel'; +import { isEnableEffect, SetIndex } from './define'; +import { Device, RenderPass, Shader, CommandBuffer } from '../gfx'; +import { getPhaseID } from './pass-phase'; +import { PipelineStateManager } from './pipeline-state-manager'; +import { Pass, BatchingSchemes } from '../render-scene/core/pass'; +import { Model } from '../render-scene/scene/model'; +import { Camera, ProbeType, ReflectionProbe, SKYBOX_FLAG } from '../render-scene/scene'; +import { PipelineRuntime } from './custom/pipeline'; +import { IMacroPatch, RenderScene } from '../render-scene'; +import { RenderInstancedQueue } from './render-instanced-queue'; +import { RenderBatchedQueue } from './render-batched-queue'; +import { cclegacy, geometry } from '../core'; +import { Layers } from '../scene-graph/layers'; + +// eslint-disable-next-line max-len +const REFLECTION_PROBE_DEFAULT_MASK = Layers.makeMaskExclude([Layers.BitMask.UI_2D, Layers.BitMask.UI_3D, Layers.BitMask.GIZMOS, Layers.BitMask.EDITOR, + Layers.BitMask.SCENE_GIZMO, Layers.BitMask.PROFILER]); + +const CC_USE_RGBE_OUTPUT = 'CC_USE_RGBE_OUTPUT'; +let _phaseID = getPhaseID('default'); +let _phaseReflectMapID = getPhaseID('reflect-map'); +function getPassIndex (subModel: SubModel): number { + const passes = subModel.passes; + const r = cclegacy.rendering; + if (isEnableEffect()) _phaseID = r.getPhaseID(r.getPassID('default'), 'default'); + for (let k = 0; k < passes.length; k++) { + if (((!r || !r.enableEffectImport) && passes[k].phase === _phaseID) || (isEnableEffect() && passes[k].phaseID === _phaseID)) { + return k; + } + } + return -1; +} + +function getReflectMapPassIndex (subModel: SubModel): number { + const passes = subModel.passes; + const r = cclegacy.rendering; + if (isEnableEffect()) _phaseReflectMapID = r.getPhaseID(r.getPassID('default'), 'reflect-map'); + for (let k = 0; k < passes.length; k++) { + if (((!r || !r.enableEffectImport) && passes[k].phase === _phaseReflectMapID) + || (isEnableEffect() && passes[k].phaseID === _phaseReflectMapID)) { + return k; + } + } + return -1; +} + +/** + * @zh + * 反射探针渲染队列 + */ +export class RenderReflectionProbeQueue { + private _pipeline: PipelineRuntime; + private _subModelsArray: SubModel[] = []; + private _passArray: Pass[] = []; + private _shaderArray: Shader[] = []; + private _rgbeSubModelsArray: SubModel[]=[] + private _instancedQueue: RenderInstancedQueue; + private _batchedQueue: RenderBatchedQueue; + + public constructor (pipeline: PipelineRuntime) { + this._pipeline = pipeline; + this._instancedQueue = new RenderInstancedQueue(); + this._batchedQueue = new RenderBatchedQueue(); + } + public gatherRenderObjects (probe: ReflectionProbe, camera: Camera, cmdBuff: CommandBuffer) { + this.clear(); + const scene = camera.scene!; + const sceneData = this._pipeline.pipelineSceneData; + const skybox = sceneData.skybox; + + if (skybox.enabled && skybox.model && (probe.camera.clearFlag & SKYBOX_FLAG)) { + this.add(skybox.model); + } + + const models = scene.models; + const visibility = probe.camera.visibility; + + for (let i = 0; i < models.length; i++) { + const model = models[i]; + if (scene.isCulledByLod(camera, model)) { + continue; + } + // filter model by view visibility + if (model.enabled && model.node && model.worldBounds && model.bakeToReflectionProbe) { + if (probe.probeType === ProbeType.CUBE) { + if ((((visibility & model.node.layer) === model.node.layer) || (visibility & model.visFlags)) + && geometry.intersect.aabbWithAABB(model.worldBounds, probe.boundingBox!)) { + this.add(model); + } + } else if (((model.node.layer & REFLECTION_PROBE_DEFAULT_MASK) === model.node.layer) + || (REFLECTION_PROBE_DEFAULT_MASK & model.visFlags)) { + if (geometry.intersect.aabbFrustum(model.worldBounds, probe.camera.frustum)) { + this.add(model); + } + } + } + } + this._instancedQueue.uploadBuffers(cmdBuff); + this._batchedQueue.uploadBuffers(cmdBuff); + } + + public clear () { + this._subModelsArray.length = 0; + this._shaderArray.length = 0; + this._passArray.length = 0; + this._instancedQueue.clear(); + this._batchedQueue.clear(); + this._rgbeSubModelsArray.length = 0; + } + + public add (model: Model) { + const subModels = model.subModels; + for (let j = 0; j < subModels.length; j++) { + const subModel = subModels[j]; + + let passIdx = getReflectMapPassIndex(subModel); + let bUseReflectPass = true; + if (passIdx < 0) { + passIdx = getPassIndex(subModel); + bUseReflectPass = false; + } + if (passIdx < 0) { continue; } + + const pass = subModel.passes[passIdx]; + const batchingScheme = pass.batchingScheme; + + if (!bUseReflectPass) { + let patches: IMacroPatch[] | null = subModel.patches; + const useRGBEPatchs: IMacroPatch[] = [ + { name: CC_USE_RGBE_OUTPUT, value: true }, + ]; + patches = patches ? patches.concat(useRGBEPatchs) : useRGBEPatchs; + subModel.onMacroPatchesStateChanged(patches); + this._rgbeSubModelsArray.push(subModel); + } + + if (batchingScheme === BatchingSchemes.INSTANCING) { // instancing + const buffer = pass.getInstancedBuffer(); + buffer.merge(subModel, passIdx); + this._instancedQueue.queue.add(buffer); + } else if (pass.batchingScheme === BatchingSchemes.VB_MERGING) { // vb-merging + const buffer = pass.getBatchedBuffer(); + buffer.merge(subModel, passIdx, model); + this._batchedQueue.queue.add(buffer); + } else { + const shader = subModel.shaders[passIdx]; + this._subModelsArray.push(subModel); + if (shader) this._shaderArray.push(shader); + this._passArray.push(pass); + } + } + } + + /** + * @zh + * record CommandBuffer + */ + public recordCommandBuffer (device: Device, renderPass: RenderPass, cmdBuff: CommandBuffer) { + this._instancedQueue.recordCommandBuffer(device, renderPass, cmdBuff); + this._batchedQueue.recordCommandBuffer(device, renderPass, cmdBuff); + + for (let i = 0; i < this._subModelsArray.length; ++i) { + const subModel = this._subModelsArray[i]; + const shader = this._shaderArray[i]; + const pass = this._passArray[i]; + const ia = subModel.inputAssembler; + const pso = PipelineStateManager.getOrCreatePipelineState(device, pass, shader, renderPass, ia); + const descriptorSet = pass.descriptorSet; + + cmdBuff.bindPipelineState(pso); + cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, descriptorSet); + cmdBuff.bindDescriptorSet(SetIndex.LOCAL, subModel.descriptorSet); + cmdBuff.bindInputAssembler(ia); + cmdBuff.draw(ia); + } + this.resetRGBEMacro(); + this._instancedQueue.clear(); + this._batchedQueue.clear(); + } + public resetRGBEMacro () { + for (let i = 0; i < this._rgbeSubModelsArray.length; i++) { + const subModel = this._rgbeSubModelsArray[i]; + // eslint-disable-next-line prefer-const + let patches: IMacroPatch[] | null = subModel.patches; + if (!patches) continue; + for (let j = 0; j < patches.length; j++) { + const patch = patches[j]; + if (patch.name === CC_USE_RGBE_OUTPUT) { + patches.splice(j, 1); + break; + } + } + subModel.onMacroPatchesStateChanged(patches); + } + } +} diff --git a/cocos/rendering/render-shadow-map-batched-queue.ts b/cocos/rendering/render-shadow-map-batched-queue.ts index 9974df385d7..36f2eb25a9c 100644 --- a/cocos/rendering/render-shadow-map-batched-queue.ts +++ b/cocos/rendering/render-shadow-map-batched-queue.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { SubModel } from '../render-scene/scene/submodel'; -import { SetIndex } from './define'; +import { isEnableEffect, SetIndex } from './define'; import { Device, RenderPass, Shader, CommandBuffer } from '../gfx'; import { getPhaseID } from './pass-phase'; import { PipelineStateManager } from './pipeline-state-manager'; @@ -33,17 +32,20 @@ import { RenderInstancedQueue } from './render-instanced-queue'; import { RenderBatchedQueue } from './render-batched-queue'; import { ShadowType } from '../render-scene/scene/shadows'; import { Light, LightType } from '../render-scene/scene/light'; -import { intersect } from '../core/geometry'; +import { cclegacy, geometry } from '../core'; import { Model } from '../render-scene/scene/model'; import { Camera, DirectionalLight, SpotLight } from '../render-scene/scene'; import { shadowCulling } from './scene-culling'; import { PipelineRuntime } from './custom/pipeline'; -const _phaseID = getPhaseID('shadow-caster'); -function getShadowPassIndex (subModel: SubModel) : number { +let _phaseID = getPhaseID('shadow-caster'); +function getShadowPassIndex (subModel: SubModel): number { const passes = subModel.passes; + const r = cclegacy.rendering; + if (isEnableEffect()) _phaseID = r.getPhaseID(r.getPassID('default'), 'shadow-caster'); for (let k = 0; k < passes.length; k++) { - if (passes[k].phase === _phaseID) { + if (((!r || !r.enableEffectImport) && passes[k].phase === _phaseID) + || (isEnableEffect() && passes[k].phaseID === _phaseID)) { return k; } } @@ -100,12 +102,14 @@ export class RenderShadowMapBatchedQueue { // eslint-disable-next-line no-case-declarations const spotLight = light as SpotLight; if (spotLight.shadowEnabled) { + const visibility = spotLight.visibility; const castShadowObjects = sceneData.csmLayers.castShadowObjects; for (let i = 0; i < castShadowObjects.length; i++) { const ro = castShadowObjects[i]; const model = ro.model; if (model.worldBounds) { - if (!intersect.aabbFrustum(model.worldBounds, spotLight.frustum)) { continue; } + if (((visibility & model.node.layer) !== model.node.layer) + || !geometry.intersect.aabbFrustum(model.worldBounds, spotLight.frustum)) { continue; } } this.add(model); diff --git a/cocos/rendering/render-stage.jsb.ts b/cocos/rendering/render-stage.jsb.ts new file mode 100644 index 00000000000..937994e78ac --- /dev/null +++ b/cocos/rendering/render-stage.jsb.ts @@ -0,0 +1,30 @@ +/* + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +declare var nr:any; + +import { legacyCC } from '../core/global-exports'; +export const RenderStage = nr.RenderStage; +// Do not delete, for the class detection of editor +legacyCC.RenderStage = RenderStage; diff --git a/cocos/rendering/render-stage.ts b/cocos/rendering/render-stage.ts index 574121a07ce..843afb27806 100644 --- a/cocos/rendering/render-stage.ts +++ b/cocos/rendering/render-stage.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,10 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, serializable } from 'cc.decorator'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core'; import { RenderPipeline } from './render-pipeline'; import { RenderFlow } from './render-flow'; import { RenderQueueDesc } from './pipeline-serialization'; @@ -148,4 +147,4 @@ export abstract class RenderStage { public abstract render (camera: Camera); } -legacyCC.RenderStage = RenderStage; +cclegacy.RenderStage = RenderStage; diff --git a/cocos/rendering/scene-culling.ts b/cocos/rendering/scene-culling.ts index 9f20ec4f05c..6d3ba30e535 100644 --- a/cocos/rendering/scene-culling.ts +++ b/cocos/rendering/scene-culling.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,22 +20,22 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -import { intersect, Sphere } from '../core/geometry'; +*/ +import { EDITOR } from 'internal:constants'; import { Model } from '../render-scene/scene/model'; -import { Camera, SKYBOX_FLAG } from '../render-scene/scene/camera'; -import { Vec3 } from '../core/math'; +import { Camera, CameraUsage, SKYBOX_FLAG } from '../render-scene/scene/camera'; +import { Vec3, Pool, warnID, geometry, cclegacy } from '../core'; import { RenderPipeline } from './render-pipeline'; -import { Pool } from '../core/memop'; import { IRenderObject, UBOShadow } from './define'; import { ShadowType, CSMOptimizationMode } from '../render-scene/scene/shadows'; import { PipelineSceneData } from './pipeline-scene-data'; import { ShadowLayerVolume } from './shadow/csm-layers'; -import { warnID } from '../core/platform'; +import { AABB } from '../core/geometry'; const _tempVec3 = new Vec3(); -const _sphere = Sphere.create(0, 0, 0, 1); +const _sphere = geometry.Sphere.create(0, 0, 0, 1); +const _rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5); +const _tmpBoundingBox = new AABB(); const roPool = new Pool(() => ({ model: null!, depth: 0 }), 128); @@ -64,8 +63,8 @@ export function validPunctualLightsCulling (pipeline: RenderPipeline, camera: Ca continue; } - Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); - if (intersect.sphereFrustum(_sphere, camera.frustum)) { + geometry.Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (geometry.intersect.sphereFrustum(_sphere, camera.frustum)) { validPunctualLights.push(light); } } @@ -76,12 +75,36 @@ export function validPunctualLightsCulling (pipeline: RenderPipeline, camera: Ca if (light.baked) { continue; } - Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); - if (intersect.sphereFrustum(_sphere, camera.frustum)) { + geometry.Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (geometry.intersect.sphereFrustum(_sphere, camera.frustum)) { + validPunctualLights.push(light); + } + } + + const { pointLights } = camera.scene!; + for (let i = 0; i < pointLights.length; i++) { + const light = pointLights[i]; + if (light.baked) { + continue; + } + geometry.Sphere.set(_sphere, light.position.x, light.position.y, light.position.z, light.range); + if (geometry.intersect.sphereFrustum(_sphere, camera.frustum)) { validPunctualLights.push(light); } } + + const { rangedDirLights } = camera.scene!; + for (let i = 0; i < rangedDirLights.length; i++) { + const light = rangedDirLights[i]; + AABB.transform(_tmpBoundingBox, _rangedDirLightBoundingBox, light.node!.getWorldMatrix()); + if (geometry.intersect.aabbFrustum(_tmpBoundingBox, camera.frustum)) { + validPunctualLights.push(light); + } + } + // in jsb, std::vector is not synchronized, so we need to assign it manually + sceneData.validPunctualLights = validPunctualLights; } + export function shadowCulling (camera: Camera, sceneData: PipelineSceneData, layer: ShadowLayerVolume) { const scene = camera.scene!; const mainLight = scene.mainLight!; @@ -93,28 +116,33 @@ export function shadowCulling (camera: Camera, sceneData: PipelineSceneData, lay const visibility = camera.visibility; for (let i = csmLayerObjects.length - 1; i >= 0; i--) { - const csmLayerObject = csmLayerObjects.array[i]; - if (csmLayerObject) { - const model = csmLayerObject.model; - // filter model by view visibility - if (model.enabled) { - if (model.node && ((visibility & model.node.layer) === model.node.layer)) { - // shadow render Object - if (dirShadowObjects != null && model.castShadow && model.worldBounds) { - // frustum culling - // eslint-disable-next-line no-lonely-if - const accurate = intersect.aabbFrustum(model.worldBounds, dirLightFrustum); - if (accurate) { - dirShadowObjects.push(csmLayerObject); - if (layer.level < mainLight.csmLevel) { - if (mainLight.csmOptimizationMode === CSMOptimizationMode.RemoveDuplicates - && intersect.aabbFrustumCompletelyInside(model.worldBounds, dirLightFrustum)) { - csmLayerObjects.fastRemove(i); - } - } - } - } - } + const obj = csmLayerObjects.array[i]; + if (!obj) { + csmLayerObjects.fastRemove(i); + continue; + } + const model = obj.model; + if (!model || !model.enabled || !model.node) { + csmLayerObjects.fastRemove(i); + continue; + } + if (((visibility & model.node.layer) !== model.node.layer) && (!(visibility & model.visFlags))) { + csmLayerObjects.fastRemove(i); + continue; + } + if (!model.worldBounds || !model.castShadow) { + csmLayerObjects.fastRemove(i); + continue; + } + const accurate = geometry.intersect.aabbFrustum(model.worldBounds, dirLightFrustum); + if (!accurate) { + continue; + } + dirShadowObjects.push(obj); + if (layer.level < mainLight.csmLevel) { + if (mainLight.csmOptimizationMode === CSMOptimizationMode.RemoveDuplicates + && geometry.intersect.aabbFrustumCompletelyInside(model.worldBounds, dirLightFrustum)) { + csmLayerObjects.fastRemove(i); } } } @@ -149,19 +177,21 @@ export function sceneCulling (pipeline: RenderPipeline, camera: Camera) { if ((camera.clearFlag & SKYBOX_FLAG)) { if (skybox.enabled && skybox.model) { renderObjects.push(getRenderObject(skybox.model, camera)); - } else { - warnID(15100, camera.name); + } else if (camera.cameraUsage !== CameraUsage.EDITOR && camera.cameraUsage !== CameraUsage.SCENE_VIEW) { + cclegacy.warnID(15100, camera.name); } } const models = scene.models; const visibility = camera.visibility; - for (let i = 0; i < models.length; i++) { - const model = models[i]; - + function enqueueRenderObject (model: Model) { // filter model by view visibility if (model.enabled) { + if (scene.isCulledByLod(camera, model)) { + return; + } + if (model.castShadow) { castShadowObjects.push(getRenderObject(model, camera)); csmLayerObjects.push(getRenderObject(model, camera)); @@ -170,12 +200,16 @@ export function sceneCulling (pipeline: RenderPipeline, camera: Camera) { if (model.node && ((visibility & model.node.layer) === model.node.layer) || (visibility & model.visFlags)) { // frustum culling - if (model.worldBounds && !intersect.aabbFrustum(model.worldBounds, camera.frustum)) { - continue; + if (model.worldBounds && !geometry.intersect.aabbFrustum(model.worldBounds, camera.frustum)) { + return; } renderObjects.push(getRenderObject(model, camera)); } } } + + for (let i = 0; i < models.length; i++) { + enqueueRenderObject(models[i]); + } } diff --git a/cocos/rendering/shadow/csm-layers.ts b/cocos/rendering/shadow/csm-layers.ts index 8951670dd29..e5bab7a50ee 100644 --- a/cocos/rendering/shadow/csm-layers.ts +++ b/cocos/rendering/shadow/csm-layers.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,15 +18,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { DirectionalLight, Camera, Shadows, CSMLevel, CSMOptimizationMode } from '../../render-scene/scene'; import { Mat4, Vec3, Vec2, Vec4 } from '../../core/math'; import { Frustum, AABB } from '../../core/geometry'; import { IRenderObject } from '../define'; -import { legacyCC } from '../../core/global-exports'; import { PipelineSceneData } from '../pipeline-scene-data'; import { CachedArray } from '../../core/memop/cached-array'; +import { cclegacy } from '../../core'; const _mat4Trans = new Mat4(); const _matShadowTrans = new Mat4(); @@ -138,7 +139,7 @@ export class ShadowLayerVolume { } public createMatrix (dirLight: DirectionalLight, shadowMapWidth: number, onlyForCulling: boolean) { - const device = legacyCC.director.root.device; + const device = cclegacy.director.root.device; const invisibleOcclusionRange = dirLight.shadowInvisibleOcclusionRange; Frustum.copy(this._lightViewFrustum, this._splitFrustum); @@ -160,7 +161,7 @@ export class ShadowLayerVolume { orthoSizeWidth = orthoSizeHeight = Vec3.distance(this._lightViewFrustum.vertices[0], this._lightViewFrustum.vertices[6]); } - const csmLevel = legacyCC.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; + const csmLevel = cclegacy.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; if (csmLevel > 1 && dirLight.csmOptimizationMode === CSMOptimizationMode.RemoveDuplicates) { if (this._level >= csmLevel - 1) { @@ -249,7 +250,7 @@ export class CSMShadowLayer extends ShadowLayerVolume { } private _calculateAtlas (level: number) { - const clipSpaceSignY = legacyCC.director.root.device.capabilities.clipSpaceSignY; + const clipSpaceSignY = cclegacy.director.root.device.capabilities.clipSpaceSignY; const x = level % 2 - 0.5; const y = (0.5 - Math.floor(level / 2)) * clipSpaceSignY; this._csmAtlas.set(0.5, 0.5, x, y); @@ -299,7 +300,7 @@ export class CSMLayers { if (dirLight === null) { return; } const shadowInfo = sceneData.shadows; - const levelCount = legacyCC.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; + const levelCount = cclegacy.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; const shadowDistance = dirLight.shadowDistance; if (!shadowInfo.enabled || !dirLight.shadowEnabled) { return; } @@ -327,7 +328,7 @@ export class CSMLayers { } private _updateFixedArea (dirLight: DirectionalLight) { - const device = legacyCC.director.root.device; + const device = cclegacy.director.root.device; const x = dirLight.shadowOrthoSize; const y = dirLight.shadowOrthoSize; const near = dirLight.shadowNear; @@ -348,7 +349,7 @@ export class CSMLayers { const nd = 0.1; const fd = dirLight.shadowDistance; const ratio = fd / nd; - const level = legacyCC.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; + const level = cclegacy.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; const lambda = dirLight.csmLayerLambda; this._layers[0].splitCameraNear = nd; for (let i = 1; i < level; i++) { @@ -368,7 +369,7 @@ export class CSMLayers { } private _calculateCSM (camera: Camera, dirLight: DirectionalLight, shadowInfo: Shadows) { - const level = legacyCC.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; + const level = cclegacy.director.root.pipeline.pipelineSceneData.csmSupported ? dirLight.csmLevel : 1; const shadowMapWidth = level > 1 ? shadowInfo.size.x * 0.5 : shadowInfo.size.x; if (shadowMapWidth < 0.0) { return; } diff --git a/cocos/rendering/shadow/shadow-flow.ts b/cocos/rendering/shadow/shadow-flow.ts index ed641b23e88..8347ce105f7 100644 --- a/cocos/rendering/shadow/shadow-flow.ts +++ b/cocos/rendering/shadow/shadow-flow.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; import { PIPELINE_FLOW_SHADOW, supportsR32FloatTexture, UBOCamera, UBOCSM, UBOGlobal, UBOShadow } from '../define'; @@ -97,6 +96,9 @@ export class ShadowFlow extends RenderFlow { // 0: CC_DIR_LIGHT_SHADOW_NONE, 1: CC_DIR_LIGHT_SHADOW_UNIFORM, 2: CC_DIR_LIGHT_SHADOW_CASCADED, 3: CC_DIR_LIGHT_SHADOW_VARIANCE pipeline.macros.CC_DIR_LIGHT_SHADOW_TYPE = 0; + // 0: CC_CASCADED_LAYERS_TRANSITION_OFF, 1: CC_CASCADED_LAYERS_TRANSITION_ON + pipeline.macros.CC_CASCADED_LAYERS_TRANSITION = 0; + pipeline.onGlobalPipelineStateChanged(); } diff --git a/cocos/rendering/shadow/shadow-stage.ts b/cocos/rendering/shadow/shadow-stage.ts index 6ee5bc22142..4f8d8b38bfd 100644 --- a/cocos/rendering/shadow/shadow-stage.ts +++ b/cocos/rendering/shadow/shadow-stage.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; import { Color, Rect, Framebuffer, DescriptorSet } from '../../gfx'; @@ -72,6 +71,7 @@ export class ShadowStage extends RenderStage { private _light: Light | null = null; private _globalDS: DescriptorSet | null = null; private _level = 0; + private _isShadowMapCleared = false; public destroy () { this._shadowFrameBuffer = null; @@ -82,7 +82,7 @@ export class ShadowStage extends RenderStage { } public clearFramebuffer (camera: Camera) { - if (!this._light || !this._shadowFrameBuffer) { return; } + if (!this._light || !this._shadowFrameBuffer || this._isShadowMapCleared) { return; } colors[0].w = camera.clearColor.w; const pipeline = this._pipeline as ForwardPipeline; @@ -101,6 +101,7 @@ export class ShadowStage extends RenderStage { cmdBuff.beginRenderPass(renderPass, this._shadowFrameBuffer, this._renderArea, colors, camera.clearDepth, camera.clearStencil); cmdBuff.endRenderPass(); + this._isShadowMapCleared = true; } public render (camera: Camera) { @@ -110,6 +111,7 @@ export class ShadowStage extends RenderStage { const descriptorSet = this._globalDS!; const cmdBuff = pipeline.commandBuffers[0]; const level = this._level; + const device = pipeline.device; if (!this._light || !this._shadowFrameBuffer) { return; } this._pipeline.pipelineUBO.updateShadowUBOLight(descriptorSet, this._light, level); @@ -125,8 +127,13 @@ export class ShadowStage extends RenderStage { this._renderArea.width = shadowMapSize.x; this._renderArea.height = shadowMapSize.y; } else { + const screenSpaceSignY = device.capabilities.screenSpaceSignY; this._renderArea.x = level % 2 * 0.5 * shadowMapSize.x; - this._renderArea.y = (1 - Math.floor(level / 2)) * 0.5 * shadowMapSize.y; + if (screenSpaceSignY > 0.0) { + this._renderArea.y = (1 - Math.floor(level / 2)) * 0.5 * shadowMapSize.y; + } else { + this._renderArea.y = Math.floor(level / 2) * 0.5 * shadowMapSize.y; + } this._renderArea.width = 0.5 * shadowMapSize.x; this._renderArea.height = 0.5 * shadowMapSize.y; } @@ -142,7 +149,6 @@ export class ShadowStage extends RenderStage { default: } - const device = pipeline.device; const renderPass = this._shadowFrameBuffer.renderPass; cmdBuff.beginRenderPass(renderPass, this._shadowFrameBuffer, this._renderArea, @@ -152,10 +158,12 @@ export class ShadowStage extends RenderStage { this._additiveShadowQueue.recordCommandBuffer(device, renderPass, cmdBuff); cmdBuff.endRenderPass(); + this._isShadowMapCleared = false; } public activate (pipeline: ForwardPipeline, flow: ShadowFlow) { super.activate(pipeline, flow); this._additiveShadowQueue = new RenderShadowMapBatchedQueue(pipeline); + this._isShadowMapCleared = false; } } diff --git a/cocos/rendering/ui-phase.ts b/cocos/rendering/ui-phase.ts index 83a7d172f6c..50a827ecdf7 100644 --- a/cocos/rendering/ui-phase.ts +++ b/cocos/rendering/ui-phase.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,14 +24,19 @@ import { RenderPass } from '../gfx'; import { PipelineStateManager } from './pipeline-state-manager'; -import { SetIndex } from './define'; +import { isEnableEffect, SetIndex } from './define'; import { Camera } from '../render-scene/scene/camera'; import { RenderPipeline } from './render-pipeline'; import { getPhaseID } from './pass-phase'; +import { cclegacy } from '../core'; export class UIPhase { private _phaseID = getPhaseID('default'); private declare _pipeline: RenderPipeline; + constructor () { + const r = cclegacy.rendering; + if (isEnableEffect()) this._phaseID = r.getPhaseID(r.getPassID('default'), 'default'); + } public activate (pipeline: RenderPipeline) { this._pipeline = pipeline; diff --git a/cocos/root.jsb.ts b/cocos/root.jsb.ts index 7a989da1b7c..96f233b5f41 100644 --- a/cocos/root.jsb.ts +++ b/cocos/root.jsb.ts @@ -1,11 +1,31 @@ -import { Pool } from './core/memop'; -import { warnID } from './core/platform/debug'; -import legacyCC from '../predefine'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { legacyCC } from './core/global-exports'; import { DataPoolManager } from './3d/skeletal-animation/data-pool-manager'; import { Device, deviceManager } from './gfx'; -import { DebugView } from './rendering/debug-view'; -import { buildDeferredLayout, buildForwardLayout } from './rendering/custom/effect'; -import { settings, Settings } from './core/settings'; +import { settings, Settings, warnID, Pool, macro } from './core'; import { ForwardPipeline } from './rendering'; declare const nr: any; @@ -17,6 +37,8 @@ enum LightType { DIRECTIONAL, SPHERE, SPOT, + POINT, + RANGED_DIRECTIONAL, UNKNOWN, } @@ -61,27 +83,19 @@ Object.defineProperty(rootProto, 'dataPoolManager', { Object.defineProperty(rootProto, 'pipelineEvent', { configurable: true, enumerable: true, - get () { + get() { return this._pipelineEvent; } }); -Object.defineProperty(rootProto, 'debugView', { - configurable: true, - enumerable: true, - get () { - return this._debugView; - } -}); - class DummyPipelineEvent { - on (type: any, callback: any, target?: any, once?: boolean) {} - once (type: any, callback: any, target?: any) {} - off (type: any, callback?: any, target?: any) {} - emit (type: any, arg0?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any) {} - targetOff (typeOrTarget: any) {} - removeAll (typeOrTarget: any) {} - hasEventListener (type: any, callback?: any, target?: any): boolean { return false; } + on(type: any, callback: any, target?: any, once?: boolean) { } + once(type: any, callback: any, target?: any) { } + off(type: any, callback?: any, target?: any) { } + emit(type: any, arg0?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any) { } + targetOff(typeOrTarget: any) { } + removeAll(typeOrTarget: any) { } + hasEventListener(type: any, callback?: any, target?: any): boolean { return false; } } rootProto._ctor = function (device: Device) { @@ -91,8 +105,6 @@ rootProto._ctor = function (device: Device) { this._lightPools = new Map(); this._batcher = null; this._pipelineEvent = new DummyPipelineEvent(); - this._debugView = new DebugView(); - this.setDebugViewConfig(this._debugView._nativeConfig); this._registerListeners(); }; @@ -150,6 +162,12 @@ rootProto.destroyLight = function (l) { case LightType.SPOT: l.scene.removeSpotLight(l); break; + case LightType.POINT: + l.scene.removePointLight(l); + break; + case LightType.RANGED_DIRECTIONAL: + l.scene.removeRangedDirLight(l); + break; default: break; } @@ -163,17 +181,23 @@ rootProto.recycleLight = function (l) { p.free(l); if (l.scene) { switch (l.type) { - case LightType.DIRECTIONAL: - l.scene.removeDirectionalLight(l); - break; - case LightType.SPHERE: - l.scene.removeSphereLight(l); - break; - case LightType.SPOT: - l.scene.removeSpotLight(l); - break; - default: - break; + case LightType.DIRECTIONAL: + l.scene.removeDirectionalLight(l); + break; + case LightType.SPHERE: + l.scene.removeSphereLight(l); + break; + case LightType.SPOT: + l.scene.removeSpotLight(l); + break; + case LightType.POINT: + l.scene.removePointLight(l); + break; + case LightType.RANGED_DIRECTIONAL: + l.scene.removeRangedDirLight(l); + break; + default: + break; } } } @@ -187,6 +211,17 @@ rootProto._onDirectorBeforeRender = function () { legacyCC.director.emit(legacyCC.Director.EVENT_BEFORE_RENDER); }; +rootProto._onDirectorAfterRender = function () { + legacyCC.director.emit(legacyCC.Director.EVENT_AFTER_RENDER); +}; + +rootProto._onDirectorPipelineChanged = function () { + const scene = legacyCC.director.getScene(); + if (scene) { + scene._activate(); + } +} + const oldFrameMove = rootProto.frameMove; rootProto.frameMove = function (deltaTime: number) { oldFrameMove.call(this, deltaTime, legacyCC.director.getTotalFrames()); @@ -195,25 +230,17 @@ rootProto.frameMove = function (deltaTime: number) { const oldSetPipeline = rootProto.setRenderPipeline; rootProto.setRenderPipeline = function (pipeline) { let ppl; - if (this.usesCustomPipeline) { - const result = oldSetPipeline.call(this, null); - const ppl = this.customPipeline; - if (this.useDeferredPipeline) { - buildDeferredLayout(ppl); - } else { - buildForwardLayout(ppl); - } - ppl.layoutGraphBuilder.compile(); - return result; + if (macro.CUSTOM_PIPELINE_NAME !== '' && legacyCC.rendering && this.usesCustomPipeline) { + legacyCC.rendering.createCustomPipeline(); + ppl = oldSetPipeline.call(this, null); } else { if (!pipeline) { // pipeline should not be created in C++, ._ctor need to be triggered pipeline = new ForwardPipeline(); pipeline.init(); } - ppl = oldSetPipeline.call(this, pipeline); + ppl = oldSetPipeline.call(this, pipeline); } - this._createBatcher2D(); return ppl; } diff --git a/cocos/root.ts b/cocos/root.ts index d0b7b37ef1a..403089b3e3e 100644 --- a/cocos/root.ts +++ b/cocos/root.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,9 +20,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -import { Pool } from './core/memop'; +import { Pool, cclegacy, warnID, settings, Settings, macro } from './core'; import { RenderPipeline, createDefaultPipeline, DeferredPipeline } from './rendering'; import { DebugView } from './rendering/debug-view'; import { Camera, Light, Model } from './render-scene/scene'; @@ -33,16 +32,14 @@ import { IRenderSceneInfo, RenderScene } from './render-scene/core/render-scene' import { DirectionalLight } from './render-scene/scene/directional-light'; import { SphereLight } from './render-scene/scene/sphere-light'; import { SpotLight } from './render-scene/scene/spot-light'; -import { legacyCC } from './core/global-exports'; +import { PointLight } from './render-scene/scene/point-light'; +import { RangedDirectionalLight } from './render-scene/scene/ranged-directional-light'; import { RenderWindow, IRenderWindowInfo } from './render-scene/core/render-window'; -import { ColorAttachment, DepthStencilAttachment, RenderPassInfo, StoreOp, Device, Swapchain, Feature, deviceManager } from './gfx'; -import { warnID } from './core/platform/debug'; +import { ColorAttachment, DepthStencilAttachment, RenderPassInfo, StoreOp, Device, Swapchain, Feature, deviceManager, LegacyRenderMode } from './gfx'; import { Pipeline, PipelineRuntime } from './rendering/custom/pipeline'; import { Batcher2D } from './2d/renderer/batcher-2d'; import { IPipelineEvent } from './rendering/pipeline-event'; -import { settings, Settings } from './core/settings'; -import { localDescriptorSetLayout_ResizeMaxJoints } from './rendering/define'; -import { macro } from './core/platform/macro'; +import { localDescriptorSetLayout_ResizeMaxJoints, UBOCamera, UBOGlobal, UBOLocal, UBOShadow } from './rendering/define'; /** * @en Initialization information for the Root @@ -119,7 +116,7 @@ export class Root { * 启用自定义渲染管线 */ public get usesCustomPipeline (): boolean { - return this._usesCustomPipeline && macro.CUSTOM_PIPELINE_NAME !== ''; + return this._usesCustomPipeline; } /** @@ -230,7 +227,7 @@ export class Root { * @en Whether the built-in deferred pipeline is used. * @zh 是否启用内置延迟渲染管线 */ - public get useDeferredPipeline () : boolean { + public get useDeferredPipeline (): boolean { return this._useDeferredPipeline; } @@ -282,7 +279,7 @@ export class Root { */ constructor (device: Device) { this._device = device; - this._dataPoolMgr = legacyCC.internal.DataPoolManager && new legacyCC.internal.DataPoolManager(device) as DataPoolManager; + this._dataPoolMgr = cclegacy.internal.DataPoolManager && new cclegacy.internal.DataPoolManager(device) as DataPoolManager; RenderScene.registerCreateFunc(this); RenderWindow.registerCreateFunc(this); @@ -339,6 +336,10 @@ export class Root { this._curWindow = null; this._mainWindow = null; this.dataPoolManager.clear(); + + if (cclegacy.rendering) { + cclegacy.rendering.destroy(); + } } /** @@ -363,6 +364,7 @@ export class Root { * @returns The setup is successful or not */ public setRenderPipeline (rppl?: RenderPipeline): boolean { + const { internal, director, rendering } = cclegacy; //----------------------------------------------- // prepare classic pipeline //----------------------------------------------- @@ -386,8 +388,8 @@ export class Root { //----------------------------------------------- // choose pipeline //----------------------------------------------- - if (this.usesCustomPipeline && legacyCC.rendering) { - this._customPipeline = legacyCC.rendering.createCustomPipeline(); + if (macro.CUSTOM_PIPELINE_NAME !== '' && rendering && this.usesCustomPipeline) { + this._customPipeline = rendering.createCustomPipeline(); isCreateDefaultPipeline = true; this._pipeline = this._customPipeline!; } else { @@ -397,29 +399,32 @@ export class Root { this._usesCustomPipeline = false; } - if (!this._pipeline.activate(this._mainWindow!.swapchain)) { - if (isCreateDefaultPipeline) { - this._pipeline.destroy(); - } - this._classicPipeline = null; - this._customPipeline = null; - this._pipeline = null; - this._pipelineEvent = null; + const renderMode = settings.querySettings(Settings.Category.RENDERING, 'renderMode'); + if (renderMode !== LegacyRenderMode.HEADLESS || this._classicPipeline) { + if (!this._pipeline.activate(this._mainWindow!.swapchain)) { + if (isCreateDefaultPipeline) { + this._pipeline.destroy(); + } + this._classicPipeline = null; + this._customPipeline = null; + this._pipeline = null; + this._pipelineEvent = null; - return false; + return false; + } } //----------------------------------------------- // pipeline initialization completed //----------------------------------------------- - const scene = legacyCC.director.getScene(); + const scene = director.getScene(); if (scene) { scene.globals.activate(); } this.onGlobalPipelineStateChanged(); - if (!this._batcher && legacyCC.internal.Batcher2D) { - this._batcher = new legacyCC.internal.Batcher2D(this); + if (!this._batcher && internal.Batcher2D) { + this._batcher = new internal.Batcher2D(this); if (!this._batcher!.initialize()) { this.destroy(); return false; @@ -464,6 +469,7 @@ export class Root { * @param deltaTime @en The delta time since last update. @zh 距离上一帧间隔时间 */ public frameMove (deltaTime: number) { + const { director, Director } = cclegacy; this._frameTime = deltaTime; /* @@ -501,7 +507,8 @@ export class Root { if (this._pipeline && cameraList.length > 0) { this._device.acquire([deviceManager.swapchain]); const scenes = this._scenes; - const stamp = legacyCC.director.getTotalFrames(); + const stamp = director.getTotalFrames(); + if (this._batcher) { this._batcher.update(); this._batcher.uploadBuffers(); @@ -511,14 +518,15 @@ export class Root { scenes[i].update(stamp); } - legacyCC.director.emit(legacyCC.Director.EVENT_BEFORE_COMMIT); + director.emit(Director.EVENT_BEFORE_COMMIT); cameraList.sort((a: Camera, b: Camera) => a.priority - b.priority); for (let i = 0; i < cameraList.length; ++i) { cameraList[i].geometryRenderer?.update(); } - legacyCC.director.emit(legacyCC.Director.EVENT_BEFORE_RENDER); + director.emit(Director.EVENT_BEFORE_RENDER); this._pipeline.render(cameraList); + director.emit(Director.EVENT_AFTER_RENDER); this._device.present(); } @@ -679,6 +687,12 @@ export class Root { case LightType.SPOT: l.scene.removeSpotLight(l as SpotLight); break; + case LightType.POINT: + l.scene.removePointLight(l as PointLight); + break; + case LightType.RANGED_DIRECTIONAL: + l.scene.removeRangedDirLight(l as RangedDirectionalLight); + break; default: break; } @@ -706,6 +720,12 @@ export class Root { case LightType.SPOT: l.scene.removeSpotLight(l as SpotLight); break; + case LightType.POINT: + l.scene.removePointLight(l as PointLight); + break; + case LightType.RANGED_DIRECTIONAL: + l.scene.removeRangedDirLight(l as RangedDirectionalLight); + break; default: break; } @@ -714,10 +734,11 @@ export class Root { } private _resizeMaxJointForDS () { - let maxJoints = Math.floor((deviceManager.gfxDevice.capabilities.maxVertexUniformVectors - 38) / 3); + const usedUBOVectorCount = (UBOGlobal.COUNT + UBOCamera.COUNT + UBOShadow.COUNT + UBOLocal.COUNT) / 4; + let maxJoints = Math.floor((deviceManager.gfxDevice.capabilities.maxVertexUniformVectors - usedUBOVectorCount) / 3); maxJoints = maxJoints < 256 ? maxJoints : 256; localDescriptorSetLayout_ResizeMaxJoints(maxJoints); } } -legacyCC.Root = Root; +cclegacy.Root = Root; diff --git a/cocos/scene-graph/component-event-handler.schema.ts b/cocos/scene-graph/component-event-handler.schema.ts index 887558c4eff..d814a849ca4 100644 --- a/cocos/scene-graph/component-event-handler.schema.ts +++ b/cocos/scene-graph/component-event-handler.schema.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { CCClass } from '../core/data'; import { Node } from './node'; import { EventHandler } from './component-event-handler'; diff --git a/cocos/scene-graph/component-event-handler.ts b/cocos/scene-graph/component-event-handler.ts index 8051d3dc95a..40e7883174f 100644 --- a/cocos/scene-graph/component-event-handler.ts +++ b/cocos/scene-graph/component-event-handler.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/scene-graph/component-scheduler.ts b/cocos/scene-graph/component-scheduler.ts index be455d65174..e8b855502f5 100644 --- a/cocos/scene-graph/component-scheduler.ts +++ b/cocos/scene-graph/component-scheduler.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,13 +24,12 @@ import { EDITOR, SUPPORT_JIT, DEV, TEST } from 'internal:constants'; import { CCObject } from '../core/data/object'; -import { MutableForwardIterator } from '../core/utils/array'; -import { array } from '../core/utils/js'; +import { js } from '../core'; import { tryCatchFunctor_EDITOR } from '../core/utils/misc'; import { legacyCC } from '../core/global-exports'; import { error, assert } from '../core/platform/debug'; -const fastRemoveAt = array.fastRemoveAt; +const fastRemoveAt = js.array.fastRemoveAt; const IsStartCalled = CCObject.Flags.IsStartCalled; const IsOnEnableCalled = CCObject.Flags.IsOnEnableCalled; @@ -90,12 +88,12 @@ function stableRemoveInactive (iterator, flagToClear) { export class LifeCycleInvoker { public static stableRemoveInactive = stableRemoveInactive; - protected _zero: MutableForwardIterator; - protected _neg: MutableForwardIterator; - protected _pos: MutableForwardIterator; + protected _zero: js.array.MutableForwardIterator; + protected _neg: js.array.MutableForwardIterator; + protected _pos: js.array.MutableForwardIterator; protected _invoke: any; constructor (invokeFunc) { - const Iterator = MutableForwardIterator; + const Iterator = js.array.MutableForwardIterator; // components which priority === 0 (default) this._zero = new Iterator([]); // components which priority < 0 diff --git a/cocos/scene-graph/component.ts b/cocos/scene-graph/component.ts index 19f0870bebf..654bc9461a1 100644 --- a/cocos/scene-graph/component.ts +++ b/cocos/scene-graph/component.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,7 +27,7 @@ import { ccclass, tooltip, displayName, type, serializable, disallowAnimation } import { EDITOR, TEST } from 'internal:constants'; import { Script } from '../asset/assets/scripts'; import { CCObject } from '../core/data/object'; -import IDGenerator from '../core/utils/id-generator'; +import { IDGenerator } from '../core/utils/id-generator'; import { getClassName, value } from '../core/utils/js'; import { RenderScene } from '../render-scene/core/render-scene'; import { Rect } from '../core/math'; @@ -36,7 +35,7 @@ import * as RF from '../core/data/utils/requiring-frame'; import { Node } from './node'; import { legacyCC } from '../core/global-exports'; import { errorID, warnID, assertID } from '../core/platform/debug'; -import { CompPrefabInfo } from '../core/utils/prefab/prefab-info'; +import { CompPrefabInfo } from './prefab/prefab-info'; import { EventHandler } from './component-event-handler'; const idGenerator = new IDGenerator('Comp'); diff --git a/cocos/scene-graph/deprecated-3.7.0.ts b/cocos/scene-graph/deprecated-3.7.0.ts index 5428f5b173c..a62b7a8afc2 100644 --- a/cocos/scene-graph/deprecated-3.7.0.ts +++ b/cocos/scene-graph/deprecated-3.7.0.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { deprecateModuleExportedName } from '../core/utils/x-deprecated'; deprecateModuleExportedName({ diff --git a/cocos/scene-graph/deprecated.ts b/cocos/scene-graph/deprecated.ts index d5acb2f5cae..c55908ab551 100644 --- a/cocos/scene-graph/deprecated.ts +++ b/cocos/scene-graph/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { ccclass } from 'cc.decorator'; diff --git a/cocos/scene-graph/find.ts b/cocos/scene-graph/find.ts index 8d83c3cf867..c8b93b9300f 100644 --- a/cocos/scene-graph/find.ts +++ b/cocos/scene-graph/find.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/scene-graph/index.jsb.ts b/cocos/scene-graph/index.jsb.ts index 181f85346f6..c4bcdc8a885 100644 --- a/cocos/scene-graph/index.jsb.ts +++ b/cocos/scene-graph/index.jsb.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import './component-event-handler.schema'; import './node-event-processor'; @@ -16,3 +40,4 @@ export { EventHandler } from './component-event-handler'; export { Component } from './component'; export * from './deprecated'; export { default as NodeActivator } from './node-activator'; +export { Prefab } from './prefab'; diff --git a/cocos/scene-graph/index.ts b/cocos/scene-graph/index.ts index 3b80ad6002c..477e5464ced 100644 --- a/cocos/scene-graph/index.ts +++ b/cocos/scene-graph/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -40,3 +39,4 @@ export { EventHandler } from './component-event-handler'; export { Component } from './component'; export * from './deprecated'; export { default as NodeActivator } from './node-activator'; +export { Prefab } from './prefab'; diff --git a/cocos/scene-graph/layers.jsb.ts b/cocos/scene-graph/layers.jsb.ts index d769520386b..3aff979942f 100644 --- a/cocos/scene-graph/layers.jsb.ts +++ b/cocos/scene-graph/layers.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { legacyCC } from '../core/global-exports'; diff --git a/cocos/scene-graph/layers.ts b/cocos/scene-graph/layers.ts index 17c63e3608a..5e95be58cdb 100644 --- a/cocos/scene-graph/layers.ts +++ b/cocos/scene-graph/layers.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -26,7 +25,7 @@ import { BitMask, Enum } from '../core/value-types'; import { legacyCC } from '../core/global-exports'; import { log2 } from '../core/math/bits'; -import { js } from '../core/utils/js'; +import { js } from '../core'; import { assertIsTrue } from '../core/data/utils/asserts'; import { getError } from '../core/platform/debug'; import { Settings, settings } from '../core/settings'; diff --git a/cocos/scene-graph/node-activator.ts b/cocos/scene-graph/node-activator.ts index 715d765add7..3af611b86c3 100644 --- a/cocos/scene-graph/node-activator.ts +++ b/cocos/scene-graph/node-activator.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/scene-graph/node-dev.ts b/cocos/scene-graph/node-dev.ts index 8b3d9979a57..3dde917d87e 100644 --- a/cocos/scene-graph/node-dev.ts +++ b/cocos/scene-graph/node-dev.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -31,8 +30,21 @@ import { error, errorID, getError } from '../core/platform/debug'; import { Component } from './component'; const Destroying = CCObject.Flags.Destroying; +const IS_PREVIEW = !!legacyCC.GAME_VIEW; export function nodePolyfill (Node) { + if ((EDITOR && !IS_PREVIEW) || TEST) { + Node.prototype._onPreDestroy = function () { + const destroyByParent: boolean = this._onPreDestroyBase(); + if (!destroyByParent) { + // ensure this node can reattach to scene by undo system + // (simulate some destruct logic to make undo system work correctly) + this._parent = null; + } + return destroyByParent; + }; + } + if (EDITOR || TEST) { Node.prototype._checkMultipleComp = function (ctor) { const existing = this.getComponent(ctor._disallowMultiple); @@ -45,7 +57,32 @@ export function nodePolyfill (Node) { } return true; }; - + /** + * @method _getDependComponent + * @param {Component} depended + * @return {Component[]} + */ + Node.prototype._getDependComponent = function (depended) { + const dependant: Component[] = []; + for (let i = 0; i < this._components.length; i++) { + const comp = this._components[i]; + if (comp !== depended && comp.isValid && !legacyCC.Object._willDestroy(comp)) { + const reqComps = comp.constructor._requireComponent; + if (reqComps) { + if (Array.isArray(reqComps)) { + for (let i = 0; i < reqComps.length; i++) { + if (depended instanceof reqComps[i]) { + dependant.push(comp); + } + } + } else if (depended instanceof reqComps) { + dependant.push(comp); + } + } + } + } + return dependant; + }; /** * This api should only used by undo system * @method _addComponentAt @@ -87,7 +124,7 @@ export function nodePolyfill (Node) { comp.node = this; this._components.splice(index, 0, comp); - if (EDITOR && EditorExtends.Node && EditorExtends.Component) { + if (EDITOR && !IS_PREVIEW && EditorExtends.Node && EditorExtends.Component) { const node = EditorExtends.Node.getNode(this._id); if (node) { EditorExtends.Component.add(comp._id, comp); @@ -99,33 +136,6 @@ export function nodePolyfill (Node) { return undefined; }; - /** - * @method _getDependComponent - * @param {Component} depended - * @return {Component[]} - */ - Node.prototype._getDependComponent = function (depended) { - const dependant: Component[] = []; - for (let i = 0; i < this._components.length; i++) { - const comp = this._components[i]; - if (comp !== depended && comp.isValid && !legacyCC.Object._willDestroy(comp)) { - const reqComps = comp.constructor._requireComponent; - if (reqComps) { - if (Array.isArray(reqComps)) { - for (let i = 0; i < reqComps.length; i++) { - if (depended instanceof reqComps[i]) { - dependant.push(comp); - } - } - } else if (depended instanceof reqComps) { - dependant.push(comp); - } - } - } - } - return dependant; - }; - Node.prototype.onRestore = function () { // check activity state const shouldActiveNow = this._active && !!(this._parent && this._parent._activeInHierarchy); @@ -133,21 +143,8 @@ export function nodePolyfill (Node) { legacyCC.director._nodeActivator.activateNode(this, shouldActiveNow); } }; - - Node.prototype._onPreDestroy = function () { - const destroyByParent: boolean = this._onPreDestroyBase(); - if (!destroyByParent) { - // ensure this node can reattach to scene by undo system - // (simulate some destruct logic to make undo system work correctly) - this._parent = null; - } - return destroyByParent; - }; - Node.prototype._onRestoreBase = Node.prototype.onRestore; - } - if (EDITOR || TEST) { Node.prototype._registerIfAttached = function (register) { if (!this._id) { console.warn(`Node(${this && this.name}}) is invalid or its data is corrupted.`); @@ -191,8 +188,9 @@ export function nodePolyfill (Node) { // promote debug info js.get(Node.prototype, ' INFO ', function () { let path = ''; - // @ts-expect-error - let node = this; + // @ts-expect-error: type of this + // eslint-disable-next-line @typescript-eslint/no-this-alias + let node: any = this; while (node && !(node instanceof legacyCC.Scene)) { if (path) { path = `${node.name}/${path}`; @@ -201,7 +199,7 @@ export function nodePolyfill (Node) { } node = node._parent; } - // @ts-expect-error + // @ts-expect-error: type of this return `${this.name}, path: ${path}`; }); } diff --git a/cocos/scene-graph/node-enum.ts b/cocos/scene-graph/node-enum.ts index ed7d57a3f9e..086dcec26ff 100644 --- a/cocos/scene-graph/node-enum.ts +++ b/cocos/scene-graph/node-enum.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,6 +23,7 @@ */ import { legacyCC } from '../core/global-exports'; +import { Enum } from '../core/value-types'; /** * @en Node's coordinate space @@ -77,3 +77,27 @@ export enum TransformBit { } legacyCC.internal.TransformBit = TransformBit; + +/** + * @en Node's mobility + * @zh 节点的移动性 + */ +export const MobilityMode = Enum({ + /** + * @en Static node + * @zh 静态节点 + */ + Static: 0, + + /** + * @en Stationary node + * @zh 固定节点 + */ + Stationary: 1, + + /** + * @en Movable node + * @zh 可移动节点 + */ + Movable: 2, +}); diff --git a/cocos/scene-graph/node-event-processor.ts b/cocos/scene-graph/node-event-processor.ts index 08ea516b12d..5001909e462 100644 --- a/cocos/scene-graph/node-event-processor.ts +++ b/cocos/scene-graph/node-event-processor.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -163,6 +162,19 @@ export class NodeEventProcessor { child._eventProcessor.setEnabled(value, true); } } + // When a node is dispatching touch events and the node is set to disabled, + // the dispatching events function will hang until the node is enabled. + // If the node is re-enabled, any touch events will be handled by this node, + // even if the touch events are not in the scope of this node. This is an error. + // So, sending a cancel event when the node is set to disabled. + if (this._dispatchingTouch && !this._isEnabled) { + // Dispatch touch cancel event when node is destroyed. + const cancelEvent = new EventTouch([this._dispatchingTouch], true, InputEventType.TOUCH_CANCEL); + cancelEvent.touch = this._dispatchingTouch; + this.dispatchEvent(cancelEvent); + this.claimedTouchIdList.length = 0; + this._dispatchingTouch = null; + } } public reattach (): void { diff --git a/cocos/scene-graph/node-event.ts b/cocos/scene-graph/node-event.ts index 2123b5a0213..9d18185c689 100644 --- a/cocos/scene-graph/node-event.ts +++ b/cocos/scene-graph/node-event.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2019-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -159,6 +158,14 @@ export enum NodeEventType { */ TRANSFORM_CHANGED = 'transform-changed', + /** + * @en + * The event occur when mobility changed. + * @zh + * 当可移动性改变时触发的事件 + */ + MOBILITY_CHANGED = 'mobility-changed', + /** * @en The event type for notifying the host scene has been changed for a persist node. * @zh 当场景常驻节点的场景发生改变时触发的事件,一般在切换场景过程中触发。 @@ -267,4 +274,20 @@ export enum NodeEventType { * 当节点上移除组件时触发的事件 */ COMPONENT_REMOVED = 'component-removed', + + /** + * @en + * The event occur when light probe changed in light probe group. + * @zh + * 当光照探针组组件的探针改变时触发的事件 + */ + LIGHT_PROBE_CHANGED = 'light-probe-changed', + + /** + * @en + * The event occur after light probe's baking data is changed + * @zh + * 当光照探针烘焙数据修改后触发的事件 + */ + LIGHT_PROBE_BAKING_CHANGED = 'light-probe-baking-changed', } diff --git a/cocos/scene-graph/node-ui-properties.ts b/cocos/scene-graph/node-ui-properties.ts index 8914e216c8c..0b4ff97199c 100644 --- a/cocos/scene-graph/node-ui-properties.ts +++ b/cocos/scene-graph/node-ui-properties.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/scene-graph/node.jsb.ts b/cocos/scene-graph/node.jsb.ts index 17a8a3069bb..4aa7e122414 100644 --- a/cocos/scene-graph/node.jsb.ts +++ b/cocos/scene-graph/node.jsb.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,7 +28,7 @@ import { Component } from './component'; import { NodeEventType } from './node-event'; import { CCObject } from '../core/data/object'; import { NodeUIProperties } from './node-ui-properties'; -import { NodeSpace, TransformBit } from './node-enum'; +import { MobilityMode, NodeSpace, TransformBit } from './node-enum'; import { Mat4, Quat, Vec3 } from '../core/math'; import { Layers } from './layers'; import { editorExtrasTag, SerializationContext, SerializationOutput, serializeTag } from '../core/data'; @@ -181,9 +182,9 @@ nodeProto.addComponent = function (typeOrClassName) { throw TypeError(getError(3810)); } - // if (EDITOR && (constructor as typeof constructor & { _disallowMultiple?: unknown })._disallowMultiple) { - // this._checkMultipleComp!(constructor); - // } + if (EDITOR && (constructor as typeof constructor & { _disallowMultiple?: unknown })._disallowMultiple) { + this._checkMultipleComp!(constructor); + } // check requirement @@ -235,10 +236,10 @@ nodeProto.removeComponent = function (component) { const REGISTERED_EVENT_MASK_TRANSFORM_CHANGED = (1 << 0); const REGISTERED_EVENT_MASK_PARENT_CHANGED = (1 << 1); -const REGISTERED_EVENT_MASK_LAYER_CHANGED = (1 << 2); -const REGISTERED_EVENT_MASK_CHILD_REMOVED_CHANGED = (1 << 3); -const REGISTERED_EVENT_MASK_CHILD_ADDED_CHANGED = (1 << 4); -const REGISTERED_EVENT_MASK_SIBLING_ORDER_CHANGED_CHANGED = (1 << 5); +const REGISTERED_EVENT_MASK_MOBILITY_CHANGED = (1 << 2); +const REGISTERED_EVENT_MASK_LAYER_CHANGED = (1 << 3); +const REGISTERED_EVENT_MASK_SIBLING_ORDER_CHANGED = (1 << 4); +const REGISTERED_EVENT_MASK_LIGHT_PROBE_BAKING_CHANGED = (1 << 5); nodeProto.on = function (type, callback, target, useCapture: any = false) { switch (type) { @@ -255,28 +256,28 @@ nodeProto.on = function (type, callback, target, useCapture: any = false) { this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_PARENT_CHANGED; } break; + case NodeEventType.MOBILITY_CHANGED: + if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_MOBILITY_CHANGED)) { + this._registerOnMobilityChanged(); + this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_MOBILITY_CHANGED; + } + break; case NodeEventType.LAYER_CHANGED: if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_LAYER_CHANGED)) { this._registerOnLayerChanged(); this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_LAYER_CHANGED; } break; - case NodeEventType.CHILD_REMOVED: - if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_CHILD_REMOVED_CHANGED)) { - this._registerOnChildRemoved(); - this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_CHILD_REMOVED_CHANGED; - } - break; - case NodeEventType.CHILD_ADDED: - if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_CHILD_ADDED_CHANGED)) { - this._registerOnChildAdded(); - this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_CHILD_ADDED_CHANGED; - } - break; case NodeEventType.SIBLING_ORDER_CHANGED: - if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_SIBLING_ORDER_CHANGED_CHANGED)) { + if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_SIBLING_ORDER_CHANGED)) { this._registerOnSiblingOrderChanged(); - this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_SIBLING_ORDER_CHANGED_CHANGED; + this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_SIBLING_ORDER_CHANGED; + } + break; + case NodeEventType.LIGHT_PROBE_BAKING_CHANGED: + if (!(this._registeredNodeEventTypeMask & REGISTERED_EVENT_MASK_LIGHT_PROBE_BAKING_CHANGED)) { + this._registerOnLightProbeBakingChanged(); + this._registeredNodeEventTypeMask |= REGISTERED_EVENT_MASK_LIGHT_PROBE_BAKING_CHANGED; } break; default: @@ -318,6 +319,7 @@ nodeProto.hasEventListener = function (type: string, callback?, target?: unknown }; nodeProto.targetOff = function (target: string | unknown) { + this._eventProcessor.targetOff(target); // Check for event mask reset if ((this._eventMask & TRANSFORM_ON) && !this._eventProcessor.hasEventListener(NodeEventType.TRANSFORM_CHANGED)) { this._eventMask &= ~TRANSFORM_ON; @@ -413,28 +415,29 @@ nodeProto._onDestroyComponents = function () { } }; +nodeProto._onMobilityChanged = function () { + this.emit(NodeEventType.MOBILITY_CHANGED); +}; + nodeProto._onLayerChanged = function (layer) { this.emit(NodeEventType.LAYER_CHANGED, layer); }; nodeProto._onChildRemoved = function (child) { + const removeAt = this._children.indexOf(child); + if (removeAt < 0) { + errorID(1633); + return; + } + this._children.splice(removeAt, 1); this.emit(NodeEventType.CHILD_REMOVED, child); }; nodeProto._onChildAdded = function (child) { + this._children.push(child); this.emit(NodeEventType.CHILD_ADDED, child); }; -nodeProto._onNodeDestroyed = function () { - this.emit(NodeEventType.NODE_DESTROYED, this); - // destroy children - const children = this._children; - for (let i = 0; i < children.length; ++i) { - // destroy immediate so its _onPreDestroy can be called - children[i]._destroyImmediate(); - } -}; - const oldPreDestroy = nodeProto._onPreDestroy; nodeProto._onPreDestroy = function _onPreDestroy () { const ret = oldPreDestroy.call(this); @@ -494,6 +497,10 @@ nodeProto._onPostActivated = function (active: boolean) { } }; +nodeProto._onLightProbeBakingChanged = function () { + this.emit(NodeEventType.LIGHT_PROBE_BAKING_CHANGED); +}; + // Static functions. NodeCls._findComponent = function (node, constructor) { @@ -788,6 +795,17 @@ nodeProto.getWorldRS = function getWorldRS (out?: Mat4): Mat4 { return out; }; +Object.defineProperty(nodeProto, 'name', { + configurable: true, + enumerable: true, + get(): string { + return this._name; + }, + set(v: string) { + this._name = v; + } +}); + Object.defineProperty(nodeProto, 'position', { configurable: true, enumerable: true, @@ -1269,6 +1287,20 @@ nodeProto._instantiate = function (cloned: Node, isSyncedNode: boolean) { return cloned; }; +nodeProto._onSiblingIndexChanged = function (index) { + const siblings = this._parent._children; + index = index !== -1 ? index : siblings.length - 1; + const oldIndex = siblings.indexOf(this); + if (index !== oldIndex) { + siblings.splice(oldIndex, 1); + if (index < siblings.length) { + siblings.splice(index, 0, this); + } else { + siblings.push(this); + } + } +} + // nodeProto._ctor = function (name?: string) { this.__nativeRefs = {}; @@ -1281,7 +1313,7 @@ nodeProto._ctor = function (name?: string) { this._eventProcessor = new legacyCC.NodeEventProcessor(this); this._uiProps = new NodeUIProperties(this); - const sharedArrayBuffer = this._getSharedArrayBufferObject(); + const sharedArrayBuffer = this._initAndReturnSharedBuffer(); // Uint32Array with 3 elements: eventMask, layer, dirtyFlags this._sharedUint32Arr = new Uint32Array(sharedArrayBuffer, 0, 3); // Int32Array with 1 element: siblingIndex @@ -1296,8 +1328,6 @@ nodeProto._ctor = function (name?: string) { // record scene's id when set this node as persist node this._originalSceneId = ''; - this._registerListeners(); - this._children = []; // this._isChildrenRedefined = false; @@ -1307,33 +1337,6 @@ nodeProto._ctor = function (name?: string) { this._euler = new Vec3(); this._registeredNodeEventTypeMask = 0; - - this.on(NodeEventType.CHILD_ADDED, (child) => { - this._children.push(child); - }); - - this.on(NodeEventType.CHILD_REMOVED, (child) => { - const removeAt = this._children.indexOf(child); - if (removeAt < 0) { - errorID(1633); - return; - } - this._children.splice(removeAt, 1); - }); - - this._onSiblingIndexChanged = function (index) { - const siblings = this._parent._children; - index = index !== -1 ? index : siblings.length - 1; - const oldIndex = siblings.indexOf(this); - if (index !== oldIndex) { - siblings.splice(oldIndex, 1); - if (index < siblings.length) { - siblings.splice(index, 0, this); - } else { - siblings.push(this); - } - } - } }; // handle meta data, it is generated automatically @@ -1350,20 +1353,24 @@ const activeInHierarchyDescriptor = Object.getOwnPropertyDescriptor(NodeProto, ' editable(NodeProto, 'activeInHierarchy', activeInHierarchyDescriptor); const parentDescriptor = Object.getOwnPropertyDescriptor(NodeProto, 'parent'); editable(NodeProto, 'parent', parentDescriptor); -serializable(NodeProto, '_parent'); -serializable(NodeProto, '_children'); -serializable(NodeProto, '_active'); -serializable(NodeProto, '_components'); -serializable(NodeProto, '_prefab'); -serializable(NodeProto, '_lpos'); -serializable(NodeProto, '_lrot'); -serializable(NodeProto, '_lscale'); -serializable(NodeProto, '_layer'); -serializable(NodeProto, '_euler'); +serializable(NodeProto, '_parent', () => null); +serializable(NodeProto, '_children', () => []); +serializable(NodeProto, '_active', () => true); +serializable(NodeProto, '_components', () => []); +serializable(NodeProto, '_prefab', () => null); +serializable(NodeProto, '_lpos', () => new Vec3()); +serializable(NodeProto, '_lrot', () => new Quat()); +serializable(NodeProto, '_lscale', () => new Vec3(1, 1, 1)); +serializable(NodeProto, '_mobility', () => MobilityMode.Static); +serializable(NodeProto, '_layer', () => Layers.Enum.DEFAULT); +serializable(NodeProto, '_euler', () => new Vec3()); const eulerAnglesDescriptor = Object.getOwnPropertyDescriptor(NodeProto, 'eulerAngles'); type(Vec3)(NodeProto, 'eulerAngles', eulerAnglesDescriptor); const angleDescriptor = Object.getOwnPropertyDescriptor(NodeProto, 'angle'); editable(NodeProto, 'angle', angleDescriptor); +const mobilityDescriptor = Object.getOwnPropertyDescriptor(NodeProto, 'mobility'); +editable(NodeProto, 'mobility', mobilityDescriptor); +type(MobilityMode)(NodeProto, 'mobility', mobilityDescriptor); const layerDescriptor = Object.getOwnPropertyDescriptor(NodeProto, 'layer'); editable(NodeProto, 'layer', layerDescriptor); diff --git a/cocos/scene-graph/node.ts b/cocos/scene-graph/node.ts index d05c6e9ed5a..84e7ac6ca12 100644 --- a/cocos/scene-graph/node.ts +++ b/cocos/scene-graph/node.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -31,16 +30,14 @@ import { legacyCC } from '../core/global-exports'; import { nodePolyfill } from './node-dev'; import { ISchedulable } from '../core/scheduler'; import { approx, EPSILON, Mat3, Mat4, Quat, Vec3 } from '../core/math'; -import { NodeSpace, TransformBit } from './node-enum'; +import { MobilityMode, NodeSpace, TransformBit } from './node-enum'; import { CustomSerializable, editorExtrasTag, SerializationContext, SerializationOutput, serializeTag } from '../core/data'; import { errorID, warnID, error, log, getError } from '../core/platform/debug'; import { Component } from './component'; import { property } from '../core/data/decorators/property'; -import { CCObject } from '../core/data/object'; -import * as js from '../core/utils/js'; -import IdGenerator from '../core/utils/id-generator'; +import { CCObject, js } from '../core'; import type { Scene } from './scene'; -import { PrefabInfo } from '../core/utils/prefab/prefab-info'; +import { PrefabInfo } from './prefab/prefab-info'; import { NodeEventType } from './node-event'; import { Event } from '../input/types'; @@ -50,10 +47,9 @@ const Deactivating = CCObject.Flags.Deactivating; export const TRANSFORM_ON = 1 << 0; -const idGenerator = new IdGenerator('Node'); +const idGenerator = new js.IDGenerator('Node'); -function getConstructor -(typeOrClassName: string | Constructor | AbstractedConstructor): Constructor | AbstractedConstructor | null | undefined { +function getConstructor (typeOrClassName: string | Constructor | AbstractedConstructor): Constructor | AbstractedConstructor | null | undefined { if (!typeOrClassName) { errorID(3804); return null; @@ -66,12 +62,14 @@ function getConstructor } const v3_a = new Vec3(); +const v3_b = new Vec3(); const q_a = new Quat(); const q_b = new Quat(); const qt_1 = new Quat(); const m3_1 = new Mat3(); const m3_scaling = new Mat3(); const m4_1 = new Mat4(); +const m4_2 = new Mat4(); const dirtyNodes: any[] = []; const reserveContentsForAllSyncablePrefabTag = Symbol('ReserveContentsForAllSyncablePrefab'); @@ -264,8 +262,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { node._updateScene(); } - protected static _findComponent - (node: Node, constructor: Constructor | AbstractedConstructor): T | null { + protected static _findComponent (node: Node, constructor: Constructor | AbstractedConstructor): T | null { const cls = constructor; const comps = node._components; // @ts-expect-error internal rtti property @@ -287,8 +284,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { return null; } - protected static _findComponents - (node: Node, constructor: Constructor | AbstractedConstructor, components: Component[]) { + protected static _findComponents (node: Node, constructor: Constructor | AbstractedConstructor, components: Component[]) { const cls = constructor; const comps = node._components; // @ts-expect-error internal rtti property @@ -309,8 +305,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { } } - protected static _findChildComponent - (children: Node[], constructor: Constructor | AbstractedConstructor): T | null { + protected static _findChildComponent (children: Node[], constructor: Constructor | AbstractedConstructor): T | null { for (let i = 0; i < children.length; ++i) { const node = children[i]; let comp = Node._findComponent(node, constructor); @@ -352,7 +347,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { // The PrefabInfo object @serializable - protected _prefab: PrefabInfo|null = null; + protected _prefab: PrefabInfo | null = null; protected _scene: Scene = null!; @@ -790,7 +785,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var sprite = node.getComponent(Sprite); * ``` */ - public getComponent (classConstructor: Constructor | AbstractedConstructor): T | null; + public getComponent(classConstructor: Constructor | AbstractedConstructor): T | null; /** * @en @@ -806,7 +801,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var test = node.getComponent("Test"); * ``` */ - public getComponent (className: string): Component | null; + public getComponent(className: string): Component | null; public getComponent (typeOrClassName: string | Constructor | AbstractedConstructor) { const constructor = getConstructor(typeOrClassName); @@ -821,14 +816,14 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 返回节点上指定类型的所有组件。 * @param classConstructor The class of the target component */ - public getComponents (classConstructor: Constructor | AbstractedConstructor): T[]; + public getComponents(classConstructor: Constructor | AbstractedConstructor): T[]; /** * @en Returns all components of given type in the node. * @zh 返回节点上指定类型的所有组件。 * @param className The class name of the target component */ - public getComponents (className: string): Component[]; + public getComponents(className: string): Component[]; public getComponents (typeOrClassName: string | Constructor | AbstractedConstructor) { const constructor = getConstructor(typeOrClassName); @@ -848,7 +843,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var sprite = node.getComponentInChildren(Sprite); * ``` */ - public getComponentInChildren (classConstructor: Constructor | AbstractedConstructor): T | null; + public getComponentInChildren(classConstructor: Constructor | AbstractedConstructor): T | null; /** * @en Returns the component of given type in any of its children using depth first search. @@ -859,7 +854,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var Test = node.getComponentInChildren("Test"); * ``` */ - public getComponentInChildren (className: string): Component | null; + public getComponentInChildren(className: string): Component | null; public getComponentInChildren (typeOrClassName: string | Constructor | AbstractedConstructor) { const constructor = getConstructor(typeOrClassName); @@ -878,7 +873,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var sprites = node.getComponentsInChildren(Sprite); * ``` */ - public getComponentsInChildren (classConstructor: Constructor | AbstractedConstructor): T[]; + public getComponentsInChildren(classConstructor: Constructor | AbstractedConstructor): T[]; /** * @en Returns all components of given type in self or any of its children. @@ -889,7 +884,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var tests = node.getComponentsInChildren("Test"); * ``` */ - public getComponentsInChildren (className: string): Component[]; + public getComponentsInChildren(className: string): Component[]; public getComponentsInChildren (typeOrClassName: string | Constructor | AbstractedConstructor) { const constructor = getConstructor(typeOrClassName); @@ -911,7 +906,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var sprite = node.addComponent(Sprite); * ``` */ - public addComponent (classConstructor: Constructor): T; + public addComponent(classConstructor: Constructor): T; /** * @en Adds a component class to the node. You can also add component to node by passing in the name of the script. @@ -923,7 +918,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * var test = node.addComponent("Test"); * ``` */ - public addComponent (className: string): Component; + public addComponent(className: string): Component; public addComponent (typeOrClassName: string | Constructor) { if (EDITOR && (this._objFlags & Destroying)) { @@ -1019,7 +1014,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * node.removeComponent(Sprite); * ``` */ - public removeComponent (classConstructor: Constructor | AbstractedConstructor): void; + public removeComponent(classConstructor: Constructor | AbstractedConstructor): void; /** * @en @@ -1040,7 +1035,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * node.removeComponent('Sprite'); * ``` */ - public removeComponent (classNameOrInstance: string | Component): void; + public removeComponent(classNameOrInstance: string | Component): void; public removeComponent (component: any) { if (!component) { @@ -1385,7 +1380,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { return destroyByParent; } - protected _onSiblingIndexChanged? (siblingIndex: number): void; + protected _onSiblingIndexChanged?(siblingIndex: number): void; /** * @en @@ -1395,7 +1390,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param constructor Constructor of the component. * @throws If one or more component of same type have been existed in this node. */ - protected _checkMultipleComp? (constructor: Constructor): void; + protected _checkMultipleComp?(constructor: Constructor): void; // ---------------------- Node ------------------------ /** @@ -1464,6 +1459,9 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { @serializable protected _lscale = new Vec3(1, 1, 1); + @serializable + protected _mobility = MobilityMode.Static; + @serializable protected _layer = Layers.Enum.DEFAULT; // the layer this node belongs to @@ -1671,6 +1669,17 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { return Vec3.transformQuat(new Vec3(), Vec3.RIGHT, this.worldRotation); } + @editable + @type(MobilityMode) + set mobility (m) { + this._mobility = m; + this.emit(NodeEventType.MOBILITY_CHANGED); + } + + get mobility () { + return this._mobility; + } + /** * @en Layer of the current Node, it affects raycast, physics etc, refer to [[Layers]] * @zh 节点所属层,主要影响射线检测、物理碰撞等,参考 [[Layers]] @@ -1917,7 +1926,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { let j = 0; let l = 0; let cur: this; - let children:this[]; + let children: this[]; let hasChangedFlags = 0; const childDirtyBit = dirtyBit | TransformBit.POSITION; @@ -1928,7 +1937,6 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { hasChangedFlags = cur.hasChangedFlags; if (cur.isValid && (cur._dirtyFlags & hasChangedFlags & dirtyBit) !== dirtyBit) { cur._dirtyFlags |= dirtyBit; - cur.hasChangedFlags = hasChangedFlags | dirtyBit; children = cur._children; @@ -1971,14 +1979,9 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { if (dirtyBits & TransformBit.RS) { Mat4.fromRTS(child._mat, child._lrot, child._lpos, child._lscale); Mat4.multiply(child._mat, cur._mat, child._mat); - if (dirtyBits & TransformBit.ROTATION) { - Quat.multiply(child._rot, cur._rot, child._lrot); - } - Mat3.fromQuat(m3_1, Quat.conjugate(qt_1, child._rot)); - Mat3.multiplyMat4(m3_1, m3_1, child._mat); - child._scale.x = m3_1.m00; - child._scale.y = m3_1.m04; - child._scale.z = m3_1.m08; + + const rotTmp = dirtyBits & TransformBit.ROTATION ? child._rot : null; + Mat4.toRTS(child._mat, rotTmp, null, child._scale); } } else { if (dirtyBits & TransformBit.POSITION) { @@ -2012,7 +2015,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 设置本地坐标 * @param position Target position */ - public setPosition (position: Readonly): void; + public setPosition(position: Readonly): void; /** * @en Set position in local coordinate system @@ -2021,7 +2024,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param y Y axis position * @param z Z axis position */ - public setPosition (x: number, y: number, z?: number): void; + public setPosition(x: number, y: number, z?: number): void; public setPosition (val: Readonly | number, y?: number, z?: number): void { if (y === undefined && z === undefined) { @@ -2057,7 +2060,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 用四元数设置本地旋转, 请确保设置的四元数已归一化。 * @param rotation Rotation in quaternion */ - public setRotation (rotation: Readonly): void; + public setRotation(rotation: Readonly): void; /** * @en Set rotation in local coordinate system with a quaternion representing the rotation. @@ -2068,7 +2071,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param z Z value in quaternion * @param w W value in quaternion */ - public setRotation (x: number, y: number, z: number, w: number): void; + public setRotation(x: number, y: number, z: number, w: number): void; public setRotation (val: Readonly | number, y?: number, z?: number, w?: number) { if (y === undefined || z === undefined || w === undefined) { @@ -2089,7 +2092,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 用欧拉角设置本地旋转 * @param rotation Rotation in vector */ - public setRotationFromEuler (rotation: Vec3): void; + public setRotationFromEuler(rotation: Vec3): void; /** * @en Set rotation in local coordinate system with euler angles @@ -2098,7 +2101,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param y Y axis rotation * @param z Z axis rotation */ - public setRotationFromEuler (x: number, y: number, zOpt?: number): void; + public setRotationFromEuler(x: number, y: number, zOpt?: number): void; public setRotationFromEuler (val: Vec3 | number, y?: number, zOpt?: number): void { const z = zOpt === undefined ? this._euler.z : zOpt; @@ -2137,7 +2140,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 设置本地缩放 * @param scale Target scale */ - public setScale (scale: Readonly): void; + public setScale(scale: Readonly): void; /** * @en Set scale in local coordinate system @@ -2146,7 +2149,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param y Y axis scale * @param z Z axis scale */ - public setScale (x: number, y: number, z?: number): void; + public setScale(x: number, y: number, z?: number): void; public setScale (val: Readonly | number, y?: number, z?: number) { if (y === undefined && z === undefined) { @@ -2204,7 +2207,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 设置世界坐标 * @param position Target position */ - public setWorldPosition (position: Vec3): void; + public setWorldPosition(position: Vec3): void; /** * @en Set position in world coordinate system @@ -2213,7 +2216,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param y Y axis position * @param z Z axis position */ - public setWorldPosition (x: number, y: number, z: number): void; + public setWorldPosition(x: number, y: number, z: number): void; public setWorldPosition (val: Vec3 | number, y?: number, z?: number) { if (y === undefined || z === undefined) { @@ -2260,7 +2263,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 用四元数设置世界坐标系下的旋转 * @param rotation Rotation in quaternion */ - public setWorldRotation (rotation: Quat): void; + public setWorldRotation(rotation: Quat): void; /** * @en Set rotation in world coordinate system with a quaternion representing the rotation @@ -2270,7 +2273,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param z Z value in quaternion * @param w W value in quaternion */ - public setWorldRotation (x: number, y: number, z: number, w: number): void; + public setWorldRotation(x: number, y: number, z: number, w: number): void; public setWorldRotation (val: Quat | number, y?: number, z?: number, w?: number) { if (y === undefined || z === undefined || w === undefined) { @@ -2334,7 +2337,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 设置世界坐标系下的缩放 * @param scale Target scale */ - public setWorldScale (scale: Vec3): void; + public setWorldScale(scale: Vec3): void; /** * @en Set scale in world coordinate system @@ -2343,23 +2346,26 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @param y Y axis scale * @param z Z axis scale */ - public setWorldScale (x: number, y: number, z: number): void; + public setWorldScale(x: number, y: number, z: number): void; public setWorldScale (val: Vec3 | number, y?: number, z?: number) { + const parent = this._parent; + if (parent) { + this.updateWorldTransform(); + } if (y === undefined || z === undefined) { Vec3.copy(this._scale, val as Vec3); } else { Vec3.set(this._scale, val as number, y, z); } - const parent = this._parent; if (parent) { - parent.updateWorldTransform(); - Mat3.fromQuat(m3_1, Quat.conjugate(qt_1, parent._rot)); - Mat3.multiplyMat4(m3_1, m3_1, parent._mat); - m3_scaling.m00 = this._scale.x; - m3_scaling.m04 = this._scale.y; - m3_scaling.m08 = this._scale.z; - Mat3.multiply(m3_1, m3_scaling, Mat3.invert(m3_1, m3_1)); + v3_a.x = this._scale.x / Vec3.set(v3_b, this._mat.m00, this._mat.m01, this._mat.m02).length(); + v3_a.y = this._scale.y / Vec3.set(v3_b, this._mat.m04, this._mat.m05, this._mat.m06).length(); + v3_a.z = this._scale.z / Vec3.set(v3_b, this._mat.m08, this._mat.m09, this._mat.m10).length(); + Mat4.scale(m4_1, this._mat, v3_a); + Mat4.multiply(m4_2, Mat4.invert(m4_2, parent._mat), m4_1); + Mat3.fromQuat(m3_1, Quat.conjugate(qt_1, this._lrot)); + Mat3.multiplyMat4(m3_1, m3_1, m4_2); this._lscale.x = Vec3.set(v3_a, m3_1.m00, m3_1.m01, m3_1.m02).length(); this._lscale.y = Vec3.set(v3_a, m3_1.m03, m3_1.m04, m3_1.m05).length(); this._lscale.z = Vec3.set(v3_a, m3_1.m06, m3_1.m07, m3_1.m08).length(); diff --git a/cocos/scene-graph/prefab/index.ts b/cocos/scene-graph/prefab/index.ts new file mode 100644 index 00000000000..7865f2c341f --- /dev/null +++ b/cocos/scene-graph/prefab/index.ts @@ -0,0 +1,29 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +// To keep compatibility: +// - prefab-info.ts is exported in utils.ts +// - utils.ts is exported in prefab.ts +// - so here just export prefab.ts +export * from './prefab'; diff --git a/cocos/core/utils/prefab/prefab-info.ts b/cocos/scene-graph/prefab/prefab-info.ts similarity index 73% rename from cocos/core/utils/prefab/prefab-info.ts rename to cocos/scene-graph/prefab/prefab-info.ts index 36b8b5412e6..e1e994e29fe 100644 --- a/cocos/core/utils/prefab/prefab-info.ts +++ b/cocos/scene-graph/prefab/prefab-info.ts @@ -1,9 +1,34 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { ccclass, serializable, editable, type } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; -import { legacyCC } from '../../global-exports'; -import { Prefab } from '../../../asset/assets'; -import { CCObject } from '../../data'; -import { Component, Node } from '../../../scene-graph'; +import { cclegacy } from '../../core'; +import { Prefab } from './prefab'; +import { CCObject } from '../../core/data'; +import { Component } from '../component'; +import { Node } from '../node'; function compareStringArray (array1: string[] | undefined, array2: string[] | undefined) { if (!array1 || !array2) { @@ -19,7 +44,7 @@ function compareStringArray (array1: string[] | undefined, array2: string[] | un @ccclass('cc.TargetInfo') export class TargetInfo { - // 用于标识目标在prefab 资源中的ID,区别于UUID + // as the target's fileId in prefab asset,used to find the target when prefab expanded. @serializable public localID: string[] = []; } @@ -114,26 +139,27 @@ export class PrefabInstance { @serializable public fileId = ''; - // 记录PrefabInstance所属的Prefab的Root节点信息 + // record the node with the Prefab that this prefabInstance belongs to. @serializable @type(Node) public prefabRootNode?: Node; - // 实例化的Prefab中额外增加的子节点数据 + // record children nodes that exist in this prefabInstance but not in prefab asset. @serializable @type([MountedChildrenInfo]) public mountedChildren: MountedChildrenInfo[] = []; - // 实例化的Prefab中额外增加的Component数据 + // record components that exist in this prefabInstance but not in prefab asset. @serializable @type([MountedComponentsInfo]) public mountedComponents: MountedComponentsInfo[] = []; - // 属性的覆盖数据 + // override properties info in this prefabInstance. @serializable @type([PropertyOverrideInfo]) public propertyOverrides: PropertyOverrideInfo[] = []; + // record components that exist in ths prefab asset but not in prefabInstance. @serializable @type([TargetInfo]) public removedComponents: TargetInfo[] = []; @@ -179,12 +205,12 @@ export class PrefabInfo { @type(Node) public root?: Node; - // 所属的 prefab 资源对象 (cc.Prefab) + // reference to the prefab asset file. // In Editor, only asset._uuid is usable because asset will be changed. @serializable public asset?: Prefab; - // 用来标识别该节点在 prefab 资源中的位置,因此这个 ID 只需要保证在 Assets 里不重复就行 + // prefabInfo's id,unique in the asset. @serializable @editable public fileId = ''; @@ -204,4 +230,4 @@ export class PrefabInfo { public nestedPrefabInstanceRoots?: Node[]; } -legacyCC._PrefabInfo = PrefabInfo; +cclegacy._PrefabInfo = PrefabInfo; diff --git a/cocos/asset/assets/prefab.ts b/cocos/scene-graph/prefab/prefab.ts similarity index 87% rename from cocos/asset/assets/prefab.ts rename to cocos/scene-graph/prefab/prefab.ts index 8c01c152485..d9da0f7a0d2 100644 --- a/cocos/asset/assets/prefab.ts +++ b/cocos/scene-graph/prefab/prefab.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,15 +24,16 @@ */ import { ccclass, serializable, editable } from 'cc.decorator'; -import { SUPPORT_JIT, ALIPAY, RUNTIME_BASED } from 'internal:constants'; -import { compile } from '../../core/data/instantiate-jit'; -import { js, obsolete } from '../../core/utils/js'; +import { SUPPORT_JIT, ALIPAY, RUNTIME_BASED, JSB } from 'internal:constants'; +import { compile } from '../../serialization/instantiate-jit'; +import { js } from '../../core'; import { Enum } from '../../core/value-types'; -import { Asset } from './asset'; -import { Node } from '../../scene-graph/node'; +import { Asset } from '../../asset/assets/asset'; +import { Node } from '../node'; import { legacyCC } from '../../core/global-exports'; import { warnID } from '../../core/platform/debug'; -import * as utils from '../../core/utils/prefab'; +import { updateChildrenForDeserialize } from '../../core/utils/jsb-utils'; +import * as utils from './utils'; /** * @en An enumeration used with the [[Prefab.optimizationPolicy]] to specify how to optimize the instantiate operation. @@ -200,6 +200,9 @@ export class Prefab extends Asset { const rootNode = this.data as Node; utils.expandNestedPrefabInstanceNode(rootNode); utils.applyTargetOverrides(rootNode); + if (JSB) { + updateChildrenForDeserialize(rootNode); + } } } @@ -213,5 +216,5 @@ legacyCC.Prefab = Prefab; if (ALIPAY || RUNTIME_BASED) { legacyCC._Prefab = Prefab; } else { - obsolete(legacyCC, 'cc._Prefab', 'Prefab'); + js.obsolete(legacyCC, 'cc._Prefab', 'Prefab'); } diff --git a/cocos/core/utils/prefab/utils.ts b/cocos/scene-graph/prefab/utils.ts similarity index 87% rename from cocos/core/utils/prefab/utils.ts rename to cocos/scene-graph/prefab/utils.ts index a416c39a883..8b46e08592c 100644 --- a/cocos/core/utils/prefab/utils.ts +++ b/cocos/scene-graph/prefab/utils.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,13 +24,13 @@ */ import { EDITOR, SUPPORT_JIT } from 'internal:constants'; -import { legacyCC } from '../../global-exports'; -import type { Node, Component } from '../../../scene-graph'; -import { errorID, warn } from '../../platform/debug'; -import { MountedChildrenInfo, PropertyOverrideInfo } from './prefab-info'; -import { MountedComponentsInfo, TargetInfo } from '.'; -import { editorExtrasTag } from '../../data'; -import { ValueType } from '../../value-types'; +import { cclegacy, errorID, warn, editorExtrasTag } from '../../core'; +import { Node } from '../node'; +import { Component } from '../component'; +import { MountedChildrenInfo, PropertyOverrideInfo, MountedComponentsInfo, TargetInfo } from './prefab-info'; +import { ValueType } from '../../core/value-types'; + +export * from './prefab-info'; export function createNodeWithPrefab (node: Node) { // @ts-expect-error: private member access @@ -68,7 +67,7 @@ export function createNodeWithPrefab (node: Node) { const editorExtras = node[editorExtrasTag]; // instantiate prefab - legacyCC.game._isCloning = true; + cclegacy.game._isCloning = true; if (SUPPORT_JIT) { // @ts-expect-error: private member access prefabInfo.asset._doInstantiate(node); @@ -80,9 +79,9 @@ export function createNodeWithPrefab (node: Node) { prefabRoot._iN$t = node; // instantiate prefab and apply to node - legacyCC.instantiate._clone(prefabRoot, prefabRoot); + cclegacy.instantiate._clone(prefabRoot, prefabRoot); } - legacyCC.game._isCloning = false; + cclegacy.game._isCloning = false; // restore preserved props node._objFlags = _objFlags; @@ -191,7 +190,7 @@ export function applyMountedChildren (node: Node, mountedChildren: MountedChildr // @ts-expect-error private member access target._children.push(childNode); - // @ts-expect-error private member access + // @ts-expect-error: private member access childNode._parent = target; if (EDITOR) { if (!childNode[editorExtrasTag]) { @@ -202,7 +201,7 @@ export function applyMountedChildren (node: Node, mountedChildren: MountedChildr } // mounted node need to add to the target map generateTargetMap(childNode, curTargetMap, false); - // siblingIndex update is in _onBatchCreated function, and it needs a parent. + // siblingIndex update is in _onBatchCreated function, and it p needs a parent. // @ts-expect-error private member access childNode._siblingIndex = target._children.length - 1; expandPrefabInstanceNode(childNode, true); @@ -407,8 +406,6 @@ export function expandPrefabInstanceNode (node: Node, recursively = false) { }); } } - // nested prefab children's id will be the same: 3dtask#12511 - // applyNodeAndComponentId(node, node.uuid); const targetMap: Record = {}; prefabInstance.targetMap = targetMap; @@ -434,20 +431,35 @@ export function expandNestedPrefabInstanceNode (node: Node) { if (prefabInfo && prefabInfo.nestedPrefabInstanceRoots) { prefabInfo.nestedPrefabInstanceRoots.forEach((instanceNode: Node) => { expandPrefabInstanceNode(instanceNode); + // when expanding the prefab,it's children will be change,so need to apply after expanded + if (!EDITOR) { + // @ts-expect-error private member access + applyNodeAndComponentId(instanceNode, instanceNode._prefab?.instance?.fileId); + } }); } } -export function applyNodeAndComponentId (node: Node, rootId: string) { - const { components, children } = node; +// make sure prefab instance's children id is fixed +export function applyNodeAndComponentId (prefabInstanceNode: Node, rootId: string) { + const { components, children } = prefabInstanceNode; for (let i = 0; i < components.length; i++) { const comp = components[i]; - comp._id = `${rootId}${comp.__prefab?.fileId}`; + const fileID = comp.__prefab?.fileId ?? ''; + comp._id = `${rootId}${fileID}`; } for (let i = 0; i < children.length; i++) { const child = children[i]; // @ts-expect-error private member access - child._id = `${rootId}${child._prefab?.fileId}`; - applyNodeAndComponentId(child, rootId); + const prefabInfo = child._prefab!; + const fileId = prefabInfo?.instance ? prefabInfo.instance.fileId : prefabInfo?.fileId; + if (!fileId) continue; + // @ts-expect-error private member access + child._id = `${rootId}${fileId}`; + + // ignore prefab instance,because it will be apply in 'nestedPrefabInstanceRoots' for loop; + if (!prefabInfo?.instance) { + applyNodeAndComponentId(child, rootId); + } } } diff --git a/cocos/scene-graph/scene-globals.jsb.ts b/cocos/scene-graph/scene-globals.jsb.ts index f582d06300a..7b1e6475ccb 100644 --- a/cocos/scene-graph/scene-globals.jsb.ts +++ b/cocos/scene-graph/scene-globals.jsb.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,15 +30,20 @@ import { tooltip, type, visible -// @ts-ignore + // @ts-ignore } from 'cc.decorator'; import { legacyCC } from '../core/global-exports'; import { CCFloat, CCInteger } from '../core/data'; import { TextureCube } from '../asset/assets/texture-cube'; import { Enum } from '../core/value-types'; import { ccclass, displayOrder, rangeMin, rangeStep, slide } from '../core/data/decorators'; -import { EnvironmentLightingType } from '../render-scene/scene'; +import { Ambient, EnvironmentLightingType } from '../render-scene/scene'; import { Material } from '../asset/assets/material'; +import { Vec2, Vec3, Color, Vec4 } from '../core/math'; + +export const DEFAULT_WORLD_MIN_POS = new Vec3(-1024.0, -1024.0, -1024.0); +export const DEFAULT_WORLD_MAX_POS = new Vec3(1024.0, 1024.0, 1024.0); +export const DEFAULT_OCTREE_DEPTH = 8; /** * @zh @@ -163,6 +169,10 @@ legacyCC.ShadowsInfo = ShadowsInfo; export const OctreeInfo = jsb.OctreeInfo; legacyCC.OctreeInfo = OctreeInfo; +// @ts-ignore +export const LightProbeInfo = jsb.LightProbeInfo; +//legacyCC.LightProbeInfo = LightProbeInfo; + // @ts-ignore export const SceneGlobals = jsb.SceneGlobals; legacyCC.SceneGlobals = SceneGlobals; @@ -171,20 +181,21 @@ legacyCC.SceneGlobals = SceneGlobals; const sceneGlobalsProto: any = SceneGlobals.prototype; sceneGlobalsProto._ctor = function () { - this._ambientRef = null; - this._shadowsRef = null; - this._skyboxRef = null; - this._fogRef = null; - this._octreeRef = null; + this._ambientRef = this.getAmbientInfo(); + this._shadowsRef = this.getShadowsInfo(); + this._skyboxRef = this.getSkyboxInfo(); + this._fogRef = this.getFogInfo(); + this._octreeRef = this.getOctreeInfo(); + this._lightProbeRef = this.getLightProbeInfo(); }; Object.defineProperty(sceneGlobalsProto, 'ambient', { enumerable: true, configurable: true, - get () { + get() { return this._ambientRef; }, - set (v) { + set(v) { this._ambientRef = v; this.setAmbientInfo(v); }, @@ -193,10 +204,10 @@ legacyCC.SceneGlobals = SceneGlobals; Object.defineProperty(sceneGlobalsProto, 'shadows', { enumerable: true, configurable: true, - get () { + get() { return this._shadowsRef; }, - set (v) { + set(v) { this._shadowsRef = v; this.setShadowsInfo(v); }, @@ -205,10 +216,10 @@ legacyCC.SceneGlobals = SceneGlobals; Object.defineProperty(sceneGlobalsProto, '_skybox', { enumerable: true, configurable: true, - get () { + get() { return this._skyboxRef; }, - set (v) { + set(v) { this._skyboxRef = v; this.setSkyboxInfo(v); }, @@ -217,10 +228,10 @@ legacyCC.SceneGlobals = SceneGlobals; Object.defineProperty(sceneGlobalsProto, 'skybox', { enumerable: true, configurable: true, - get () { + get() { return this._skyboxRef; }, - set (v) { + set(v) { this._skyboxRef = v; this.setSkyboxInfo(v); }, @@ -229,10 +240,10 @@ legacyCC.SceneGlobals = SceneGlobals; Object.defineProperty(sceneGlobalsProto, 'fog', { enumerable: true, configurable: true, - get () { + get() { return this._fogRef; }, - set (v) { + set(v) { this._fogRef = v; this.setFogInfo(v); }, @@ -241,38 +252,74 @@ legacyCC.SceneGlobals = SceneGlobals; Object.defineProperty(sceneGlobalsProto, 'octree', { enumerable: true, configurable: true, - get () { + get() { return this._octreeRef; }, - set (v) { + set(v) { this._octreeRef = v; this.setOctreeInfo(v); }, }); + + Object.defineProperty(sceneGlobalsProto, 'lightProbeInfo', { + enumerable: true, + configurable: true, + get() { + return this._lightProbeRef; + }, + set(v) { + this._lightProbeRef = v; + this.setLightProbeInfo(v); + }, + }); })(); + +function ambientSkyLightEnable() { + const scene = legacyCC.director.getScene(); + const skybox = scene.globals.skybox; + if (skybox.useIBL && skybox.applyDiffuseMap) { + return false; + } else { + return true; + } +} + +function checkFieldIs(attr: string, value: number) { + return function () { + return this[attr] === value; + }; +} +function checkFieldNot(attr: string, value: number) { + return function () { + return this[attr] !== value; + }; +} + // handle meta data, it is generated automatically const SceneGlobalsProto = SceneGlobals.prototype; -editable(SceneGlobalsProto, 'ambient'); -serializable(SceneGlobalsProto, 'ambient'); -editable(SceneGlobalsProto, 'shadows'); -serializable(SceneGlobalsProto, 'shadows'); -serializable(SceneGlobalsProto, '_skybox'); -serializable(SceneGlobalsProto, 'fog'); -editable(SceneGlobalsProto, 'fog'); +editable(SceneGlobalsProto, 'ambient', () => new AmbientInfo()); +serializable(SceneGlobalsProto, 'ambient', () => new AmbientInfo()); +editable(SceneGlobalsProto, 'shadows', () => new ShadowsInfo()); +serializable(SceneGlobalsProto, 'shadows', () => new ShadowsInfo()); +serializable(SceneGlobalsProto, '_skybox', () => new SkyboxInfo()); +serializable(SceneGlobalsProto, 'fog', () => new FogInfo()); +editable(SceneGlobalsProto, 'fog', () => new FogInfo()); const skyboxDescriptor = Object.getOwnPropertyDescriptor(SceneGlobalsProto, 'skybox'); type(SkyboxInfo)(SceneGlobalsProto, 'skybox', skyboxDescriptor); editable(SceneGlobalsProto, 'skybox', skyboxDescriptor); -serializable(SceneGlobalsProto, 'octree'); -editable(SceneGlobalsProto, 'octree'); +serializable(SceneGlobalsProto, 'octree', () => new OctreeInfo()); +editable(SceneGlobalsProto, 'octree', () => new OctreeInfo()); +serializable(SceneGlobalsProto, 'lightProbeInfo', () => new LightProbeInfo()); +editable(SceneGlobalsProto, 'lightProbeInfo', () => new LightProbeInfo()); ccclass('cc.SceneGlobals')(SceneGlobals); const OctreeInfoProto = OctreeInfo.prototype; -serializable(OctreeInfoProto, '_enabled'); -serializable(OctreeInfoProto, '_minPos'); -serializable(OctreeInfoProto, '_maxPos'); -serializable(OctreeInfoProto, '_depth'); +serializable(OctreeInfoProto, '_enabled', () => false); +serializable(OctreeInfoProto, '_minPos', () => new Vec3(DEFAULT_WORLD_MIN_POS)); +serializable(OctreeInfoProto, '_maxPos', () => new Vec3(DEFAULT_WORLD_MAX_POS)); +serializable(OctreeInfoProto, '_depth', () => DEFAULT_OCTREE_DEPTH); const enabledDescriptor = Object.getOwnPropertyDescriptor(OctreeInfoProto, 'enabled'); tooltip('i18n:octree_culling.enabled')(OctreeInfoProto, 'enabled', enabledDescriptor); editable(OctreeInfoProto, 'enabled', enabledDescriptor); @@ -293,50 +340,52 @@ editable(OctreeInfoProto, 'depth', depthDescriptor); ccclass('cc.OctreeInfo')(OctreeInfo); const ShadowsInfoProto = ShadowsInfo.prototype; -serializable(ShadowsInfoProto, '_enabled'); -serializable(ShadowsInfoProto, '_type'); -serializable(ShadowsInfoProto, '_normal'); -serializable(ShadowsInfoProto, '_distance'); -serializable(ShadowsInfoProto, '_shadowColor'); -serializable(ShadowsInfoProto, '_maxReceived'); -serializable(ShadowsInfoProto, '_size'); +serializable(ShadowsInfoProto, '_enabled', () => false); +serializable(ShadowsInfoProto, '_type', () => ShadowType.Planar); +serializable(ShadowsInfoProto, '_normal', () => new Vec3(0, 1, 0)); +serializable(ShadowsInfoProto, '_distance', () => 0); +serializable(ShadowsInfoProto, '_shadowColor', () => new Color(0, 0, 0, 76)); +serializable(ShadowsInfoProto, '_maxReceived', () => 4); +serializable(ShadowsInfoProto, '_size', () => new Vec2(1024, 1024)); const shadowEnabledDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'enabled'); tooltip('i18n:shadow.enabled')(ShadowsInfoProto, 'enabled', shadowEnabledDescriptor); editable(ShadowsInfoProto, 'enabled', shadowEnabledDescriptor); const typeDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'type'); +tooltip('i18n:shadow.type')(ShadowsInfoProto, 'type', typeDescriptor) type(ShadowType)(ShadowsInfoProto, 'type', typeDescriptor); editable(ShadowsInfoProto, 'type', typeDescriptor); const shadowColorDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'shadowColor'); -visible(function (this) { /* Need to copy source code */ })(ShadowsInfoProto, 'shadowColor', shadowColorDescriptor); +tooltip('i18n:shadow.shadowColor')(ShadowsInfoProto, 'shadowColor', shadowColorDescriptor); +visible(checkFieldIs("_type", ShadowType.Planar))(ShadowsInfoProto, 'shadowColor', shadowColorDescriptor); const planeDirectionDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'planeDirection'); tooltip('i18n:shadow.planeDirection')(ShadowsInfoProto, 'planeDirection', planeDirectionDescriptor); -visible(function (this) { /* Need to copy source code */ })(ShadowsInfoProto, 'planeDirection', planeDirectionDescriptor); +visible(checkFieldIs("_type", ShadowType.Planar))(ShadowsInfoProto, 'planeDirection', planeDirectionDescriptor); const planeHeightDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'planeHeight'); tooltip('i18n:shadow.planeHeight')(ShadowsInfoProto, 'planeHeight', planeHeightDescriptor); -visible(function (this) { /* Need to copy source code */ })(ShadowsInfoProto, 'planeHeight', planeHeightDescriptor); +visible(checkFieldIs("_type", ShadowType.Planar))(ShadowsInfoProto, 'planeHeight', planeHeightDescriptor); type(CCFloat)(ShadowsInfoProto, 'planeHeight', planeHeightDescriptor); editable(ShadowsInfoProto, 'planeHeight', planeHeightDescriptor); const maxReceivedDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'maxReceived'); -visible(function (this) { /* Need to copy source code */ })(ShadowsInfoProto, 'maxReceived', maxReceivedDescriptor); +visible(checkFieldIs("_type", ShadowType.ShadowMap))(ShadowsInfoProto, 'maxReceived', maxReceivedDescriptor); tooltip('i18n:shadow.maxReceived')(ShadowsInfoProto, 'maxReceived', maxReceivedDescriptor); type(CCInteger)(ShadowsInfoProto, 'maxReceived', maxReceivedDescriptor); const shadowMapSizeDescriptor = Object.getOwnPropertyDescriptor(ShadowsInfoProto, 'shadowMapSize'); -visible(function (this) { /* Need to copy source code */ })(ShadowsInfoProto, 'shadowMapSize', shadowMapSizeDescriptor); +visible(checkFieldIs("_type", ShadowType.ShadowMap))(ShadowsInfoProto, 'shadowMapSize', shadowMapSizeDescriptor); tooltip('i18n:shadow.shadowMapSize')(ShadowsInfoProto, 'shadowMapSize', shadowMapSizeDescriptor); type(ShadowSize)(ShadowsInfoProto, 'shadowMapSize', shadowMapSizeDescriptor); ccclass('cc.ShadowsInfo')(ShadowsInfo); const FogInfoProto = FogInfo.prototype; -serializable(FogInfoProto, '_type'); -serializable(FogInfoProto, '_fogColor'); -serializable(FogInfoProto, '_enabled'); -serializable(FogInfoProto, '_fogDensity'); -serializable(FogInfoProto, '_fogStart'); -serializable(FogInfoProto, '_fogEnd'); -serializable(FogInfoProto, '_fogAtten'); -serializable(FogInfoProto, '_fogTop'); -serializable(FogInfoProto, '_fogRange'); -serializable(FogInfoProto, '_accurate'); +serializable(FogInfoProto, '_type', () => FogType.LINEAR); +serializable(FogInfoProto, '_fogColor', () => new Color('#C8C8C8')); +serializable(FogInfoProto, '_enabled', () => false); +serializable(FogInfoProto, '_fogDensity', () => 0.3); +serializable(FogInfoProto, '_fogStart', () => 0.5); +serializable(FogInfoProto, '_fogEnd', () => 300); +serializable(FogInfoProto, '_fogAtten', () => 5); +serializable(FogInfoProto, '_fogTop', () => 1.5); +serializable(FogInfoProto, '_fogRange', () => 1.2); +serializable(FogInfoProto, '_accurate', () => false); const fogEnabledDescriptor = Object.getOwnPropertyDescriptor(FogInfoProto, 'enabled'); displayOrder(0)(FogInfoProto, 'enabled', fogEnabledDescriptor); tooltip('i18n:fog.enabled')(FogInfoProto, 'enabled', fogEnabledDescriptor); @@ -359,54 +408,68 @@ slide(FogInfoProto, 'fogDensity', fogDensityDescriptor); rangeStep(0.01)(FogInfoProto, 'fogDensity', fogDensityDescriptor); range([0, 1])(FogInfoProto, 'fogDensity', fogDensityDescriptor); type(CCFloat)(FogInfoProto, 'fogDensity', fogDensityDescriptor); -visible(function (this) { /* Need to copy source code */ })(FogInfoProto, 'fogDensity', fogDensityDescriptor); +visible(function () { this._type !== FogType.LAYERED && this._type !== FogType.LINEAR; })(FogInfoProto, 'fogDensity', fogDensityDescriptor); const fogStartDescriptor = Object.getOwnPropertyDescriptor(FogInfoProto, 'fogStart'); tooltip('i18n:fog.fogStart')(FogInfoProto, 'fogStart', fogStartDescriptor); rangeStep(0.01)(FogInfoProto, 'fogStart', fogStartDescriptor); type(CCFloat)(FogInfoProto, 'fogStart', fogStartDescriptor); -visible(function (this) { /* Need to copy source code */ })(FogInfoProto, 'fogStart', fogStartDescriptor); +visible(checkFieldNot("_type", FogType.LAYERED))(FogInfoProto, 'fogStart', fogStartDescriptor); const fogEndDescriptor = Object.getOwnPropertyDescriptor(FogInfoProto, 'fogEnd'); tooltip('i18n:fog.fogEnd')(FogInfoProto, 'fogEnd', fogEndDescriptor); rangeStep(0.01)(FogInfoProto, 'fogEnd', fogEndDescriptor); type(CCFloat)(FogInfoProto, 'fogEnd', fogEndDescriptor); -visible(function (this) { /* Need to copy source code */ })(FogInfoProto, 'fogEnd', fogEndDescriptor); +visible(checkFieldIs("_type", FogType.LINEAR))(FogInfoProto, 'fogEnd', fogEndDescriptor); const fogAttenDescriptor = Object.getOwnPropertyDescriptor(FogInfoProto, 'fogAtten'); tooltip('i18n:fog.fogAtten')(FogInfoProto, 'fogAtten', fogAttenDescriptor); rangeStep(0.01)(FogInfoProto, 'fogAtten', fogAttenDescriptor); rangeMin(0.01)(FogInfoProto, 'fogAtten', fogAttenDescriptor); type(CCFloat)(FogInfoProto, 'fogAtten', fogAttenDescriptor); -visible(function (this) { /* Need to copy source code */ })(FogInfoProto, 'fogAtten', fogAttenDescriptor); +visible(checkFieldNot("_type", FogType.LINEAR))(FogInfoProto, 'fogAtten', fogAttenDescriptor); const fogTopDescriptor = Object.getOwnPropertyDescriptor(FogInfoProto, 'fogTop'); tooltip('i18n:fog.fogTop')(FogInfoProto, 'fogTop', fogTopDescriptor); rangeStep(0.01)(FogInfoProto, 'fogTop', fogTopDescriptor); type(CCFloat)(FogInfoProto, 'fogTop', fogTopDescriptor); -visible(function (this) { /* Need to copy source code */ })(FogInfoProto, 'fogTop', fogTopDescriptor); +visible(checkFieldIs("_type", FogType.LAYERED))(FogInfoProto, 'fogTop', fogTopDescriptor); const fogRangeDescriptor = Object.getOwnPropertyDescriptor(FogInfoProto, 'fogRange'); tooltip('i18n:fog.fogRange')(FogInfoProto, 'fogRange', fogRangeDescriptor); rangeStep(0.01)(FogInfoProto, 'fogRange', fogRangeDescriptor); type(CCFloat)(FogInfoProto, 'fogRange', fogRangeDescriptor); -visible(function (this) { /* Need to copy source code */ })(FogInfoProto, 'fogRange', fogRangeDescriptor); +visible(checkFieldIs("_type", FogType.LAYERED))(FogInfoProto, 'fogRange', fogRangeDescriptor); ccclass('cc.FogInfo')(FogInfo); const SkyboxInfoProto = SkyboxInfo.prototype; -serializable(SkyboxInfoProto, '_envLightingType'); -formerlySerializedAs('_envmap')(SkyboxInfoProto, '_envmapHDR'); -type(TextureCube)(SkyboxInfoProto, '_envmapHDR'); -serializable(SkyboxInfoProto, '_envmapHDR'); -type(TextureCube)(SkyboxInfoProto, '_envmapLDR'); -serializable(SkyboxInfoProto, '_envmapLDR'); -type(TextureCube)(SkyboxInfoProto, '_diffuseMapHDR'); -serializable(SkyboxInfoProto, '_diffuseMapHDR'); -type(TextureCube)(SkyboxInfoProto, '_diffuseMapLDR'); -serializable(SkyboxInfoProto, '_diffuseMapLDR'); -serializable(SkyboxInfoProto, '_enabled'); -serializable(SkyboxInfoProto, '_useHDR'); -type(Material)(SkyboxInfoProto, '_editableMaterial'); -serializable(SkyboxInfoProto, '_editableMaterial'); -type(TextureCube)(SkyboxInfoProto, '_reflectionHDR'); -serializable(SkyboxInfoProto, '_reflectionHDR'); -type(TextureCube)(SkyboxInfoProto, '_reflectionLDR'); -serializable(SkyboxInfoProto, '_reflectionLDR'); +serializable(SkyboxInfoProto, '_envLightingType', () => EnvironmentLightingType.HEMISPHERE_DIFFUSE); +formerlySerializedAs('_envmap')(SkyboxInfoProto, '_envmapHDR', () => null); +type(TextureCube)(SkyboxInfoProto, '_envmapHDR', () => null); +serializable(SkyboxInfoProto, '_envmapHDR', () => null); +type(TextureCube)(SkyboxInfoProto, '_envmapLDR', () => null); +serializable(SkyboxInfoProto, '_envmapLDR', () => null); +type(TextureCube)(SkyboxInfoProto, '_diffuseMapHDR', () => null); +serializable(SkyboxInfoProto, '_diffuseMapHDR', () => null); +type(TextureCube)(SkyboxInfoProto, '_diffuseMapLDR', () => null); +serializable(SkyboxInfoProto, '_diffuseMapLDR', () => null); +serializable(SkyboxInfoProto, '_enabled', () => false); +serializable(SkyboxInfoProto, '_useHDR', () => true); +type(Material)(SkyboxInfoProto, '_editableMaterial', () => null); +serializable(SkyboxInfoProto, '_editableMaterial', () => null); +type(TextureCube)(SkyboxInfoProto, '_reflectionHDR', () => null); +serializable(SkyboxInfoProto, '_reflectionHDR', () => null); +type(TextureCube)(SkyboxInfoProto, '_reflectionLDR', () => null); +serializable(SkyboxInfoProto, '_reflectionLDR', () => null); + +const skyboxRotationAngleDescriptor = Object.getOwnPropertyDescriptor(SkyboxInfoProto, 'rotationAngle'); +type(CCFloat)(SkyboxInfoProto, 'rotationAngle', skyboxRotationAngleDescriptor); +range([0, 360])(SkyboxInfoProto, 'rotationAngle', skyboxRotationAngleDescriptor); +rangeStep(1)(SkyboxInfoProto, 'rotationAngle', skyboxRotationAngleDescriptor); +slide(SkyboxInfoProto, 'rotationAngle', skyboxRotationAngleDescriptor); +tooltip('i18n:skybox.rotationAngle')(SkyboxInfoProto, 'rotationAngle', skyboxRotationAngleDescriptor); + +const skyboxReflectionMapDescriptor = Object.getOwnPropertyDescriptor(SkyboxInfoProto, 'reflectionMap'); +editable(SkyboxInfoProto, 'reflectionMap', skyboxReflectionMapDescriptor); +readOnly(SkyboxInfoProto, 'reflectionMap', skyboxReflectionMapDescriptor) +type(TextureCube)(SkyboxInfoProto, 'reflectionMap', skyboxReflectionMapDescriptor) +displayOrder(100)(SkyboxInfoProto, 'reflectionMap', skyboxReflectionMapDescriptor) + const skyboxEnabledDescriptor = Object.getOwnPropertyDescriptor(SkyboxInfoProto, 'enabled'); tooltip('i18n:skybox.enabled')(SkyboxInfoProto, 'enabled', skyboxEnabledDescriptor); editable(SkyboxInfoProto, 'enabled', skyboxEnabledDescriptor); @@ -426,27 +489,28 @@ displayOrder(100)(SkyboxInfoProto, 'diffuseMap', diffuseMapDescriptor); type(TextureCube)(SkyboxInfoProto, 'diffuseMap', diffuseMapDescriptor); readOnly(SkyboxInfoProto, 'diffuseMap', diffuseMapDescriptor); editable(SkyboxInfoProto, 'diffuseMap', diffuseMapDescriptor); -visible(function (this) { /* Need to copy source code */ })(SkyboxInfoProto, 'diffuseMap', diffuseMapDescriptor); +visible(function () { return this.useIBL && this.applyDiffuseMap; })(SkyboxInfoProto, 'diffuseMap', diffuseMapDescriptor); const skyboxMaterialDescriptor = Object.getOwnPropertyDescriptor(SkyboxInfoProto, 'skyboxMaterial'); tooltip('i18n:skybox.material')(SkyboxInfoProto, 'skyboxMaterial', skyboxMaterialDescriptor); type(Material)(SkyboxInfoProto, 'skyboxMaterial', skyboxMaterialDescriptor); editable(SkyboxInfoProto, 'skyboxMaterial', skyboxMaterialDescriptor); +serializable(SkyboxInfoProto, '_rotationAngle', () => 0); ccclass('cc.SkyboxInfo')(SkyboxInfo); const AmbientInfoProto = AmbientInfo.prototype; -formerlySerializedAs('_skyColor')(AmbientInfoProto, '_skyColorHDR'); -serializable(AmbientInfoProto, '_skyColorHDR'); -formerlySerializedAs('_skyIllum')(AmbientInfoProto, '_skyIllumHDR'); -serializable(AmbientInfoProto, '_skyIllumHDR'); -formerlySerializedAs('_groundAlbedo')(AmbientInfoProto, '_groundAlbedoHDR'); -serializable(AmbientInfoProto, '_groundAlbedoHDR'); -serializable(AmbientInfoProto, '_skyColorLDR'); -serializable(AmbientInfoProto, '_skyIllumLDR'); -serializable(AmbientInfoProto, '_groundAlbedoLDR'); +formerlySerializedAs('_skyColor')(AmbientInfoProto, '_skyColorHDR', () => new Vec4(0.2, 0.5, 0.8, 1.0)); +serializable(AmbientInfoProto, '_skyColorHDR', () => new Vec4(0.2, 0.5, 0.8, 1.0)); +formerlySerializedAs('_skyIllum')(AmbientInfoProto, '_skyIllumHDR', () => Ambient.SKY_ILLUM); +serializable(AmbientInfoProto, '_skyIllumHDR', () => Ambient.SKY_ILLUM); +formerlySerializedAs('_groundAlbedo')(AmbientInfoProto, '_groundAlbedoHDR', () => new Vec4(0.2, 0.2, 0.2, 1.0)); +serializable(AmbientInfoProto, '_groundAlbedoHDR', () => new Vec4(0.2, 0.2, 0.2, 1.0)); +serializable(AmbientInfoProto, '_skyColorLDR', () => new Vec4(0.2, 0.5, 0.8, 1.0)); +serializable(AmbientInfoProto, '_skyIllumLDR', () => Ambient.SKY_ILLUM); +serializable(AmbientInfoProto, '_groundAlbedoLDR', () => new Vec4(0.2, 0.2, 0.2, 1.0)); const skyLightingColorDescriptor = Object.getOwnPropertyDescriptor(AmbientInfoProto, 'skyLightingColor'); tooltip('i18n:ambient.skyLightingColor')(AmbientInfoProto, 'skyLightingColor', skyLightingColorDescriptor); editable(AmbientInfoProto, 'skyLightingColor', skyLightingColorDescriptor); -visible(() => { /* Need to copy source code */ })(AmbientInfoProto, 'skyLightingColor', skyLightingColorDescriptor); +visible(ambientSkyLightEnable)(AmbientInfoProto, 'skyLightingColor', skyLightingColorDescriptor); const skyIllumDescriptor = Object.getOwnPropertyDescriptor(AmbientInfoProto, 'skyIllum'); tooltip('i18n:ambient.skyIllum')(AmbientInfoProto, 'skyIllum', skyIllumDescriptor); type(CCFloat)(AmbientInfoProto, 'skyIllum', skyIllumDescriptor); @@ -454,5 +518,57 @@ editable(AmbientInfoProto, 'skyIllum', skyIllumDescriptor); const groundLightingColorDescriptor = Object.getOwnPropertyDescriptor(AmbientInfoProto, 'groundLightingColor'); tooltip('i18n:ambient.groundLightingColor')(AmbientInfoProto, 'groundLightingColor', groundLightingColorDescriptor); editable(AmbientInfoProto, 'groundLightingColor', groundLightingColorDescriptor); -visible(() => { /* Need to copy source code */ })(AmbientInfoProto, 'groundLightingColor', groundLightingColorDescriptor); +visible(ambientSkyLightEnable)(AmbientInfoProto, 'groundLightingColor', groundLightingColorDescriptor); ccclass('cc.AmbientInfo')(AmbientInfo); + +const LightProbeInfoProto = LightProbeInfo.prototype; +serializable(LightProbeInfoProto, '_giScale', () => 1.0); +serializable(LightProbeInfoProto, '_giSamples', () => 1024); +serializable(LightProbeInfoProto, '_bounces', () => 2); +serializable(LightProbeInfoProto, '_reduceRinging', () => 0.0); +serializable(LightProbeInfoProto, '_showProbe', () => true); +serializable(LightProbeInfoProto, '_showWireframe', () => true); +serializable(LightProbeInfoProto, '_showConvex', () => false); +serializable(LightProbeInfoProto, '_data', () => null); + +const lightProbeGIScaleDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'giScale'); +range([0, 100, 1])(LightProbeInfoProto, 'giScale', lightProbeGIScaleDescriptor) +type(CCFloat)(LightProbeInfoProto, 'giScale', lightProbeGIScaleDescriptor) +displayName('GIScale')(LightProbeInfoProto, 'giScale', lightProbeGIScaleDescriptor) +tooltip('i18n:light_probe.giScale')(LightProbeInfoProto, 'giScale', lightProbeGIScaleDescriptor); +editable(LightProbeInfoProto, 'giScale', lightProbeGIScaleDescriptor); + +const lightProbeGISamplesDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'giSamples'); +tooltip('i18n:light_probe.giSamples')(LightProbeInfoProto, 'giSamples', lightProbeGISamplesDescriptor); +editable(LightProbeInfoProto, 'giSamples', lightProbeGISamplesDescriptor); +range([64, 65536, 1])(LightProbeInfoProto, 'giSamples', lightProbeGISamplesDescriptor); +type(CCInteger)(LightProbeInfoProto, 'giSamples', lightProbeGISamplesDescriptor); +displayName('GISamples')(LightProbeInfoProto, 'giSamples', lightProbeGISamplesDescriptor); + +const lightProbeBouncesDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'bounces'); +tooltip('i18n:light_probe.bounces')(LightProbeInfoProto, 'bounces', lightProbeBouncesDescriptor); +editable(LightProbeInfoProto, 'bounces', lightProbeBouncesDescriptor); +range([1, 4, 1])(LightProbeInfoProto, 'bounces', lightProbeBouncesDescriptor); +type(CCInteger)(LightProbeInfoProto, 'bounces', lightProbeBouncesDescriptor); +tooltip('i18n:light_probe.bounces')(LightProbeInfoProto, 'bounces', lightProbeBouncesDescriptor); + +const lightProbeReduceRingingDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'reduceRinging'); +tooltip('i18n:light_probe.reduceRinging')(LightProbeInfoProto, 'reduceRinging', lightProbeReduceRingingDescriptor); +editable(LightProbeInfoProto, 'reduceRinging', lightProbeReduceRingingDescriptor); +range([0.0, 0.05, 0.001])(LightProbeInfoProto, 'reduceRinging', lightProbeReduceRingingDescriptor); +slide(LightProbeInfoProto, 'reduceRinging', lightProbeReduceRingingDescriptor); +type(CCFloat)(LightProbeInfoProto, 'reduceRinging', lightProbeReduceRingingDescriptor); + +const lightProbeShowProbeDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'showProbe'); +tooltip('i18n:light_probe.showProbe')(LightProbeInfoProto, 'showProbe', lightProbeShowProbeDescriptor); +editable(LightProbeInfoProto, 'showProbe', lightProbeShowProbeDescriptor); + +const lightProbeShowWireframeDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'showWireframe'); +tooltip('i18n:light_probe.showWireframe')(LightProbeInfoProto, 'showWireframe', lightProbeShowWireframeDescriptor); +editable(LightProbeInfoProto, 'showWireframe', lightProbeShowWireframeDescriptor); + +const lightProbeShowConvexDescriptor = Object.getOwnPropertyDescriptor(LightProbeInfoProto, 'showConvex'); +tooltip('i18n:light_probe.showConvex')(LightProbeInfoProto, 'showConvex', lightProbeShowConvexDescriptor); +editable(LightProbeInfoProto, 'showConvex', lightProbeShowConvexDescriptor); + +ccclass('cc.LightProbeInfo')(LightProbeInfo); \ No newline at end of file diff --git a/cocos/scene-graph/scene-globals.ts b/cocos/scene-graph/scene-globals.ts index 081edd0e5fe..fa120c4186f 100644 --- a/cocos/scene-graph/scene-globals.ts +++ b/cocos/scene-graph/scene-globals.ts @@ -1,16 +1,17 @@ /* eslint-disable func-names */ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,11 +32,15 @@ import { Shadows, ShadowType, ShadowSize } from '../render-scene/scene/shadows'; import { Skybox, EnvironmentLightingType } from '../render-scene/scene/skybox'; import { Octree } from '../render-scene/scene/octree'; import { Fog, FogType } from '../render-scene/scene/fog'; +import { LightProbesData, LightProbes } from '../gi/light-probe/light-probe'; import { Node } from './node'; import { legacyCC } from '../core/global-exports'; import { Root } from '../root'; import { warnID } from '../core/platform/debug'; import { Material } from '../asset/assets/material'; +import { cclegacy } from '../core'; +import { Scene } from './scene'; +import { NodeEventType } from './node-event'; const _up = new Vec3(0, 1, 0); const _v3 = new Vec3(); @@ -44,7 +49,7 @@ const _col = new Color(); const _qt = new Quat(); // Normalize HDR color -const normalizeHDRColor = (color : Vec4) => { +const normalizeHDRColor = (color: Vec4) => { const intensity = 1.0 / Math.max(Math.max(Math.max(color.x, color.y), color.z), 0.0001); if (intensity < 1.0) { color.x *= intensity; @@ -62,7 +67,7 @@ export class AmbientInfo { * @en The sky color in HDR mode * @zh HDR 模式下的天空光照色 */ - get skyColorHDR () : Readonly { + get skyColorHDR (): Readonly { return this._skyColorHDR; } @@ -70,7 +75,7 @@ export class AmbientInfo { * @en The ground color in HDR mode * @zh HDR 模式下的地面光照色 */ - get groundAlbedoHDR () : Readonly { + get groundAlbedoHDR (): Readonly { return this._groundAlbedoHDR; } @@ -86,7 +91,7 @@ export class AmbientInfo { * @en The sky color in LDR mode * @zh LDR 模式下的天空光照色 */ - get skyColorLDR () : Readonly { + get skyColorLDR (): Readonly { return this._skyColorLDR; } @@ -94,7 +99,7 @@ export class AmbientInfo { * @en The ground color in LDR mode * @zh LDR 模式下的地面光照色 */ - get groundAlbedoLDR () : Readonly { + get groundAlbedoLDR (): Readonly { return this._groundAlbedoLDR; } @@ -414,8 +419,7 @@ export class SkyboxInfo { * @zh 旋转天空盒 */ @type(CCFloat) - @range([0, 360]) - @rangeStep(1) + @range([0, 360, 1]) @slide @tooltip('i18n:skybox.rotationAngle') set rotationAngle (val: number) { @@ -430,7 +434,7 @@ export class SkyboxInfo { * @en The optional diffusion convolution map used in tandem with IBL * @zh 使用的漫反射卷积图 */ - @visible(function (this : SkyboxInfo) { + @visible(function (this: SkyboxInfo) { if (this.useIBL && this.applyDiffuseMap) { return true; } @@ -440,7 +444,7 @@ export class SkyboxInfo { @readOnly @type(TextureCube) @displayOrder(100) - set diffuseMap (val : TextureCube | null) { + set diffuseMap (val: TextureCube | null) { const isHDR = (legacyCC.director.root as Root).pipeline.pipelineSceneData.isHDR; if (isHDR) { this._diffuseMapHDR = val; @@ -465,7 +469,7 @@ export class SkyboxInfo { * @en Convolutional map using environmental reflections * @zh 使用环境反射卷积图 */ - @visible(function (this : SkyboxInfo) { + @visible(function (this: SkyboxInfo) { if (this._resource?.reflectionMap) { return true; } @@ -627,7 +631,7 @@ export class FogInfo { if (this._resource) { this._resource.fogColor = this._fogColor; } } - get fogColor () : Readonly { + get fogColor (): Readonly { return this._fogColor; } @@ -656,8 +660,7 @@ export class FogInfo { return this._type !== FogType.LAYERED && this._type !== FogType.LINEAR; }) @type(CCFloat) - @range([0, 1]) - @rangeStep(0.01) + @range([0, 1, 0.01]) @slide @tooltip('i18n:fog.fogDensity') get fogDensity () { @@ -845,7 +848,7 @@ export class ShadowsInfo { this._shadowColor.set(val); if (this._resource) { this._resource.shadowColor = val; } } - get shadowColor () : Readonly { + get shadowColor (): Readonly { return this._shadowColor; } @@ -859,7 +862,7 @@ export class ShadowsInfo { Vec3.copy(this._normal, val); if (this._resource) { this._resource.normal = val; } } - get planeDirection () : Readonly { + get planeDirection (): Readonly { return this._normal; } @@ -1051,6 +1054,346 @@ export class OctreeInfo { this._resource.initialize(this); } } +legacyCC.OctreeInfo = OctreeInfo; + +export interface ILightProbeNode { + node: Node; + probes: Vec3[] | null; +} + +/** + * @en light probe configuration + * @zh 光照探针配置 + */ +@ccclass('cc.LightProbeInfo') +export class LightProbeInfo { + /** + * @en GI multiplier + * @zh GI乘数 + */ + @editable + @range([0, 100, 1]) + @type(CCFloat) + @tooltip('i18n:light_probe.giScale') + @displayName('GIScale') + set giScale (val: number) { + if (this._giScale === val) return; + this._giScale = val; + if (this._resource) { + this._resource.giScale = val; + } + } + get giScale (): number { + return this._giScale; + } + + /** + * @en GI sample counts + * @zh GI 采样数量 + */ + @editable + @range([64, 65535, 1]) + @type(CCInteger) + @tooltip('i18n:light_probe.giSamples') + @displayName('GISamples') + set giSamples (val: number) { + if (this._giSamples === val) return; + this._giSamples = val; + if (this._resource) { + this._resource.giSamples = val; + } + } + get giSamples (): number { + return this._giSamples; + } + + /** + * @en light bounces + * @zh 光照反弹次数 + */ + @editable + @range([1, 4, 1]) + @type(CCInteger) + @tooltip('i18n:light_probe.bounces') + set bounces (val: number) { + if (this._bounces === val) return; + this._bounces = val; + if (this._resource) { + this._resource.bounces = val; + } + } + get bounces (): number { + return this._bounces; + } + + /** + * @en Reduce ringing of light probe + * @zh 减少光照探针的振铃效果 + */ + @editable + @range([0.0, 0.05, 0.001]) + @slide + @type(CCFloat) + @tooltip('i18n:light_probe.reduceRinging') + set reduceRinging (val: number) { + if (this._reduceRinging === val) return; + this._reduceRinging = val; + if (this._resource) { + this._resource.reduceRinging = val; + } + } + get reduceRinging (): number { + return this._reduceRinging; + } + + /** + * @en Whether to show light probe + * @zh 是否显示光照探针 + */ + @editable + @tooltip('i18n:light_probe.showProbe') + set showProbe (val: boolean) { + if (this._showProbe === val) return; + this._showProbe = val; + if (this._resource) { + this._resource.showProbe = val; + } + } + get showProbe (): boolean { + return this._showProbe; + } + + /** + * @en Whether to show light probe's connection + * @zh 是否显示光照探针连线 + */ + @editable + @tooltip('i18n:light_probe.showWireframe') + set showWireframe (val: boolean) { + if (this._showWireframe === val) return; + this._showWireframe = val; + if (this._resource) { + this._resource.showWireframe = val; + } + } + get showWireframe (): boolean { + return this._showWireframe; + } + + /** + * @en Whether to show light probe's convex + * @zh 是否显示光照探针凸包 + */ + @editable + @tooltip('i18n:light_probe.showConvex') + set showConvex (val: boolean) { + if (this._showConvex === val) return; + this._showConvex = val; + if (this._resource) { + this._resource.showConvex = val; + } + } + get showConvex (): boolean { + return this._showConvex; + } + + /** + * @en light probe's vertex and tetrahedron data + * @zh 光照探针顶点及四面体数据 + */ + set data (val: LightProbesData | null) { + if (this._data === val) return; + this._data = val; + if (this._resource) { + this._resource.data = val; + } + } + get data (): LightProbesData | null { + return this._data; + } + + @serializable + protected _giScale = 1.0; + @serializable + protected _giSamples = 1024; + @serializable + protected _bounces = 2; + @serializable + protected _reduceRinging = 0.0; + @serializable + protected _showProbe = true; + @serializable + protected _showWireframe = true; + @serializable + protected _showConvex = false; + @serializable + protected _data: LightProbesData | null = null; + + protected _nodes: ILightProbeNode[] = []; + protected _scene: Scene | null = null; + protected _resource: LightProbes | null = null; + + public activate (scene: Scene, resource: LightProbes) { + this._scene = scene; + this._resource = resource; + this._resource.initialize(this); + } + + public onProbeBakeFinished () { + this.onProbeBakingChanged(this._scene); + } + + public onProbeBakeCleared () { + this.clearSHCoefficients(); + this.onProbeBakingChanged(this._scene); + } + + private onProbeBakingChanged (node: Node | null) { + if (!node) { + return; + } + + node.emit(NodeEventType.LIGHT_PROBE_BAKING_CHANGED); + + for (let i = 0; i < node.children.length; i++) { + const child = node.children[i]; + this.onProbeBakingChanged(child); + } + } + + public clearSHCoefficients () { + if (!this._data) { + return; + } + + const probes = this._data.probes; + for (let i = 0; i < probes.length; i++) { + probes[i].coefficients.length = 0; + } + + this.clearAllSHUBOs(); + } + + public isUniqueNode (): boolean { + return this._nodes.length === 1; + } + + public addNode (node: Node): boolean { + if (!node) { + return false; + } + + for (let i = 0; i < this._nodes.length; i++) { + if (this._nodes[i].node === node) { + return false; + } + } + + this._nodes.push({ node, probes: null }); + + return true; + } + + public removeNode (node: Node): boolean { + if (!node) { + return false; + } + + const index = this._nodes.findIndex((element) => element.node === node); + if (index === -1) { + return false; + } + + this._nodes.splice(index, 1); + + return true; + } + + public syncData (node: Node, probes: Vec3[]) { + for (let i = 0; i < this._nodes.length; i++) { + if (this._nodes[i].node === node) { + this._nodes[i].probes = probes; + return; + } + } + } + + public update (updateTet = true) { + if (!cclegacy.internal.LightProbesData) { + return; + } + + if (!this._data) { + this._data = new cclegacy.internal.LightProbesData(); + if (this._resource) { + this._resource.data = this._data; + } + } + + const points: Vec3[] = []; + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i].node; + const probes = this._nodes[i].probes; + const worldPosition = node.worldPosition; + + if (!probes) { + continue; + } + + for (let j = 0; j < probes.length; j++) { + const position = new Vec3(0, 0, 0); + Vec3.add(position, probes[j], worldPosition); + points.push(position); + } + } + + const pointCount = points.length; + if (pointCount < 4) { + this.resetAllTetraIndices(); + this._data!.reset(); + return; + } + + this._data!.updateProbes(points); + + if (updateTet) { + this.resetAllTetraIndices(); + this._data!.updateTetrahedrons(); + } + } + + private clearAllSHUBOs () { + if (!this._scene) { + return; + } + + const renderScene = this._scene.renderScene; + if (!renderScene) { + return; + } + + const models = renderScene.models; + for (let i = 0; i < models.length; i++) { + models[i].clearSHUBOs(); + } + } + + private resetAllTetraIndices () { + if (!this._scene) { + return; + } + + const renderScene = this._scene.renderScene; + if (!renderScene) { + return; + } + + const models = renderScene.models; + for (let i = 0; i < models.length; i++) { + models[i].tetrahedronIndex = -1; + } + } +} /** * @en All scene related global parameters, it affects all content in the corresponding scene @@ -1106,11 +1449,35 @@ export class SceneGlobals { @serializable public octree = new OctreeInfo(); + /** + * @en Light probe related configuration + * @zh 光照探针相关配置 + */ + @editable + @serializable + public lightProbeInfo = new LightProbeInfo(); + + /** + * @en bake with stationary main light + * @zh 主光源是否以静止状态烘培 + */ + @editable + @serializable + public bakedWithStationaryMainLight = false; + + /** + * @en bake lightmap with highp mode + * @zh 是否使用高精度模式烘培光照图 + */ + @editable + @serializable + public bakedWithHighpLightmap = false; + /** * @en Activate and initialize the global configurations of the scene, no need to invoke manually. * @zh 启用和初始化场景全局配置,不需要手动调用 */ - public activate () { + public activate (scene: Scene) { const sceneData = (legacyCC.director.root as Root).pipeline.pipelineSceneData; this.skybox.activate(sceneData.skybox); this.ambient.activate(sceneData.ambient); @@ -1118,6 +1485,9 @@ export class SceneGlobals { this.shadows.activate(sceneData.shadows); this.fog.activate(sceneData.fog); this.octree.activate(sceneData.octree); + if (this.lightProbeInfo && sceneData.lightProbes) { + this.lightProbeInfo.activate(scene, sceneData.lightProbes); + } const root = legacyCC.director.root as Root; root.onGlobalPipelineStateChanged(); diff --git a/cocos/scene-graph/scene.jsb.ts b/cocos/scene-graph/scene.jsb.ts index 9ecb43ac4db..1c69e73eca5 100644 --- a/cocos/scene-graph/scene.jsb.ts +++ b/cocos/scene-graph/scene.jsb.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2021 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,9 +24,10 @@ import { ccclass, editable, serializable } from 'cc.decorator'; import { EDITOR, TEST } from "internal:constants"; import { legacyCC } from '../core/global-exports'; import { Node } from './node'; -import { applyTargetOverrides, expandNestedPrefabInstanceNode } from "../core/utils/prefab/utils"; +import { applyTargetOverrides, expandNestedPrefabInstanceNode } from "./prefab/utils"; import { assert } from "../core/platform/debug"; import { updateChildrenForDeserialize } from '../core/utils/jsb-utils'; +import { SceneGlobals } from './scene-globals'; export const Scene = jsb.Scene; export type Scene = jsb.Scene; @@ -84,16 +86,17 @@ sceneProto._ctor = function () { }; sceneProto._onBatchCreated = function (dontSyncChildPrefab: boolean) { - // Don't invoke Node.prototype._onBatchCreated because we refactor Node&BaseNode, BaseNode is empty just for - // instanceof check in ts engine. After ts engine removes BaseNode, we could remove BaseNode.h/.cpp too. if (this._parent) { this._siblingIndex = this._parent.children.indexOf(this); } // - const len = this._children.length; + const children = this._children; + const len = children.length; + let child; for (let i = 0; i < len; ++i) { - this.children[i]._siblingIndex = i; - this._children[i]._onBatchCreated(dontSyncChildPrefab); + child = children[i]; + child._siblingIndex = i; + child._onBatchCreated(dontSyncChildPrefab); } }; @@ -122,8 +125,8 @@ sceneProto._activate = function (active: boolean) { } legacyCC.director._nodeActivator.activateNode(this, active); // The test environment does not currently support the renderer - if (!TEST) { - this._globals.activate(); + if (!TEST || EDITOR) { + this._globals.activate(this); if (this._renderScene) { this._renderScene.activate(); } @@ -134,7 +137,7 @@ sceneProto._activate = function (active: boolean) { const SceneProto = Scene.prototype; const globalsDescriptor = Object.getOwnPropertyDescriptor(SceneProto, 'globals'); editable(SceneProto, 'globals', globalsDescriptor); -editable(SceneProto, 'autoReleaseAssets'); -serializable(SceneProto, 'autoReleaseAssets'); -serializable(SceneProto, '_globals'); +editable(SceneProto, 'autoReleaseAssets', () => false); +serializable(SceneProto, 'autoReleaseAssets', () => false); +serializable(SceneProto, '_globals', () => new SceneGlobals()); ccclass('cc.Scene')(Scene); diff --git a/cocos/scene-graph/scene.ts b/cocos/scene-graph/scene.ts index 5b1a05e4865..57774710357 100644 --- a/cocos/scene-graph/scene.ts +++ b/cocos/scene-graph/scene.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -32,7 +31,7 @@ import { Node } from './node'; import { legacyCC } from '../core/global-exports'; import { Component } from './component'; import { SceneGlobals } from './scene-globals'; -import { applyTargetOverrides, expandNestedPrefabInstanceNode } from '../core/utils/prefab/utils'; +import { applyTargetOverrides, expandNestedPrefabInstanceNode } from './prefab/utils'; /** * @en @@ -187,7 +186,7 @@ export class Scene extends Node { legacyCC.director._nodeActivator.activateNode(this, active); // The test environment does not currently support the renderer if (!TEST) { - this._globals.activate(); + this._globals.activate(this); } } } diff --git a/cocos/scene-graph/utils.jsb.ts b/cocos/scene-graph/utils.jsb.ts index ffe993522cc..3181272e12f 100644 --- a/cocos/scene-graph/utils.jsb.ts +++ b/cocos/scene-graph/utils.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { IMat4Like, Mat4 } from '../core/math'; diff --git a/cocos/core/data/ccon.ts b/cocos/serialization/ccon.ts similarity index 82% rename from cocos/core/data/ccon.ts rename to cocos/serialization/ccon.ts index c0d5cff5c2b..a284dc0a396 100644 --- a/cocos/core/data/ccon.ts +++ b/cocos/serialization/ccon.ts @@ -1,5 +1,28 @@ -import legacyCC from '../../../predefine'; -import { getError } from '../platform/debug'; +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { getError, cclegacy } from '../core'; const VERSION = 1; @@ -230,6 +253,6 @@ export class BufferBuilder { } } -legacyCC.internal.parseCCONJson = parseCCONJson; -legacyCC.internal.decodeCCONBinary = decodeCCONBinary; -legacyCC.internal.CCON = CCON; +cclegacy.internal.parseCCONJson = parseCCONJson; +cclegacy.internal.decodeCCONBinary = decodeCCONBinary; +cclegacy.internal.CCON = CCON; diff --git a/cocos/serialization/deserialize-dynamic-empty.ts b/cocos/serialization/deserialize-dynamic-empty.ts new file mode 100644 index 00000000000..2b82628f855 --- /dev/null +++ b/cocos/serialization/deserialize-dynamic-empty.ts @@ -0,0 +1,32 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + + +export function deserializeDynamic() { + throw new Error(`Should not called`); +} + +export function parseUuidDependenciesDynamic() { + throw new Error(`Should not called`); +} diff --git a/cocos/core/data/deserialize-dynamic.ts b/cocos/serialization/deserialize-dynamic.ts similarity index 92% rename from cocos/core/data/deserialize-dynamic.ts rename to cocos/serialization/deserialize-dynamic.ts index b22c09949cd..54026a7b239 100644 --- a/cocos/core/data/deserialize-dynamic.ts +++ b/cocos/serialization/deserialize-dynamic.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,21 +24,13 @@ */ import { EDITOR, TEST, DEV, DEBUG, JSB, PREVIEW, SUPPORT_JIT } from 'internal:constants'; -import { legacyCC } from '../global-exports'; -import * as js from '../utils/js'; -import * as misc from '../utils/misc'; -import { CCClass, ENUM_TAG, BITMASK_TAG } from './class'; -import * as Attr from './utils/attribute'; -import { MissingScript } from '../../misc/missing-script'; +import { cclegacy, js, misc, CCClass, ENUM_TAG, BITMASK_TAG, sys, error, assertIsTrue, CustomSerializable, DeserializationContext, deserializeTag, SerializationInput } from '../core'; +import { MissingScript } from '../misc/missing-script'; import { Details } from './deserialize'; -import { Platform } from '../../../pal/system-info/enum-type'; -import { sys } from '../platform/sys'; -import { error } from '../platform/debug'; -import { CustomSerializable, DeserializationContext, deserializeTag, SerializationInput } from './custom-serializable'; +import { Platform } from '../../pal/system-info/enum-type'; import type { deserialize, CCClassConstructor } from './deserialize'; import { CCON } from './ccon'; -import { assertIsTrue } from './utils/asserts'; -import { Asset } from '../../asset/assets'; +import { Asset } from '../asset/assets'; function compileObjectTypeJit ( sources: string[], @@ -48,7 +39,7 @@ function compileObjectTypeJit ( propNameLiteralToSet: string, assumeHavePropIfIsValue: boolean, ) { - if (defaultValue instanceof legacyCC.ValueType) { + if (defaultValue instanceof cclegacy.ValueType) { // fast case if (!assumeHavePropIfIsValue) { sources.push('if(prop){'); @@ -84,7 +75,7 @@ export type CompiledDeserializeFn = ( const compileDeserialize = SUPPORT_JIT ? compileDeserializeJIT : compileDeserializeNative; -const DELIMITER = Attr.DELIMETER; +const DELIMITER = CCClass.Attr.DELIMETER; const POSTFIX_TYPE: `${typeof DELIMITER}type` = `${DELIMITER}type`; const POSTFIX_EDITOR_ONLY: `${typeof DELIMITER}editorOnly` = `${DELIMITER}editorOnly`; const POSTFIX_DEFAULT: `${typeof DELIMITER}default` = `${DELIMITER}default`; @@ -102,7 +93,7 @@ type AttrResult = { }; function compileDeserializeJIT (self: _Deserializer, klass: CCClassConstructor): CompiledDeserializeFn { - const attrs: AttrResult = Attr.getClassAttrs(klass); + const attrs: AttrResult = CCClass.Attr.getClassAttrs(klass); const props = klass.__values__; // self, obj, serializedData, klass @@ -148,7 +139,7 @@ function compileDeserializeJIT (self: _Deserializer, klass: CCClassConstructor): CompiledDeserializeFn { const fastMode = misc.BUILTIN_CLASSID_RE.test(js.getClassId(klass)); - const shouldCopyId = js.isChildClassOf(klass, legacyCC.Node) || js.isChildClassOf(klass, legacyCC.Component); + const shouldCopyId = js.isChildClassOf(klass, cclegacy.Node) || js.isChildClassOf(klass, cclegacy.Component); let shouldCopyRawData = false; const simpleProps: string[] = []; @@ -206,7 +197,7 @@ function compileDeserializeNative (_self: _Deserializer, klass: CCClassConstruct const props: string[] = klass.__values__; shouldCopyRawData = props[props.length - 1] === '_$erialized'; - const attrs = Attr.getClassAttrs(klass); + const attrs = CCClass.Attr.getClassAttrs(klass); for (let p = 0; p < props.length; p++) { const propName = props[p]; @@ -220,7 +211,7 @@ function compileDeserializeNative (_self: _Deserializer, klass: CCClassConstruct let isPrimitiveType = false; if (fastMode && (defaultValue !== undefined || userType)) { if (defaultValue === undefined) { - isPrimitiveType = userType instanceof Attr.PrimitiveType || userType === ENUM_TAG || userType === BITMASK_TAG; + isPrimitiveType = userType instanceof CCClass.Attr.PrimitiveType || userType === ENUM_TAG || userType === BITMASK_TAG; } else { const defaultType = typeof defaultValue; isPrimitiveType = defaultType === 'string' @@ -244,7 +235,7 @@ function compileDeserializeNative (_self: _Deserializer, klass: CCClassConstruct if (advancedPropsToRead !== advancedProps) { advancedPropsToRead.push(propNameToRead); } - advancedPropsValueType.push((defaultValue instanceof legacyCC.ValueType) && defaultValue.constructor); + advancedPropsValueType.push((defaultValue instanceof cclegacy.ValueType) && defaultValue.constructor); } } })(); @@ -560,7 +551,7 @@ class _Deserializer { return obj; }; - if (!(EDITOR && legacyCC.js.isChildClassOf(klass, legacyCC.Component))) { + if (!(EDITOR && js.isChildClassOf(klass, cclegacy.Component))) { const obj = createObject(klass); this._deserializeInto(value, obj, klass); return obj; @@ -604,7 +595,7 @@ class _Deserializer { return; } - if (legacyCC.Class._isCCClass(constructor)) { + if (cclegacy.Class._isCCClass(constructor)) { this._deserializeFireClass(object, value, constructor as CCClassConstructor); } else { this._deserializeFastDefinedObject(object, value, constructor); @@ -764,18 +755,18 @@ class _Deserializer { serialized: SerializedGeneralTypedObject, klass: SerializableClassConstructor, ) { - if (klass === legacyCC.Vec2) { + if (klass === cclegacy.Vec2) { type SerializedVec2 = { x?: number; y?: number; }; instance.x = (serialized as SerializedVec2).x || 0; instance.y = (serialized as SerializedVec2).y || 0; return; - } else if (klass === legacyCC.Vec3) { + } else if (klass === cclegacy.Vec3) { type SerializedVec3 = { x?: number; y?: number; z?: number; }; instance.x = (serialized as SerializedVec3).x || 0; instance.y = (serialized as SerializedVec3).y || 0; instance.z = (serialized as SerializedVec3).z || 0; return; - } else if (klass === legacyCC.Color) { + } else if (klass === cclegacy.Color) { type SerializedColor = { r?: number; g?: number; b?: number; a?: number; }; instance.r = (serialized as SerializedColor).r || 0; instance.g = (serialized as SerializedColor).g || 0; @@ -783,14 +774,14 @@ class _Deserializer { const a = (serialized as SerializedColor).a; instance.a = (a === undefined ? 255 : a); return; - } else if (klass === legacyCC.Size) { + } else if (klass === cclegacy.Size) { type SerializedSize = { width?: number; height?: number; }; instance.width = (serialized as SerializedSize).width || 0; instance.height = (serialized as SerializedSize).height || 0; return; } - const attrs = Attr.getClassAttrs(klass); + const attrs = CCClass.Attr.getClassAttrs(klass); // @ts-expect-error 2339 const props: string[] = klass.__values__; if (DEBUG && !props) { @@ -833,7 +824,7 @@ export function deserializeDynamic (data: SerializedData | CCON, details: Detail const createAssetRefs = options.createAssetRefs || sys.platform === Platform.EDITOR_CORE; const customEnv = options.customEnv; const ignoreEditorOnly = options.ignoreEditorOnly; - const reportMissingClass = options.reportMissingClass ?? legacyCC.deserialize.reportMissingClass; + const reportMissingClass = options.reportMissingClass ?? cclegacy.deserialize.reportMissingClass; // var oldJson = JSON.stringify(data, null, 2); @@ -841,9 +832,9 @@ export function deserializeDynamic (data: SerializedData | CCON, details: Detail const deserializer = _Deserializer.pool.get(details, classFinder, reportMissingClass, customEnv, ignoreEditorOnly); - legacyCC.game._isCloning = true; + cclegacy.game._isCloning = true; const res = deserializer.deserialize(data); - legacyCC.game._isCloning = false; + cclegacy.game._isCloning = false; _Deserializer.pool.put(deserializer); if (createAssetRefs) { diff --git a/cocos/serialization/deserialize-symbols.ts b/cocos/serialization/deserialize-symbols.ts new file mode 100644 index 00000000000..82329e14e69 --- /dev/null +++ b/cocos/serialization/deserialize-symbols.ts @@ -0,0 +1,25 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +export const onAfterDeserializedTag = Symbol('[[OnAfterDeserialized]]'); diff --git a/cocos/core/data/deserialize.ts b/cocos/serialization/deserialize.ts similarity index 97% rename from cocos/core/data/deserialize.ts rename to cocos/serialization/deserialize.ts index 8139c99b91a..17416b775ca 100644 --- a/cocos/core/data/deserialize.ts +++ b/cocos/serialization/deserialize.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,19 +23,16 @@ */ import { EDITOR, TEST, PREVIEW, DEBUG, JSB, DEV } from 'internal:constants'; -import { legacyCC } from '../global-exports'; -import { ValueType } from '../value-types'; -import { Vec2, Vec3, Vec4, Color, Size, Rect, Quat, Mat4 } from '../math'; -import { errorID, getError } from '../platform/debug'; -import * as js from '../utils/js'; +import { cclegacy, ValueType, Vec2, Vec3, Vec4, Color, Size, Rect, Quat, Mat4, errorID, getError, js } from '../core'; import { deserializeDynamic, parseUuidDependenciesDynamic } from './deserialize-dynamic'; -import { Asset } from '../../asset/assets/asset'; +import { Asset } from '../asset/assets/asset'; import type { CCON } from './ccon'; -import { reportMissingClass as defaultReportMissingClass } from './report-missing-class'; import type { CompiledDeserializeFn } from './deserialize-dynamic'; +import { reportMissingClass as defaultReportMissingClass } from './report-missing-class'; + const FORCE_COMPILED = false; // TODO: BUILD; /** ************************************************************************** @@ -747,10 +743,10 @@ function assignInstanceRef (data: IFileData, owner: any, key: string, value: Ins function genArrayParser (parser: ParseFunction): ParseFunction { return (data: IFileData, owner: any, key: string, value: T[]) => { - owner[key] = value; for (let i = 0; i < value.length; ++i) { parser(data, value, i as unknown as string, value[i]); } + owner[key] = value; }; } @@ -807,7 +803,6 @@ function parseDict (data: IFileData, owner: any, key: string, value: IDictData) function parseArray (data: IFileData, owner: any, key: string, value: IArrayData) { const array = value[ARRAY_ITEM_VALUES]; - owner[key] = array; for (let i = 0; i < array.length; ++i) { const subValue = array[i]; const type = value[i + 1] as DataTypeID; @@ -816,6 +811,8 @@ function parseArray (data: IFileData, owner: any, key: string, value: IArrayData op(data, array, i, subValue); } } + + owner[key] = array; } // function parseTypedArray (data: IFileData, owner: any, key: string, value: ITypedArrayData) { @@ -1062,10 +1059,10 @@ export function deserialize (data: IFileData | string | CCON | any, details: Det cacheMasks(data); } - legacyCC.game._isCloning = true; + cclegacy.game._isCloning = true; const instances = data[File.Instances]; const rootIndex = parseInstances(data); - legacyCC.game._isCloning = false; + cclegacy.game._isCloning = false; if (data[File.Refs]) { dereference(data[File.Refs] as IRefs, instances, data[File.SharedStrings]); @@ -1198,7 +1195,7 @@ if (EDITOR || TEST) { } if (TEST) { - legacyCC._Test.deserializeCompiled = { + cclegacy._Test.deserializeCompiled = { deserialize, dereference, deserializeCCObject, @@ -1242,4 +1239,4 @@ if (TEST) { }; } -legacyCC.deserialize = deserialize; +cclegacy.deserialize = deserialize; diff --git a/cocos/serialization/index.ts b/cocos/serialization/index.ts new file mode 100644 index 00000000000..5f62357032f --- /dev/null +++ b/cocos/serialization/index.ts @@ -0,0 +1,27 @@ +/* + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +export { deserialize } from './deserialize'; +export { Details } from './deserialize'; +export { instantiate } from './instantiate'; diff --git a/cocos/core/data/instantiate-jit.ts b/cocos/serialization/instantiate-jit.ts similarity index 91% rename from cocos/core/data/instantiate-jit.ts rename to cocos/serialization/instantiate-jit.ts index 7980ca87f09..32956f79f56 100644 --- a/cocos/core/data/instantiate-jit.ts +++ b/cocos/serialization/instantiate-jit.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,16 +26,11 @@ // Some helper methods for compile instantiation code import { TEST } from 'internal:constants'; -import * as js from '../utils/js'; -import { CCClass, isCCClassOrFastDefined } from './class'; -import { CCObject, isCCObject } from './object'; -import * as Attr from './utils/attribute'; -import { flattenCodeArray } from './utils/compiler'; -import { legacyCC } from '../global-exports'; +import { CCClass, isCCClassOrFastDefined, js, CCObject, isCCObject, cclegacy, flattenCodeArray } from '../core'; const Destroyed = CCObject.Flags.Destroyed; const PersistentMask = CCObject.Flags.PersistentMask; -const DEFAULT = `${Attr.DELIMETER}default`; +const DEFAULT = `${CCClass.Attr.DELIMETER}default`; const IDENTIFIER_RE = CCClass.IDENTIFIER_RE; const VAR = 'var '; @@ -304,7 +298,7 @@ class Parser { public enumerateCCClass (codeArray, obj, klass) { const props = klass.__values__; - const attrs = Attr.getClassAttrs(klass); + const attrs = CCClass.Attr.getClassAttrs(klass); for (let p = 0; p < props.length; p++) { const key = props[p]; const val = obj[key]; @@ -312,7 +306,7 @@ class Parser { if (equalsToDefault(defaultValue, val)) { continue; } - if (typeof val === 'object' && val instanceof legacyCC.ValueType) { + if (typeof val === 'object' && val instanceof cclegacy.ValueType) { defaultValue = CCClass.getDefault(defaultValue); if (defaultValue && defaultValue.constructor === val.constructor) { // fast case @@ -444,10 +438,10 @@ class Parser { } public instantiateObj (obj) { - if (obj instanceof legacyCC.ValueType) { + if (obj instanceof cclegacy.ValueType) { return CCClass.getNewValueTypeCode(obj); } - if (obj instanceof legacyCC.Asset) { + if (obj instanceof cclegacy.Asset) { // register to asset list and just return the reference. return this.getObjRef(obj); } @@ -460,17 +454,17 @@ class Parser { const ctor = obj.constructor; if (isCCClassOrFastDefined(ctor)) { if (this.parent) { - if (this.parent instanceof legacyCC.Component) { - if (obj instanceof legacyCC.Node || obj instanceof legacyCC.Component) { + if (this.parent instanceof cclegacy.Component) { + if (obj instanceof cclegacy.Node || obj instanceof cclegacy.Component) { return this.getObjRef(obj); } - } else if (this.parent instanceof legacyCC.Node) { - if (obj instanceof legacyCC.Node) { + } else if (this.parent instanceof cclegacy.Node) { + if (obj instanceof cclegacy.Node) { if (!obj.isChildOf(this.parent)) { // should not clone other nodes if not descendant return this.getObjRef(obj); } - } else if (obj instanceof legacyCC.Component) { + } else if (obj instanceof cclegacy.Component) { if (!obj.node?.isChildOf(this.parent)) { // should not clone other component if not descendant return this.getObjRef(obj); @@ -521,7 +515,7 @@ export function equalsToDefault (def: any, value: any) { && typeof def === 'object' && typeof value === 'object' && def.constructor === value.constructor ) { - if (def instanceof legacyCC.ValueType) { + if (def instanceof cclegacy.ValueType) { if (def.equals(value)) { return true; } @@ -535,13 +529,13 @@ export function equalsToDefault (def: any, value: any) { } export function compile (node) { - const root = (node instanceof legacyCC.Node) && node; + const root = (node instanceof cclegacy.Node) && node; const parser = new Parser(node, root); return parser.result; } if (TEST) { - legacyCC._Test.IntantiateJit = { + cclegacy._Test.IntantiateJit = { equalsToDefault, compile, }; diff --git a/cocos/core/data/instantiate.ts b/cocos/serialization/instantiate.ts similarity index 82% rename from cocos/core/data/instantiate.ts rename to cocos/serialization/instantiate.ts index b595e42fb73..77d01f42a50 100644 --- a/cocos/core/data/instantiate.ts +++ b/cocos/serialization/instantiate.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -25,16 +24,9 @@ */ import { DEV, JSB } from 'internal:constants'; -import { isDomNode } from '../utils/misc'; -import { ValueType } from '../value-types'; -import { CCObject, isCCObject } from './object'; -import { js } from '../utils/js'; -import { getError, warn } from '../platform/debug'; -import { legacyCC } from '../global-exports'; -import { Prefab } from '../../asset/assets/prefab'; -import { Node } from '../../scene-graph/node'; -import { updateChildrenForDeserialize } from '../utils/jsb-utils'; -import { isCCClassOrFastDefined } from './class'; +import { CCObject, isCCObject, js, ValueType, jsbUtils, isCCClassOrFastDefined, getError, warn, misc, cclegacy } from '../core'; +import { Prefab } from '../scene-graph/prefab'; +import { Node } from '../scene-graph/node'; const Destroyed = CCObject.Flags.Destroyed; const PersistentMask = CCObject.Flags.PersistentMask; @@ -92,10 +84,10 @@ export function instantiate (original: any, internalForce?: boolean) { if (!original) { throw new TypeError(getError(6901)); } - if (!legacyCC.isValid(original)) { + if (!cclegacy.isValid(original)) { throw new TypeError(getError(6901)); } - if (original instanceof legacyCC.Component) { + if (original instanceof cclegacy.Component) { warn('Should not instantiate a single cc.Component directly, you must instantiate the entire node.'); } } @@ -105,24 +97,24 @@ export function instantiate (original: any, internalForce?: boolean) { if (isCCObject(original)) { if (original._instantiate) { - legacyCC.game._isCloning = true; + cclegacy.game._isCloning = true; clone = original._instantiate(null, true); - legacyCC.game._isCloning = false; + cclegacy.game._isCloning = false; if (JSB) { - updateChildrenForDeserialize(clone); + jsbUtils.updateChildrenForDeserialize(clone); } // eslint-disable-next-line @typescript-eslint/no-unsafe-return return clone; - } else if (original instanceof legacyCC.Asset) { + } else if (original instanceof cclegacy.Asset) { throw new TypeError(getError(6903)); } } - legacyCC.game._isCloning = true; + cclegacy.game._isCloning = true; clone = doInstantiate(original); - legacyCC.game._isCloning = false; + cclegacy.game._isCloning = false; if (JSB) { - updateChildrenForDeserialize(clone); + jsbUtils.updateChildrenForDeserialize(clone); } // eslint-disable-next-line @typescript-eslint/no-unsafe-return return clone; @@ -145,7 +137,7 @@ function doInstantiate (obj, parent?) { if (Array.isArray(obj)) { throw new TypeError(getError(6904)); } - if (isDomNode && isDomNode(obj)) { + if (misc.isDomNode(obj)) { throw new TypeError(getError(6905)); } } @@ -238,7 +230,7 @@ function instantiateObj (obj, parent) { if (obj instanceof ValueType) { return obj.clone(); } - if (obj instanceof legacyCC.Asset) { + if (obj instanceof cclegacy.Asset) { // 所有资源直接引用,不需要拷贝 // eslint-disable-next-line @typescript-eslint/no-unsafe-return return obj; @@ -280,19 +272,19 @@ function instantiateObj (obj, parent) { const ctor = obj.constructor; if (isCCClassOrFastDefined(ctor)) { if (parent) { - if (parent instanceof legacyCC.Component) { - if (obj instanceof legacyCC.Node || obj instanceof legacyCC.Component) { + if (parent instanceof cclegacy.Component) { + if (obj instanceof cclegacy.Node || obj instanceof cclegacy.Component) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return obj; } - } else if (parent instanceof legacyCC.Node) { - if (obj instanceof legacyCC.Node) { + } else if (parent instanceof cclegacy.Node) { + if (obj instanceof cclegacy.Node) { if (!obj.isChildOf(parent)) { // should not clone other nodes if not descendant // eslint-disable-next-line @typescript-eslint/no-unsafe-return return obj; } - } else if (obj instanceof legacyCC.Component) { + } else if (obj instanceof cclegacy.Component) { if (obj.node && !obj.node.isChildOf(parent)) { // should not clone other component if not descendant // eslint-disable-next-line @typescript-eslint/no-unsafe-return @@ -318,4 +310,4 @@ function instantiateObj (obj, parent) { } instantiate._clone = doInstantiate; -legacyCC.instantiate = instantiate; +cclegacy.instantiate = instantiate; diff --git a/cocos/serialization/report-missing-class.ts b/cocos/serialization/report-missing-class.ts new file mode 100644 index 00000000000..f561104290b --- /dev/null +++ b/cocos/serialization/report-missing-class.ts @@ -0,0 +1,39 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { EDITOR } from 'internal:constants'; +import { errorID } from '../core'; + +/** + * + * @engineInternal + */ +export function reportMissingClass (id: string) { + if (EDITOR && EditorExtends.UuidUtils.isUuid(id)) { + id = EditorExtends.UuidUtils.decompressUuid(id); + errorID(5301, id); + } else { + errorID(5302, id); + } +} diff --git a/cocos/sorting/index.ts b/cocos/sorting/index.ts index 710478baf02..7f27c195217 100644 --- a/cocos/sorting/index.ts +++ b/cocos/sorting/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/sorting/sorting-layers.ts b/cocos/sorting/sorting-layers.ts index b2cac74833d..7a005327940 100644 --- a/cocos/sorting/sorting-layers.ts +++ b/cocos/sorting/sorting-layers.ts @@ -1,15 +1,16 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -131,12 +132,24 @@ export class SortingLayers { } } + /** + * @zh 获取内置 Sorting Layer 数组 + * @en Get Builtin Layer array + */ + public static getBuiltinLayers (): ReadonlyArray { + return [{ id: 0, name: 'default', value: 0 }]; + // Tips:If want ues more builtin layer, builtin layer id should smaller than 0, custom layer id is bigger than 0 + // 'default' layer id is 0 + } + /** * @engineInternal */ public static init () { - const sortingLayers = settings.querySettings(Settings.Category.ENGINE, 'sortingLayers'); - if (!sortingLayers) return; + let sortingLayers = settings.querySettings>(Settings.Category.ENGINE, 'sortingLayers'); + if (!sortingLayers || sortingLayers.length === 0) { + sortingLayers = this.getBuiltinLayers(); + } SortingLayers.resetState(); for (let i = 0; i < sortingLayers.length; i++) { const layer = sortingLayers[i]; diff --git a/cocos/sorting/sorting.ts b/cocos/sorting/sorting.ts index ea11231d282..399f0837618 100644 --- a/cocos/sorting/sorting.ts +++ b/cocos/sorting/sorting.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, disallowMultiple, editable, executeInEditMode, menu, range, serializable, type } from 'cc.decorator'; import { clamp } from '../core/math'; diff --git a/cocos/spine/assembler/index.ts b/cocos/spine/assembler/index.ts index f4e6c4dcc88..afd9d245271 100644 --- a/cocos/spine/assembler/index.ts +++ b/cocos/spine/assembler/index.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + import { IAssemblerManager } from '../../2d/renderer/base'; import { Skeleton } from '../skeleton'; import { simple } from './simple'; diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index e89697e291d..0c4ee90d7e9 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -1,19 +1,18 @@ /* eslint-disable max-len */ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import spine from '../lib/spine-core.js'; import { IAssembler } from '../../2d/renderer/base'; @@ -102,7 +101,6 @@ let _needColor: boolean; let _vertexEffect: spine.VertexEffect | null = null; let _currentMaterial: MaterialInstance | null = null; let _currentTexture: Texture2D | null = null; -const _inv255 = 1.0 / 255.0; function _getSlotMaterial (blendMode: spine.BlendMode) { let src: BlendFactor; @@ -766,6 +764,7 @@ function cacheTraverse (worldMat: Mat4 | null) { let prevDrawIndexOffset = 0; const rd = _renderData!; const vbuf = rd.chunk.vb; + _vUintBuf = new Uint32Array(vbuf.buffer, vbuf.byteOffset, vbuf.length); const ibuf = rd.indices!; for (let i = 0, n = segments.length; i < n; i++) { const segInfo = segments[i]; @@ -812,7 +811,7 @@ function cacheTraverse (worldMat: Mat4 | null) { // Update color if (_needColor) { // handle color - // tip: step of frameColorOffset should fix with vertex attributes, (xyzuvrgbargba--xyuvcc) + // tip: step of frameColorOffset should fix with vertex attributes, (xyzuvrcc--xyuvcc) let frameColorOffset = frameVFOffset / 7 * 6; for (let ii = frameVFOffset, iEnd = frameVFOffset + segVFCount; ii < iEnd; ii += _perVertexSize, frameColorOffset += 6) { if (frameColorOffset >= maxVFOffset) { diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index 076426cd9b1..05535143a52 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Mat4 } from '../core'; import { Skeleton } from './skeleton'; diff --git a/cocos/spine/deprecated.ts b/cocos/spine/deprecated.ts deleted file mode 100644 index 5309ad8a142..00000000000 --- a/cocos/spine/deprecated.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. - - https://www.cocos.com/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import { removeProperty } from '../core/utils/x-deprecated'; -import { Skeleton } from './skeleton'; - -removeProperty(Skeleton.prototype, 'Skeleton', [ -]); diff --git a/cocos/spine/index.jsb.ts b/cocos/spine/index.jsb.ts index bf974f52add..191be172ae3 100644 --- a/cocos/spine/index.jsb.ts +++ b/cocos/spine/index.jsb.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccenum } from '../core'; import { legacyCC } from '../core/global-exports'; @@ -48,8 +47,7 @@ export * from './skeleton'; export * from './skeleton-data'; export * from './assembler'; -declare const window: any; -export const spine = window.spine; +export const spine = globalThis.spine; export const VertexEffectDelegate = spine.VertexEffectDelegate; /** diff --git a/cocos/spine/index.ts b/cocos/spine/index.ts index bd25ed13d3e..b3d27ab1c28 100644 --- a/cocos/spine/index.ts +++ b/cocos/spine/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccenum } from '../core'; import spine from './lib/spine-core'; @@ -49,7 +48,6 @@ export * from './skeleton-data'; export * from './skeleton-texture'; export * from './vertex-effect-delegate'; export * from './assembler'; -export * from './deprecated'; export { spine }; diff --git a/cocos/spine/lib/spine-core.d.ts b/cocos/spine/lib/spine-core.d.ts index 6d7e143adc9..e39bcae1206 100644 --- a/cocos/spine/lib/spine-core.d.ts +++ b/cocos/spine/lib/spine-core.d.ts @@ -1,3 +1,27 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + declare namespace spine { class Animation { name: string; diff --git a/cocos/spine/lib/spine-core.js b/cocos/spine/lib/spine-core.js index b2137750c12..bb3d70d30ce 100644 --- a/cocos/spine/lib/spine-core.js +++ b/cocos/spine/lib/spine-core.js @@ -14,7 +14,10 @@ var __extends = (this && this.__extends) || (function () { }; })(); var spine; +const ccwindow = typeof globalThis.jsb !== 'undefined' ? ( typeof jsb.window !== 'undefined' ? jsb.window : window) : window; (function (spine) { + + var Animation = (function () { function Animation(name, timelines, duration) { if (name == null) @@ -2245,7 +2248,7 @@ var spine; if (error === void 0) { error = null; } path = this.pathPrefix + path; this.toLoad++; - var img = new Image(); + var img = new ccwindow.Image(); img.crossOrigin = "anonymous"; img.onload = function (ev) { var texture = _this.textureLoader(img); @@ -2270,7 +2273,7 @@ var spine; if (error === void 0) { error = null; } path = this.pathPrefix + path; this.toLoad++; - var img = new Image(); + var img = new ccwindow.Image(); img.onload = function (ev) { var texture = _this.textureLoader(img); _this.assets[path] = texture; @@ -2301,7 +2304,7 @@ var spine; try { var atlas = new spine.TextureAtlas(atlasData, function (path) { atlasPages.push(parent + "/" + path); - var image = document.createElement("img"); + var image = new ccwindow.Image(); image.width = 16; image.height = 16; return new spine.FakeTexture(image); @@ -3543,7 +3546,7 @@ var spine; path = this.pathPrefix + path; if (!this.queueAsset(clientId, textureLoader, path)) return; - var img = new Image(); + var img = new ccwindow.Image(); img.src = path; img.crossOrigin = "anonymous"; img.onload = function (ev) { diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index 62d35b1585e..075856fd0dd 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { TrackEntryListeners } from './track-entry-listeners'; import spine from './lib/spine-core.js'; @@ -285,13 +284,13 @@ export class AnimationCache { _finalColor.a = _tempa; if (slot.darkColor == null) { - _darkColor.set(0.0, 0, 0, 1.0); + _darkColor.set(0.0, 0, 0, 0.0); } else { _darkColor.r = slot.darkColor.r * _tempr; _darkColor.g = slot.darkColor.g * _tempg; _darkColor.b = slot.darkColor.b * _tempb; + _darkColor.a = 0; } - _darkColor.a = 0; _finalColor32 = ((_finalColor.a << 24) >>> 0) + (_finalColor.b << 16) + (_finalColor.g << 8) + _finalColor.r; _darkColor32 = ((_darkColor.a << 24) >>> 0) + (_darkColor.b << 16) + (_darkColor.g << 8) + _darkColor.r; @@ -322,7 +321,8 @@ export class AnimationCache { _vertices[v + 5] = _darkColor32; // dark color } } else { - clipper.clipTriangles(_vertices, _vfCount, _indices, _indexCount, + const subIndices = _indices.slice(_indexOffset, _indices.length); + clipper.clipTriangles(_vertices, _vfCount, subIndices, _indexCount, _vertices, _finalColor, _darkColor, true, PerVertexSize, _vfOffset, _vfOffset + 2); const clippedVertices = clipper.clippedVertices; const clippedTriangles = clipper.clippedTriangles; diff --git a/cocos/spine/skeleton-data.ts b/cocos/spine/skeleton-data.ts index 8e8f63a0a65..4b0fd10274d 100644 --- a/cocos/spine/skeleton-data.ts +++ b/cocos/spine/skeleton-data.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { CCString, Enum } from '../core'; diff --git a/cocos/spine/skeleton-system.ts b/cocos/spine/skeleton-system.ts index 1b3822e13cd..35623625bce 100644 --- a/cocos/spine/skeleton-system.ts +++ b/cocos/spine/skeleton-system.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { director } from '../game/director'; import { System } from '../core'; diff --git a/cocos/spine/skeleton-texture.ts b/cocos/spine/skeleton-texture.ts index d6a39ee0b3f..b211781a051 100644 --- a/cocos/spine/skeleton-texture.ts +++ b/cocos/spine/skeleton-texture.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Material, Texture2D } from '../asset/assets'; import { Filter, WrapMode } from '../asset/assets/asset-enum'; diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 4dea8c01ad9..1a9c8dcb8d5 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; import { TrackEntryListeners } from './track-entry-listeners'; @@ -30,13 +29,12 @@ import SkeletonCache, { AnimationCache, AnimationFrame } from './skeleton-cache' import { AttachUtil } from './attach-util'; import { ccclass, executeInEditMode, help, menu } from '../core/data/class-decorator'; import { UIRenderer } from '../2d/framework/ui-renderer'; -import { CCClass, CCObject, Color, Enum, ccenum, logID, warn, RecyclePool } from '../core'; +import { CCClass, CCObject, Color, Enum, ccenum, logID, warn, RecyclePool, js } from '../core'; import { displayName, displayOrder, editable, override, serializable, tooltip, type, visible } from '../core/data/decorators'; import { SkeletonData } from './skeleton-data'; import { VertexEffectDelegate } from './vertex-effect-delegate'; import { Graphics } from '../2d/components/graphics'; import { MaterialInstance } from '../render-scene'; -import { js } from '../core/utils/js'; import { BlendFactor, BlendOp } from '../gfx'; import { legacyCC } from '../core/global-exports'; import { SkeletonSystem } from './skeleton-system'; @@ -162,6 +160,11 @@ export class Skeleton extends UIRenderer { public static AnimationCacheMode = AnimationCacheMode; get drawList () { return this._drawList; } + protected _updateBuiltinMaterial (): Material { + const material = builtinResMgr.get('default-spine-material'); + return material; + } + @override @type(Material) @displayOrder(0) @@ -171,11 +174,18 @@ export class Skeleton extends UIRenderer { } set customMaterial (val) { this._customMaterial = val; - this._cleanMaterialCache(); - this.setMaterial(this._customMaterial, 0); + this.updateMaterial(); this.markForUpdateRenderData(); } + protected updateMaterial () { + let mat; + if (this._customMaterial) mat = this._customMaterial; + else mat = this._updateBuiltinMaterial(); + this.setMaterial(mat, 0); + this._cleanMaterialCache(); + } + /** * @en The skeletal animation is paused? * @zh 该骨骼动画是否暂停。 @@ -1356,11 +1366,10 @@ export class Skeleton extends UIRenderer { } private getMaterialTemplate () : Material { - let material = this.customMaterial; - if (material === null) { - material = builtinResMgr.get('default-spine-material'); - } - return material; + if (this.customMaterial !== null) return this.customMaterial; + if (this.material) return this.material; + this.updateMaterial(); + return this.material!; } public getMaterialForBlendAndTint (src: BlendFactor, dst: BlendFactor, type: SpineMaterialType): MaterialInstance { diff --git a/cocos/spine/track-entry-listeners.ts b/cocos/spine/track-entry-listeners.ts index c2af46bd425..2ae1c55538a 100644 --- a/cocos/spine/track-entry-listeners.ts +++ b/cocos/spine/track-entry-listeners.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import spine from './lib/spine-core.js'; diff --git a/cocos/spine/vertex-effect-delegate.ts b/cocos/spine/vertex-effect-delegate.ts index d642564fa7f..d54addf4b1c 100644 --- a/cocos/spine/vertex-effect-delegate.ts +++ b/cocos/spine/vertex-effect-delegate.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020-2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import spine from './lib/spine-core.js'; diff --git a/cocos/terrain/height-field.ts b/cocos/terrain/height-field.ts index 2f2176afb61..ba5b5488102 100644 --- a/cocos/terrain/height-field.ts +++ b/cocos/terrain/height-field.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { clamp } from '../core/math'; diff --git a/cocos/terrain/index.ts b/cocos/terrain/index.ts index c7e2590f7fb..ca25f8d60c0 100644 --- a/cocos/terrain/index.ts +++ b/cocos/terrain/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './height-field'; export * from './terrain'; diff --git a/cocos/terrain/terrain-asset.ts b/cocos/terrain/terrain-asset.ts index e1d9a4f470b..2a23b841097 100644 --- a/cocos/terrain/terrain-asset.ts +++ b/cocos/terrain/terrain-asset.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; import { Asset, Texture2D } from '../asset/assets'; @@ -47,6 +46,7 @@ export const TERRAIN_DATA_VERSION3 = 0x01010003; export const TERRAIN_DATA_VERSION4 = 0x01010004; export const TERRAIN_DATA_VERSION5 = 0x01010005; export const TERRAIN_DATA_VERSION6 = 0x01010006; +export const TERRAIN_DATA_VERSION7 = 0x01010007; export const TERRAIN_DATA_VERSION_DEFAULT = 0x01010111; class TerrainBuffer { @@ -127,6 +127,22 @@ class TerrainBuffer { this.length += 4 * value.length; } + public writeDouble (value: number) { + this.reserve(this.length + 8); + + this._buffView.setFloat64(this.length, value, true); + this.length += 8; + } + + public writeDoubleArray (value: number[]) { + this.reserve(this.length + 8 * value.length); + + for (let i = 0; i < value.length; ++i) { + this._buffView.setFloat64(this.length + i * 8, value[i], true); + } + this.length += 8 * value.length; + } + public writeString (value: string) { this.reserve(this.length + value.length + 4); @@ -177,6 +193,20 @@ class TerrainBuffer { return value; } + public readDouble () { + const value = this._buffView.getFloat64(this._seekPos, true); + this._seekPos += 8; + return value; + } + + public readDoubleArray (value: number[]) { + for (let i = 0; i < value.length; ++i) { + value[i] = this._buffView.getFloat64(this._seekPos + i * 4, true); + } + this._seekPos += 8 * value.length; + return value; + } + public readString () { const length = this.readInt(); @@ -444,12 +474,19 @@ export class TerrainAsset extends Asset { && this._version !== TERRAIN_DATA_VERSION3 && this._version !== TERRAIN_DATA_VERSION4 && this._version !== TERRAIN_DATA_VERSION5 - && this._version !== TERRAIN_DATA_VERSION6) { + && this._version !== TERRAIN_DATA_VERSION6 + && this._version !== TERRAIN_DATA_VERSION7) { return false; } // geometry info - this.tileSize = stream.readFloat(); + if (this._version >= TERRAIN_DATA_VERSION7) { + this.tileSize = stream.readDouble(); + } else { + this.tileSize = stream.readFloat(); + } + this.tileSize = Math.floor(this.tileSize * 100) / 100.0; + stream.readIntArray(this._blockCount); this.weightMapSize = stream.readInt16(); this.lightMapSize = stream.readInt16(); @@ -493,13 +530,22 @@ export class TerrainAsset extends Asset { for (let i = 0; i < this._layerBinaryInfos.length; ++i) { this._layerBinaryInfos[i] = new TerrainLayerBinaryInfo(); this._layerBinaryInfos[i].slot = stream.readInt(); - this._layerBinaryInfos[i].tileSize = stream.readFloat(); + if (this._version >= TERRAIN_DATA_VERSION7) { + this._layerBinaryInfos[i].tileSize = stream.readDouble(); + } else { + this._layerBinaryInfos[i].tileSize = stream.readFloat(); + } this._layerBinaryInfos[i].detailMapId = stream.readString(); if (this._version >= TERRAIN_DATA_VERSION4) { this._layerBinaryInfos[i].normalMapId = stream.readString(); - this._layerBinaryInfos[i].roughness = stream.readFloat(); - this._layerBinaryInfos[i].metallic = stream.readFloat(); + if (this._version >= TERRAIN_DATA_VERSION7) { + this._layerBinaryInfos[i].roughness = stream.readDouble(); + this._layerBinaryInfos[i].metallic = stream.readDouble(); + } else { + this._layerBinaryInfos[i].roughness = stream.readFloat(); + this._layerBinaryInfos[i].metallic = stream.readFloat(); + } } } } @@ -514,10 +560,10 @@ export class TerrainAsset extends Asset { const stream = new TerrainBuffer(); // version - stream.writeInt32(TERRAIN_DATA_VERSION6); + stream.writeInt32(TERRAIN_DATA_VERSION7); // geometry info - stream.writeFloat(this.tileSize); + stream.writeDouble(this.tileSize); stream.writeIntArray(this._blockCount); stream.writeInt16(this.weightMapSize); stream.writeInt16(this.lightMapSize); @@ -565,11 +611,11 @@ export class TerrainAsset extends Asset { stream.writeInt32(layerBinaryInfos.length); for (let i = 0; i < layerBinaryInfos.length; ++i) { stream.writeInt32(layerBinaryInfos[i].slot); - stream.writeFloat(layerBinaryInfos[i].tileSize); + stream.writeDouble(layerBinaryInfos[i].tileSize); stream.writeString(layerBinaryInfos[i].detailMapId); stream.writeString(layerBinaryInfos[i].normalMapId); - stream.writeFloat(layerBinaryInfos[i].roughness); - stream.writeFloat(layerBinaryInfos[i].metallic); + stream.writeDouble(layerBinaryInfos[i].roughness); + stream.writeDouble(layerBinaryInfos[i].metallic); } return stream.buffer; diff --git a/cocos/terrain/terrain-lod.ts b/cocos/terrain/terrain-lod.ts index 02bab8ca672..45bb73f27f5 100644 --- a/cocos/terrain/terrain-lod.ts +++ b/cocos/terrain/terrain-lod.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export const TERRAIN_LOD_VERTS = 33; export const TERRAIN_LOD_TILES = 32; diff --git a/cocos/terrain/terrain.ts b/cocos/terrain/terrain.ts index 90b42ffe1fc..39f8c7ca311 100644 --- a/cocos/terrain/terrain.ts +++ b/cocos/terrain/terrain.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, disallowMultiple, executeInEditMode, help, visible, type, serializable, editable, disallowAnimation } from 'cc.decorator'; import { builtinResMgr } from '../asset/asset-manager'; @@ -45,10 +44,13 @@ import { TerrainLod, TerrainLodKey, TERRAIN_LOD_LEVELS, TERRAIN_LOD_MAX_DISTANCE import { TerrainAsset, TerrainLayerInfo, TERRAIN_HEIGHT_BASE, TERRAIN_HEIGHT_FACTORY, TERRAIN_BLOCK_TILE_COMPLEXITY, TERRAIN_BLOCK_VERTEX_SIZE, TERRAIN_BLOCK_VERTEX_COMPLEXITY, TERRAIN_MAX_LAYER_COUNT, TERRAIN_HEIGHT_FMIN, TERRAIN_HEIGHT_FMAX, TERRAIN_MAX_BLEND_LAYERS, TERRAIN_DATA_VERSION5 } from './terrain-asset'; -import { CCBoolean, CCFloat } from '../core'; +import { CCFloat } from '../core'; import { PipelineEventType } from '../rendering'; import { Node } from '../scene-graph'; +// the same as dependentAssets: legacy/terrain.effect +const TERRAIN_EFFECT_UUID = '1d08ef62-a503-4ce2-8b9a-46c90873f7d3'; + /** * @en Terrain info * @zh 地形信息 @@ -221,6 +223,11 @@ class TerrainRenderable extends ModelRenderer { legacyCC.director.root.destroyModel(this._model); this._model = null; } + + if (this._meshData != null) { + this._meshData.destroy(); + this._meshData = null; + } } /** @@ -441,6 +448,11 @@ export class TerrainBlock { public update () { this._updateMaterial(false); + if (this._renderable._model && this.lightmap !== this._renderable._lightmap) { + this._renderable._lightmap = this.lightmap; + this._renderable._model?.updateLightingmap(this.lightmap, this.lightmapUVParam); + } + const useNormalMap = this._terrain.useNormalMap; const usePBR = this._terrain.usePBR; @@ -582,11 +594,6 @@ export class TerrainBlock { mtl.setProperty('roughness', roughness); mtl.setProperty('metallic', metallic); } - - if (this._renderable._model && this.lightmap !== this._renderable._lightmap) { - this._renderable._lightmap = this.lightmap; - this._renderable._model?.updateLightingmap(this.lightmap, this.lightmapUVParam); - } } } @@ -804,9 +811,15 @@ export class TerrainBlock { } public _getMaterialDefines (nlayers: number): MacroRecord { + let lightmapMacroValue = 1; /*static*/ + if (this._terrain.node && this._terrain.node.scene) { + if (this._terrain.node.scene.globals.bakedWithStationaryMainLight) { + lightmapMacroValue = 2; /*stationary*/ + } + } return { LAYERS: nlayers + 1, - CC_USE_LIGHTMAP: this.lightmap !== null ? 1 : 0, + CC_USE_LIGHTMAP: this.lightmap !== null ? lightmapMacroValue : 0, USE_NORMALMAP: this._terrain.useNormalMap ? 1 : 0, USE_PBR: this._terrain.usePBR ? 1 : 0, // CC_RECEIVE_SHADOW: this._terrain.receiveShadow ? 1 : 0, @@ -823,6 +836,9 @@ export class TerrainBlock { if (this.lightmap !== null) { this.lightmap.setWrapMode(WrapMode.CLAMP_TO_BORDER, WrapMode.CLAMP_TO_BORDER); } + + this._renderable._lightmap = this.lightmap; + this._renderable._model?.updateLightingmap(this.lightmap, this.lightmapUVParam); } } @@ -1147,22 +1163,18 @@ export class Terrain extends Component { @disallowAnimation protected _lightmapInfos: TerrainBlockLightmapInfo[] = []; - @type(CCBoolean) @serializable @disallowAnimation protected _receiveShadow = false; - @type(CCBoolean) @serializable @disallowAnimation protected _useNormalmap = false; - @type(CCBoolean) @serializable @disallowAnimation protected _usePBR = false; - @type(CCBoolean) @serializable @disallowAnimation protected _lodEnable = false; @@ -1173,7 +1185,7 @@ export class Terrain extends Component { protected _lodBias = 0; // when the terrain undo, __asset is changed by serialize, but the internal block is created by last asset, here saved last asset - protected _buitinAsset : TerrainAsset|null = null; + protected _buitinAsset: TerrainAsset|null = null; protected _tileSize = 1; protected _blockCount: number[] = [1, 1]; protected _weightMapSize = 128; @@ -1628,7 +1640,7 @@ export class Terrain extends Component { public getEffectAsset () { if (this._effectAsset === null) { - return legacyCC.EffectAsset.get('builtin-terrain') as EffectAsset; + return legacyCC.EffectAsset.get(TERRAIN_EFFECT_UUID) as EffectAsset; } return this._effectAsset; @@ -1667,6 +1679,9 @@ export class Terrain extends Component { if (this._sharedIndexBuffer != null) { this._sharedIndexBuffer.destroy(); } + if (this._sharedLodIndexBuffer != null) { + this._sharedLodIndexBuffer.destroy(); + } } public onRestore () { @@ -2211,6 +2226,10 @@ export class Terrain extends Component { return this._sharedIndexBuffer; } + if (this.lodEnable && this._lod === null) { + this._lod = new TerrainLod(); + } + if (this._lod !== null) { this._sharedLodIndexBuffer = this._createSharedIndexBuffer(); return this._sharedLodIndexBuffer; @@ -2463,7 +2482,7 @@ export class Terrain extends Component { return false; } - const layerBuffer:number[] = []; + const layerBuffer: number[] = []; layerBuffer.length = info.blockCount[0] * info.blockCount[1] * TERRAIN_MAX_BLEND_LAYERS; for (let i = 0; i < layerBuffer.length; ++i) { layerBuffer[i] = -1; diff --git a/cocos/tiledmap/assembler/index.ts b/cocos/tiledmap/assembler/index.ts index 38f4cbf1919..04348706612 100644 --- a/cocos/tiledmap/assembler/index.ts +++ b/cocos/tiledmap/assembler/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/tiledmap/assembler/simple.ts b/cocos/tiledmap/assembler/simple.ts index 6ba7d36e5b1..8ba6a9309f9 100644 --- a/cocos/tiledmap/assembler/simple.ts +++ b/cocos/tiledmap/assembler/simple.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/tiledmap/index.ts b/cocos/tiledmap/index.ts index 9c4b8315d3b..97060cf7104 100644 --- a/cocos/tiledmap/index.ts +++ b/cocos/tiledmap/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2018-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './tiled-map'; export * from './tiled-map-asset'; diff --git a/cocos/tiledmap/tiled-layer.ts b/cocos/tiledmap/tiled-layer.ts index fcb4ac15b72..595e577944a 100644 --- a/cocos/tiledmap/tiled-layer.ts +++ b/cocos/tiledmap/tiled-layer.ts @@ -1,20 +1,19 @@ /* eslint-disable default-case */ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass } from 'cc.decorator'; @@ -176,7 +175,7 @@ export class TiledLayer extends UIRenderer { get leftDownToCenterX () { return this._leftDownToCenterX; } get leftDownToCenterY () { return this._leftDownToCenterY; } - private _drawInfoList : RenderDrawInfo[] = []; + private _drawInfoList: RenderDrawInfo[] = []; private requestDrawInfo (idx: number) { if (!this._drawInfoList[idx]) { this._drawInfoList[idx] = new RenderDrawInfo(); @@ -798,16 +797,13 @@ export class TiledLayer extends UIRenderer { _tempRowCol.col++; } - // avoid range out of max rect - if (_tempRowCol.row > this._rightTop.row) _tempRowCol.row = this._rightTop.row; - if (_tempRowCol.col > this._rightTop.col) _tempRowCol.col = this._rightTop.col; - if (_tempRowCol.row !== rightTop.row || _tempRowCol.col !== rightTop.col) { rightTop.row = _tempRowCol.row; rightTop.col = _tempRowCol.col; this._cullingDirty = true; - this.markForUpdateRenderData(); } + + if (this._cullingDirty) this.markForUpdateRenderData(); } // the result may not precise, but it dose't matter, it just uses to be got range @@ -1346,18 +1342,20 @@ export class TiledLayer extends UIRenderer { if (this._layerOrientation === Orientation.HEX) { let width = 0; let height = 0; + const tileWidth = maptw & ~1; + const tileHeight = mapth & ~1; this._odd_even = (this._staggerIndex === StaggerIndex.STAGGERINDEX_ODD) ? 1 : -1; if (this._staggerAxis === StaggerAxis.STAGGERAXIS_X) { - this._diffX1 = (maptw - this._hexSideLength) / 2; + this._diffX1 = (tileWidth - this._hexSideLength) / 2; this._diffY1 = 0; - height = mapth * (layerH + 0.5); - width = (maptw + this._hexSideLength) * Math.floor(layerW / 2) + maptw * (layerW % 2); + width = (this._diffX1 + this._hexSideLength) * layerW + this._diffX1; + height = (tileHeight * layerH) + tileHeight / 2; } else { this._diffX1 = 0; - this._diffY1 = (mapth - this._hexSideLength) / 2; - width = maptw * (layerW + 0.5); - height = (mapth + this._hexSideLength) * Math.floor(layerH / 2) + mapth * (layerH % 2); + this._diffY1 = (tileHeight - this._hexSideLength) / 2; + width = (tileWidth * layerW) + tileWidth / 2; + height = (this._diffY1 + this._hexSideLength) * layerH + this._diffY1; } this.node._uiProps.uiTransformComp!.setContentSize(width, height); } else if (this._layerOrientation === Orientation.ISO) { diff --git a/cocos/tiledmap/tiled-map-asset.ts b/cocos/tiledmap/tiled-map-asset.ts index 75952efab96..02e52d9e04c 100644 --- a/cocos/tiledmap/tiled-map-asset.ts +++ b/cocos/tiledmap/tiled-map-asset.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, type, serializable } from 'cc.decorator'; import { Asset } from '../asset/assets/asset'; diff --git a/cocos/tiledmap/tiled-map.ts b/cocos/tiledmap/tiled-map.ts index deee0188668..908bb0f4224 100644 --- a/cocos/tiledmap/tiled-map.ts +++ b/cocos/tiledmap/tiled-map.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, executeInEditMode, help, menu, requireComponent, type, serializable, editable } from 'cc.decorator'; import { EDITOR, JSB } from 'internal:constants'; diff --git a/cocos/tiledmap/tiled-object-group.ts b/cocos/tiledmap/tiled-object-group.ts index 21210b4e6d9..7b735fd66be 100644 --- a/cocos/tiledmap/tiled-object-group.ts +++ b/cocos/tiledmap/tiled-object-group.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, help, type, requireComponent } from 'cc.decorator'; import { Component } from '../scene-graph/component'; diff --git a/cocos/tiledmap/tiled-tile.ts b/cocos/tiledmap/tiled-tile.ts index 101c9226a11..82cb6e19591 100644 --- a/cocos/tiledmap/tiled-tile.ts +++ b/cocos/tiledmap/tiled-tile.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @en TiledTile can control the specified map tile. diff --git a/cocos/tiledmap/tiled-types.ts b/cocos/tiledmap/tiled-types.ts index 1724c5da9b7..7967ecd725d 100644 --- a/cocos/tiledmap/tiled-types.ts +++ b/cocos/tiledmap/tiled-types.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Color, Rect, Size, Vec2 } from '../core'; import { SpriteFrame } from '../2d/assets'; diff --git a/cocos/tiledmap/tiled-utils.ts b/cocos/tiledmap/tiled-utils.ts index 7aa1a012837..9770636e9c9 100644 --- a/cocos/tiledmap/tiled-utils.ts +++ b/cocos/tiledmap/tiled-utils.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { SpriteFrame } from '../2d/assets'; import { Texture2D } from '../asset/assets'; diff --git a/cocos/tiledmap/tmx-xml-parser.ts b/cocos/tiledmap/tmx-xml-parser.ts index 125b86b452b..38f347abccf 100644 --- a/cocos/tiledmap/tmx-xml-parser.ts +++ b/cocos/tiledmap/tmx-xml-parser.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Label, HorizontalTextAlignment, VerticalTextAlignment } from '../2d/components/label'; import codec from '../../external/compression/ZipUtils.js'; diff --git a/cocos/tween/actions/action-instant.ts b/cocos/tween/actions/action-instant.ts index cc73f8352fe..3847be7b86b 100644 --- a/cocos/tween/actions/action-instant.ts +++ b/cocos/tween/actions/action-instant.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. diff --git a/cocos/tween/actions/action-interval.ts b/cocos/tween/actions/action-interval.ts index 7ff1598cd1b..5ef489ccf74 100644 --- a/cocos/tween/actions/action-interval.ts +++ b/cocos/tween/actions/action-interval.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. diff --git a/cocos/tween/actions/action-manager.ts b/cocos/tween/actions/action-manager.ts index c6cd78ffac6..82eacd281fd 100644 --- a/cocos/tween/actions/action-manager.ts +++ b/cocos/tween/actions/action-manager.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -23,7 +23,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { errorID, logID } from '../../core/platform/debug'; import { Action } from './action'; diff --git a/cocos/tween/actions/action.ts b/cocos/tween/actions/action.ts index ae58ee11fbe..4da6f6c7756 100644 --- a/cocos/tween/actions/action.ts +++ b/cocos/tween/actions/action.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. diff --git a/cocos/tween/export-api.ts b/cocos/tween/export-api.ts index 7fcc90a0e7c..339043ac1f4 100644 --- a/cocos/tween/export-api.ts +++ b/cocos/tween/export-api.ts @@ -1,19 +1,18 @@ /* eslint-disable @typescript-eslint/ban-types */ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @en diff --git a/cocos/tween/index.ts b/cocos/tween/index.ts index f7c4f0fa8c6..fbafe260329 100644 --- a/cocos/tween/index.ts +++ b/cocos/tween/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/tween/set-action.ts b/cocos/tween/set-action.ts index 43d0cc649bc..3adb5c77f39 100644 --- a/cocos/tween/set-action.ts +++ b/cocos/tween/set-action.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ActionInstant } from './actions/action-instant'; diff --git a/cocos/tween/tween-action.ts b/cocos/tween/tween-action.ts index 20b4fe30ef1..5c47092a056 100644 --- a/cocos/tween/tween-action.ts +++ b/cocos/tween/tween-action.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { warnID, warn, easing } from '../core'; import { ActionInterval } from './actions/action-interval'; diff --git a/cocos/tween/tween-system.ts b/cocos/tween/tween-system.ts index f527b3fb7aa..008b6f46cc5 100644 --- a/cocos/tween/tween-system.ts +++ b/cocos/tween/tween-system.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,12 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EDITOR } from 'internal:constants'; -import { System } from '../core'; +import { System, cclegacy } from '../core'; import { ActionManager } from './actions/action-manager'; -import { legacyCC } from '../core/global-exports'; import { Director, director } from '../game'; /** @@ -72,7 +70,7 @@ export class TweenSystem extends System { * @param dt @en The delta time @zh 间隔时间 */ update (dt: number) { - if (!EDITOR || legacyCC.GAME_VIEW || this._executeInEditMode) { + if (!EDITOR || cclegacy.GAME_VIEW || this._executeInEditMode) { this.actionMgr.update(dt); } } diff --git a/cocos/tween/tween.ts b/cocos/tween/tween.ts index 2275b9b29f4..4b808601d8f 100644 --- a/cocos/tween/tween.ts +++ b/cocos/tween/tween.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { TweenSystem } from './tween-system'; import { warn } from '../core'; @@ -167,7 +166,7 @@ export class Tween { /** * @en - * Add an action which calculate with absolute value. + * Add an action which calculates with absolute value. * @zh * 添加一个对属性进行绝对值计算的 action。 * @method to @@ -187,7 +186,7 @@ export class Tween { /** * @en - * Add an action which calculate with relative value. + * Add an action which calculates with relative value. * @zh * 添加一个对属性进行相对值计算的 action。 * @method by @@ -223,7 +222,7 @@ export class Tween { /** * @en - * Add an delay action. + * Add a delay action. * @zh * 添加一个延时 action。 * @method delay @@ -238,7 +237,7 @@ export class Tween { /** * @en - * Add an callback action. + * Add a callback action. * @zh * 添加一个回调 action。 * @method call @@ -254,7 +253,7 @@ export class Tween { /** * @en - * Add an sequence action. + * Add a sequence action. * @zh * 添加一个队列 action。 * @method sequence @@ -268,7 +267,7 @@ export class Tween { /** * @en - * Add an parallel action. + * Add a parallel action. * @zh * 添加一个并行 action。 * @method parallel @@ -282,7 +281,7 @@ export class Tween { /** * @en - * Add an repeat action. + * Add a repeat action. * This action will integrate before actions to a sequence action as their parameters. * @zh * 添加一个重复 action,这个 action 会将前一个动作作为他的参数。 @@ -310,7 +309,7 @@ export class Tween { /** * @en - * Add an repeat forever action. + * Add a repeat forever action. * This action will integrate before actions to a sequence action as their parameters. * @zh * 添加一个永久重复 action,这个 action 会将前一个动作作为他的参数。 @@ -333,7 +332,7 @@ export class Tween { /** * @en - * Add an reverse time action. + * Add a reverse time action. * This action will integrate before actions to a sequence action as their parameters. * @zh * 添加一个倒置时间 action,这个 action 会将前一个动作作为他的参数。 @@ -356,7 +355,7 @@ export class Tween { /** * @en - * Add an hide action, only for node target. + * Add a hide action, only for node target. * @zh * 添加一个隐藏 action,只适用于 target 是节点类型的。 */ @@ -368,7 +367,7 @@ export class Tween { /** * @en - * Add an show action, only for node target. + * Add a show action, only for node target. * @zh * 添加一个显示 action,只适用于 target 是节点类型的。 */ @@ -380,7 +379,7 @@ export class Tween { /** * @en - * Add an removeSelf action, only for node target. + * Add a removeSelf action, only for node target. * @zh * 添加一个移除自己 action,只适用于 target 是节点类型的。 */ diff --git a/cocos/ui/block-input-events.ts b/cocos/ui/block-input-events.ts index 0161bdf31a8..7321e501cd1 100644 --- a/cocos/ui/block-input-events.ts +++ b/cocos/ui/block-input-events.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/button.ts b/cocos/ui/button.ts index 20fab274e6c..b7f9fadf575 100644 --- a/cocos/ui/button.ts +++ b/cocos/ui/button.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -243,6 +242,9 @@ export class Button extends Component { } } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ set _resizeToTarget (value: boolean) { if (value) { this._resizeNodeToTargetNode(); @@ -516,7 +518,15 @@ export class Button extends Component { this._updateState(); } + /** + * @en Enum for transition type. + * @zh 过渡类型。 + */ public static Transition = Transition; + /** + * @en The event types of [[Button]]. All button events are distributed by the owner Node, not the component + * @zh [[Button]] 的事件类型,注意:事件是从该组件所属的 Node 上面派发出来的,需要用 node.on 来监听。 + */ public static EventType = EventType; /** * @en diff --git a/cocos/ui/deprecated-1.2.0.ts b/cocos/ui/deprecated-1.2.0.ts index a99c7de028b..e8c944e0970 100644 --- a/cocos/ui/deprecated-1.2.0.ts +++ b/cocos/ui/deprecated-1.2.0.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { deprecateModuleExportedName } from '../core/utils/x-deprecated'; diff --git a/cocos/ui/deprecated.ts b/cocos/ui/deprecated.ts index f5fbe347bf8..a706f9ae989 100644 --- a/cocos/ui/deprecated.ts +++ b/cocos/ui/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import './deprecated-1.2.0'; import { UICoordinateTracker } from './ui-coordinate-tracker'; @@ -41,10 +40,9 @@ import { PageViewIndicator } from './page-view-indicator'; import { SafeArea } from './safe-area'; import { warnID } from '../core/platform/debug'; import { ccclass } from '../core/data/class-decorator'; -import { js } from '../core/utils/js'; +import { js, removeProperty, markAsWarning } from '../core'; import { legacyCC } from '../core/global-exports'; import { View } from './view'; -import { removeProperty, markAsWarning } from '../core'; /** * @deprecated Since v1.2 diff --git a/cocos/ui/editbox/edit-box-impl-base.ts b/cocos/ui/editbox/edit-box-impl-base.ts index 79cafb19b50..7d75bbd1919 100644 --- a/cocos/ui/editbox/edit-box-impl-base.ts +++ b/cocos/ui/editbox/edit-box-impl-base.ts @@ -2,20 +2,19 @@ Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2012 James Chen Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/editbox/edit-box-impl.ts b/cocos/ui/editbox/edit-box-impl.ts index ff8c68c0ee1..9fcc7b7a958 100644 --- a/cocos/ui/editbox/edit-box-impl.ts +++ b/cocos/ui/editbox/edit-box-impl.ts @@ -2,20 +2,19 @@ Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2012 James Chen Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -30,7 +29,7 @@ import { screenAdapter } from 'pal/screen-adapter'; import { BitmapFont } from '../../2d/assets'; import { director } from '../../game/director'; import { game } from '../../game'; -import { Mat4, Vec3 } from '../../core/math'; +import { Mat4, Vec3, visibleRect, sys } from '../../core'; import { view } from '../view'; import { KeyCode } from '../../input/types'; import { contains } from '../../core/utils/misc'; @@ -38,10 +37,11 @@ import { Label } from '../../2d/components/label'; import { EditBox } from './edit-box'; import { tabIndexUtil } from './tabIndexUtil'; import { InputFlag, InputMode, KeyboardReturnType } from './types'; -import { sys } from '../../core/platform/sys'; -import visibleRect from '../../core/platform/visible-rect'; import { EditBoxImplBase } from './edit-box-impl-base'; import { BrowserType, OS } from '../../../pal/system-info/enum-type'; +import { ccwindow } from '../../core/global-exports'; + +const ccdocument = ccwindow.document; // https://segmentfault.com/q/1010000002914610 const SCROLLY = 40; @@ -171,18 +171,18 @@ export class EditBoxImpl extends EditBoxImplBase { private _createInput () { this._isTextArea = false; - this._edTxt = document.createElement('input'); + this._edTxt = ccdocument.createElement('input'); } private _createTextArea () { this._isTextArea = true; - this._edTxt = document.createElement('textarea'); + this._edTxt = ccdocument.createElement('textarea'); } private _addDomToGameContainer () { if (game.container && this._edTxt) { game.container.appendChild(this._edTxt); - document.head.appendChild(this._placeholderStyleSheet!); + ccdocument.head.appendChild(this._placeholderStyleSheet!); } } @@ -191,9 +191,9 @@ export class EditBoxImpl extends EditBoxImplBase { if (hasElem && this._edTxt) { game.container!.removeChild(this._edTxt); } - const hasStyleSheet = contains(document.head, this._placeholderStyleSheet); + const hasStyleSheet = contains(ccdocument.head, this._placeholderStyleSheet); if (hasStyleSheet) { - document.head.removeChild(this._placeholderStyleSheet!); + ccdocument.head.removeChild(this._placeholderStyleSheet!); } this._edTxt = null; @@ -243,7 +243,7 @@ export class EditBoxImpl extends EditBoxImplBase { private _adjustWindowScroll () { setTimeout(() => { - if (window.scrollY < SCROLLY) { + if (ccwindow.scrollY < SCROLLY) { this._edTxt!.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' }); } }, DELAY_TIME); @@ -252,14 +252,14 @@ export class EditBoxImpl extends EditBoxImplBase { private _scrollBackWindow () { setTimeout(() => { if (sys.browserType === BrowserType.WECHAT && sys.os === OS.IOS) { - if (window.top) { - window.top.scrollTo(0, 0); + if (ccwindow.top) { + ccwindow.top.scrollTo(0, 0); } return; } - window.scrollTo(0, 0); + ccwindow.scrollTo(0, 0); }, DELAY_TIME); } @@ -430,7 +430,7 @@ export class EditBoxImpl extends EditBoxImplBase { elem.style.overflowY = 'scroll'; } - this._placeholderStyleSheet = document.createElement('style'); + this._placeholderStyleSheet = ccdocument.createElement('style'); } private _updateStyleSheet () { diff --git a/cocos/ui/editbox/edit-box.ts b/cocos/ui/editbox/edit-box.ts index a46fd92816f..6ac0ee6fb40 100644 --- a/cocos/ui/editbox/edit-box.ts +++ b/cocos/ui/editbox/edit-box.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -125,10 +124,10 @@ export class EditBox extends Component { /** * @en - * The Label component attached to the node for EditBox's input text label + * The Label component attached to the node for EditBox's input text label. * * @zh - * 输入框输入文本节点上挂载的 Label 组件对象 + * 输入框输入文本节点上挂载的 Label 组件对象。 */ @type(Label) @displayOrder(3) @@ -303,10 +302,29 @@ export class EditBox extends Component { } } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public static _EditBoxImpl = EditBoxImplBase; + /** + * @en Keyboard Return Type. + * @zh 键盘的返回键类型。 + */ public static KeyboardReturnType = KeyboardReturnType; + /** + * @en Defines some flag bits for setting text display and text formatting. + * @zh 定义了一些用于设置文本显示和文本格式化的标志位。 + */ public static InputFlag = InputFlag; + /** + * @en Input Mode. + * @zh 输入模式。 + */ public static InputMode = InputMode; + /** + * @en Keyboard event enumeration. + * @zh 键盘的事件枚举。 + */ public static EventType = EventType; /** * @en @@ -352,7 +370,7 @@ export class EditBox extends Component { * The event handler to be called when return key is pressed. Windows is not supported. * * @zh - * 当用户按下回车按键时的事件回调,目前不支持 windows 平台 + * 当用户按下回车按键时的事件回调,目前不支持 windows 平台。 */ @type([ComponentEventHandler]) @serializable @@ -427,7 +445,7 @@ export class EditBox extends Component { } /** - * @en Let the EditBox get focus + * @en Let the EditBox get focus. * @zh 让当前 EditBox 获得焦点。 */ public setFocus () { @@ -437,8 +455,8 @@ export class EditBox extends Component { } /** - * @en Let the EditBox get focus - * @zh 让当前 EditBox 获得焦点 + * @en Let the EditBox get focus. + * @zh 让当前 EditBox 获得焦点。 */ public focus () { if (this._impl) { @@ -447,8 +465,8 @@ export class EditBox extends Component { } /** - * @en Let the EditBox lose focus - * @zh 让当前 EditBox 失去焦点 + * @en Let the EditBox lose focus. + * @zh 让当前 EditBox 失去焦点。 */ public blur () { if (this._impl) { @@ -478,10 +496,13 @@ export class EditBox extends Component { /** * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @param text content filtered by sensitive words.This parameter may be undefined. + * If relevant platform returns desensitized content, it will be passed to developer by EventType.EDITING_DID_ENDED. + * Now only ByteDance minigame platform */ - public _editBoxEditingDidEnded () { + public _editBoxEditingDidEnded (text?: string) { ComponentEventHandler.emitEvents(this.editingDidEnded, this); - this.node.emit(EventType.EDITING_DID_ENDED, this); + this.node.emit(EventType.EDITING_DID_ENDED, this, text); } /** @@ -496,10 +517,13 @@ export class EditBox extends Component { /** * @deprecated since v3.5.0, this is an engine private interface that will be removed in the future. + * @param text content filtered by sensitive words.This parameter may be undefined. + * If relevant platform returns desensitized content, it will be passed to developer by EventType.EDITING_RETURN. + * Now only ByteDance minigame platform */ - public _editBoxEditingReturn () { + public _editBoxEditingReturn (text?: string) { ComponentEventHandler.emitEvents(this.editingReturn, this); - this.node.emit(EventType.EDITING_RETURN, this); + this.node.emit(EventType.EDITING_RETURN, this, text); } /** @@ -584,10 +608,6 @@ export class EditBox extends Component { this._textLabel = textLabel; } - // update - const transformComp = this._textLabel!.node._uiProps.uiTransformComp; - transformComp!.setAnchorPoint(0, 1); - textLabel.overflow = Label.Overflow.CLAMP; if (this._inputMode === InputMode.ANY) { textLabel.verticalAlign = VerticalTextAlignment.TOP; textLabel.enableWrapText = true; @@ -615,9 +635,6 @@ export class EditBox extends Component { this._placeholderLabel = placeholderLabel; } - // update - const transform = this._placeholderLabel!.node._uiProps.uiTransformComp; - transform!.setAnchorPoint(0, 1); if (this._inputMode === InputMode.ANY) { placeholderLabel.enableWrapText = true; } else { @@ -783,46 +800,6 @@ if (typeof window === 'object' && typeof document === 'object' && !MINIGAME && ! EditBox._EditBoxImpl = EditBoxImpl; } -/** - * @en - * Note: This event is emitted from the node to which the component belongs. - * @zh - * 注意:此事件是从该组件所属的 Node 上面派发出来的,需要用 node.on 来监听。 - * @event editing-did-began - * @param {Event.EventCustom} event - * @param {EditBox} editbox - The EditBox component. - */ - -/** - * @en - * Note: This event is emitted from the node to which the component belongs. - * @zh - * 注意:此事件是从该组件所属的 Node 上面派发出来的,需要用 node.on 来监听。 - * @event editing-did-ended - * @param {Event.EventCustom} event - * @param {EditBox} editbox - The EditBox component. - */ - -/** - * @en - * Note: This event is emitted from the node to which the component belongs. - * @zh - * 注意:此事件是从该组件所属的 Node 上面派发出来的,需要用 node.on 来监听。 - * @event text-changed - * @param {Event.EventCustom} event - * @param {EditBox} editbox - The EditBox component. - */ - -/** - * @en - * Note: This event is emitted from the node to which the component belongs. - * @zh - * 注意:此事件是从该组件所属的 Node 上面派发出来的,需要用 node.on 来监听。 - * @event editing-return - * @param {Event.EventCustom} event - * @param {EditBox} editbox - The EditBox component. - */ - /** * @en if you don't need the EditBox and it isn't in any running Scene, you should * call the destroy method on this component or the associated node explicitly. diff --git a/cocos/ui/editbox/tabIndexUtil.ts b/cocos/ui/editbox/tabIndexUtil.ts index 6b003f05406..525fc542ddd 100644 --- a/cocos/ui/editbox/tabIndexUtil.ts +++ b/cocos/ui/editbox/tabIndexUtil.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { EditBoxImpl } from './edit-box-impl'; diff --git a/cocos/ui/editbox/types.ts b/cocos/ui/editbox/types.ts index a8388920b94..709136b9cf1 100644 --- a/cocos/ui/editbox/types.ts +++ b/cocos/ui/editbox/types.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/index.ts b/cocos/ui/index.ts index 0dc6e8c996c..29028e2e91c 100644 --- a/cocos/ui/index.ts +++ b/cocos/ui/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export { Button } from './button'; export { EditBox } from './editbox/edit-box'; diff --git a/cocos/ui/layout.ts b/cocos/ui/layout.ts index aed2ae20220..b1f0d7978d4 100644 --- a/cocos/ui/layout.ts +++ b/cocos/ui/layout.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -334,7 +333,7 @@ export class Layout extends Component { /** * @en * The start axis for grid layout. If you choose horizontal, then children will layout horizontally at first, - * and then break line on demand. Choose vertical if you want to layout vertically at first . + * and then break line on demand. Choose vertical if you want to layout vertically at first. * * @zh * 起始轴方向类型,可进行水平和垂直布局排列,只有布局类型为 GRID 的时候才有效。 @@ -609,11 +608,35 @@ export class Layout extends Component { this._doLayoutDirty(); } + /** + * @en Layout type. + * @zh 布局类型。 + */ public static Type = Type; + /** + * @en Vertical layout direction. + * @zh 垂直方向布局方式。 + */ public static VerticalDirection = VerticalDirection; + /** + * @en Horizontal layout direction. + * @zh 水平方向布局方式。 + */ public static HorizontalDirection = HorizontalDirection; + /** + * @en Layout Resize Mode. + * @zh 缩放模式。 + */ public static ResizeMode = ResizeMode; + /** + * @en Grid Layout start axis direction. + * @zh 布局轴向,只用于 GRID 布局。 + */ public static AxisDirection = AxisDirection; + /** + * @en Layout constraint. + * @zh 布局约束。 + */ public static Constraint = Constraint; @serializable @@ -661,7 +684,7 @@ export class Layout extends Component { * * @zh * 立即执行更新布局。 - * + * @param force @en force update or not. @zh 是否强制更新。 * @example * ```ts * import { Layout, log } from 'cc'; @@ -673,7 +696,7 @@ export class Layout extends Component { * ``` */ public updateLayout (force = false) { - if ((this._layoutDirty || force) && this.node.children.length > 0) { + if (this._layoutDirty || force) { this._doLayout(); this._layoutDirty = false; } diff --git a/cocos/ui/page-view-indicator.ts b/cocos/ui/page-view-indicator.ts index f8512099be2..6ba3fd1f74f 100644 --- a/cocos/ui/page-view-indicator.ts +++ b/cocos/ui/page-view-indicator.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -41,7 +40,7 @@ const _color = new Color(); /** * @en Enum for PageView Indicator direction. * - * @zh 页面视图指示器的摆放方向 + * @zh 页面视图指示器的摆放方向。 * * @enum PageViewIndicator.Direction */ @@ -49,14 +48,14 @@ enum Direction { /** * @en The horizontal direction. * - * @zh 水平方向 + * @zh 水平方向。 */ HORIZONTAL = 0, /** * @en The vertical direction. * - * @zh 垂直方向 + * @zh 垂直方向。 */ VERTICAL = 1, } @@ -67,7 +66,7 @@ ccenum(Direction); * The Page View Indicator Component. * * @zh - * 页面视图每页标记组件 + * 页面视图每页标记组件。 */ @ccclass('cc.PageViewIndicator') @help('i18n:cc.PageViewIndicator') @@ -79,7 +78,7 @@ export class PageViewIndicator extends Component { * The spriteFrame for each element. * * @zh - * 每个页面标记显示的图片 + * 每个页面标记显示的图片。 */ @type(SpriteFrame) @tooltip('i18n:pageview_indicator.spriteFrame') @@ -99,9 +98,9 @@ export class PageViewIndicator extends Component { * The location direction of PageViewIndicator. * * @zh - * 页面标记摆放方向 + * 页面标记摆放方向。 * - * @param direction @en The direction of the PageViewIndicator @zh 页面标记的摆放方向 + * @param direction @en The direction of the PageViewIndicator. @zh 页面标记的摆放方向。 */ @type(Direction) @tooltip('i18n:pageview_indicator.direction') @@ -121,7 +120,7 @@ export class PageViewIndicator extends Component { * The cellSize for each element. * * @zh - * 每个页面标记的大小 + * 每个页面标记的大小。 */ @type(Size) @tooltip('i18n:pageview_indicator.cell_size') @@ -136,6 +135,11 @@ export class PageViewIndicator extends Component { this._cellSize = value; } + /** + * @en Enum for PageView Indicator direction. + * @zh 页面视图指示器的摆放方向。 + * @enum PageViewIndicator.Direction + */ public static Direction = Direction; /** @@ -143,7 +147,7 @@ export class PageViewIndicator extends Component { * The distance between each element. * * @zh - * 每个页面标记之间的边距 + * 每个页面标记之间的边距。 */ @serializable @tooltip('i18n:pageview_indicator.spacing') @@ -167,9 +171,9 @@ export class PageViewIndicator extends Component { * Set Page View. * * @zh - * 设置页面视图 + * 设置页面视图。 * - * @param target @en The page view which is attached with this indicator @zh 当前标记对象附着到的页面视图对象 + * @param target @en The page view which is attached with this indicator. @zh 当前标记对象附着到的页面视图对象。 */ public setPageView (target: PageView) { this._pageView = target; diff --git a/cocos/ui/page-view.ts b/cocos/ui/page-view.ts index 6046b8cc794..71a281cb4b5 100644 --- a/cocos/ui/page-view.ts +++ b/cocos/ui/page-view.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -44,17 +43,17 @@ const _tempVec2 = new Vec2(); /** * @en Enum for Page View Size Mode. * - * @zh 页面视图每个页面统一的大小类型 + * @zh 页面视图每个页面统一的大小类型。 */ enum SizeMode { /** - * @en Each page is unified in size - * @zh 每个页面统一大小 + * @en Each page is unified in size. + * @zh 每个页面统一大小。 */ Unified = 0, /** - * @en Each page is in free size - * @zh 每个页面大小随意 + * @en Each page is in free size. + * @zh 每个页面大小随意。 */ Free = 1, } @@ -64,17 +63,17 @@ ccenum(SizeMode); /** * @en Enum for Page View Direction. * - * @zh 页面视图滚动类型 + * @zh 页面视图滚动类型。 */ enum Direction { /** * @en Horizontal scroll. - * @zh 水平滚动 + * @zh 水平滚动。 */ Horizontal = 0, /** * @en Vertical scroll. - * @zh 垂直滚动 + * @zh 垂直滚动。 */ Vertical = 1, } @@ -84,7 +83,7 @@ ccenum(Direction); /** * @en Enum for ScrollView event type. * - * @zh 滚动视图事件类型 + * @zh 滚动视图事件类型。 */ enum EventType { PAGE_TURNING = 'page-turning', @@ -95,7 +94,7 @@ enum EventType { * The PageView control. * * @zh - * 页面视图组件 + * 页面视图组件。 */ @ccclass('cc.PageView') @help('i18n:cc.PageView') @@ -107,7 +106,7 @@ export class PageView extends ScrollView { * Specify the size type of each page in PageView. * * @zh - * 页面视图中每个页面大小类型 + * 页面视图中每个页面大小类型。 */ @type(SizeMode) @tooltip('i18n:pageview.sizeMode') @@ -129,7 +128,7 @@ export class PageView extends ScrollView { * The page view direction. * * @zh - * 页面视图滚动类型 + * 页面视图滚动类型。 */ @type(Direction) @tooltip('i18n:pageview.direction') @@ -196,7 +195,7 @@ export class PageView extends ScrollView { * The Page View Indicator. * * @zh - * 页面视图指示器组件 + * 页面视图指示器组件。 */ @type(PageViewIndicator) @tooltip('i18n:pageview.indicator') @@ -219,8 +218,20 @@ export class PageView extends ScrollView { return this._curPageIdx; } + /** + * @en Enum for Page View Size Mode. + * @zh 页面视图每个页面统一的大小类型。 + */ public static SizeMode = SizeMode; + /** + * @en Enum for Page View Direction. + * @zh 页面视图滚动类型。 + */ public static Direction = Direction; + /** + * @en Enum for Page View event. + * @zh 页面视图事件枚举 + */ public static EventType = extendsEnum(EventType, ScrollEventType); /** @@ -238,6 +249,12 @@ export class PageView extends ScrollView { @tooltip('i18n:pageview.autoPageTurningThreshold') public autoPageTurningThreshold = 100; + /** + * @en + * The vertical scrollbar reference. + * @zh + * 垂直滚动的 ScrollBar。 + */ @type(ScrollBar) @override @visible(false) @@ -249,6 +266,12 @@ export class PageView extends ScrollView { super.verticalScrollBar = value; } + /** + * @en + * The horizontal scrollbar reference. + * @zh + * 水平滚动的 ScrollBar。 + */ @type(ScrollBar) @override @visible(false) @@ -260,21 +283,47 @@ export class PageView extends ScrollView { super.horizontalScrollBar = value; } + /** + * @en + * Enable horizontal scroll. + * @zh + * 是否开启水平滚动。 + */ @override @serializable @visible(false) public horizontal = true; + /** + * @en + * Enable vertical scroll. + * @zh + * 是否开启垂直滚动。 + */ @override @serializable @visible(false) public vertical = true; + /** + * @en + * If cancelInnerEvents is set to true, the scroll behavior will cancel touch events on inner content nodes + * It's set to true by default. + * @zh + * 如果这个属性被设置为 true,那么滚动行为会取消子节点上注册的触摸事件,默认被设置为 true。
+ * 注意,子节点上的 touchstart 事件仍然会触发,触点移动距离非常短的情况下 touchmove 和 touchend 也不会受影响。 + */ @override @serializable @visible(false) public cancelInnerEvents = true; + /** + * @en + * ScrollView events callback. + * @zh + * 滚动视图的事件回调函数。 + */ @type([ComponentEventHandler]) @serializable @override @@ -282,8 +331,8 @@ export class PageView extends ScrollView { public scrollEvents: ComponentEventHandler[] = []; /** - * @en The time required to turn over a page. unit: second - * @zh 每个页面翻页时所需时间。单位:秒 + * @en The time required to turn over a page, unit: second. + * @zh 每个页面翻页时所需时间,单位:秒。 */ @serializable @editable @@ -291,8 +340,8 @@ export class PageView extends ScrollView { public pageTurningSpeed = 0.3; /** - * @en PageView events callback - * @zh 滚动视图的事件回调函数 + * @en PageView events callback. + * @zh 滚动视图的事件回调函数。 */ @type([ComponentEventHandler]) @serializable @@ -349,7 +398,7 @@ export class PageView extends ScrollView { * @zh * 返回当前页面索引。 * - * @returns @en Current page index of this page view @zh 当前页面索引。 + * @returns @en Current page index of this page view. @zh 当前页面索引。 */ public getCurrentPageIndex () { return this._curPageIdx; @@ -361,7 +410,7 @@ export class PageView extends ScrollView { * * @zh * 设置当前页面索引。 - * @param index @en The page index to scroll to @zh 需要滚动到的页面索引 + * @param index @en The page index to scroll to. @zh 需要滚动到的页面索引。 */ public setCurrentPageIndex (index: number) { this.scrollToPage(index, 1); @@ -374,7 +423,7 @@ export class PageView extends ScrollView { * @zh * 返回视图中的所有页面。 * - * @returns @en return all pages of this page view @zh 返回当前视图所有页面 + * @returns @en return all pages of this page view. @zh 返回当前视图所有页面。 */ public getPages () { return this._pages; @@ -387,7 +436,7 @@ export class PageView extends ScrollView { * @zh * 在当前页面视图的尾部插入一个新视图。 * - * @param page @en New page to add to this page view @zh 新加入的视图 + * @param page @en New page to add to this page view. @zh 新加入的视图。 */ public addPage (page: Node) { if (!page || this._pages.indexOf(page) !== -1 || !this.content) { @@ -409,8 +458,8 @@ export class PageView extends ScrollView { * @zh * 将页面插入指定位置中。 * - * @param page @en New page to insert to this page view @zh 新插入的视图 - * @param index @en The index of new page to be inserted @zh 新插入视图的索引 + * @param page @en New page to insert to this page view. @zh 新插入的视图。 + * @param index @en The index of new page to be inserted. @zh 新插入视图的索引。 */ public insertPage (page: Node, index: number) { if (index < 0 || !page || this._pages.indexOf(page) !== -1 || !this.content) { @@ -437,7 +486,7 @@ export class PageView extends ScrollView { * @zh * 移除指定页面。 * - * @param page @en The page to be removed @zh 将被移除的页面 + * @param page @en The page to be removed. @zh 将被移除的页面。 */ public removePage (page: Node) { if (!page || !this.content) { return; } @@ -456,7 +505,7 @@ export class PageView extends ScrollView { * @zh * 移除指定下标的页面。 * - * @param index @en The index of the page to be removed @zh 将被移除界面的页面下标 + * @param index @en The index of the page to be removed. @zh 将被移除界面的页面下标。 */ public removePageAtIndex (index: number) { const pageList = this._pages; @@ -492,8 +541,8 @@ export class PageView extends ScrollView { * @zh * 滚动到指定页面 * - * @param idx @en The index of page to be scroll to @zh 希望滚动到的页面下标 - * @param timeInSecond @en How long time to scroll to the page, in seconds @zh 滚动到指定页面所需时间,单位:秒 + * @param idx @en The index of page to be scroll to. @zh 希望滚动到的页面下标。 + * @param timeInSecond @en How long time to scroll to the page, in seconds. @zh 滚动到指定页面所需时间,单位:秒。 */ public scrollToPage (idx: number, timeInSecond = 0.3) { if (idx < 0 || idx >= this._pages.length) { diff --git a/cocos/ui/progress-bar.ts b/cocos/ui/progress-bar.ts index a149919a0d7..02571362986 100644 --- a/cocos/ui/progress-bar.ts +++ b/cocos/ui/progress-bar.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/safe-area.ts b/cocos/ui/safe-area.ts index 0ea07fdea6e..a2f1f61c8da 100644 --- a/cocos/ui/safe-area.ts +++ b/cocos/ui/safe-area.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, help, executionOrder, menu, executeInEditMode, requireComponent } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; @@ -72,8 +71,8 @@ export class SafeArea extends Component { } /** - * @en Adapt to safe area - * @zh 立即适配安全区域 + * @en Adapt to safe area. + * @zh 立即适配安全区域。 * @method updateArea * @example * let safeArea = this.node.addComponent(cc.SafeArea); diff --git a/cocos/ui/scroll-bar.ts b/cocos/ui/scroll-bar.ts index a8d0bbf3c47..d4a4f29aaa5 100644 --- a/cocos/ui/scroll-bar.ts +++ b/cocos/ui/scroll-bar.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -214,6 +213,8 @@ export class ScrollBar extends Component { */ public show () { this._autoHideRemainingTime = this._autoHideTime; + // because scrollbar's onEnable is later than scrollView, its _opacity is be modified in onEnable. we should reset it. + this._opacity = 255; this._setOpacity(this._opacity); } @@ -224,7 +225,7 @@ export class ScrollBar extends Component { * @zh * 重置滚动条位置。 * - * @param outOfBoundary @en Rolling displacement @zh 滚动位移。 + * @param outOfBoundary @en Rolling displacement. @zh 滚动位移。 */ public onScroll (outOfBoundary: Vec2 | Readonly) { if (!this._scrollView) { @@ -290,7 +291,7 @@ export class ScrollBar extends Component { * @zh * 滚动视窗设置。 * - * @param scrollView @en The scroll view which is attached with this scroll bar @zh 当前滚动条附着的滚动视窗 + * @param scrollView @en The scroll view which is attached with this scroll bar. @zh 当前滚动条附着的滚动视窗。 */ public setScrollView (scrollView: ScrollView) { this._scrollView = scrollView; diff --git a/cocos/ui/scroll-view.ts b/cocos/ui/scroll-view.ts index c696b019d3e..0468a27420d 100644 --- a/cocos/ui/scroll-view.ts +++ b/cocos/ui/scroll-view.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,7 +28,7 @@ import { EDITOR } from 'internal:constants'; import { EventHandler as ComponentEventHandler } from '../scene-graph/component-event-handler'; import { UITransform } from '../2d/framework'; import { Event, EventMouse, EventTouch, Touch, SystemEventType, EventHandle, EventGamepad } from '../input/types'; -import { logID } from '../core/platform/debug'; +import { errorID, logID } from '../core/platform/debug'; import { Size, Vec2, Vec3 } from '../core/math'; import { Layout } from './layout'; import { ScrollBar } from './scroll-bar'; @@ -83,7 +82,7 @@ const eventMap = { * Enum for ScrollView event type. * * @zh - * 滚动视图事件类型 + * 滚动视图事件类型。 */ export enum EventType { /** @@ -315,6 +314,9 @@ export class ScrollView extends ViewGroup { @displayOrder(0) @tooltip('i18n:scrollview.horizontal_bar') get horizontalScrollBar () { + if (this._horizontalScrollBar && !this._horizontalScrollBar.isValid) { + errorID(4303, 'horizontal', this.node.name); + } return this._horizontalScrollBar; } @@ -354,6 +356,9 @@ export class ScrollView extends ViewGroup { @displayOrder(1) @tooltip('i18n:scrollview.vertical_bar') get verticalScrollBar () { + if (this._verticalScrollBar && !this._verticalScrollBar.isValid) { + errorID(4303, 'vertical', this.node.name); + } return this._verticalScrollBar; } @@ -397,6 +402,10 @@ export class ScrollView extends ViewGroup { @tooltip('i18n:scrollview.scrollEvents') public scrollEvents: ComponentEventHandler[] = []; + /** + * @en The display view in the scroll view component. + * @zh scroll view 组件中的显示区域。 + */ get view () { const parent = this._content && this._content.parent; if (!parent) { @@ -444,7 +453,6 @@ export class ScrollView extends ViewGroup { protected _deltaPos = new Vec3(); protected _hoverIn: XrhoverType = XrhoverType.NONE; - protected _scrollState = new Vec2(0, 0); /** * @en @@ -485,7 +493,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true * @example * ```ts * // Scroll to the top of the view. @@ -515,7 +523,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to the left of the view. @@ -545,7 +553,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to the right of the view. @@ -575,7 +583,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to the upper left corner of the view. @@ -605,7 +613,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to the top right corner of the view. @@ -635,7 +643,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to the lower left corner of the view. @@ -665,7 +673,7 @@ export class ScrollView extends ViewGroup { * * @param timeInSecond * @en The rolling time(in seconds). If time is up, the content will slide to the bottom border. @zh 滚动时间(s)。 如果超时,内容将立即跳到底部边界。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to the lower right corner of the view. @@ -698,7 +706,7 @@ export class ScrollView extends ViewGroup { * @en After scrolling the view, the position of the view content relative to the view window. @zh 滚动视图后,视图内容(content)相对于视图窗口(viewport)的位置。 * @param timeInSecond * @en Scroll time (s). If it times out, the content immediately jumps to the specified offset. @zh 滚动时间(s)。 如果超时,内容将立即跳到指定偏移量处。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to middle position in 0.1 second in x-axis @@ -733,7 +741,7 @@ export class ScrollView extends ViewGroup { * @zh * 获取滚动视图相对于视图窗口左上角原点的位置。 * - * @return @en Current rolling offset @zh 当前滚动偏移量 + * @return @en Current rolling offset. @zh 当前滚动偏移量。 */ public getScrollOffset () { const topDelta = this._getContentTopBoundary() - this._topBoundary; @@ -749,7 +757,7 @@ export class ScrollView extends ViewGroup { * @zh * 获取滚动视图最大可以滚动的偏移量。 * - * @return @en Maximum scrollable offset @zh 最大可滚动偏移量 + * @return @en Maximum scrollable offset. @zh 最大可滚动偏移量。 */ public getMaxScrollOffset () { if (!this._content || !this.view) { @@ -775,7 +783,7 @@ export class ScrollView extends ViewGroup { * @en Scroll to the destination which is located at the percent interpolation from left border to the right border @zh 滚动到从左到右指定百分比插值的位置 * @param timeInSecond * @en Scroll time (s). If it times out, the content immediately jumps to the specified offset. @zh 滚动时间(s)。 如果超时,内容将立即跳到指定偏移量处。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Scroll to middle position. @@ -804,11 +812,11 @@ export class ScrollView extends ViewGroup { * 视图内容在规定时间内进行垂直方向和水平方向的滚动,并且滚动到指定百分比位置上。 * * @param anchor - * @en Scroll to the destination which is located at the anchor interpolation from left/top border to the right/bottom border - * @zh 滚动到从左/上到右/下指定锚点对应分量插值的位置 + * @en Scroll to the destination which is located at the anchor interpolation from left/top border to the right/bottom border. + * @zh 滚动到从左/上到右/下指定锚点对应分量插值的位置。 * @param timeInSecond * @en Scroll time (s). If it times out, the content immediately jumps to the specified offset. @zh 滚动时间(s)。 如果超时,内容将立即跳到指定偏移量处。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * // Vertical scroll to the bottom of the view. @@ -840,10 +848,10 @@ export class ScrollView extends ViewGroup { * 视图内容在规定时间内滚动到 ScrollView 垂直方向的百分比位置上。 * * @param percent - * @en Scroll to the destination which is located at the percent interpolation from top border to the bottom border @zh 滚动到从上到下指定百分比插值的位置 + * @en Scroll to the destination which is located at the percent interpolation from top border to the bottom border. @zh 滚动到从上到下指定百分比插值的位置。 * @param timeInSecond * @en Scroll time (s). If it times out, the content immediately jumps to the specified offset. @zh 滚动时间(s)。 如果超时,内容将立即跳到指定偏移量处。 - * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true) @zh 滚动加速是否衰减,默认为 true + * @param attenuated @en Whether the rolling acceleration is attenuated(The default is true). @zh 滚动加速是否衰减,默认为 true。 * @example * ```ts * scrollView.scrollToPercentVertical(0.5, 0.1); @@ -882,7 +890,7 @@ export class ScrollView extends ViewGroup { * @zh * 设置当前视图内容的坐标点。 * - * @param position @en Current content position @zh 希望设置内容框体的位置 + * @param position @en Current content position. @zh 希望设置内容框体的位置。 * @deprecated Since 3.1.0, setContentPosition is deprecated, please use scrollToOffset instead. */ public setContentPosition (position: Vec3) { @@ -909,7 +917,7 @@ export class ScrollView extends ViewGroup { * @zh * 获取当前视图内容的坐标点。 * - * @returns - current content position. + * @returns @en current content position. @zh 当前视图内容的坐标点。 * @deprecated Since 3.1.0, getContentPosition is deprecated. */ public getContentPosition () { @@ -932,7 +940,7 @@ export class ScrollView extends ViewGroup { * @zh * 用户是否在拖拽当前滚动视图。 * - * @returns - 是否在拖拽当前滚动视图。 + * @returns @en If or not the current scrolling view is being dragged. @zh 是否在拖拽当前滚动视图。 */ public isScrolling () { return this._scrolling; @@ -945,12 +953,17 @@ export class ScrollView extends ViewGroup { * @zh * 当前滚动视图是否在惯性滚动。 * - * @returns - 滚动视图是否在惯性滚动。 + * @returns @en Whether the scrolling view is scrolling inertially. @zh 滚动视图是否在惯性滚动。 */ public isAutoScrolling () { return this._autoScrolling; } + /** + * @en Get the minimum precision time of the end-of-scroll event. + * @zh 获得滚动结束的事件的最小精度时间。 + * @returns @en Minimum time. @zh 最小时间。 + */ public getScrollEndedEventTiming () { return EPSILON; } @@ -1364,32 +1377,32 @@ export class ScrollView extends ViewGroup { } protected _updateScrollBar (outOfBoundary: Vec2 | Readonly) { - if (this._horizontalScrollBar) { + if (this._horizontalScrollBar && this._horizontalScrollBar.isValid) { this._horizontalScrollBar.onScroll(outOfBoundary); } - if (this.verticalScrollBar) { - this.verticalScrollBar.onScroll(outOfBoundary); + if (this._verticalScrollBar && this._verticalScrollBar.isValid) { + this._verticalScrollBar.onScroll(outOfBoundary); } } protected _onScrollBarTouchBegan () { - if (this._horizontalScrollBar) { + if (this._horizontalScrollBar && this._horizontalScrollBar.isValid) { this._horizontalScrollBar.onTouchBegan(); } - if (this.verticalScrollBar) { - this.verticalScrollBar.onTouchBegan(); + if (this._verticalScrollBar && this._verticalScrollBar.isValid) { + this._verticalScrollBar.onTouchBegan(); } } protected _onScrollBarTouchEnded () { - if (this._horizontalScrollBar) { + if (this._horizontalScrollBar && this._horizontalScrollBar.isValid) { this._horizontalScrollBar.onTouchEnded(); } - if (this.verticalScrollBar) { - this.verticalScrollBar.onTouchEnded(); + if (this._verticalScrollBar && this._verticalScrollBar.isValid) { + this._verticalScrollBar.onTouchEnded(); } } @@ -1422,17 +1435,17 @@ export class ScrollView extends ViewGroup { const outOfBoundary = this._getHowMuchOutOfBoundary(); _tempVec3.set(this._getContentPosition()); _tempVec3.add(outOfBoundary); - this._content.setPosition(_tempVec3); + this._setContentPosition(_tempVec3); this._updateScrollBar(Vec2.ZERO); } } protected _hideScrollBar () { - if (this._horizontalScrollBar) { + if (this._horizontalScrollBar && this._horizontalScrollBar.isValid) { this._horizontalScrollBar.hide(); } - if (this._verticalScrollBar) { + if (this._verticalScrollBar && this._verticalScrollBar.isValid) { this._verticalScrollBar.hide(); } } @@ -1443,19 +1456,19 @@ export class ScrollView extends ViewGroup { } const viewTrans = this.view; const uiTrans = this._content._uiProps.uiTransformComp!; - if (this.verticalScrollBar) { + if (this._verticalScrollBar && this._verticalScrollBar.isValid) { if (uiTrans.height < viewTrans.height) { - this.verticalScrollBar.hide(); + this._verticalScrollBar.hide(); } else { - this.verticalScrollBar.show(); + this._verticalScrollBar.show(); } } - if (this.horizontalScrollBar) { + if (this._horizontalScrollBar && this._horizontalScrollBar.isValid) { if (uiTrans.width < viewTrans.width) { - this.horizontalScrollBar.hide(); + this._horizontalScrollBar.hide(); } else { - this.horizontalScrollBar.show(); + this._horizontalScrollBar.show(); } } } @@ -1839,14 +1852,10 @@ export class ScrollView extends ViewGroup { } else if (event.deviceType === DeviceType.Right) { this._hoverIn = XrhoverType.RIGHT; } - this._autoScrolling = false; - this._dispatchEvent(EventType.SCROLL_BEGAN); } - protected _xrHoverExit () { + protected _xrHoverExit (event: XrUIPressEvent) { this._hoverIn = XrhoverType.NONE; - this._autoScrolling = true; - this._dispatchEvent(EventType.SCROLL_ENDED); } private _dispatchEventHandleInput (event: EventHandle | EventGamepad) { @@ -1857,12 +1866,10 @@ export class ScrollView extends ViewGroup { handleInputDevice = event.handleInputDevice; } let value; - if (!this.enabledInHierarchy) { + if (!this.enabledInHierarchy || this._hoverIn === XrhoverType.NONE) { return; } - if (this._hoverIn === XrhoverType.NONE) { - return; - } else if (this._hoverIn === XrhoverType.LEFT) { + if (this._hoverIn === XrhoverType.LEFT) { value = handleInputDevice.leftStick.getValue(); if (!value.equals(Vec2.ZERO)) { this._xrThumbStickMove(value); @@ -1873,14 +1880,13 @@ export class ScrollView extends ViewGroup { this._xrThumbStickMove(value); } } - - if (!value && this._scrollState.equals(Vec2.ZERO)) { - this._xrThumbStickMoveEnd(); - this._scrollState.set(value); - } } protected _xrThumbStickMove (event: Vec2) { + if (!this.enabledInHierarchy) { + return; + } + const deltaMove = new Vec3(); const wheelPrecision = -62.5; const scrollY = event.y; @@ -1892,12 +1898,12 @@ export class ScrollView extends ViewGroup { this._mouseWheelEventElapsedTime = 0; this._processDeltaMove(deltaMove); - this._dispatchEvent(EventType.SCROLLING); - } - protected _xrThumbStickMoveEnd () { - this._autoScrolling = true; - this._dispatchEvent(EventType.TOUCH_UP); + if (!this._stopMouseWheel) { + this._handlePressLogic(); + this.schedule(this._checkMouseWheel, 1.0 / 60, NaN, 0); + this._stopMouseWheel = true; + } } } diff --git a/cocos/ui/slider.ts b/cocos/ui/slider.ts index c4742170ae3..adb6f9d5426 100644 --- a/cocos/ui/slider.ts +++ b/cocos/ui/slider.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/sub-context-view.ts b/cocos/ui/sub-context-view.ts index ff5e73c021e..f1cb7a51a99 100644 --- a/cocos/ui/sub-context-view.ts +++ b/cocos/ui/sub-context-view.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/toggle-container.ts b/cocos/ui/toggle-container.ts index d320ef98baa..eed1e4eafe1 100644 --- a/cocos/ui/toggle-container.ts +++ b/cocos/ui/toggle-container.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -86,14 +85,14 @@ export class ToggleContainer extends Component { * @zh * 只读属性,返回 toggleContainer 管理的 toggle 数组引用。 */ - get toggleItems () { + get toggleItems (): Toggle[] { return this.node.children.map((item) => { const toggle = item.getComponent('cc.Toggle') as Toggle; if (toggle && toggle.enabled) { return toggle; } return null; - }).filter(Boolean); + }).filter(Boolean) as Toggle[]; } public onEnable () { @@ -122,8 +121,8 @@ export class ToggleContainer extends Component { * @zh * 刷新管理的 toggle 状态。 * - * @param toggle @en The toggle to be updated @zh 需要被更新的切换键 - * @param emitEvent @en Whether events are needed to be emitted @zh 是否需要触发事件 + * @param toggle @en The toggle to be updated. @zh 需要被更新的切换键。 + * @param emitEvent @en Whether events are needed to be emitted. @zh 是否需要触发事件。 */ public notifyToggleCheck (toggle: Toggle, emitEvent = true) { if (!this.enabledInHierarchy) { return; } @@ -145,6 +144,10 @@ export class ToggleContainer extends Component { } } + /** + * @en Ensure toggles state valid. + * @zh 确保 toggles 状态有效。 + */ public ensureValidState () { const toggles = this.toggleItems; if (!this._allowSwitchOff && !this.anyTogglesChecked() && toggles.length !== 0) { diff --git a/cocos/ui/toggle.ts b/cocos/ui/toggle.ts index 952ba3d292d..6a0855fce4e 100644 --- a/cocos/ui/toggle.ts +++ b/cocos/ui/toggle.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -92,6 +91,9 @@ export class Toggle extends Button { this._checkMark = value; } + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ set _resizeToTarget (value: boolean) { if (value) { this._resizeNodeToTargetNode(); @@ -109,6 +111,10 @@ export class Toggle extends Button { return null; } + /** + * @en Enum for toggle event. + * @zh toggle 事件枚举。 + */ public static EventType = extendsEnum(EventType, ButtonEventType); /** @@ -150,7 +156,9 @@ export class Toggle extends Button { } } - // + /** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ public playEffect () { if (this._checkMark) { this._checkMark.node.active = this._isChecked; @@ -164,7 +172,7 @@ export class Toggle extends Button { * @zh * 设置 isChecked 而不调用 checkEvents 回调。 * - * @param value @en Whether this toggle is pressed @zh 是否被按下 + * @param value @en Whether this toggle is pressed. @zh 是否被按下。 */ public setIsCheckedWithoutNotify (value: boolean) { this._set(value, false); @@ -185,13 +193,6 @@ export class Toggle extends Button { } } - public OnDestroy () { - const group = this._toggleContainer; - if (group) { - group.ensureValidState(); - } - } - protected _emitToggleEvents () { this.node.emit(Toggle.EventType.TOGGLE, this); if (this.checkEvents) { @@ -207,8 +208,8 @@ export class Toggle extends Button { * @zh * 注意:此事件是从该组件所属的 Node 上面派发出来的,需要用 node.on 来监听。 * @event toggle - * @param event @en The event when toggle is pressed up or down @zh 切换键被按下或抬起时发送的事件 - * @param toggle @en The Toggle component @zh 切换键组件 + * @param event @en The event when toggle is pressed up or down. @zh 切换键被按下或抬起时发送的事件。 + * @param toggle @en The Toggle component. @zh 切换键组件。 */ legacyCC.Toggle = Toggle; diff --git a/cocos/ui/ui-coordinate-tracker.ts b/cocos/ui/ui-coordinate-tracker.ts index 678d4c24dde..e0ce7d3d9c4 100644 --- a/cocos/ui/ui-coordinate-tracker.ts +++ b/cocos/ui/ui-coordinate-tracker.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/view-group.ts b/cocos/ui/view-group.ts index 4f72c078896..383afce0c60 100644 --- a/cocos/ui/view-group.ts +++ b/cocos/ui/view-group.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/cocos/ui/view.ts b/cocos/ui/view.ts index 3e5faf6a677..f6d04bd6e71 100644 --- a/cocos/ui/view.ts +++ b/cocos/ui/view.ts @@ -2,16 +2,16 @@ Copyright (c) 2008-2010 Ricardo Quesada Copyright (c) 2011-2012 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -30,14 +30,9 @@ import { MINIGAME, JSB, RUNTIME_BASED, EDITOR } from 'internal:constants'; import { screenAdapter } from 'pal/screen-adapter'; import { Eventify } from '../core/event'; import { Rect, Size, Vec2 } from '../core/math'; -import visibleRect from '../core/platform/visible-rect'; -import { legacyCC } from '../core/global-exports'; -import { errorID } from '../core/platform/debug'; -import { screen } from '../core/platform/screen'; -import { macro } from '../core/platform/macro'; +import { visibleRect, cclegacy, errorID, screen, macro, System } from '../core'; import { Orientation } from '../../pal/screen-adapter/enum-type'; import { director } from '../game/director'; -import System from '../core/system'; import { Settings, settings } from '../core/settings'; /** @@ -173,7 +168,7 @@ export class View extends Eventify(System) { * 仅在 Web 平台下有效。 * @param callback - The callback function */ - public setResizeCallback (callback: (()=> void) | null) { + public setResizeCallback (callback: (() => void) | null) { if (typeof callback === 'function' || callback == null) { this._resizeCallback = callback; } @@ -593,7 +588,8 @@ export class View extends Eventify(System) { } private _updateAdaptResult (width: number, height: number, windowId?: number) { - legacyCC.director.root.resize(width, height, windowId === undefined ? 1 : windowId); + // The default invalid windowId is 0 + cclegacy.director.root.resize(width, height, (windowId === undefined || windowId === 0) ? 1 : windowId); // Frame size changed, do resize works const w = this._designResolutionSize.width; const h = this._designResolutionSize.height; @@ -659,11 +655,15 @@ class ContainerStrategy { protected _setupCanvas () { // TODO: need to figure out why set width and height of canvas - const locCanvas = legacyCC.game.canvas; + const locCanvas = cclegacy.game.canvas; if (locCanvas) { const windowSize = screen.windowSize; - locCanvas.width = windowSize.width; - locCanvas.height = windowSize.height; + if (locCanvas.width !== windowSize.width) { + locCanvas.width = windowSize.width; + } + if (locCanvas.height !== windowSize.height) { + locCanvas.height = windowSize.height; + } } } } @@ -1025,13 +1025,13 @@ export class ResolutionPolicy { } } } -legacyCC.ResolutionPolicy = ResolutionPolicy; +cclegacy.ResolutionPolicy = ResolutionPolicy; /** * @en view is the singleton view object. * @zh view 是全局的视图单例对象。 */ -export const view = View.instance = legacyCC.view = new View(); +export const view = View.instance = cclegacy.view = new View(); director.registerSystem('view', view, 0); /** @@ -1040,4 +1040,4 @@ director.registerSystem('view', view, 0); * * @deprecated since v3.3, please use view.getVisibleSize() instead. */ -legacyCC.winSize = localWinSize; +cclegacy.winSize = localWinSize; diff --git a/cocos/ui/widget-manager.ts b/cocos/ui/widget-manager.ts index bf9e7b9994a..ddd6b8aaa1d 100644 --- a/cocos/ui/widget-manager.ts +++ b/cocos/ui/widget-manager.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,15 +26,12 @@ import { EDITOR, DEV } from 'internal:constants'; import { screenAdapter } from 'pal/screen-adapter'; import { Director, director } from '../game/director'; -import { Vec2, Vec3 } from '../core/math'; +import { Vec2, Vec3, visibleRect, js, cclegacy } from '../core'; import { View } from './view'; -import visibleRect from '../core/platform/visible-rect'; import { Scene } from '../scene-graph'; import { Node } from '../scene-graph/node'; -import { array } from '../core/utils/js'; import { AlignFlags, AlignMode, computeInverseTransForTarget, getReadonlyNodeSize, Widget } from './widget'; import { UITransform } from '../2d/framework'; -import { legacyCC } from '../core/global-exports'; const _tempPos = new Vec3(); const _defaultAnchor = new Vec2(); @@ -207,7 +203,7 @@ function visitNode (node: any) { // if ((!EDITOR || widgetManager.animationState!.animatedSinceLastFrame) && widget.alignMode === AlignMode.ONCE) { // widget.enabled = false; // } else { - if (!legacyCC.isValid(node, true)) { + if (!cclegacy.isValid(node, true)) { return; } activeWidgets.push(widget); @@ -265,10 +261,15 @@ function updateAlignment (node: Node) { } } -export const widgetManager = legacyCC._widgetManager = { +/** + * @en widget Manager, use to align widget + * @zh widget 管理器,用于对齐操作 + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ +export const widgetManager = cclegacy._widgetManager = { isAligning: false, _nodesOrderDirty: false, - _activeWidgetsIterator: new array.MutableForwardIterator(activeWidgets), + _activeWidgetsIterator: new js.array.MutableForwardIterator(activeWidgets), // hack animationState: EDITOR ? { previewing: false, @@ -284,7 +285,7 @@ export const widgetManager = legacyCC._widgetManager = { if (!EDITOR) { const thisOnResized = this.onResized.bind(this); View.instance.on('canvas-resize', thisOnResized); - screenAdapter.on('orientation-change', thisOnResized); + screenAdapter.on('window-resize', thisOnResized); } }, add (widget: Widget) { diff --git a/cocos/ui/widget.ts b/cocos/ui/widget.ts index cfb0a4b700f..e101f31a6ad 100644 --- a/cocos/ui/widget.ts +++ b/cocos/ui/widget.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -28,15 +27,11 @@ import { ccclass, help, executeInEditMode, executionOrder, menu, requireComponen import { EDITOR, DEV } from 'internal:constants'; import { Component } from '../scene-graph/component'; import { UITransform } from '../2d/framework/ui-transform'; -import { Size, Vec2, Vec3 } from '../core/math'; -import { errorID } from '../core/platform/debug'; +import { Size, Vec2, Vec3, visibleRect, ccenum, errorID, cclegacy } from '../core'; import { View } from './view'; -import visibleRect from '../core/platform/visible-rect'; import { Scene } from '../scene-graph'; import { Node } from '../scene-graph/node'; -import { ccenum } from '../core/value-types/enum'; import { TransformBit } from '../scene-graph/node-enum'; -import { legacyCC } from '../core/global-exports'; import { NodeEventType } from '../scene-graph/node-event'; const _tempScale = new Vec2(); @@ -240,7 +235,7 @@ export class Widget extends Component { this._registerTargetEvents(); if (EDITOR /* && !cc.engine._isPlaying */ && this.node.parent) { // adjust the offsets to keep the size and position unchanged after target changed - legacyCC._widgetManager.updateOffsetsToStayPut(this); + cclegacy._widgetManager.updateOffsetsToStayPut(this); } this._validateTargetInDEV(); @@ -704,7 +699,9 @@ export class Widget extends Component { /** * @zh - * 对齐开关,由 AlignFlags 组成 + * 对齐标志位。 + * @en + * Align flags. */ @editable get alignFlags () { @@ -796,7 +793,7 @@ export class Widget extends Component { * ``` */ public updateAlignment () { - legacyCC._widgetManager.updateAlignment(this.node); + cclegacy._widgetManager.updateAlignment(this.node); } /** @@ -824,14 +821,14 @@ export class Widget extends Component { public onEnable () { this.node.getPosition(this._lastPos); this._lastSize.set(this.node._uiProps.uiTransformComp!.contentSize); - legacyCC._widgetManager.add(this); + cclegacy._widgetManager.add(this); this._hadAlignOnce = false; this._registerEvent(); this._registerTargetEvents(); } public onDisable () { - legacyCC._widgetManager.remove(this); + cclegacy._widgetManager.remove(this); this._unregisterEvent(); this._unregisterTargetEvents(); } @@ -870,7 +867,7 @@ export class Widget extends Component { } protected _registerEvent () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { this.node.on(NodeEventType.TRANSFORM_CHANGED, this._adjustWidgetToAllowMovingInEditor, this); this.node.on(NodeEventType.SIZE_CHANGED, this._adjustWidgetToAllowResizingInEditor, this); } else { @@ -882,7 +879,7 @@ export class Widget extends Component { } protected _unregisterEvent () { - if (EDITOR && !legacyCC.GAME_VIEW) { + if (EDITOR && !cclegacy.GAME_VIEW) { this.node.off(NodeEventType.TRANSFORM_CHANGED, this._adjustWidgetToAllowMovingInEditor, this); this.node.off(NodeEventType.SIZE_CHANGED, this._adjustWidgetToAllowResizingInEditor, this); } else { @@ -951,7 +948,7 @@ export class Widget extends Component { } protected _setDirtyByMode () { - if (this.alignMode === AlignMode.ALWAYS || (EDITOR && !legacyCC.GAME_VIEW)) { + if (this.alignMode === AlignMode.ALWAYS || (EDITOR && !cclegacy.GAME_VIEW)) { this._recursiveDirty(); } } @@ -992,7 +989,7 @@ export class Widget extends Component { if (EDITOR && this.node.parent) { // adjust the offsets to keep the size and position unchanged after alignment changed - legacyCC._widgetManager.updateOffsetsToStayPut(this, flag); + cclegacy._widgetManager.updateOffsetsToStayPut(this, flag); } } else { if (isHorizontal) { @@ -1018,12 +1015,15 @@ export class Widget extends Component { } } +/** + * @deprecated since v3.7.0, this is an engine private interface that will be removed in the future. + */ export declare namespace Widget { export type AlignMode = EnumAlias; } // cc.Widget = module.exports = Widget; -legacyCC.internal.computeInverseTransForTarget = computeInverseTransForTarget; -legacyCC.internal.getReadonlyNodeSize = getReadonlyNodeSize; +cclegacy.internal.computeInverseTransForTarget = computeInverseTransForTarget; +cclegacy.internal.getReadonlyNodeSize = getReadonlyNodeSize; -legacyCC.Widget = Widget; +cclegacy.Widget = Widget; diff --git a/cocos/video/assets/video-clip.ts b/cocos/video/assets/video-clip.ts index 677b325fe43..74f88eb9266 100644 --- a/cocos/video/assets/video-clip.ts +++ b/cocos/video/assets/video-clip.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, serializable } from 'cc.decorator'; import { Asset } from '../../asset/assets'; diff --git a/cocos/video/deprecated.ts b/cocos/video/deprecated.ts index 9e58ea66f1c..0adb22686a7 100644 --- a/cocos/video/deprecated.ts +++ b/cocos/video/deprecated.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { replaceProperty } from '../core/utils/x-deprecated'; import { VideoPlayer } from './video-player'; diff --git a/cocos/video/index.ts b/cocos/video/index.ts index e3154fd7808..84f2f61f309 100644 --- a/cocos/video/index.ts +++ b/cocos/video/index.ts @@ -1,26 +1,25 @@ /* -Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. +Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license -to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: -The software or tools in this License Agreement are licensed, not sold. -Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. */ import './video-downloader'; diff --git a/cocos/video/video-downloader.ts b/cocos/video/video-downloader.ts index 8201ff48a56..06c5b43e5e7 100644 --- a/cocos/video/video-downloader.ts +++ b/cocos/video/video-downloader.ts @@ -1,19 +1,18 @@ /* Copyright (c) 2013-2016 Chukong Technologies Inc. - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -22,18 +21,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import downloader from '../asset/asset-manager/downloader'; import factory from '../asset/asset-manager/factory'; -import { CompleteCallback, IDownloadParseOptions } from '../asset/asset-manager/shared'; import { log } from '../core/platform/debug'; import { VideoClip } from './assets/video-clip'; +import { ccwindow } from '../core/global-exports'; + +const ccdocument = ccwindow.document; // eslint-disable-next-line consistent-return -export function downloadVideo (url: string, options: IDownloadParseOptions, onComplete: CompleteCallback) { - const video = document.createElement('video'); - const source = document.createElement('source'); +export function downloadVideo (url: string, options: Record, onComplete: (err: Error | null, data?: any | null) => void) { + const video = ccdocument.createElement('video'); + const source = ccdocument.createElement('source'); video.appendChild(source); const req = new XMLHttpRequest(); @@ -55,7 +56,7 @@ export function downloadVideo (url: string, options: IDownloadParseOptions, onCo req.send(); } -function createVideoClip (id: string, data: HTMLVideoElement, options: IDownloadParseOptions, onComplete: CompleteCallback) { +function createVideoClip (id: string, data: HTMLVideoElement, options: Record, onComplete: (err: Error | null, data?: VideoClip | null) => void) { const out = new VideoClip(); out._nativeUrl = id; out._nativeAsset = data; diff --git a/cocos/video/video-player-enums.ts b/cocos/video/video-player-enums.ts index c4e10653279..21c5fc0ad57 100644 --- a/cocos/video/video-player-enums.ts +++ b/cocos/video/video-player-enums.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,11 +20,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /** * @en Enum for video resource type. - * @zh 视频来源 + * @zh 视频资源类型枚举。 */ import { Enum } from '../core/value-types'; @@ -34,71 +33,91 @@ export const ResourceType = Enum({ * @en * The remote resource type. * @zh - * 远程视频 + * 远程视频。 */ REMOTE: 0, /** * @en * The local resource type. * @zh - * 本地视频 + * 本地视频。 */ LOCAL: 1, }); export enum EventType { /** - * @en None - * @zh 无 + * @en None. + * @zh 无。 */ NONE = 'none', /** * @en The video is playing. - * @zh 视频播放中 + * @zh 视频播放中。 */ PLAYING = 'playing', /** - * @en Video paused - * @zh 视频暂停中 + * @en Video paused. + * @zh 视频暂停中。 */ PAUSED = 'paused', /** - * @en Video stopped - * @zh 视频停止中 + * @en Video stopped. + * @zh 视频停止中。 */ STOPPED = 'stopped', /** - * @en End of video - * @zh 视频播放完毕 + * @en Video playback complete. + * @zh 视频播放完毕。 */ COMPLETED = 'completed', /** - * @en Video metadata loading complete - * @zh 视频元数据加载完毕 + * @en Video metadata loading complete. + * @zh 视频元数据加载完毕。 */ META_LOADED = 'meta-loaded', /** - * @en The video is ready to play when loaded - * @zh 视频加载完毕可播放 + * @en The video is ready to play when loaded. + * @zh 视频加载完毕可播放。 */ READY_TO_PLAY = 'ready-to-play', /** - * @en Video Trigger Error - * @zh 处理视频时触发的错误 + * @en Errors triggered while processing video + * @zh 处理视频时触发的错误。 */ ERROR = 'error', /** - * @en Video clicked - * @zh 视频被点击 + * @en Video is clicked. + * @zh 视频被点击。 */ CLICKED = 'clicked', } export enum READY_STATE { - HAVE_NOTHING, // 没有关于音频/视频是否就绪的信息 - HAVE_METADATA, // 关于音频/视频就绪的元数据 - HAVE_CURRENT_DATA, // 关于当前播放位置的数据是可用的,但没有足够的数据来播放下一帧/毫秒 - HAVE_FUTURE_DATA, // 当前及至少下一帧的数据是可用的 - HAVE_ENOUGH_DATA // 可用数据足以开始播放 + /** + * @en No information about whether audio/video is ready. + * @zh 没有关于音频/视频是否就绪的信息。 + */ + HAVE_NOTHING, + /** + * @en Metadata about audio/video ready. + * @zh 关于音频/视频就绪的元数据。 + */ + HAVE_METADATA, + /** + * @en Data is available for the current playback position, but not enough data to play the next frame/ms. + * @zh 当前播放位置的数据可用,但没有足够的数据来播放下一帧/毫秒。 + */ + HAVE_CURRENT_DATA, + /** + * @en Data for the current and at least the next frame is available. + * @zh 当前及至少下一帧的数据是可用的。 + */ + HAVE_FUTURE_DATA, + /** + * @en Available data is enough to start playback. + * @zh 可用数据足以开始播放。 + */ + HAVE_ENOUGH_DATA } diff --git a/cocos/video/video-player-impl-manager.ts b/cocos/video/video-player-impl-manager.ts index 4a1e653d860..4b709dd5df6 100644 --- a/cocos/video/video-player-impl-manager.ts +++ b/cocos/video/video-player-impl-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { legacyCC } from '../core/global-exports'; import { VideoPlayer } from './video-player'; diff --git a/cocos/video/video-player-impl-web.ts b/cocos/video/video-player-impl-web.ts index dce96e86710..9cb65e21abf 100644 --- a/cocos/video/video-player-impl-web.ts +++ b/cocos/video/video-player-impl-web.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,18 +20,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { screenAdapter } from 'pal/screen-adapter'; -import { mat4 } from '../core/math'; +import { mat4, visibleRect } from '../core'; import { sys, screen, warn } from '../core/platform'; import { game } from '../game'; import { contains } from '../core/utils/misc'; import { EventType, READY_STATE } from './video-player-enums'; import { VideoPlayerImpl } from './video-player-impl'; import { ClearFlagBit } from '../gfx'; -import visibleRect from '../core/platform/visible-rect'; import { BrowserType, OS } from '../../pal/system-info/enum-type'; +import { ccwindow } from '../core/global-exports'; + +const ccdocument = ccwindow.document; const MIN_ZINDEX = -(2 ** 15); @@ -49,7 +50,7 @@ export class VideoPlayerImplWeb extends VideoPlayerImpl { super(component); } - protected addListener (type: string, handler: (e: Event)=> void) { + protected addListener (type: string, handler: (e: Event) => void) { if (!this._video) { return; } @@ -70,7 +71,7 @@ export class VideoPlayerImplWeb extends VideoPlayerImpl { if (this.video) { const promise = this.video.play(); // the play API can only be initiated by user gesture. - if (window.Promise && promise instanceof Promise) { + if (ccwindow.Promise && promise instanceof Promise) { // eslint-disable-next-line @typescript-eslint/no-floating-promises promise.catch((error) => { // Auto-play was prevented @@ -251,7 +252,7 @@ export class VideoPlayerImplWeb extends VideoPlayerImpl { } public createVideoPlayer (url: string) { - const video = this._video = document.createElement('video'); + const video = this._video = ccdocument.createElement('video'); video.className = 'cocosVideo'; video.style.visibility = 'hidden'; video.style.position = 'absolute'; @@ -267,7 +268,7 @@ export class VideoPlayerImplWeb extends VideoPlayerImpl { video.setAttribute('playsinline', ''); this._bindDomEvent(); game.container!.appendChild(video); - const source = document.createElement('source'); + const source = ccdocument.createElement('source'); video.appendChild(source); source.src = url; } diff --git a/cocos/video/video-player-impl.ts b/cocos/video/video-player-impl.ts index 9ea80a354bb..33c00ffd305 100644 --- a/cocos/video/video-player-impl.ts +++ b/cocos/video/video-player-impl.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { legacyCC } from '../core/global-exports'; import { UITransform } from '../2d/framework'; @@ -36,8 +35,8 @@ export abstract class VideoPlayerImpl { protected _state = EventType.NONE; protected _video: HTMLVideoElement | null = null; - protected _onHide: () => void; - protected _onShow: () => void; + protected _onInterruptedBegin: () => void; + protected _onInterruptedEnd: () => void; protected _interrupted = false; protected _loaded = false; @@ -75,20 +74,20 @@ export abstract class VideoPlayerImpl { this._component = component; this._node = component.node; this._uiTrans = component.node.getComponent(UITransform); - this._onHide = () => { + this._onInterruptedBegin = () => { if (!this.video || this._state !== EventType.PLAYING) { return; } this.video.pause(); this._interrupted = true; }; - this._onShow = () => { + this._onInterruptedEnd = () => { if (!this._interrupted || !this.video) { return; } // eslint-disable-next-line @typescript-eslint/no-floating-promises this.video.play(); this._interrupted = false; }; - /* handle hide & show */ - legacyCC.game.on(legacyCC.Game.EVENT_HIDE, this._onHide); - legacyCC.game.on(legacyCC.Game.EVENT_SHOW, this._onShow); + /* handle pause & resume */ + legacyCC.game.on(legacyCC.Game.EVENT_PAUSE, this._onInterruptedBegin); + legacyCC.game.on(legacyCC.Game.EVENT_RESUME, this._onInterruptedEnd); } // @@ -114,7 +113,7 @@ export abstract class VideoPlayerImpl { public abstract syncPlaybackRate(val: number): void; public abstract syncVolume(val: number): void; public abstract syncMute(enabled: boolean): void; - public abstract syncLoop(enabled: boolean):void + public abstract syncLoop(enabled: boolean): void public abstract syncMatrix(): void; // get video player data @@ -253,8 +252,8 @@ export abstract class VideoPlayerImpl { public destroy () { this.removeVideoPlayer(); this._componentEventList.clear(); - legacyCC.game.off(legacyCC.Game.EVENT_HIDE, this._onHide); - legacyCC.game.off(legacyCC.Game.EVENT_SHOW, this._onShow); + legacyCC.game.off(legacyCC.Game.EVENT_PAUSE, this._onInterruptedBegin); + legacyCC.game.off(legacyCC.Game.EVENT_RESUME, this._onInterruptedEnd); } } diff --git a/cocos/video/video-player.ts b/cocos/video/video-player.ts index 67fc4c080b1..75a9cf8409b 100644 --- a/cocos/video/video-player.ts +++ b/cocos/video/video-player.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, displayOrder, executeInEditMode, help, menu, slide, range, requireComponent, tooltip, type, serializable } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; @@ -99,7 +98,7 @@ export class VideoPlayer extends Component { * @en * The remote URL of video. * @zh - * 远程视频的 URL + * 远程视频的 URL。 */ @tooltip('i18n:videoplayer.remoteURL') get remoteURL () { @@ -114,7 +113,7 @@ export class VideoPlayer extends Component { /** * @en - * The local video clip + * The local video clip. * @zh * 本地视频剪辑。 */ @@ -132,9 +131,9 @@ export class VideoPlayer extends Component { /** * @en - * Whether the video start playing automatically after loaded? + * Whether the video start playing automatically after loaded. * @zh - * 视频加载后是否自动开始播放? + * 视频加载后是否自动开始播放。 */ @tooltip('i18n:videoplayer.playOnAwake') get playOnAwake () { @@ -146,9 +145,9 @@ export class VideoPlayer extends Component { /** * @en - * The Video playback rate + * The Video playback rate. The value range is from [0.0 ~ 10.0]. * @zh - * 视频播放时的速率(0.0 ~ 10.0) + * 视频播放时的速率, 值的区间为[0.0 ~ 10.0]。 */ @slide @range([0.0, 10, 1.0]) @@ -165,9 +164,9 @@ export class VideoPlayer extends Component { /** * @en - * The volume of the video. + * The volume of the video. The value range is from [0.0 ~ 1.0]. * @zh - * 视频的音量(0.0 ~ 1.0) + * 视频的音量. 值的区间为[0.0 ~ 1.0]。 */ @slide @range([0.0, 1.0, 0.1]) @@ -184,9 +183,9 @@ export class VideoPlayer extends Component { /** * @en - * Mutes the VideoPlayer. Mute sets the volume=0, Un-Mute restore the original volume. + * Mutes the VideoPlayer. When the volume is set to 0, the volume is muted, and unmuted is to restore the original volume. * @zh - * 是否静音视频。静音时设置音量为 0,取消静音是恢复原来的音量。 + * 是否静音视频。设置音量为0时是静音,取消静音是恢复原来的音量。 */ @tooltip('i18n:videoplayer.mute') get mute () { @@ -201,9 +200,9 @@ export class VideoPlayer extends Component { /** * @en - * Whether the video should be played again at the end + * Whether the video should play again when it ends. * @zh - * 视频是否应在结束时再次播放 + * 视频是否应在结束时再次播放。 */ @tooltip('i18n:videoplayer.loop') get loop () { @@ -218,9 +217,9 @@ export class VideoPlayer extends Component { /** * @en - * Whether keep the aspect ration of the original video. + * Whether to keep the original aspect ratio of the video. * @zh - * 是否保持视频原来的宽高比 + * 是否保持视频原来的宽高比。 */ @tooltip('i18n:videoplayer.keepAspectRatio') get keepAspectRatio () { @@ -237,9 +236,9 @@ export class VideoPlayer extends Component { /** * @en - * Whether play video in fullscreen mode. + * Whether to play the video in full screen. * @zh - * 是否全屏播放视频 + * 是否全屏播放视频。 */ @tooltip('i18n:videoplayer.fullScreenOnAwake') get fullScreenOnAwake () { @@ -262,12 +261,14 @@ export class VideoPlayer extends Component { /** * @en - * Always below the game view (only useful on Web. - * Note: The specific effects are not guaranteed to be consistent, depending on whether each browser supports or restricts). - * Note: This property depends on the translucency of Canvas, please enable ENABLE_TRANSPARENT_CANVAS in the project preferences + * Always at the bottom of the game view. + * This property relies on the translucency feature of Canvas, please enable ENABLE_TRANSPARENT_CANVAS in project preferences. + * Note: It's only available on the Web platform. + * Due to the support and limitations of each browser, the effect may not be guaranteed to be consistent. * @zh - * 永远在游戏视图最底层(这个属性只有在 Web 平台上有效果。注意:具体效果无法保证一致,跟各个浏览器是否支持与限制有关) - * 注意:该属性依赖 Canvas 的半透明特性,请在项目偏好设置里开启 ENABLE_TRANSPARENT_CANVAS + * 永远在游戏视图最底层。 + * 该属性依赖 Canvas 的半透明特性,请在项目偏好设置里开启 ENABLE_TRANSPARENT_CANVAS。 + * 注意:该属性只有在 Web 平台上有效果。由于各浏览器的支持与限制,效果可能无法保证一致。 */ @tooltip('i18n:videoplayer.stayOnBottom') get stayOnBottom () { @@ -287,7 +288,7 @@ export class VideoPlayer extends Component { /** * @en - * The video player's callback, it will be triggered when certain event occurs, like: playing, paused, stopped and completed. + * The video player's callback, it will be triggered in certain situations, such as playing, paused, stopped and completed. * @zh * 视频播放回调函数,该回调函数会在特定情况被触发,比如播放中,暂时,停止和完成播放。 */ @@ -299,9 +300,9 @@ export class VideoPlayer extends Component { /** * @en - * Raw video objects for user customization + * Gets the original video object, generally used for user customization. * @zh - * 原始视频对象,用于用户定制 + * 获取原始视频对象,一般用于用户定制。 */ get nativeVideo () { return (this._impl && this._impl.video) || null; @@ -309,14 +310,21 @@ export class VideoPlayer extends Component { /** * @en - * The current playback time of the now playing item in seconds, you could also change the start playback time. + * Gets the time progress of the current video playback. * @zh - * 指定视频从什么时间点开始播放,单位是秒,也可以用来获取当前视频播放的时间进度。 + * 获取当前视频播放的时间进度。 */ get currentTime () { if (!this._impl) { return this._cachedCurrentTime; } return this._impl.getCurrentTime(); } + + /** + * @en + * Sets the time point when the video starts to play, in seconds. + * @zh + * 设置视频开始播放的时间点,单位是秒。 + */ set currentTime (val: number) { if (Number.isNaN(val)) { warn(`illegal video time! value:${val}`); return; } val = clamp(val, 0, this.duration); @@ -328,7 +336,7 @@ export class VideoPlayer extends Component { /** * @en - * Get the audio duration, in seconds. + * Gets the audio duration, in seconds. * @zh * 获取以秒为单位的视频总时长。 */ @@ -339,7 +347,7 @@ export class VideoPlayer extends Component { /** * @en - * Get current audio state. + * Gets current audio state. * @zh * 获取当前视频状态。 */ @@ -350,9 +358,9 @@ export class VideoPlayer extends Component { /** * @en - * Is the audio currently playing? + * Whether the current video is playing, The return value type is Boolean. * @zh - * 当前视频是否正在播放? + * 当前视频是否正在播放,返回值为布尔类型。 */ get isPlaying () { if (!this._impl) { return false; } @@ -390,6 +398,7 @@ export class VideoPlayer extends Component { this._impl.componentEventList.set(EventType.STOPPED, this.onStopped.bind(this)); this._impl.componentEventList.set(EventType.COMPLETED, this.onCompleted.bind(this)); this._impl.componentEventList.set(EventType.ERROR, this.onError.bind(this)); + this._impl.componentEventList.set(EventType.CLICKED, this.onClicked.bind(this)); if (this._playOnAwake && this._impl.loaded) { this.play(); } @@ -456,6 +465,11 @@ export class VideoPlayer extends Component { this.node.emit(EventType.ERROR, this); } + public onClicked () { + ComponentEventHandler.emitEvents(this.videoPlayerEvent, this, EventType.CLICKED); + this.node.emit(EventType.CLICKED, this); + } + /** * @en * Play the clip.
@@ -474,9 +488,10 @@ export class VideoPlayer extends Component { /** * @en + * Resume the clip. * If a video is paused, call this method to resume playing. * @zh - * 如果一个视频播放被暂停播放了,调用这个接口可以继续播放。 + * 继续播放。如果一个视频播放被暂停播放了,调用这个接口可以继续播放。 */ public resume () { if (this._impl) { diff --git a/cocos/web-view/web-view-enums.ts b/cocos/web-view/web-view-enums.ts index 7996f3e80e5..dbbc9d159d3 100644 --- a/cocos/web-view/web-view-enums.ts +++ b/cocos/web-view/web-view-enums.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,27 +20,27 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export enum EventType { /** - * @en None - * @zh 无 + * @en None. + * @zh 无。 */ NONE = 'none', /** - * @en Web page Load completed. - * @zh 网页加载完成 + * @en Web page is loading. + * @zh 网页加载中。 */ LOADING = 'loading', /** - * @en Web page is loading. - * @zh 网页加载中 + * @en Web page Load completed. + * @zh 网页加载完成。 */ LOADED = 'loaded', /** * @en Web page error occurs when loading. - * @zh 网页加载出错 + * @zh 网页加载出错。 */ ERROR = 'error', } diff --git a/cocos/web-view/web-view-impl-manager.ts b/cocos/web-view/web-view-impl-manager.ts index 0b9ddf3b023..885ed6ae5ff 100644 --- a/cocos/web-view/web-view-impl-manager.ts +++ b/cocos/web-view/web-view-impl-manager.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { legacyCC } from '../core/global-exports'; import { WebViewImplWeb } from './web-view-impl-web'; diff --git a/cocos/web-view/web-view-impl-web.ts b/cocos/web-view/web-view-impl-web.ts index 9b91107c0bf..8e95e1f4dbb 100644 --- a/cocos/web-view/web-view-impl-web.ts +++ b/cocos/web-view/web-view-impl-web.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { screenAdapter } from 'pal/screen-adapter'; import { EventType } from './web-view-enums'; @@ -30,6 +29,9 @@ import { WebViewImpl } from './web-view-impl'; import { game } from '../game'; import { mat4 } from '../core/math'; import { contains } from '../core/utils/misc'; +import { ccwindow } from '../core/global-exports'; + +const ccdocument = ccwindow.document; const _mat4_temp = mat4(); @@ -65,7 +67,7 @@ export class WebViewImplWeb extends WebViewImpl { } public createWebView () { - const wrapper = document.createElement('div'); + const wrapper = ccdocument.createElement('div'); this._wrapper = wrapper; wrapper.id = 'webview-wrapper'; wrapper.style['-webkit-overflow'] = 'auto'; @@ -77,7 +79,7 @@ export class WebViewImplWeb extends WebViewImpl { wrapper.style['-webkit-transform-origin'] = '0px 100% 0px'; game.container!.appendChild(wrapper); - const webview = document.createElement('iframe'); + const webview = ccdocument.createElement('iframe'); this._webview = webview; webview.id = 'webview'; webview.style.border = 'none'; diff --git a/cocos/web-view/web-view-impl.ts b/cocos/web-view/web-view-impl.ts index 815de297fc5..101f50974a3 100644 --- a/cocos/web-view/web-view-impl.ts +++ b/cocos/web-view/web-view-impl.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { legacyCC } from '../core/global-exports'; import { WebView } from './web-view'; diff --git a/cocos/web-view/web-view.ts b/cocos/web-view/web-view.ts index 2aaa5129d70..5708291d55d 100644 --- a/cocos/web-view/web-view.ts +++ b/cocos/web-view/web-view.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { ccclass, help, executeInEditMode, menu, tooltip, type, displayOrder, serializable, requireComponent } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; @@ -34,10 +33,9 @@ import type { WebViewImpl } from './web-view-impl'; /** * @en - * WebView is a component for display web pages in the game. - * Because different platforms have different authorization, - * API and control methods for WebView component. - * And have not yet formed a unified standard, only Web, iOS, and Android platforms are currently supported. + * WebView component, used to display web pages in the game. + * Since different platforms have different authorizations, APIs, and control methods for WebView components, there is no unified standard yet. + * So currently only Web, iOS, and Android platforms are supported. * @zh * WebView 组件,用于在游戏中显示网页。 * 由于不同平台对于 WebView 组件的授权、API、控制方式都不同,还没有形成统一的标准,所以目前只支持 Web、iOS 和 Android 平台。 @@ -54,8 +52,8 @@ export class WebView extends Component { protected _impl: WebViewImpl | null = null; /** - * @en WebView event type - * @zh 网页视图事件类型 + * @en WebView event type. + * @zh 网页视图事件类型。 */ public static EventType = EventType; @@ -63,7 +61,7 @@ export class WebView extends Component { * @en * A given URL to be loaded by the WebView, it should have a http or https prefix. * @zh - * 指定 WebView 加载的网址,它应该是一个 http 或者 https 开头的字符串 + * 指定 WebView 加载的网址,它应该是一个 http 或者 https 开头的字符串。 */ @tooltip('i18n:webview.url') get url () { @@ -78,9 +76,9 @@ export class WebView extends Component { /** * @en - * The webview's event callback , it will be triggered when certain webview event occurs. + * The webview's event callback, it will be triggered after the loading is completed or when the loading error occurs. * @zh - * WebView 的回调事件,当网页加载过程中,加载完成后或者加载出错时都会回调此函数 + * WebView 的回调事件,当网页加载过程中,加载完成后或者加载出错时都会回调此函数。 */ @serializable @type([ComponentEventHandler]) @@ -90,9 +88,9 @@ export class WebView extends Component { /** * @en - * Raw webview objects for user customization + * Raw webview objects for user customization. * @zh - * 原始网页对象,用于用户定制 + * 原始网页对象,用于用户定制。 */ get nativeWebView () { return (this._impl && this._impl.webview) || null; @@ -100,7 +98,7 @@ export class WebView extends Component { /** * @en - * Get current audio state. + * Gets the current webview state. * @zh * 获取当前网页视图状态。 */ @@ -111,12 +109,12 @@ export class WebView extends Component { /** * @en - * Set javascript interface scheme (see also setOnJSCallback).
- * Note: Supports only on the Android and iOS. For HTML5, please refer to the official documentation.
+ * Sets javascript interface scheme (see also setOnJSCallback). + * Note: Supports only on the Android and iOS. For HTML5, please refer to the official documentation. * Please refer to the official documentation for more details. * @zh - * 设置 JavaScript 接口方案(与 'setOnJSCallback' 配套使用)。
- * 注意:只支持 Android 和 iOS ,Web 端用法请前往官方文档查看。
+ * 设置 JavaScript 接口方案(与 'setOnJSCallback' 配套使用)。 + * 注意:只支持 Android 和 iOS ,Web 端用法请前往官方文档查看。 * 详情请参阅官方文档 * @method setJavascriptInterfaceScheme * @param {String} scheme @@ -130,13 +128,13 @@ export class WebView extends Component { /** * @en * This callback called when load URL that start with javascript - * interface scheme (see also setJavascriptInterfaceScheme).
- * Note: Supports only on the Android and iOS. For HTML5, please refer to the official documentation.
+ * interface scheme (see also setJavascriptInterfaceScheme). + * Note: Supports only on the Android and iOS. For HTML5, please refer to the official documentation. * Please refer to the official documentation for more details. * @zh - * 当加载 URL 以 JavaScript 接口方案开始时调用这个回调函数。
+ * 当加载 URL 以 JavaScript 接口方案开始时调用这个回调函数。 * 注意:只支持 Android 和 iOS,Web 端用法请前往官方文档查看。 - * 详情请参阅官方文档 + * 详情请参阅官方文档。 * @method setOnJSCallback * @param {Function} callback */ @@ -148,12 +146,12 @@ export class WebView extends Component { /** * @en - * Evaluates JavaScript in the context of the currently displayed page.
- * Please refer to the official document for more details
- * Note: Cross domain issues need to be resolved by yourself
+ * Evaluates JavaScript in the context of the currently displayed page. + * Please refer to the official document for more details + * Note: Cross domain issues need to be resolved by yourself * @zh - * 执行 WebView 内部页面脚本(详情请参阅官方文档)
- * 注意:需要自行解决跨域问题 + * 执行 WebView 内部页面脚本(详情请参阅官方文档)。 + * 注意:需要自行解决跨域问题。 * @method evaluateJS * @param {String} str */ diff --git a/cocos/webgpu/instantiated.ts b/cocos/webgpu/instantiated.ts index ef9a10fb09f..633c4417139 100644 --- a/cocos/webgpu/instantiated.ts +++ b/cocos/webgpu/instantiated.ts @@ -1,20 +1,19 @@ /* eslint-disable @typescript-eslint/no-floating-promises */ /* eslint-disable no-void */ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,7 +22,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { WEBGPU } from 'internal:constants'; import webgpuUrl from 'url:native/external/emscripten/webgpu/webgpu_wasm.wasm'; import glslangUrl from 'url:native/external/emscripten/webgpu/glslang.wasm'; diff --git a/cocos/webgpu/webgpu_wasm.js b/cocos/webgpu/webgpu_wasm.js index 973bfbb9a31..6ab1ff11f39 100644 --- a/cocos/webgpu/webgpu_wasm.js +++ b/cocos/webgpu/webgpu_wasm.js @@ -6,7 +6,7 @@ var wasmDevice = (() => { function(wasmDevice) { wasmDevice = wasmDevice || {}; -var Module=typeof wasmDevice!="undefined"?wasmDevice:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var POINTER_SIZE=4;var tempRet0=0;var setTempRet0=value=>{tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heapOrArray,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}var wasmBinaryFile;wasmBinaryFile="webgpu_wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["_a"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["ab"];addOnInit(Module["asm"]["$a"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){callbacks.shift()(Module)}}function handleException(e){if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function __embind_finalize_value_object(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(field=>field.getterReturnType).concat(fieldRecords.map(field=>field.setterArgumentType));whenDependentTypesAreResolved([structType],fieldTypes,fieldTypes=>{var fields={};fieldRecords.forEach((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>{return getterReturnType["fromWireType"](getter(getterContext,ptr))},write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError('Missing field: "'+fieldName+'"')}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]})}function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}var name=registeredInstance.name;if(!rawType){throwBindingError('type "'+name+'" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError("Cannot register type '"+name+"' twice")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function attachFinalizer(handle){if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}var wasmTableMirror=[];function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func}function dynCall(sig,ptr,args){if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn}function getDynCaller(sig,ptr){var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError("unknown function pointer with signature "+signature+": "+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+": "+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError("Cannot construct "+name+" due to unbound types",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError("Tried to invoke ctor of "+name+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(registeredClass.constructor_body).toString()+") parameters instead!")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function new_(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError("new_ called with constructor type "+typeof constructor+" which is not a function")}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}function validateThis(this_,classType,humanName){if(!(this_ instanceof Object)){throwBindingError(humanName+' with invalid "this": '+this_)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(humanName+' incompatible with "this" of type '+this_.constructor.name)}if(!this_.$$.ptr){throwBindingError("cannot call emscripten binding method "+humanName+" on deleted object")}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)}function __embind_register_class_property(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){fieldName=readLatin1String(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],function(classType){classType=classType[0];var humanName=classType.name+"."+fieldName;var desc={get:function(){throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=()=>{throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])}}else{desc.set=v=>{throwBindingError(humanName+" is a read-only property")}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],function(types){var getterReturnType=types[0];var desc={get:function(){var ptr=validateThis(this,classType,humanName+" getter");return getterReturnType["fromWireType"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+" setter");var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":function(destructors,value){return Emval.toHandle(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value=="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __emval_as(handle,returnType,destructorsRef){handle=Emval.toValue(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=Emval.toHandle(destructors);HEAPU32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}return symbol}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=Emval.toValue(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i>2],"parameter "+i)}return a}var emval_registeredMethods=[];function __emval_get_method_caller(argCount,argTypes){var types=emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var returnId=emval_registeredMethods[signatureName];if(returnId!==undefined){return returnId}var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function __emval_new_array(){return Emval.toHandle([])}function __emval_new_cstring(v){return Emval.toHandle(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=Emval.toValue(handle);runDestructors(destructors);__emval_decref(handle)}function __emval_set_property(handle,key,value){handle=Emval.toValue(handle);key=Emval.toValue(key);value=Emval.toValue(value);handle[key]=value}function __emval_take_value(type,arg){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)}function _abort(){abort("")}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}let alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var WebGPU={initManagers:function(){if(WebGPU.mgrDevice)return;function Manager(){this.objects={};this.nextId=1;this.create=function(object,wrapper){wrapper=wrapper||{};var id=this.nextId++;wrapper.refcount=1;wrapper.object=object;this.objects[id]=wrapper;return id};this.get=function(id){if(!id)return undefined;var o=this.objects[id];return o.object};this.reference=function(id){var o=this.objects[id];o.refcount++};this.release=function(id){var o=this.objects[id];o.refcount--;if(o.refcount<=0){delete this.objects[id]}}}WebGPU.mgrSurface=WebGPU.mgrSurface||new Manager;WebGPU.mgrSwapChain=WebGPU.mgrSwapChain||new Manager;WebGPU.mgrAdapter=WebGPU.mgrAdapter||new Manager;WebGPU.mgrDevice=WebGPU.mgrDevice||new Manager;WebGPU.mgrQueue=WebGPU.mgrQueue||new Manager;WebGPU.mgrCommandBuffer=WebGPU.mgrCommandBuffer||new Manager;WebGPU.mgrCommandEncoder=WebGPU.mgrCommandEncoder||new Manager;WebGPU.mgrRenderPassEncoder=WebGPU.mgrRenderPassEncoder||new Manager;WebGPU.mgrComputePassEncoder=WebGPU.mgrComputePassEncoder||new Manager;WebGPU.mgrBindGroup=WebGPU.mgrBindGroup||new Manager;WebGPU.mgrBuffer=WebGPU.mgrBuffer||new Manager;WebGPU.mgrSampler=WebGPU.mgrSampler||new Manager;WebGPU.mgrTexture=WebGPU.mgrTexture||new Manager;WebGPU.mgrTextureView=WebGPU.mgrTextureView||new Manager;WebGPU.mgrQuerySet=WebGPU.mgrQuerySet||new Manager;WebGPU.mgrBindGroupLayout=WebGPU.mgrBindGroupLayout||new Manager;WebGPU.mgrPipelineLayout=WebGPU.mgrPipelineLayout||new Manager;WebGPU.mgrRenderPipeline=WebGPU.mgrRenderPipeline||new Manager;WebGPU.mgrComputePipeline=WebGPU.mgrComputePipeline||new Manager;WebGPU.mgrShaderModule=WebGPU.mgrShaderModule||new Manager;WebGPU.mgrRenderBundleEncoder=WebGPU.mgrRenderBundleEncoder||new Manager;WebGPU.mgrRenderBundle=WebGPU.mgrRenderBundle||new Manager},makeColor:function(ptr){return{"r":HEAPF64[ptr>>3],"g":HEAPF64[ptr+8>>3],"b":HEAPF64[ptr+16>>3],"a":HEAPF64[ptr+24>>3]}},makeExtent3D:function(ptr){return{"width":HEAPU32[ptr>>2],"height":HEAPU32[ptr+4>>2],"depthOrArrayLayers":HEAPU32[ptr+8>>2]}},makeOrigin3D:function(ptr){return{"x":HEAPU32[ptr>>2],"y":HEAPU32[ptr+4>>2],"z":HEAPU32[ptr+8>>2]}},makeImageCopyTexture:function(ptr){return{"texture":WebGPU.mgrTexture.get(HEAPU32[ptr+4>>2]),"mipLevel":HEAPU32[ptr+8>>2],"origin":WebGPU.makeOrigin3D(ptr+12),"aspect":WebGPU.TextureAspect[HEAPU32[ptr+24>>2]]}},makeTextureDataLayout:function(ptr){var bytesPerRow=HEAPU32[ptr+16>>2];var rowsPerImage=HEAPU32[ptr+20>>2];return{"offset":HEAPU32[ptr+4+8>>2]*4294967296+HEAPU32[ptr+8>>2],"bytesPerRow":bytesPerRow===4294967295?undefined:bytesPerRow,"rowsPerImage":rowsPerImage===4294967295?undefined:rowsPerImage}},makeImageCopyBuffer:function(ptr){var layoutPtr=ptr+8;var bufferCopyView=WebGPU.makeTextureDataLayout(layoutPtr);bufferCopyView["buffer"]=WebGPU.mgrBuffer.get(HEAPU32[ptr+32>>2]);return bufferCopyView},makePipelineConstants:function(constantCount,constantsPtr){if(!constantCount)return;var constants={};for(var i=0;i>2]);constants[key]=HEAPF64[entryPtr+8>>3]}return constants},makeProgrammableStageDescriptor:function(ptr){if(!ptr)return undefined;return{"module":WebGPU.mgrShaderModule.get(HEAPU32[ptr+4>>2]),"entryPoint":UTF8ToString(HEAPU32[ptr+8>>2]),"constants":WebGPU.makePipelineConstants(HEAPU32[ptr+12>>2],HEAPU32[ptr+16>>2])}},DeviceLostReason:{undefined:0,destroyed:1},PreferredFormat:{rgba8unorm:18,bgra8unorm:23},AddressMode:["repeat","mirror-repeat","clamp-to-edge"],BlendFactor:["zero","one","src","one-minus-src","src-alpha","one-minus-src-alpha","dst","one-minus-dst","dst-alpha","one-minus-dst-alpha","src-alpha-saturated","constant","one-minus-constant"],BlendOperation:["add","subtract","reverse-subtract","min","max"],BufferBindingType:[,"uniform","storage","read-only-storage"],CompareFunction:[,"never","less","less-equal","greater","greater-equal","equal","not-equal","always"],CompilationInfoRequestStatus:["success","error","device-lost","unknown"],ComputePassTimestampLocation:["beginning","end"],CullMode:["none","front","back"],ErrorFilter:["validation","out-of-memory"],FeatureName:{0:undefined,1:"depth-clip-control",2:"depth24unorm-stencil8",3:"depth32float-stencil8",4:"timestamp-query",5:"pipeline-statistics-query",6:"texture-compression-bc",7:"texture-compression-etc2",8:"texture-compression-astc",9:"indirect-first-instance",1e3:"depth-clamping"},FilterMode:["nearest","linear"],FrontFace:["ccw","cw"],IndexFormat:[,"uint16","uint32"],LoadOp:[,"clear","load"],PipelineStatisticName:["vertex-shader-invocations","clipper-invocations","clipper-primitives-out","fragment-shader-invocations","compute-shader-invocations"],PowerPreference:[,"low-power","high-performance"],PredefinedColorSpace:[,"srgb"],PrimitiveTopology:["point-list","line-list","line-strip","triangle-list","triangle-strip"],QueryType:["occlusion","pipeline-statistics","timestamp"],RenderPassTimestampLocation:["beginning","end"],SamplerBindingType:[,"filtering","non-filtering","comparison"],StencilOperation:["keep","zero","replace","invert","increment-clamp","decrement-clamp","increment-wrap","decrement-wrap"],StorageTextureAccess:[,"write-only"],StoreOp:[,"store","discard"],TextureAspect:["all","stencil-only","depth-only"],TextureComponentType:["float","sint","uint","depth-comparison"],TextureDimension:["1d","2d","3d"],TextureFormat:[,"r8unorm","r8snorm","r8uint","r8sint","r16uint","r16sint","r16float","rg8unorm","rg8snorm","rg8uint","rg8sint","r32float","r32uint","r32sint","rg16uint","rg16sint","rg16float","rgba8unorm","rgba8unorm-srgb","rgba8snorm","rgba8uint","rgba8sint","bgra8unorm","bgra8unorm-srgb","rgb10a2unorm","rg11b10ufloat","rgb9e5ufloat","rg32float","rg32uint","rg32sint","rgba16uint","rgba16sint","rgba16float","rgba32float","rgba32uint","rgba32sint","stencil8","depth16unorm","depth24plus","depth24plus-stencil8","depth24unorm-stencil8","depth32float","depth32float-stencil8","bc1-rgba-unorm","bc1-rgba-unorm-srgb","bc2-rgba-unorm","bc2-rgba-unorm-srgb","bc3-rgba-unorm","bc3-rgba-unorm-srgb","bc4-r-unorm","bc4-r-snorm","bc5-rg-unorm","bc5-rg-snorm","bc6h-rgb-ufloat","bc6h-rgb-float","bc7-rgba-unorm","bc7-rgba-unorm-srgb","etc2-rgb8unorm","etc2-rgb8unorm-srgb","etc2-rgb8a1unorm","etc2-rgb8a1unorm-srgb","etc2-rgba8unorm","etc2-rgba8unorm-srgb","eac-r11unorm","eac-r11snorm","eac-rg11unorm","eac-rg11snorm","astc-4x4-unorm","astc-4x4-unorm-srgb","astc-5x4-unorm","astc-5x4-unorm-srgb","astc-5x5-unorm","astc-5x5-unorm-srgb","astc-6x5-unorm","astc-6x5-unorm-srgb","astc-6x6-unorm","astc-6x6-unorm-srgb","astc-8x5-unorm","astc-8x5-unorm-srgb","astc-8x6-unorm","astc-8x6-unorm-srgb","astc-8x8-unorm","astc-8x8-unorm-srgb","astc-10x5-unorm","astc-10x5-unorm-srgb","astc-10x6-unorm","astc-10x6-unorm-srgb","astc-10x8-unorm","astc-10x8-unorm-srgb","astc-10x10-unorm","astc-10x10-unorm-srgb","astc-12x10-unorm","astc-12x10-unorm-srgb","astc-12x12-unorm","astc-12x12-unorm-srgb"],TextureSampleType:[,"float","unfilterable-float","depth","sint","uint"],TextureViewDimension:[,"1d","2d","2d-array","cube","cube-array","3d"],VertexFormat:[,"uint8x2","uint8x4","sint8x2","sint8x4","unorm8x2","unorm8x4","snorm8x2","snorm8x4","uint16x2","uint16x4","sint16x2","sint16x4","unorm16x2","unorm16x4","snorm16x2","snorm16x4","float16x2","float16x4","float32","float32x2","float32x3","float32x4","uint32","uint32x2","uint32x3","uint32x4","sint32","sint32x2","sint32x3","sint32x4"],VertexStepMode:["vertex","instance"],FeatureNameString2Enum:{undefined:"0","depth-clip-control":"1","depth24unorm-stencil8":"2","depth32float-stencil8":"3","timestamp-query":"4","pipeline-statistics-query":"5","texture-compression-bc":"6","texture-compression-etc2":"7","texture-compression-astc":"8","indirect-first-instance":"9","depth-clamping":"1000"}};function _emscripten_webgpu_get_device(){var device=Module["preinitializedWebGPUDevice"];var deviceWrapper={queueId:WebGPU.mgrQueue.create(device["queue"])};return WebGPU.mgrDevice.create(device,deviceWrapper)}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var SYSCALLS={varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret}};function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAPU32[penviron_buf_size>>2]=bufSize;return 0}var printCharBuffers=[null,[],[]];function printChar(stream,curr){var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0}function _setTempRet0(val){setTempRet0(val)}function _wgpuAdapterGetProperties(adapterId,properties){HEAP32[properties+4>>2]=0;HEAP32[properties+8>>2]=0;HEAP32[properties+12>>2]=0;HEAP32[properties+16>>2]=0;HEAP32[properties+20>>2]=3;HEAP32[properties+24>>2]=1}function _wgpuAdapterHasFeature(adapterId,featureEnumValue){var adapter=WebGPU.mgrAdapter.get(adapterId);return adapter.features.has(WebGPU.FeatureName[featureEnumValue])}function _wgpuAdapterRelease(id){WebGPU.mgrAdapter.release(id)}function _wgpuBindGroupRelease(id){WebGPU.mgrBindGroup.release(id)}function _wgpuBufferDestroy(bufferId){WebGPU.mgrBuffer.get(bufferId)["destroy"]()}function _wgpuBufferGetMappedRange(bufferId,offset,size){var bufferWrapper=WebGPU.mgrBuffer.objects[bufferId];if(size===0)warnOnce("getMappedRange size=0 no longer means WGPU_WHOLE_MAP_SIZE");size=size>>>0;if(size===4294967295)size=undefined;if(bufferWrapper.mapMode!==2){return 0}var mapped;try{mapped=bufferWrapper.object["getMappedRange"](offset,size)}catch(ex){return 0}var data=_malloc(mapped.byteLength);HEAPU8.fill(0,data,mapped.byteLength);bufferWrapper.onUnmap.push(function(){new Uint8Array(mapped).set(HEAPU8.subarray(data,data+mapped.byteLength));_free(data)});return data}function _wgpuBufferRelease(id){WebGPU.mgrBuffer.release(id)}function _wgpuBufferUnmap(bufferId){var bufferWrapper=WebGPU.mgrBuffer.objects[bufferId];if(!bufferWrapper.onUnmap){return}for(var i=0;i>2]),"queryIndex":HEAPU32[twPtr+4>>2],"location":WebGPU.ComputePassTimestampLocation[HEAPU32[twPtr+8>>2]]}}function makeComputePassTimestampWrites(count,twPtr){var timestampWrites=[];for(var i=0;i>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var timestampWriteCount=HEAPU32[descriptor+8>>2];if(timestampWriteCount){desc["timestampWrites"]=makeComputePassTimestampWrites(timestampWriteCount,HEAPU32[descriptor+12>>2])}}var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);return WebGPU.mgrComputePassEncoder.create(commandEncoder["beginComputePass"](desc))}function _wgpuCommandEncoderBeginRenderPass(encoderId,descriptor){function makeColorAttachment(caPtr){var viewPtr=HEAPU32[caPtr>>2];if(viewPtr===0){return undefined}var loadOpInt=HEAPU32[caPtr+8>>2];var storeOpInt=HEAPU32[caPtr+12>>2];var clearValue=WebGPU.makeColor(caPtr+16);return{"view":WebGPU.mgrTextureView.get(viewPtr),"resolveTarget":WebGPU.mgrTextureView.get(HEAPU32[caPtr+4>>2]),"clearValue":clearValue,"loadOp":WebGPU.LoadOp[loadOpInt],"storeOp":WebGPU.StoreOp[storeOpInt]}}function makeColorAttachments(count,caPtr){var attachments=[];for(var i=0;i>2]),"depthClearValue":HEAPF32[dsaPtr+12>>2],"depthLoadOp":WebGPU.LoadOp[HEAPU32[dsaPtr+4>>2]],"depthStoreOp":WebGPU.StoreOp[HEAPU32[dsaPtr+8>>2]],"depthReadOnly":HEAP8[dsaPtr+16>>0]!==0,"stencilClearValue":HEAPU32[dsaPtr+28>>2],"stencilLoadOp":WebGPU.LoadOp[HEAPU32[dsaPtr+20>>2]],"stencilStoreOp":WebGPU.StoreOp[HEAPU32[dsaPtr+24>>2]],"stencilReadOnly":HEAP8[dsaPtr+32>>0]!==0}}function makeRenderPassTimestampWrite(twPtr){return{"querySet":WebGPU.mgrQuerySet.get(HEAPU32[twPtr>>2]),"queryIndex":HEAPU32[twPtr+4>>2],"location":WebGPU.RenderPassTimestampLocation[HEAPU32[twPtr+8>>2]]}}function makeRenderPassTimestampWrites(count,twPtr){var timestampWrites=[];for(var i=0;i>2],HEAPU32[descriptor+12>>2]),"depthStencilAttachment":makeDepthStencilAttachment(HEAPU32[descriptor+16>>2]),"occlusionQuerySet":WebGPU.mgrQuerySet.get(HEAPU32[descriptor+20>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var timestampWriteCount=HEAPU32[descriptor+24>>2];if(timestampWriteCount){desc["timestampWrites"]=makeRenderPassTimestampWrites(timestampWriteCount,HEAPU32[descriptor+28>>2])}return desc}var desc=makeRenderPassDescriptor(descriptor);var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);return WebGPU.mgrRenderPassEncoder.create(commandEncoder["beginRenderPass"](desc))}function _wgpuCommandEncoderCopyBufferToBuffer(encoderId,srcId,srcOffset_low,srcOffset_high,dstId,dstOffset_low,dstOffset_high,size_low,size_high){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);var src=WebGPU.mgrBuffer.get(srcId);var dst=WebGPU.mgrBuffer.get(dstId);commandEncoder["copyBufferToBuffer"](src,srcOffset_high*4294967296+srcOffset_low,dst,dstOffset_high*4294967296+dstOffset_low,size_high*4294967296+size_low)}function _wgpuCommandEncoderCopyBufferToTexture(encoderId,srcPtr,dstPtr,copySizePtr){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);var copySize=WebGPU.makeExtent3D(copySizePtr);commandEncoder["copyBufferToTexture"](WebGPU.makeImageCopyBuffer(srcPtr),WebGPU.makeImageCopyTexture(dstPtr),copySize)}function _wgpuCommandEncoderCopyTextureToTexture(encoderId,srcPtr,dstPtr,copySizePtr){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);var copySize=WebGPU.makeExtent3D(copySizePtr);commandEncoder["copyTextureToTexture"](WebGPU.makeImageCopyTexture(srcPtr),WebGPU.makeImageCopyTexture(dstPtr),copySize)}function _wgpuCommandEncoderFinish(encoderId){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);return WebGPU.mgrCommandBuffer.create(commandEncoder["finish"]())}function _wgpuCommandEncoderRelease(id){WebGPU.mgrCommandEncoder.release(id)}function _wgpuComputePassEncoderDispatchWorkgroups(passId,x,y,z){var pass=WebGPU.mgrComputePassEncoder.get(passId);if(pass["dispatchWorkgroups"]){pass["dispatchWorkgroups"](x,y,z)}else{pass["dispatch"](x,y,z)}}function _wgpuComputePassEncoderDispatchWorkgroupsIndirect(passId,indirectBufferId,indirectOffset_low,indirectOffset_high){var indirectBuffer=WebGPU.mgrBuffer.get(indirectBufferId);var indirectOffset=indirectOffset_high*4294967296+indirectOffset_low;var pass=WebGPU.mgrComputePassEncoder.get(passId);if(pass["dispatchWorkgroupsIndirect"]){pass["dispatchWorkgroupsIndirect"](indirectBuffer,indirectOffset)}else{pass["dispatchIndirect"](indirectBuffer,indirectOffset)}}function _wgpuComputePassEncoderEnd(passId){var pass=WebGPU.mgrComputePassEncoder.get(passId);pass["end"]()}function _wgpuComputePassEncoderRelease(id){WebGPU.mgrComputePassEncoder.release(id)}function _wgpuComputePassEncoderSetBindGroup(passId,groupIndex,groupId,dynamicOffsetCount,dynamicOffsetsPtr){var pass=WebGPU.mgrComputePassEncoder.get(passId);var group=WebGPU.mgrBindGroup.get(groupId);if(dynamicOffsetCount==0){pass["setBindGroup"](groupIndex,group)}else{var offsets=[];for(var i=0;i>2])}pass["setBindGroup"](groupIndex,group,offsets)}}function _wgpuComputePassEncoderSetPipeline(passId,pipelineId){var pass=WebGPU.mgrComputePassEncoder.get(passId);var pipeline=WebGPU.mgrComputePipeline.get(pipelineId);pass["setPipeline"](pipeline)}function _wgpuComputePipelineRelease(id){WebGPU.mgrComputePipeline.release(id)}function _wgpuDeviceCreateBindGroup(deviceId,descriptor){function makeEntry(entryPtr){var bufferId=HEAPU32[entryPtr+8>>2];var samplerId=HEAPU32[entryPtr+32>>2];var textureViewId=HEAPU32[entryPtr+36>>2];var binding=HEAPU32[entryPtr+4>>2];if(bufferId){var size_low=HEAPU32[entryPtr+24>>2];var size_high=HEAPU32[entryPtr+28>>2];var size=size_high===-1&&size_low===-1?undefined:size_high*4294967296+size_low;return{"binding":binding,"resource":{"buffer":WebGPU.mgrBuffer.get(bufferId),"offset":HEAPU32[entryPtr+4+16>>2]*4294967296+HEAPU32[entryPtr+16>>2],"size":size}}}else if(samplerId){return{"binding":binding,"resource":WebGPU.mgrSampler.get(samplerId)}}else{return{"binding":binding,"resource":WebGPU.mgrTextureView.get(textureViewId)}}}function makeEntries(count,entriesPtrs){var entries=[];for(var i=0;i>2]),"entries":makeEntries(HEAPU32[descriptor+12>>2],HEAPU32[descriptor+16>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrBindGroup.create(device["createBindGroup"](desc))}function _wgpuDeviceCreateBindGroupLayout(deviceId,descriptor){function makeBufferEntry(entryPtr){var typeInt=HEAPU32[entryPtr+4>>2];if(!typeInt)return undefined;return{"type":WebGPU.BufferBindingType[typeInt],"hasDynamicOffset":HEAP8[entryPtr+8>>0]!==0,"minBindingSize":HEAPU32[entryPtr+4+16>>2]*4294967296+HEAPU32[entryPtr+16>>2]}}function makeSamplerEntry(entryPtr){var typeInt=HEAPU32[entryPtr+4>>2];if(!typeInt)return undefined;return{"type":WebGPU.SamplerBindingType[typeInt]}}function makeTextureEntry(entryPtr){var sampleTypeInt=HEAPU32[entryPtr+4>>2];if(!sampleTypeInt)return undefined;return{"sampleType":WebGPU.TextureSampleType[sampleTypeInt],"viewDimension":WebGPU.TextureViewDimension[HEAPU32[entryPtr+8>>2]],"multisampled":HEAP8[entryPtr+12>>0]!==0}}function makeStorageTextureEntry(entryPtr){var accessInt=HEAPU32[entryPtr+4>>2];if(!accessInt)return undefined;return{"access":WebGPU.StorageTextureAccess[accessInt],"format":WebGPU.TextureFormat[HEAPU32[entryPtr+8>>2]],"viewDimension":WebGPU.TextureViewDimension[HEAPU32[entryPtr+12>>2]]}}function makeEntry(entryPtr){return{"binding":HEAPU32[entryPtr+4>>2],"visibility":HEAPU32[entryPtr+8>>2],"buffer":makeBufferEntry(entryPtr+16),"sampler":makeSamplerEntry(entryPtr+40),"texture":makeTextureEntry(entryPtr+48),"storageTexture":makeStorageTextureEntry(entryPtr+64)}}function makeEntries(count,entriesPtrs){var entries=[];for(var i=0;i>2],HEAPU32[descriptor+12>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrBindGroupLayout.create(device["createBindGroupLayout"](desc))}function _wgpuDeviceCreateBuffer(deviceId,descriptor){var mappedAtCreation=HEAP8[descriptor+24>>0]!==0;var desc={"label":undefined,"usage":HEAPU32[descriptor+8>>2],"size":HEAPU32[descriptor+4+16>>2]*4294967296+HEAPU32[descriptor+16>>2],"mappedAtCreation":mappedAtCreation};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);var bufferWrapper={};var id=WebGPU.mgrBuffer.create(device["createBuffer"](desc),bufferWrapper);if(mappedAtCreation){bufferWrapper.mapMode=2;bufferWrapper.onUnmap=[]}return id}function _wgpuDeviceCreateCommandEncoder(deviceId,descriptor){var desc;if(descriptor){desc={"label":undefined};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr)}var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrCommandEncoder.create(device["createCommandEncoder"](desc))}function _wgpuDeviceCreateComputePipeline(deviceId,descriptor){var desc={"label":undefined,"layout":WebGPU.mgrPipelineLayout.get(HEAPU32[descriptor+8>>2]),"compute":WebGPU.makeProgrammableStageDescriptor(descriptor+12)};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrComputePipeline.create(device["createComputePipeline"](desc))}function _wgpuDeviceCreatePipelineLayout(deviceId,descriptor){var bglCount=HEAPU32[descriptor+8>>2];var bglPtr=HEAPU32[descriptor+12>>2];var bgls=[];for(var i=0;i>2]))}var desc={"label":undefined,"bindGroupLayouts":bgls};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrPipelineLayout.create(device["createPipelineLayout"](desc))}function _wgpuDeviceCreateRenderPipeline(deviceId,descriptor){function makePrimitiveState(rsPtr){if(!rsPtr)return undefined;return{"topology":WebGPU.PrimitiveTopology[HEAPU32[rsPtr+4>>2]],"stripIndexFormat":WebGPU.IndexFormat[HEAPU32[rsPtr+8>>2]],"frontFace":WebGPU.FrontFace[HEAPU32[rsPtr+12>>2]],"cullMode":WebGPU.CullMode[HEAPU32[rsPtr+16>>2]]}}function makeBlendComponent(bdPtr){if(!bdPtr)return undefined;return{"operation":WebGPU.BlendOperation[HEAPU32[bdPtr>>2]],"srcFactor":WebGPU.BlendFactor[HEAPU32[bdPtr+4>>2]],"dstFactor":WebGPU.BlendFactor[HEAPU32[bdPtr+8>>2]]}}function makeBlendState(bsPtr){if(!bsPtr)return undefined;return{"alpha":makeBlendComponent(bsPtr+12),"color":makeBlendComponent(bsPtr+0)}}function makeColorState(csPtr){var formatInt=HEAPU32[csPtr+4>>2];return formatInt===0?undefined:{"format":WebGPU.TextureFormat[formatInt],"blend":makeBlendState(HEAPU32[csPtr+8>>2]),"writeMask":HEAPU32[csPtr+12>>2]}}function makeColorStates(count,csArrayPtr){var states=[];for(var i=0;i>2]],"failOp":WebGPU.StencilOperation[HEAPU32[ssfPtr+4>>2]],"depthFailOp":WebGPU.StencilOperation[HEAPU32[ssfPtr+8>>2]],"passOp":WebGPU.StencilOperation[HEAPU32[ssfPtr+12>>2]]}}function makeDepthStencilState(dssPtr){if(!dssPtr)return undefined;return{"format":WebGPU.TextureFormat[HEAPU32[dssPtr+4>>2]],"depthWriteEnabled":HEAP8[dssPtr+8>>0]!==0,"depthCompare":WebGPU.CompareFunction[HEAPU32[dssPtr+12>>2]],"stencilFront":makeStencilStateFace(dssPtr+16),"stencilBack":makeStencilStateFace(dssPtr+32),"stencilReadMask":HEAPU32[dssPtr+48>>2],"stencilWriteMask":HEAPU32[dssPtr+52>>2],"depthBias":HEAPU32[dssPtr+56>>2],"depthBiasSlopeScale":HEAPF32[dssPtr+60>>2],"depthBiasClamp":HEAPF32[dssPtr+64>>2]}}function makeVertexAttribute(vaPtr){return{"format":WebGPU.VertexFormat[HEAPU32[vaPtr>>2]],"offset":HEAPU32[vaPtr+4+8>>2]*4294967296+HEAPU32[vaPtr+8>>2],"shaderLocation":HEAPU32[vaPtr+16>>2]}}function makeVertexAttributes(count,vaArrayPtr){var vas=[];for(var i=0;i>2]*4294967296+HEAPU32[vbPtr>>2],"stepMode":WebGPU.VertexStepMode[HEAPU32[vbPtr+8>>2]],"attributes":makeVertexAttributes(HEAPU32[vbPtr+12>>2],HEAPU32[vbPtr+16>>2])}}function makeVertexBuffers(count,vbArrayPtr){if(!count)return undefined;var vbs=[];for(var i=0;i>2]),"entryPoint":UTF8ToString(HEAPU32[viPtr+8>>2]),"constants":WebGPU.makePipelineConstants(HEAPU32[viPtr+12>>2],HEAPU32[viPtr+16>>2]),"buffers":makeVertexBuffers(HEAPU32[viPtr+20>>2],HEAPU32[viPtr+24>>2])}}function makeMultisampleState(msPtr){if(!msPtr)return undefined;return{"count":HEAPU32[msPtr+4>>2],"mask":HEAPU32[msPtr+8>>2],"alphaToCoverageEnabled":HEAP8[msPtr+12>>0]!==0}}function makeFragmentState(fsPtr){if(!fsPtr)return undefined;return{"module":WebGPU.mgrShaderModule.get(HEAPU32[fsPtr+4>>2]),"entryPoint":UTF8ToString(HEAPU32[fsPtr+8>>2]),"constants":WebGPU.makePipelineConstants(HEAPU32[fsPtr+12>>2],HEAPU32[fsPtr+16>>2]),"targets":makeColorStates(HEAPU32[fsPtr+20>>2],HEAPU32[fsPtr+24>>2])}}var desc={"label":undefined,"layout":WebGPU.mgrPipelineLayout.get(HEAPU32[descriptor+8>>2]),"vertex":makeVertexState(descriptor+12),"primitive":makePrimitiveState(descriptor+40),"depthStencil":makeDepthStencilState(HEAPU32[descriptor+60>>2]),"multisample":makeMultisampleState(descriptor+64),"fragment":makeFragmentState(HEAPU32[descriptor+80>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrRenderPipeline.create(device["createRenderPipeline"](desc))}function _wgpuDeviceCreateSampler(deviceId,descriptor){var desc={"label":undefined,"addressModeU":WebGPU.AddressMode[HEAPU32[descriptor+8>>2]],"addressModeV":WebGPU.AddressMode[HEAPU32[descriptor+12>>2]],"addressModeW":WebGPU.AddressMode[HEAPU32[descriptor+16>>2]],"magFilter":WebGPU.FilterMode[HEAPU32[descriptor+20>>2]],"minFilter":WebGPU.FilterMode[HEAPU32[descriptor+24>>2]],"mipmapFilter":WebGPU.FilterMode[HEAPU32[descriptor+28>>2]],"lodMinClamp":HEAPF32[descriptor+32>>2],"lodMaxClamp":HEAPF32[descriptor+36>>2],"compare":WebGPU.CompareFunction[HEAPU32[descriptor+40>>2]]};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrSampler.create(device["createSampler"](desc))}function _wgpuDeviceCreateShaderModule(deviceId,descriptor){var nextInChainPtr=HEAPU32[descriptor>>2];var sType=HEAPU32[nextInChainPtr+4>>2];var desc={"label":undefined,"code":""};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);switch(sType){case 5:{var count=HEAPU32[nextInChainPtr+8>>2];var start=HEAPU32[nextInChainPtr+12>>2];desc["code"]=HEAPU32.subarray(start>>2,(start>>2)+count);break}case 6:{var sourcePtr=HEAPU32[nextInChainPtr+8>>2];if(sourcePtr){desc["code"]=UTF8ToString(sourcePtr)}break}}var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrShaderModule.create(device["createShaderModule"](desc))}function _wgpuDeviceCreateSwapChain(deviceId,surfaceId,descriptor){var device=WebGPU.mgrDevice.get(deviceId);var context=WebGPU.mgrSurface.get(surfaceId);var canvasSize=[HEAPU32[descriptor+16>>2],HEAPU32[descriptor+20>>2]];if(canvasSize[0]!==0){context["canvas"]["width"]=canvasSize[0]}if(canvasSize[1]!==0){context["canvas"]["height"]=canvasSize[1]}var configuration={"device":device,"format":WebGPU.TextureFormat[HEAPU32[descriptor+12>>2]],"usage":HEAPU32[descriptor+8>>2],"alphaMode":"opaque"};context["configure"](configuration);return WebGPU.mgrSwapChain.create(context)}function _wgpuDeviceCreateTexture(deviceId,descriptor){var desc={"label":undefined,"size":WebGPU.makeExtent3D(descriptor+16),"mipLevelCount":HEAPU32[descriptor+32>>2],"sampleCount":HEAPU32[descriptor+36>>2],"dimension":WebGPU.TextureDimension[HEAPU32[descriptor+12>>2]],"format":WebGPU.TextureFormat[HEAPU32[descriptor+28>>2]],"usage":HEAPU32[descriptor+8>>2]};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var viewFormatCount=HEAPU32[descriptor+40>>2];if(viewFormatCount){var viewFormatsPtr=HEAPU32[descriptor+44>>2];desc["viewFormats"]=Array.from(HEAP32.subarray(viewFormatsPtr>>2,(viewFormatsPtr>>2)+viewFormatCount),function(format){return WebGPU.TextureFormat[format]})}var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrTexture.create(device["createTexture"](desc))}function _wgpuDeviceGetQueue(deviceId){var queueId=WebGPU.mgrDevice.objects[deviceId].queueId;WebGPU.mgrQueue.reference(queueId);return queueId}function _wgpuDeviceRelease(id){WebGPU.mgrDevice.release(id)}function maybeCStringToJsString(cString){return cString>2?UTF8ToString(cString):cString}var specialHTMLTargets=[0,document,window];function findEventTarget(target){target=maybeCStringToJsString(target);var domElement=specialHTMLTargets[target]||document.querySelector(target);return domElement}function findCanvasEventTarget(target){return findEventTarget(target)}function _wgpuInstanceCreateSurface(instanceId,descriptor){var nextInChainPtr=HEAPU32[descriptor>>2];var descriptorFromCanvasHTMLSelector=nextInChainPtr;var selectorPtr=HEAPU32[descriptorFromCanvasHTMLSelector+8>>2];var canvas=findCanvasEventTarget(selectorPtr);var context=canvas.getContext("webgpu");if(!context)return 0;var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)context.surfaceLabelWebGPU=UTF8ToString(labelPtr);return WebGPU.mgrSurface.create(context)}function _wgpuInstanceRelease(){}function callUserCallback(func){if(ABORT){return}try{func()}catch(e){handleException(e)}}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function _wgpuInstanceRequestAdapter(instanceId,options,callback,userdata){var opts;if(options){opts={"powerPreference":WebGPU.PowerPreference[HEAPU32[options+8>>2]],"forceFallbackAdapter":HEAP8[options+12>>0]!==0}}if(!("gpu"in navigator)){var messagePtr=allocateUTF8("WebGPU not available on this browser (navigator.gpu is not available)");getWasmTableEntry(callback)(1,0,messagePtr,userdata);_free(messagePtr);return}navigator["gpu"]["requestAdapter"](opts).then(function(adapter){callUserCallback(function(){if(adapter){var adapterId=WebGPU.mgrAdapter.create(adapter);getWasmTableEntry(callback)(0,adapterId,0,userdata)}else{var messagePtr=allocateUTF8("WebGPU not available on this system (requestAdapter returned null)");getWasmTableEntry(callback)(1,0,messagePtr,userdata);_free(messagePtr)}})},function(ex){callUserCallback(function(){var messagePtr=allocateUTF8(ex.message);getWasmTableEntry(callback)(2,0,messagePtr,userdata);_free(messagePtr)})})}function _wgpuPipelineLayoutRelease(id){WebGPU.mgrPipelineLayout.release(id)}function _wgpuQuerySetDestroy(querySetId){WebGPU.mgrQuerySet.get(querySetId)["destroy"]()}function _wgpuQuerySetRelease(id){WebGPU.mgrQuerySet.release(id)}function _wgpuQueueOnSubmittedWorkDone(queueId,signalValue_low,signalValue_high,callback,userdata){var queue=WebGPU.mgrQueue.get(queueId);queue["onSubmittedWorkDone"]().then(function(){callUserCallback(function(){getWasmTableEntry(callback)(0,userdata)})},function(){callUserCallback(function(){getWasmTableEntry(callback)(1,userdata)})})}function _wgpuQueueRelease(id){WebGPU.mgrQueue.release(id)}function _wgpuQueueSubmit(queueId,commandCount,commands){var queue=WebGPU.mgrQueue.get(queueId);var cmds=Array.from(HEAP32.subarray(commands>>2,(commands>>2)+commandCount),function(id){return WebGPU.mgrCommandBuffer.get(id)});queue["submit"](cmds)}function _wgpuQueueWriteBuffer(queueId,bufferId,bufferOffset_low,bufferOffset_high,data,size){var queue=WebGPU.mgrQueue.get(queueId);var buffer=WebGPU.mgrBuffer.get(bufferId);var bufferOffset=bufferOffset_high*4294967296+bufferOffset_low;var subarray=HEAPU8.subarray(data,data+size);queue["writeBuffer"](buffer,bufferOffset,subarray,0,size)}function _wgpuQueueWriteTexture(queueId,destinationPtr,data,dataSize,dataLayoutPtr,writeSizePtr){var queue=WebGPU.mgrQueue.get(queueId);var destination=WebGPU.makeImageCopyTexture(destinationPtr);var dataLayout=WebGPU.makeTextureDataLayout(dataLayoutPtr);var writeSize=WebGPU.makeExtent3D(writeSizePtr);var subarray=HEAPU8.subarray(data,data+dataSize);queue["writeTexture"](destination,subarray,dataLayout,writeSize)}function _wgpuRenderPassEncoderDraw(passId,vertexCount,instanceCount,firstVertex,firstInstance){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["draw"](vertexCount,instanceCount,firstVertex,firstInstance)}function _wgpuRenderPassEncoderDrawIndexed(passId,indexCount,instanceCount,firstIndex,baseVertex,firstInstance){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["drawIndexed"](indexCount,instanceCount,firstIndex,baseVertex,firstInstance)}function _wgpuRenderPassEncoderDrawIndirect(passId,indirectBufferId,indirectOffset_low,indirectOffset_high){var indirectBuffer=WebGPU.mgrBuffer.get(indirectBufferId);var indirectOffset=indirectOffset_high*4294967296+indirectOffset_low;var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["drawIndirect"](indirectBuffer,indirectOffset)}function _wgpuRenderPassEncoderEnd(passId){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["end"]()}function _wgpuRenderPassEncoderRelease(id){WebGPU.mgrRenderPassEncoder.release(id)}function _wgpuRenderPassEncoderSetBindGroup(passId,groupIndex,groupId,dynamicOffsetCount,dynamicOffsetsPtr){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var group=WebGPU.mgrBindGroup.get(groupId);if(dynamicOffsetCount==0){pass["setBindGroup"](groupIndex,group)}else{var offsets=[];for(var i=0;i>2])}pass["setBindGroup"](groupIndex,group,offsets)}}function _wgpuRenderPassEncoderSetBlendConstant(passId,colorPtr){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var color=WebGPU.makeColor(colorPtr);pass["setBlendConstant"](color)}function _wgpuRenderPassEncoderSetIndexBuffer(passId,bufferId,format,offset_low,offset_high,size_low,size_high){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var buffer=WebGPU.mgrBuffer.get(bufferId);var offset=offset_high*4294967296+offset_low;var size=size_high===-1&&size_low===-1?undefined:size_high*4294967296+size_low;pass["setIndexBuffer"](buffer,WebGPU.IndexFormat[format],offset,size)}function _wgpuRenderPassEncoderSetPipeline(passId,pipelineId){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var pipeline=WebGPU.mgrRenderPipeline.get(pipelineId);pass["setPipeline"](pipeline)}function _wgpuRenderPassEncoderSetScissorRect(passId,x,y,w,h){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["setScissorRect"](x,y,w,h)}function _wgpuRenderPassEncoderSetStencilReference(passId,reference){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["setStencilReference"](reference)}function _wgpuRenderPassEncoderSetVertexBuffer(passId,slot,bufferId,offset_low,offset_high,size_low,size_high){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var buffer=WebGPU.mgrBuffer.get(bufferId);var offset=offset_high*4294967296+offset_low;var size=size_high===-1&&size_low===-1?undefined:size_high*4294967296+size_low;pass["setVertexBuffer"](slot,buffer,offset,size)}function _wgpuRenderPassEncoderSetViewport(passId,x,y,w,h,minDepth,maxDepth){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["setViewport"](x,y,w,h,minDepth,maxDepth)}function _wgpuRenderPipelineRelease(id){WebGPU.mgrRenderPipeline.release(id)}function _wgpuSamplerRelease(id){WebGPU.mgrSampler.release(id)}function _wgpuShaderModuleRelease(id){WebGPU.mgrShaderModule.release(id)}function _wgpuSurfaceRelease(id){WebGPU.mgrSurface.release(id)}function _wgpuSwapChainGetCurrentTextureView(swapChainId){var context=WebGPU.mgrSwapChain.get(swapChainId);return WebGPU.mgrTextureView.create(context["getCurrentTexture"]()["createView"]())}function _wgpuSwapChainRelease(id){WebGPU.mgrSwapChain.release(id)}function _wgpuTextureCreateView(textureId,descriptor){var desc;if(descriptor){var mipLevelCount=HEAPU32[descriptor+20>>2];var arrayLayerCount=HEAPU32[descriptor+28>>2];desc={"format":WebGPU.TextureFormat[HEAPU32[descriptor+8>>2]],"dimension":WebGPU.TextureViewDimension[HEAPU32[descriptor+12>>2]],"baseMipLevel":HEAPU32[descriptor+16>>2],"mipLevelCount":mipLevelCount===4294967295?undefined:mipLevelCount,"baseArrayLayer":HEAPU32[descriptor+24>>2],"arrayLayerCount":arrayLayerCount===4294967295?undefined:arrayLayerCount,"aspect":WebGPU.TextureAspect[HEAPU32[descriptor+32>>2]]};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr)}var texture=WebGPU.mgrTexture.get(textureId);return WebGPU.mgrTextureView.create(texture["createView"](desc))}function _wgpuTextureDestroy(textureId){WebGPU.mgrTexture.get(textureId)["destroy"]()}function _wgpuTextureRelease(id){WebGPU.mgrTexture.release(id)}function _wgpuTextureViewRelease(id){WebGPU.mgrTextureView.release(id)}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();WebGPU.initManagers();var asmLibraryArg={"h":__embind_finalize_value_object,"Ta":__embind_register_bigint,"na":__embind_register_bool,"m":__embind_register_class,"K":__embind_register_class_class_function,"q":__embind_register_class_constructor,"d":__embind_register_class_function,"c":__embind_register_class_property,"ma":__embind_register_emval,"Q":__embind_register_float,"s":__embind_register_integer,"r":__embind_register_memory_view,"R":__embind_register_std_string,"D":__embind_register_std_wstring,"i":__embind_register_value_object,"a":__embind_register_value_object_field,"oa":__embind_register_void,"k":__emval_as,"V":__emval_call_void_method,"b":__emval_decref,"W":__emval_get_method_caller,"g":__emval_get_property,"l":__emval_incref,"p":__emval_new_array,"n":__emval_new_cstring,"j":__emval_run_destructors,"o":__emval_set_property,"f":__emval_take_value,"e":_abort,"ka":_emscripten_memcpy_big,"C":_emscripten_resize_heap,"Ba":_emscripten_webgpu_get_device,"ha":_environ_get,"ia":_environ_sizes_get,"ja":_fd_write,"P":_setTempRet0,"Ga":_wgpuAdapterGetProperties,"J":_wgpuAdapterHasFeature,"Da":_wgpuAdapterRelease,"Ha":_wgpuBindGroupRelease,"ca":_wgpuBufferDestroy,"O":_wgpuBufferGetMappedRange,"ba":_wgpuBufferRelease,"B":_wgpuBufferUnmap,"N":_wgpuCommandBufferRelease,"Ja":_wgpuCommandEncoderBeginComputePass,"pa":_wgpuCommandEncoderBeginRenderPass,"Wa":_wgpuCommandEncoderCopyBufferToBuffer,"da":_wgpuCommandEncoderCopyBufferToTexture,"Ka":_wgpuCommandEncoderCopyTextureToTexture,"u":_wgpuCommandEncoderFinish,"x":_wgpuCommandEncoderRelease,"Ia":_wgpuComputePassEncoderDispatchWorkgroups,"Va":_wgpuComputePassEncoderDispatchWorkgroupsIndirect,"ya":_wgpuComputePassEncoderEnd,"wa":_wgpuComputePassEncoderRelease,"Sa":_wgpuComputePassEncoderSetBindGroup,"Ra":_wgpuComputePassEncoderSetPipeline,"S":_wgpuComputePipelineRelease,"M":_wgpuDeviceCreateBindGroup,"L":_wgpuDeviceCreateBindGroupLayout,"v":_wgpuDeviceCreateBuffer,"y":_wgpuDeviceCreateCommandEncoder,"va":_wgpuDeviceCreateComputePipeline,"xa":_wgpuDeviceCreatePipelineLayout,"ua":_wgpuDeviceCreateRenderPipeline,"ta":_wgpuDeviceCreateSampler,"G":_wgpuDeviceCreateShaderModule,"qa":_wgpuDeviceCreateSwapChain,"E":_wgpuDeviceCreateTexture,"Y":_wgpuDeviceGetQueue,"Ca":_wgpuDeviceRelease,"Aa":_wgpuInstanceCreateSurface,"Ea":_wgpuInstanceRelease,"za":_wgpuInstanceRequestAdapter,"U":_wgpuPipelineLayoutRelease,"_":_wgpuQuerySetDestroy,"Z":_wgpuQuerySetRelease,"Ua":_wgpuQueueOnSubmittedWorkDone,"I":_wgpuQueueRelease,"z":_wgpuQueueSubmit,"ga":_wgpuQueueWriteBuffer,"X":_wgpuQueueWriteTexture,"La":_wgpuRenderPassEncoderDraw,"ea":_wgpuRenderPassEncoderDrawIndexed,"Xa":_wgpuRenderPassEncoderDrawIndirect,"la":_wgpuRenderPassEncoderEnd,"Za":_wgpuRenderPassEncoderRelease,"A":_wgpuRenderPassEncoderSetBindGroup,"Pa":_wgpuRenderPassEncoderSetBlendConstant,"Ya":_wgpuRenderPassEncoderSetIndexBuffer,"Qa":_wgpuRenderPassEncoderSetPipeline,"Na":_wgpuRenderPassEncoderSetScissorRect,"Ma":_wgpuRenderPassEncoderSetStencilReference,"fa":_wgpuRenderPassEncoderSetVertexBuffer,"Oa":_wgpuRenderPassEncoderSetViewport,"T":_wgpuRenderPipelineRelease,"sa":_wgpuSamplerRelease,"H":_wgpuShaderModuleRelease,"Fa":_wgpuSurfaceRelease,"F":_wgpuSwapChainGetCurrentTextureView,"ra":_wgpuSwapChainRelease,"w":_wgpuTextureCreateView,"aa":_wgpuTextureDestroy,"$":_wgpuTextureRelease,"t":_wgpuTextureViewRelease};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["$a"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["bb"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["cb"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["db"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["eb"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["fb"]).apply(null,arguments)};var dynCall_viij=Module["dynCall_viij"]=function(){return(dynCall_viij=Module["dynCall_viij"]=Module["asm"]["gb"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["hb"]).apply(null,arguments)};var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); +var Module=typeof wasmDevice!="undefined"?wasmDevice:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var POINTER_SIZE=4;var tempRet0=0;var setTempRet0=value=>{tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heapOrArray,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}var wasmBinaryFile;wasmBinaryFile="webgpu_wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["$a"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["bb"];addOnInit(Module["asm"]["ab"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){callbacks.shift()(Module)}}function handleException(e){if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function __embind_finalize_value_object(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(field=>field.getterReturnType).concat(fieldRecords.map(field=>field.setterArgumentType));whenDependentTypesAreResolved([structType],fieldTypes,fieldTypes=>{var fields={};fieldRecords.forEach((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>{return getterReturnType["fromWireType"](getter(getterContext,ptr))},write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError('Missing field: "'+fieldName+'"')}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]})}function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}var name=registeredInstance.name;if(!rawType){throwBindingError('type "'+name+'" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError("Cannot register type '"+name+"' twice")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function attachFinalizer(handle){if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}var wasmTableMirror=[];function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func}function dynCall(sig,ptr,args){if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn}function getDynCaller(sig,ptr){var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError("unknown function pointer with signature "+signature+": "+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+": "+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError("Cannot construct "+name+" due to unbound types",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError("Tried to invoke ctor of "+name+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(registeredClass.constructor_body).toString()+") parameters instead!")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function new_(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError("new_ called with constructor type "+typeof constructor+" which is not a function")}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}function validateThis(this_,classType,humanName){if(!(this_ instanceof Object)){throwBindingError(humanName+' with invalid "this": '+this_)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(humanName+' incompatible with "this" of type '+this_.constructor.name)}if(!this_.$$.ptr){throwBindingError("cannot call emscripten binding method "+humanName+" on deleted object")}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)}function __embind_register_class_property(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){fieldName=readLatin1String(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],function(classType){classType=classType[0];var humanName=classType.name+"."+fieldName;var desc={get:function(){throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=()=>{throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])}}else{desc.set=v=>{throwBindingError(humanName+" is a read-only property")}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],function(types){var getterReturnType=types[0];var desc={get:function(){var ptr=validateThis(this,classType,humanName+" getter");return getterReturnType["fromWireType"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+" setter");var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":function(destructors,value){return Emval.toHandle(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value=="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __emval_as(handle,returnType,destructorsRef){handle=Emval.toValue(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=Emval.toHandle(destructors);HEAPU32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}return symbol}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=Emval.toValue(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i>2],"parameter "+i)}return a}var emval_registeredMethods=[];function __emval_get_method_caller(argCount,argTypes){var types=emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var returnId=emval_registeredMethods[signatureName];if(returnId!==undefined){return returnId}var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function __emval_new_array(){return Emval.toHandle([])}function __emval_new_cstring(v){return Emval.toHandle(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=Emval.toValue(handle);runDestructors(destructors);__emval_decref(handle)}function __emval_set_property(handle,key,value){handle=Emval.toValue(handle);key=Emval.toValue(key);value=Emval.toValue(value);handle[key]=value}function __emval_take_value(type,arg){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)}function _abort(){abort("")}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}let alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var WebGPU={initManagers:function(){if(WebGPU.mgrDevice)return;function Manager(){this.objects={};this.nextId=1;this.create=function(object,wrapper){wrapper=wrapper||{};var id=this.nextId++;wrapper.refcount=1;wrapper.object=object;this.objects[id]=wrapper;return id};this.get=function(id){if(!id)return undefined;var o=this.objects[id];return o.object};this.reference=function(id){var o=this.objects[id];o.refcount++};this.release=function(id){var o=this.objects[id];o.refcount--;if(o.refcount<=0){delete this.objects[id]}}}WebGPU.mgrSurface=WebGPU.mgrSurface||new Manager;WebGPU.mgrSwapChain=WebGPU.mgrSwapChain||new Manager;WebGPU.mgrAdapter=WebGPU.mgrAdapter||new Manager;WebGPU.mgrDevice=WebGPU.mgrDevice||new Manager;WebGPU.mgrQueue=WebGPU.mgrQueue||new Manager;WebGPU.mgrCommandBuffer=WebGPU.mgrCommandBuffer||new Manager;WebGPU.mgrCommandEncoder=WebGPU.mgrCommandEncoder||new Manager;WebGPU.mgrRenderPassEncoder=WebGPU.mgrRenderPassEncoder||new Manager;WebGPU.mgrComputePassEncoder=WebGPU.mgrComputePassEncoder||new Manager;WebGPU.mgrBindGroup=WebGPU.mgrBindGroup||new Manager;WebGPU.mgrBuffer=WebGPU.mgrBuffer||new Manager;WebGPU.mgrSampler=WebGPU.mgrSampler||new Manager;WebGPU.mgrTexture=WebGPU.mgrTexture||new Manager;WebGPU.mgrTextureView=WebGPU.mgrTextureView||new Manager;WebGPU.mgrQuerySet=WebGPU.mgrQuerySet||new Manager;WebGPU.mgrBindGroupLayout=WebGPU.mgrBindGroupLayout||new Manager;WebGPU.mgrPipelineLayout=WebGPU.mgrPipelineLayout||new Manager;WebGPU.mgrRenderPipeline=WebGPU.mgrRenderPipeline||new Manager;WebGPU.mgrComputePipeline=WebGPU.mgrComputePipeline||new Manager;WebGPU.mgrShaderModule=WebGPU.mgrShaderModule||new Manager;WebGPU.mgrRenderBundleEncoder=WebGPU.mgrRenderBundleEncoder||new Manager;WebGPU.mgrRenderBundle=WebGPU.mgrRenderBundle||new Manager},makeColor:function(ptr){return{"r":HEAPF64[ptr>>3],"g":HEAPF64[ptr+8>>3],"b":HEAPF64[ptr+16>>3],"a":HEAPF64[ptr+24>>3]}},makeExtent3D:function(ptr){return{"width":HEAPU32[ptr>>2],"height":HEAPU32[ptr+4>>2],"depthOrArrayLayers":HEAPU32[ptr+8>>2]}},makeOrigin3D:function(ptr){return{"x":HEAPU32[ptr>>2],"y":HEAPU32[ptr+4>>2],"z":HEAPU32[ptr+8>>2]}},makeImageCopyTexture:function(ptr){return{"texture":WebGPU.mgrTexture.get(HEAPU32[ptr+4>>2]),"mipLevel":HEAPU32[ptr+8>>2],"origin":WebGPU.makeOrigin3D(ptr+12),"aspect":WebGPU.TextureAspect[HEAPU32[ptr+24>>2]]}},makeTextureDataLayout:function(ptr){var bytesPerRow=HEAPU32[ptr+16>>2];var rowsPerImage=HEAPU32[ptr+20>>2];return{"offset":HEAPU32[ptr+4+8>>2]*4294967296+HEAPU32[ptr+8>>2],"bytesPerRow":bytesPerRow===4294967295?undefined:bytesPerRow,"rowsPerImage":rowsPerImage===4294967295?undefined:rowsPerImage}},makeImageCopyBuffer:function(ptr){var layoutPtr=ptr+8;var bufferCopyView=WebGPU.makeTextureDataLayout(layoutPtr);bufferCopyView["buffer"]=WebGPU.mgrBuffer.get(HEAPU32[ptr+32>>2]);return bufferCopyView},makePipelineConstants:function(constantCount,constantsPtr){if(!constantCount)return;var constants={};for(var i=0;i>2]);constants[key]=HEAPF64[entryPtr+8>>3]}return constants},makeProgrammableStageDescriptor:function(ptr){if(!ptr)return undefined;return{"module":WebGPU.mgrShaderModule.get(HEAPU32[ptr+4>>2]),"entryPoint":UTF8ToString(HEAPU32[ptr+8>>2]),"constants":WebGPU.makePipelineConstants(HEAPU32[ptr+12>>2],HEAPU32[ptr+16>>2])}},DeviceLostReason:{undefined:0,destroyed:1},PreferredFormat:{rgba8unorm:18,bgra8unorm:23},AddressMode:["repeat","mirror-repeat","clamp-to-edge"],BlendFactor:["zero","one","src","one-minus-src","src-alpha","one-minus-src-alpha","dst","one-minus-dst","dst-alpha","one-minus-dst-alpha","src-alpha-saturated","constant","one-minus-constant"],BlendOperation:["add","subtract","reverse-subtract","min","max"],BufferBindingType:[,"uniform","storage","read-only-storage"],CompareFunction:[,"never","less","less-equal","greater","greater-equal","equal","not-equal","always"],CompilationInfoRequestStatus:["success","error","device-lost","unknown"],ComputePassTimestampLocation:["beginning","end"],CullMode:["none","front","back"],ErrorFilter:["validation","out-of-memory"],FeatureName:{0:undefined,1:"depth-clip-control",2:"depth24unorm-stencil8",3:"depth32float-stencil8",4:"timestamp-query",5:"pipeline-statistics-query",6:"texture-compression-bc",7:"texture-compression-etc2",8:"texture-compression-astc",9:"indirect-first-instance",1e3:"depth-clamping"},FilterMode:["nearest","linear"],FrontFace:["ccw","cw"],IndexFormat:[,"uint16","uint32"],LoadOp:[,"clear","load"],PipelineStatisticName:["vertex-shader-invocations","clipper-invocations","clipper-primitives-out","fragment-shader-invocations","compute-shader-invocations"],PowerPreference:[,"low-power","high-performance"],PredefinedColorSpace:[,"srgb"],PrimitiveTopology:["point-list","line-list","line-strip","triangle-list","triangle-strip"],QueryType:["occlusion","pipeline-statistics","timestamp"],RenderPassTimestampLocation:["beginning","end"],SamplerBindingType:[,"filtering","non-filtering","comparison"],StencilOperation:["keep","zero","replace","invert","increment-clamp","decrement-clamp","increment-wrap","decrement-wrap"],StorageTextureAccess:[,"write-only"],StoreOp:[,"store","discard"],TextureAspect:["all","stencil-only","depth-only"],TextureComponentType:["float","sint","uint","depth-comparison"],TextureDimension:["1d","2d","3d"],TextureFormat:[,"r8unorm","r8snorm","r8uint","r8sint","r16uint","r16sint","r16float","rg8unorm","rg8snorm","rg8uint","rg8sint","r32float","r32uint","r32sint","rg16uint","rg16sint","rg16float","rgba8unorm","rgba8unorm-srgb","rgba8snorm","rgba8uint","rgba8sint","bgra8unorm","bgra8unorm-srgb","rgb10a2unorm","rg11b10ufloat","rgb9e5ufloat","rg32float","rg32uint","rg32sint","rgba16uint","rgba16sint","rgba16float","rgba32float","rgba32uint","rgba32sint","stencil8","depth16unorm","depth24plus","depth24plus-stencil8","depth24unorm-stencil8","depth32float","depth32float-stencil8","bc1-rgba-unorm","bc1-rgba-unorm-srgb","bc2-rgba-unorm","bc2-rgba-unorm-srgb","bc3-rgba-unorm","bc3-rgba-unorm-srgb","bc4-r-unorm","bc4-r-snorm","bc5-rg-unorm","bc5-rg-snorm","bc6h-rgb-ufloat","bc6h-rgb-float","bc7-rgba-unorm","bc7-rgba-unorm-srgb","etc2-rgb8unorm","etc2-rgb8unorm-srgb","etc2-rgb8a1unorm","etc2-rgb8a1unorm-srgb","etc2-rgba8unorm","etc2-rgba8unorm-srgb","eac-r11unorm","eac-r11snorm","eac-rg11unorm","eac-rg11snorm","astc-4x4-unorm","astc-4x4-unorm-srgb","astc-5x4-unorm","astc-5x4-unorm-srgb","astc-5x5-unorm","astc-5x5-unorm-srgb","astc-6x5-unorm","astc-6x5-unorm-srgb","astc-6x6-unorm","astc-6x6-unorm-srgb","astc-8x5-unorm","astc-8x5-unorm-srgb","astc-8x6-unorm","astc-8x6-unorm-srgb","astc-8x8-unorm","astc-8x8-unorm-srgb","astc-10x5-unorm","astc-10x5-unorm-srgb","astc-10x6-unorm","astc-10x6-unorm-srgb","astc-10x8-unorm","astc-10x8-unorm-srgb","astc-10x10-unorm","astc-10x10-unorm-srgb","astc-12x10-unorm","astc-12x10-unorm-srgb","astc-12x12-unorm","astc-12x12-unorm-srgb"],TextureSampleType:[,"float","unfilterable-float","depth","sint","uint"],TextureViewDimension:[,"1d","2d","2d-array","cube","cube-array","3d"],VertexFormat:[,"uint8x2","uint8x4","sint8x2","sint8x4","unorm8x2","unorm8x4","snorm8x2","snorm8x4","uint16x2","uint16x4","sint16x2","sint16x4","unorm16x2","unorm16x4","snorm16x2","snorm16x4","float16x2","float16x4","float32","float32x2","float32x3","float32x4","uint32","uint32x2","uint32x3","uint32x4","sint32","sint32x2","sint32x3","sint32x4"],VertexStepMode:["vertex","instance"],FeatureNameString2Enum:{undefined:"0","depth-clip-control":"1","depth24unorm-stencil8":"2","depth32float-stencil8":"3","timestamp-query":"4","pipeline-statistics-query":"5","texture-compression-bc":"6","texture-compression-etc2":"7","texture-compression-astc":"8","indirect-first-instance":"9","depth-clamping":"1000"}};function _emscripten_webgpu_get_device(){var device=Module["preinitializedWebGPUDevice"];var deviceWrapper={queueId:WebGPU.mgrQueue.create(device["queue"])};return WebGPU.mgrDevice.create(device,deviceWrapper)}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var SYSCALLS={varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret}};function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAPU32[penviron_buf_size>>2]=bufSize;return 0}var printCharBuffers=[null,[],[]];function printChar(stream,curr){var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0}function _setTempRet0(val){setTempRet0(val)}function _wgpuAdapterGetProperties(adapterId,properties){HEAP32[properties+4>>2]=0;HEAP32[properties+8>>2]=0;HEAP32[properties+12>>2]=0;HEAP32[properties+16>>2]=0;HEAP32[properties+20>>2]=3;HEAP32[properties+24>>2]=1}function _wgpuAdapterHasFeature(adapterId,featureEnumValue){var adapter=WebGPU.mgrAdapter.get(adapterId);return adapter.features.has(WebGPU.FeatureName[featureEnumValue])}function _wgpuAdapterRelease(id){WebGPU.mgrAdapter.release(id)}function _wgpuBindGroupRelease(id){WebGPU.mgrBindGroup.release(id)}function _wgpuBufferDestroy(bufferId){WebGPU.mgrBuffer.get(bufferId)["destroy"]()}function _wgpuBufferGetMappedRange(bufferId,offset,size){var bufferWrapper=WebGPU.mgrBuffer.objects[bufferId];if(size===0)warnOnce("getMappedRange size=0 no longer means WGPU_WHOLE_MAP_SIZE");size=size>>>0;if(size===4294967295)size=undefined;if(bufferWrapper.mapMode!==2){return 0}var mapped;try{mapped=bufferWrapper.object["getMappedRange"](offset,size)}catch(ex){return 0}var data=_malloc(mapped.byteLength);HEAPU8.fill(0,data,mapped.byteLength);bufferWrapper.onUnmap.push(function(){new Uint8Array(mapped).set(HEAPU8.subarray(data,data+mapped.byteLength));_free(data)});return data}function _wgpuBufferRelease(id){WebGPU.mgrBuffer.release(id)}function _wgpuBufferUnmap(bufferId){var bufferWrapper=WebGPU.mgrBuffer.objects[bufferId];if(!bufferWrapper.onUnmap){return}for(var i=0;i>2]),"queryIndex":HEAPU32[twPtr+4>>2],"location":WebGPU.ComputePassTimestampLocation[HEAPU32[twPtr+8>>2]]}}function makeComputePassTimestampWrites(count,twPtr){var timestampWrites=[];for(var i=0;i>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var timestampWriteCount=HEAPU32[descriptor+8>>2];if(timestampWriteCount){desc["timestampWrites"]=makeComputePassTimestampWrites(timestampWriteCount,HEAPU32[descriptor+12>>2])}}var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);return WebGPU.mgrComputePassEncoder.create(commandEncoder["beginComputePass"](desc))}function _wgpuCommandEncoderBeginRenderPass(encoderId,descriptor){function makeColorAttachment(caPtr){var viewPtr=HEAPU32[caPtr>>2];if(viewPtr===0){return undefined}var loadOpInt=HEAPU32[caPtr+8>>2];var storeOpInt=HEAPU32[caPtr+12>>2];var clearValue=WebGPU.makeColor(caPtr+16);return{"view":WebGPU.mgrTextureView.get(viewPtr),"resolveTarget":WebGPU.mgrTextureView.get(HEAPU32[caPtr+4>>2]),"clearValue":clearValue,"loadOp":WebGPU.LoadOp[loadOpInt],"storeOp":WebGPU.StoreOp[storeOpInt]}}function makeColorAttachments(count,caPtr){var attachments=[];for(var i=0;i>2]),"depthClearValue":HEAPF32[dsaPtr+12>>2],"depthLoadOp":WebGPU.LoadOp[HEAPU32[dsaPtr+4>>2]],"depthStoreOp":WebGPU.StoreOp[HEAPU32[dsaPtr+8>>2]],"depthReadOnly":HEAP8[dsaPtr+16>>0]!==0,"stencilClearValue":HEAPU32[dsaPtr+28>>2],"stencilLoadOp":WebGPU.LoadOp[HEAPU32[dsaPtr+20>>2]],"stencilStoreOp":WebGPU.StoreOp[HEAPU32[dsaPtr+24>>2]],"stencilReadOnly":HEAP8[dsaPtr+32>>0]!==0}}function makeRenderPassTimestampWrite(twPtr){return{"querySet":WebGPU.mgrQuerySet.get(HEAPU32[twPtr>>2]),"queryIndex":HEAPU32[twPtr+4>>2],"location":WebGPU.RenderPassTimestampLocation[HEAPU32[twPtr+8>>2]]}}function makeRenderPassTimestampWrites(count,twPtr){var timestampWrites=[];for(var i=0;i>2],HEAPU32[descriptor+12>>2]),"depthStencilAttachment":makeDepthStencilAttachment(HEAPU32[descriptor+16>>2]),"occlusionQuerySet":WebGPU.mgrQuerySet.get(HEAPU32[descriptor+20>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var timestampWriteCount=HEAPU32[descriptor+24>>2];if(timestampWriteCount){desc["timestampWrites"]=makeRenderPassTimestampWrites(timestampWriteCount,HEAPU32[descriptor+28>>2])}return desc}var desc=makeRenderPassDescriptor(descriptor);var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);return WebGPU.mgrRenderPassEncoder.create(commandEncoder["beginRenderPass"](desc))}function _wgpuCommandEncoderCopyBufferToBuffer(encoderId,srcId,srcOffset_low,srcOffset_high,dstId,dstOffset_low,dstOffset_high,size_low,size_high){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);var src=WebGPU.mgrBuffer.get(srcId);var dst=WebGPU.mgrBuffer.get(dstId);commandEncoder["copyBufferToBuffer"](src,srcOffset_high*4294967296+srcOffset_low,dst,dstOffset_high*4294967296+dstOffset_low,size_high*4294967296+size_low)}function _wgpuCommandEncoderCopyBufferToTexture(encoderId,srcPtr,dstPtr,copySizePtr){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);var copySize=WebGPU.makeExtent3D(copySizePtr);commandEncoder["copyBufferToTexture"](WebGPU.makeImageCopyBuffer(srcPtr),WebGPU.makeImageCopyTexture(dstPtr),copySize)}function _wgpuCommandEncoderCopyTextureToTexture(encoderId,srcPtr,dstPtr,copySizePtr){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);var copySize=WebGPU.makeExtent3D(copySizePtr);commandEncoder["copyTextureToTexture"](WebGPU.makeImageCopyTexture(srcPtr),WebGPU.makeImageCopyTexture(dstPtr),copySize)}function _wgpuCommandEncoderFinish(encoderId){var commandEncoder=WebGPU.mgrCommandEncoder.get(encoderId);return WebGPU.mgrCommandBuffer.create(commandEncoder["finish"]())}function _wgpuCommandEncoderRelease(id){WebGPU.mgrCommandEncoder.release(id)}function _wgpuComputePassEncoderDispatchWorkgroups(passId,x,y,z){var pass=WebGPU.mgrComputePassEncoder.get(passId);if(pass["dispatchWorkgroups"]){pass["dispatchWorkgroups"](x,y,z)}else{pass["dispatch"](x,y,z)}}function _wgpuComputePassEncoderDispatchWorkgroupsIndirect(passId,indirectBufferId,indirectOffset_low,indirectOffset_high){var indirectBuffer=WebGPU.mgrBuffer.get(indirectBufferId);var indirectOffset=indirectOffset_high*4294967296+indirectOffset_low;var pass=WebGPU.mgrComputePassEncoder.get(passId);if(pass["dispatchWorkgroupsIndirect"]){pass["dispatchWorkgroupsIndirect"](indirectBuffer,indirectOffset)}else{pass["dispatchIndirect"](indirectBuffer,indirectOffset)}}function _wgpuComputePassEncoderEnd(passId){var pass=WebGPU.mgrComputePassEncoder.get(passId);pass["end"]()}function _wgpuComputePassEncoderRelease(id){WebGPU.mgrComputePassEncoder.release(id)}function _wgpuComputePassEncoderSetBindGroup(passId,groupIndex,groupId,dynamicOffsetCount,dynamicOffsetsPtr){var pass=WebGPU.mgrComputePassEncoder.get(passId);var group=WebGPU.mgrBindGroup.get(groupId);if(dynamicOffsetCount==0){pass["setBindGroup"](groupIndex,group)}else{var offsets=[];for(var i=0;i>2])}pass["setBindGroup"](groupIndex,group,offsets)}}function _wgpuComputePassEncoderSetPipeline(passId,pipelineId){var pass=WebGPU.mgrComputePassEncoder.get(passId);var pipeline=WebGPU.mgrComputePipeline.get(pipelineId);pass["setPipeline"](pipeline)}function _wgpuComputePipelineRelease(id){WebGPU.mgrComputePipeline.release(id)}function _wgpuDeviceCreateBindGroup(deviceId,descriptor){function makeEntry(entryPtr){var bufferId=HEAPU32[entryPtr+8>>2];var samplerId=HEAPU32[entryPtr+32>>2];var textureViewId=HEAPU32[entryPtr+36>>2];var binding=HEAPU32[entryPtr+4>>2];if(bufferId){var size_low=HEAPU32[entryPtr+24>>2];var size_high=HEAPU32[entryPtr+28>>2];var size=size_high===-1&&size_low===-1?undefined:size_high*4294967296+size_low;return{"binding":binding,"resource":{"buffer":WebGPU.mgrBuffer.get(bufferId),"offset":HEAPU32[entryPtr+4+16>>2]*4294967296+HEAPU32[entryPtr+16>>2],"size":size}}}else if(samplerId){return{"binding":binding,"resource":WebGPU.mgrSampler.get(samplerId)}}else{return{"binding":binding,"resource":WebGPU.mgrTextureView.get(textureViewId)}}}function makeEntries(count,entriesPtrs){var entries=[];for(var i=0;i>2]),"entries":makeEntries(HEAPU32[descriptor+12>>2],HEAPU32[descriptor+16>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrBindGroup.create(device["createBindGroup"](desc))}function _wgpuDeviceCreateBindGroupLayout(deviceId,descriptor){function makeBufferEntry(entryPtr){var typeInt=HEAPU32[entryPtr+4>>2];if(!typeInt)return undefined;return{"type":WebGPU.BufferBindingType[typeInt],"hasDynamicOffset":HEAP8[entryPtr+8>>0]!==0,"minBindingSize":HEAPU32[entryPtr+4+16>>2]*4294967296+HEAPU32[entryPtr+16>>2]}}function makeSamplerEntry(entryPtr){var typeInt=HEAPU32[entryPtr+4>>2];if(!typeInt)return undefined;return{"type":WebGPU.SamplerBindingType[typeInt]}}function makeTextureEntry(entryPtr){var sampleTypeInt=HEAPU32[entryPtr+4>>2];if(!sampleTypeInt)return undefined;return{"sampleType":WebGPU.TextureSampleType[sampleTypeInt],"viewDimension":WebGPU.TextureViewDimension[HEAPU32[entryPtr+8>>2]],"multisampled":HEAP8[entryPtr+12>>0]!==0}}function makeStorageTextureEntry(entryPtr){var accessInt=HEAPU32[entryPtr+4>>2];if(!accessInt)return undefined;return{"access":WebGPU.StorageTextureAccess[accessInt],"format":WebGPU.TextureFormat[HEAPU32[entryPtr+8>>2]],"viewDimension":WebGPU.TextureViewDimension[HEAPU32[entryPtr+12>>2]]}}function makeEntry(entryPtr){return{"binding":HEAPU32[entryPtr+4>>2],"visibility":HEAPU32[entryPtr+8>>2],"buffer":makeBufferEntry(entryPtr+16),"sampler":makeSamplerEntry(entryPtr+40),"texture":makeTextureEntry(entryPtr+48),"storageTexture":makeStorageTextureEntry(entryPtr+64)}}function makeEntries(count,entriesPtrs){var entries=[];for(var i=0;i>2],HEAPU32[descriptor+12>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrBindGroupLayout.create(device["createBindGroupLayout"](desc))}function _wgpuDeviceCreateBuffer(deviceId,descriptor){var mappedAtCreation=HEAP8[descriptor+24>>0]!==0;var desc={"label":undefined,"usage":HEAPU32[descriptor+8>>2],"size":HEAPU32[descriptor+4+16>>2]*4294967296+HEAPU32[descriptor+16>>2],"mappedAtCreation":mappedAtCreation};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);var bufferWrapper={};var id=WebGPU.mgrBuffer.create(device["createBuffer"](desc),bufferWrapper);if(mappedAtCreation){bufferWrapper.mapMode=2;bufferWrapper.onUnmap=[]}return id}function _wgpuDeviceCreateCommandEncoder(deviceId,descriptor){var desc;if(descriptor){desc={"label":undefined};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr)}var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrCommandEncoder.create(device["createCommandEncoder"](desc))}function _wgpuDeviceCreateComputePipeline(deviceId,descriptor){var desc={"label":undefined,"layout":WebGPU.mgrPipelineLayout.get(HEAPU32[descriptor+8>>2]),"compute":WebGPU.makeProgrammableStageDescriptor(descriptor+12)};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrComputePipeline.create(device["createComputePipeline"](desc))}function _wgpuDeviceCreatePipelineLayout(deviceId,descriptor){var bglCount=HEAPU32[descriptor+8>>2];var bglPtr=HEAPU32[descriptor+12>>2];var bgls=[];for(var i=0;i>2]))}var desc={"label":undefined,"bindGroupLayouts":bgls};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrPipelineLayout.create(device["createPipelineLayout"](desc))}function _wgpuDeviceCreateRenderPipeline(deviceId,descriptor){function makePrimitiveState(rsPtr){if(!rsPtr)return undefined;return{"topology":WebGPU.PrimitiveTopology[HEAPU32[rsPtr+4>>2]],"stripIndexFormat":WebGPU.IndexFormat[HEAPU32[rsPtr+8>>2]],"frontFace":WebGPU.FrontFace[HEAPU32[rsPtr+12>>2]],"cullMode":WebGPU.CullMode[HEAPU32[rsPtr+16>>2]]}}function makeBlendComponent(bdPtr){if(!bdPtr)return undefined;return{"operation":WebGPU.BlendOperation[HEAPU32[bdPtr>>2]],"srcFactor":WebGPU.BlendFactor[HEAPU32[bdPtr+4>>2]],"dstFactor":WebGPU.BlendFactor[HEAPU32[bdPtr+8>>2]]}}function makeBlendState(bsPtr){if(!bsPtr)return undefined;return{"alpha":makeBlendComponent(bsPtr+12),"color":makeBlendComponent(bsPtr+0)}}function makeColorState(csPtr){var formatInt=HEAPU32[csPtr+4>>2];return formatInt===0?undefined:{"format":WebGPU.TextureFormat[formatInt],"blend":makeBlendState(HEAPU32[csPtr+8>>2]),"writeMask":HEAPU32[csPtr+12>>2]}}function makeColorStates(count,csArrayPtr){var states=[];for(var i=0;i>2]],"failOp":WebGPU.StencilOperation[HEAPU32[ssfPtr+4>>2]],"depthFailOp":WebGPU.StencilOperation[HEAPU32[ssfPtr+8>>2]],"passOp":WebGPU.StencilOperation[HEAPU32[ssfPtr+12>>2]]}}function makeDepthStencilState(dssPtr){if(!dssPtr)return undefined;return{"format":WebGPU.TextureFormat[HEAPU32[dssPtr+4>>2]],"depthWriteEnabled":HEAP8[dssPtr+8>>0]!==0,"depthCompare":WebGPU.CompareFunction[HEAPU32[dssPtr+12>>2]],"stencilFront":makeStencilStateFace(dssPtr+16),"stencilBack":makeStencilStateFace(dssPtr+32),"stencilReadMask":HEAPU32[dssPtr+48>>2],"stencilWriteMask":HEAPU32[dssPtr+52>>2],"depthBias":HEAPU32[dssPtr+56>>2],"depthBiasSlopeScale":HEAPF32[dssPtr+60>>2],"depthBiasClamp":HEAPF32[dssPtr+64>>2]}}function makeVertexAttribute(vaPtr){return{"format":WebGPU.VertexFormat[HEAPU32[vaPtr>>2]],"offset":HEAPU32[vaPtr+4+8>>2]*4294967296+HEAPU32[vaPtr+8>>2],"shaderLocation":HEAPU32[vaPtr+16>>2]}}function makeVertexAttributes(count,vaArrayPtr){var vas=[];for(var i=0;i>2]*4294967296+HEAPU32[vbPtr>>2],"stepMode":WebGPU.VertexStepMode[HEAPU32[vbPtr+8>>2]],"attributes":makeVertexAttributes(HEAPU32[vbPtr+12>>2],HEAPU32[vbPtr+16>>2])}}function makeVertexBuffers(count,vbArrayPtr){if(!count)return undefined;var vbs=[];for(var i=0;i>2]),"entryPoint":UTF8ToString(HEAPU32[viPtr+8>>2]),"constants":WebGPU.makePipelineConstants(HEAPU32[viPtr+12>>2],HEAPU32[viPtr+16>>2]),"buffers":makeVertexBuffers(HEAPU32[viPtr+20>>2],HEAPU32[viPtr+24>>2])}}function makeMultisampleState(msPtr){if(!msPtr)return undefined;return{"count":HEAPU32[msPtr+4>>2],"mask":HEAPU32[msPtr+8>>2],"alphaToCoverageEnabled":HEAP8[msPtr+12>>0]!==0}}function makeFragmentState(fsPtr){if(!fsPtr)return undefined;return{"module":WebGPU.mgrShaderModule.get(HEAPU32[fsPtr+4>>2]),"entryPoint":UTF8ToString(HEAPU32[fsPtr+8>>2]),"constants":WebGPU.makePipelineConstants(HEAPU32[fsPtr+12>>2],HEAPU32[fsPtr+16>>2]),"targets":makeColorStates(HEAPU32[fsPtr+20>>2],HEAPU32[fsPtr+24>>2])}}var desc={"label":undefined,"layout":WebGPU.mgrPipelineLayout.get(HEAPU32[descriptor+8>>2]),"vertex":makeVertexState(descriptor+12),"primitive":makePrimitiveState(descriptor+40),"depthStencil":makeDepthStencilState(HEAPU32[descriptor+60>>2]),"multisample":makeMultisampleState(descriptor+64),"fragment":makeFragmentState(HEAPU32[descriptor+80>>2])};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrRenderPipeline.create(device["createRenderPipeline"](desc))}function _wgpuDeviceCreateSampler(deviceId,descriptor){var desc={"label":undefined,"addressModeU":WebGPU.AddressMode[HEAPU32[descriptor+8>>2]],"addressModeV":WebGPU.AddressMode[HEAPU32[descriptor+12>>2]],"addressModeW":WebGPU.AddressMode[HEAPU32[descriptor+16>>2]],"magFilter":WebGPU.FilterMode[HEAPU32[descriptor+20>>2]],"minFilter":WebGPU.FilterMode[HEAPU32[descriptor+24>>2]],"mipmapFilter":WebGPU.FilterMode[HEAPU32[descriptor+28>>2]],"lodMinClamp":HEAPF32[descriptor+32>>2],"lodMaxClamp":HEAPF32[descriptor+36>>2],"compare":WebGPU.CompareFunction[HEAPU32[descriptor+40>>2]]};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrSampler.create(device["createSampler"](desc))}function _wgpuDeviceCreateShaderModule(deviceId,descriptor){var nextInChainPtr=HEAPU32[descriptor>>2];var sType=HEAPU32[nextInChainPtr+4>>2];var desc={"label":undefined,"code":""};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);switch(sType){case 5:{var count=HEAPU32[nextInChainPtr+8>>2];var start=HEAPU32[nextInChainPtr+12>>2];desc["code"]=HEAPU32.subarray(start>>2,(start>>2)+count);break}case 6:{var sourcePtr=HEAPU32[nextInChainPtr+8>>2];if(sourcePtr){desc["code"]=UTF8ToString(sourcePtr)}break}}var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrShaderModule.create(device["createShaderModule"](desc))}function _wgpuDeviceCreateSwapChain(deviceId,surfaceId,descriptor){var device=WebGPU.mgrDevice.get(deviceId);var context=WebGPU.mgrSurface.get(surfaceId);var canvasSize=[HEAPU32[descriptor+16>>2],HEAPU32[descriptor+20>>2]];if(canvasSize[0]!==0){context["canvas"]["width"]=canvasSize[0]}if(canvasSize[1]!==0){context["canvas"]["height"]=canvasSize[1]}var configuration={"device":device,"format":WebGPU.TextureFormat[HEAPU32[descriptor+12>>2]],"usage":HEAPU32[descriptor+8>>2],"alphaMode":"opaque"};context["configure"](configuration);return WebGPU.mgrSwapChain.create(context)}function _wgpuDeviceCreateTexture(deviceId,descriptor){var desc={"label":undefined,"size":WebGPU.makeExtent3D(descriptor+16),"mipLevelCount":HEAPU32[descriptor+32>>2],"sampleCount":HEAPU32[descriptor+36>>2],"dimension":WebGPU.TextureDimension[HEAPU32[descriptor+12>>2]],"format":WebGPU.TextureFormat[HEAPU32[descriptor+28>>2]],"usage":HEAPU32[descriptor+8>>2]};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr);var viewFormatCount=HEAPU32[descriptor+40>>2];if(viewFormatCount){var viewFormatsPtr=HEAPU32[descriptor+44>>2];desc["viewFormats"]=Array.from(HEAP32.subarray(viewFormatsPtr>>2,(viewFormatsPtr>>2)+viewFormatCount),function(format){return WebGPU.TextureFormat[format]})}var device=WebGPU.mgrDevice.get(deviceId);return WebGPU.mgrTexture.create(device["createTexture"](desc))}function _wgpuDeviceGetQueue(deviceId){var queueId=WebGPU.mgrDevice.objects[deviceId].queueId;WebGPU.mgrQueue.reference(queueId);return queueId}function _wgpuDeviceRelease(id){WebGPU.mgrDevice.release(id)}function maybeCStringToJsString(cString){return cString>2?UTF8ToString(cString):cString}var specialHTMLTargets=[0,document,window];function findEventTarget(target){target=maybeCStringToJsString(target);var domElement=specialHTMLTargets[target]||document.querySelector(target);return domElement}function findCanvasEventTarget(target){return findEventTarget(target)}function _wgpuInstanceCreateSurface(instanceId,descriptor){var nextInChainPtr=HEAPU32[descriptor>>2];var descriptorFromCanvasHTMLSelector=nextInChainPtr;var selectorPtr=HEAPU32[descriptorFromCanvasHTMLSelector+8>>2];var canvas=findCanvasEventTarget(selectorPtr);var context=canvas.getContext("webgpu");if(!context)return 0;var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)context.surfaceLabelWebGPU=UTF8ToString(labelPtr);return WebGPU.mgrSurface.create(context)}function _wgpuInstanceRelease(){}function callUserCallback(func){if(ABORT){return}try{func()}catch(e){handleException(e)}}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function _wgpuInstanceRequestAdapter(instanceId,options,callback,userdata){var opts;if(options){opts={"powerPreference":WebGPU.PowerPreference[HEAPU32[options+8>>2]],"forceFallbackAdapter":HEAP8[options+12>>0]!==0}}if(!("gpu"in navigator)){var messagePtr=allocateUTF8("WebGPU not available on this browser (navigator.gpu is not available)");getWasmTableEntry(callback)(1,0,messagePtr,userdata);_free(messagePtr);return}navigator["gpu"]["requestAdapter"](opts).then(function(adapter){callUserCallback(function(){if(adapter){var adapterId=WebGPU.mgrAdapter.create(adapter);getWasmTableEntry(callback)(0,adapterId,0,userdata)}else{var messagePtr=allocateUTF8("WebGPU not available on this system (requestAdapter returned null)");getWasmTableEntry(callback)(1,0,messagePtr,userdata);_free(messagePtr)}})},function(ex){callUserCallback(function(){var messagePtr=allocateUTF8(ex.message);getWasmTableEntry(callback)(2,0,messagePtr,userdata);_free(messagePtr)})})}function _wgpuPipelineLayoutRelease(id){WebGPU.mgrPipelineLayout.release(id)}function _wgpuQuerySetDestroy(querySetId){WebGPU.mgrQuerySet.get(querySetId)["destroy"]()}function _wgpuQuerySetRelease(id){WebGPU.mgrQuerySet.release(id)}function _wgpuQueueOnSubmittedWorkDone(queueId,signalValue_low,signalValue_high,callback,userdata){var queue=WebGPU.mgrQueue.get(queueId);queue["onSubmittedWorkDone"]().then(function(){callUserCallback(function(){getWasmTableEntry(callback)(0,userdata)})},function(){callUserCallback(function(){getWasmTableEntry(callback)(1,userdata)})})}function _wgpuQueueRelease(id){WebGPU.mgrQueue.release(id)}function _wgpuQueueSubmit(queueId,commandCount,commands){var queue=WebGPU.mgrQueue.get(queueId);var cmds=Array.from(HEAP32.subarray(commands>>2,(commands>>2)+commandCount),function(id){return WebGPU.mgrCommandBuffer.get(id)});queue["submit"](cmds)}function _wgpuQueueWriteBuffer(queueId,bufferId,bufferOffset_low,bufferOffset_high,data,size){var queue=WebGPU.mgrQueue.get(queueId);var buffer=WebGPU.mgrBuffer.get(bufferId);var bufferOffset=bufferOffset_high*4294967296+bufferOffset_low;var subarray=HEAPU8.subarray(data,data+size);queue["writeBuffer"](buffer,bufferOffset,subarray,0,size)}function _wgpuQueueWriteTexture(queueId,destinationPtr,data,dataSize,dataLayoutPtr,writeSizePtr){var queue=WebGPU.mgrQueue.get(queueId);var destination=WebGPU.makeImageCopyTexture(destinationPtr);var dataLayout=WebGPU.makeTextureDataLayout(dataLayoutPtr);var writeSize=WebGPU.makeExtent3D(writeSizePtr);var subarray=HEAPU8.subarray(data,data+dataSize);queue["writeTexture"](destination,subarray,dataLayout,writeSize)}function _wgpuRenderPassEncoderDraw(passId,vertexCount,instanceCount,firstVertex,firstInstance){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["draw"](vertexCount,instanceCount,firstVertex,firstInstance)}function _wgpuRenderPassEncoderDrawIndexed(passId,indexCount,instanceCount,firstIndex,baseVertex,firstInstance){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["drawIndexed"](indexCount,instanceCount,firstIndex,baseVertex,firstInstance)}function _wgpuRenderPassEncoderDrawIndexedIndirect(passId,indirectBufferId,indirectOffset_low,indirectOffset_high){var indirectBuffer=WebGPU.mgrBuffer.get(indirectBufferId);var indirectOffset=indirectOffset_high*4294967296+indirectOffset_low;var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["drawIndexedIndirect"](indirectBuffer,indirectOffset)}function _wgpuRenderPassEncoderDrawIndirect(passId,indirectBufferId,indirectOffset_low,indirectOffset_high){var indirectBuffer=WebGPU.mgrBuffer.get(indirectBufferId);var indirectOffset=indirectOffset_high*4294967296+indirectOffset_low;var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["drawIndirect"](indirectBuffer,indirectOffset)}function _wgpuRenderPassEncoderEnd(passId){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["end"]()}function _wgpuRenderPassEncoderRelease(id){WebGPU.mgrRenderPassEncoder.release(id)}function _wgpuRenderPassEncoderSetBindGroup(passId,groupIndex,groupId,dynamicOffsetCount,dynamicOffsetsPtr){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var group=WebGPU.mgrBindGroup.get(groupId);if(dynamicOffsetCount==0){pass["setBindGroup"](groupIndex,group)}else{var offsets=[];for(var i=0;i>2])}pass["setBindGroup"](groupIndex,group,offsets)}}function _wgpuRenderPassEncoderSetBlendConstant(passId,colorPtr){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var color=WebGPU.makeColor(colorPtr);pass["setBlendConstant"](color)}function _wgpuRenderPassEncoderSetIndexBuffer(passId,bufferId,format,offset_low,offset_high,size_low,size_high){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var buffer=WebGPU.mgrBuffer.get(bufferId);var offset=offset_high*4294967296+offset_low;var size=size_high===-1&&size_low===-1?undefined:size_high*4294967296+size_low;pass["setIndexBuffer"](buffer,WebGPU.IndexFormat[format],offset,size)}function _wgpuRenderPassEncoderSetPipeline(passId,pipelineId){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var pipeline=WebGPU.mgrRenderPipeline.get(pipelineId);pass["setPipeline"](pipeline)}function _wgpuRenderPassEncoderSetScissorRect(passId,x,y,w,h){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["setScissorRect"](x,y,w,h)}function _wgpuRenderPassEncoderSetStencilReference(passId,reference){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["setStencilReference"](reference)}function _wgpuRenderPassEncoderSetVertexBuffer(passId,slot,bufferId,offset_low,offset_high,size_low,size_high){var pass=WebGPU.mgrRenderPassEncoder.get(passId);var buffer=WebGPU.mgrBuffer.get(bufferId);var offset=offset_high*4294967296+offset_low;var size=size_high===-1&&size_low===-1?undefined:size_high*4294967296+size_low;pass["setVertexBuffer"](slot,buffer,offset,size)}function _wgpuRenderPassEncoderSetViewport(passId,x,y,w,h,minDepth,maxDepth){var pass=WebGPU.mgrRenderPassEncoder.get(passId);pass["setViewport"](x,y,w,h,minDepth,maxDepth)}function _wgpuRenderPipelineRelease(id){WebGPU.mgrRenderPipeline.release(id)}function _wgpuSamplerRelease(id){WebGPU.mgrSampler.release(id)}function _wgpuShaderModuleRelease(id){WebGPU.mgrShaderModule.release(id)}function _wgpuSurfaceRelease(id){WebGPU.mgrSurface.release(id)}function _wgpuSwapChainGetCurrentTextureView(swapChainId){var context=WebGPU.mgrSwapChain.get(swapChainId);return WebGPU.mgrTextureView.create(context["getCurrentTexture"]()["createView"]())}function _wgpuSwapChainRelease(id){WebGPU.mgrSwapChain.release(id)}function _wgpuTextureCreateView(textureId,descriptor){var desc;if(descriptor){var mipLevelCount=HEAPU32[descriptor+20>>2];var arrayLayerCount=HEAPU32[descriptor+28>>2];desc={"format":WebGPU.TextureFormat[HEAPU32[descriptor+8>>2]],"dimension":WebGPU.TextureViewDimension[HEAPU32[descriptor+12>>2]],"baseMipLevel":HEAPU32[descriptor+16>>2],"mipLevelCount":mipLevelCount===4294967295?undefined:mipLevelCount,"baseArrayLayer":HEAPU32[descriptor+24>>2],"arrayLayerCount":arrayLayerCount===4294967295?undefined:arrayLayerCount,"aspect":WebGPU.TextureAspect[HEAPU32[descriptor+32>>2]]};var labelPtr=HEAPU32[descriptor+4>>2];if(labelPtr)desc["label"]=UTF8ToString(labelPtr)}var texture=WebGPU.mgrTexture.get(textureId);return WebGPU.mgrTextureView.create(texture["createView"](desc))}function _wgpuTextureDestroy(textureId){WebGPU.mgrTexture.get(textureId)["destroy"]()}function _wgpuTextureRelease(id){WebGPU.mgrTexture.release(id)}function _wgpuTextureViewRelease(id){WebGPU.mgrTextureView.release(id)}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();WebGPU.initManagers();var asmLibraryArg={"h":__embind_finalize_value_object,"Ua":__embind_register_bigint,"wa":__embind_register_bool,"m":__embind_register_class,"T":__embind_register_class_class_function,"q":__embind_register_class_constructor,"d":__embind_register_class_function,"c":__embind_register_class_property,"va":__embind_register_emval,"Z":__embind_register_float,"s":__embind_register_integer,"r":__embind_register_memory_view,"_":__embind_register_std_string,"J":__embind_register_std_wstring,"i":__embind_register_value_object,"a":__embind_register_value_object_field,"xa":__embind_register_void,"k":__emval_as,"da":__emval_call_void_method,"b":__emval_decref,"ea":__emval_get_method_caller,"g":__emval_get_property,"l":__emval_incref,"p":__emval_new_array,"n":__emval_new_cstring,"j":__emval_run_destructors,"o":__emval_set_property,"f":__emval_take_value,"e":_abort,"ua":_emscripten_memcpy_big,"H":_emscripten_resize_heap,"Ga":_emscripten_webgpu_get_device,"ra":_environ_get,"sa":_environ_sizes_get,"ta":_fd_write,"Y":_setTempRet0,"La":_wgpuAdapterGetProperties,"S":_wgpuAdapterHasFeature,"Ia":_wgpuAdapterRelease,"U":_wgpuBindGroupRelease,"la":_wgpuBufferDestroy,"G":_wgpuBufferGetMappedRange,"R":_wgpuBufferRelease,"F":_wgpuBufferUnmap,"E":_wgpuCommandBufferRelease,"Na":_wgpuCommandEncoderBeginComputePass,"M":_wgpuCommandEncoderBeginRenderPass,"Xa":_wgpuCommandEncoderCopyBufferToBuffer,"ma":_wgpuCommandEncoderCopyBufferToTexture,"Oa":_wgpuCommandEncoderCopyTextureToTexture,"v":_wgpuCommandEncoderFinish,"x":_wgpuCommandEncoderRelease,"Ma":_wgpuComputePassEncoderDispatchWorkgroups,"Wa":_wgpuComputePassEncoderDispatchWorkgroupsIndirect,"Da":_wgpuComputePassEncoderEnd,"Ca":_wgpuComputePassEncoderRelease,"Ta":_wgpuComputePassEncoderSetBindGroup,"Sa":_wgpuComputePassEncoderSetPipeline,"aa":_wgpuComputePipelineRelease,"D":_wgpuDeviceCreateBindGroup,"C":_wgpuDeviceCreateBindGroupLayout,"B":_wgpuDeviceCreateBuffer,"y":_wgpuDeviceCreateCommandEncoder,"Ba":_wgpuDeviceCreateComputePipeline,"P":_wgpuDeviceCreatePipelineLayout,"O":_wgpuDeviceCreateRenderPipeline,"$":_wgpuDeviceCreateSampler,"u":_wgpuDeviceCreateShaderModule,"ya":_wgpuDeviceCreateSwapChain,"K":_wgpuDeviceCreateTexture,"ga":_wgpuDeviceGetQueue,"Ha":_wgpuDeviceRelease,"Fa":_wgpuInstanceCreateSurface,"Ja":_wgpuInstanceRelease,"Ea":_wgpuInstanceRequestAdapter,"ca":_wgpuPipelineLayoutRelease,"ia":_wgpuQuerySetDestroy,"ha":_wgpuQuerySetRelease,"Va":_wgpuQueueOnSubmittedWorkDone,"Q":_wgpuQueueRelease,"z":_wgpuQueueSubmit,"qa":_wgpuQueueWriteBuffer,"fa":_wgpuQueueWriteTexture,"V":_wgpuRenderPassEncoderDraw,"Pa":_wgpuRenderPassEncoderDrawIndexed,"Za":_wgpuRenderPassEncoderDrawIndexedIndirect,"Ya":_wgpuRenderPassEncoderDrawIndirect,"I":_wgpuRenderPassEncoderEnd,"X":_wgpuRenderPassEncoderRelease,"A":_wgpuRenderPassEncoderSetBindGroup,"Ra":_wgpuRenderPassEncoderSetBlendConstant,"_a":_wgpuRenderPassEncoderSetIndexBuffer,"W":_wgpuRenderPassEncoderSetPipeline,"na":_wgpuRenderPassEncoderSetScissorRect,"Qa":_wgpuRenderPassEncoderSetStencilReference,"pa":_wgpuRenderPassEncoderSetVertexBuffer,"oa":_wgpuRenderPassEncoderSetViewport,"ba":_wgpuRenderPipelineRelease,"Aa":_wgpuSamplerRelease,"N":_wgpuShaderModuleRelease,"Ka":_wgpuSurfaceRelease,"L":_wgpuSwapChainGetCurrentTextureView,"za":_wgpuSwapChainRelease,"w":_wgpuTextureCreateView,"ka":_wgpuTextureDestroy,"ja":_wgpuTextureRelease,"t":_wgpuTextureViewRelease};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["ab"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["cb"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["db"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["eb"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["fb"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["gb"]).apply(null,arguments)};var dynCall_viij=Module["dynCall_viij"]=function(){return(dynCall_viij=Module["dynCall_viij"]=Module["asm"]["hb"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["ib"]).apply(null,arguments)};var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); return wasmDevice.ready diff --git a/cocos/xr/ar/index.ts b/cocos/xr/ar/index.ts deleted file mode 100644 index cd629979373..00000000000 --- a/cocos/xr/ar/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. - -https://www.cocos.com/ - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license -to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - -The software or tools in this License Agreement are licensed, not sold. -Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -export * from './ar-module-base'; diff --git a/cocos/xr/event/xr-event-handle.ts b/cocos/xr/event/xr-event-handle.ts index c14d88fd5c9..c6a224f1c09 100644 --- a/cocos/xr/event/xr-event-handle.ts +++ b/cocos/xr/event/xr-event-handle.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ import { Vec3 } from '../../core/math'; import { Event } from '../../input/types'; diff --git a/cocos/xr/index.ts b/cocos/xr/index.ts index a1926d7d741..bd923db804e 100644 --- a/cocos/xr/index.ts +++ b/cocos/xr/index.ts @@ -1,18 +1,17 @@ /* - Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. https://www.cocos.com/ Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,6 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ export * from './event/xr-event-handle'; +export * from './rendering/ar-background-stage'; diff --git a/cocos/xr/rendering/ar-background-stage.ts b/cocos/xr/rendering/ar-background-stage.ts new file mode 100644 index 00000000000..fd5635753cc --- /dev/null +++ b/cocos/xr/rendering/ar-background-stage.ts @@ -0,0 +1,140 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +import { ColorAttachment, DepthStencilAttachment, deviceManager, Rect, RenderPassInfo, StoreOp } from '../../gfx'; +import { IRenderStageInfo, RenderStage } from '../../rendering/render-stage'; +import { ForwardStagePriority } from '../../rendering/enum'; +import { ForwardFlow } from '../../rendering/forward/forward-flow'; +import { ForwardPipeline } from '../../rendering/forward/forward-pipeline'; +import { Camera, CameraProjection } from '../../render-scene/scene'; +import { WebGL2Device } from '../../gfx/webgl2/webgl2-device'; +import { cclegacy } from '../../core'; +import { Root } from '../../root'; +import { RenderWindow } from '../../render-scene/core/render-window'; +import { WebGL2Framebuffer } from '../../gfx/webgl2/webgl2-framebuffer'; + +const layerList = { + NONE: 0, + IGNORE_RAYCAST: (1 << 20), + GIZMOS: (1 << 21), + EDITOR: (1 << 22), + UI_3D: (1 << 23), + SCENE_GIZMO: (1 << 24), + UI_2D: (1 << 25), + + PROFILER: (1 << 28), + DEFAULT: (1 << 30), + ALL: 0xffffffff, +}; + +export class ARBackgroundStage extends RenderStage { + public static initInfo: IRenderStageInfo = { + name: 'ARStage', + priority: ForwardStagePriority.AR, + tag: 0, + }; + + private _updateStateFlag = false; + private _xrWindowSetFlag = false; + private _uiWindowSetFlag = false; + + private _xrWindow : RenderWindow | null = null; + + constructor () { + super(); + } + + public initialize (info: IRenderStageInfo): boolean { + super.initialize(info); + return true; + } + + public activate (pipeline: ForwardPipeline, flow: ForwardFlow) { + super.activate(pipeline, flow); + } + + public destroy () { + } + + public render (camera: Camera) { + const armodule = globalThis.__globalXR.ar; + if (!armodule) return; + + const state = armodule.getAPIState(); + if (state < 0) return; + + const pipeline = this._pipeline as ForwardPipeline; + + if (state === 3) { // webxr need add ui camera process, TODO: Need move to ar-module + const device = pipeline.device; + if (!this._updateStateFlag) { + const { gl } = device as WebGL2Device; + + armodule.updateRenderState(gl as any); + this._updateStateFlag = true; + } + + if (this._updateStateFlag) { + const xrgpuframebuffer = armodule.getXRLayerFrameBuffer(); + const viewport = armodule.getViewport(); + if (!xrgpuframebuffer || !viewport) return; + + if (!this._xrWindow) { + const root = cclegacy.director.root as Root; + const swapchain = deviceManager.swapchain; + + const colorAttachment = new ColorAttachment(); + colorAttachment.format = swapchain.colorTexture.format; + const depthStencilAttachment = new DepthStencilAttachment(); + depthStencilAttachment.format = swapchain.depthStencilTexture.format; + depthStencilAttachment.depthStoreOp = StoreOp.DISCARD; + depthStencilAttachment.stencilStoreOp = StoreOp.DISCARD; + const renderPassInfo = new RenderPassInfo([colorAttachment], depthStencilAttachment); + + this._xrWindow = root.createWindow({ + title: 'xrWindow', + width: viewport.width, + height: viewport.height, + renderPassInfo, + swapchain, + }); + const webGL2FBO = this._xrWindow?.framebuffer as WebGL2Framebuffer; + webGL2FBO.gpuFramebuffer.glFramebuffer = xrgpuframebuffer; + } + + if (!this._xrWindowSetFlag && (armodule.CameraId === camera.node.uuid)) { + camera.changeTargetWindow(this._xrWindow); + this._xrWindowSetFlag = true; + } + + // ui camera process + if (!this._uiWindowSetFlag && camera.projectionType === CameraProjection.ORTHO + && (camera.visibility & layerList.UI_2D || camera.visibility & layerList.UI_3D)) { + camera.changeTargetWindow(this._xrWindow); + this._uiWindowSetFlag = true; + } + } + } + } +} diff --git a/docs/cocos2d/core/CCActionManager/ActionManager.js b/docs/cocos2d/core/CCActionManager/ActionManager.js deleted file mode 100644 index 999d27bd1a0..00000000000 --- a/docs/cocos2d/core/CCActionManager/ActionManager.js +++ /dev/null @@ -1,2 +0,0 @@ ----- -var mng = new cc.ActionManager(); diff --git a/docs/cocos2d/core/CCScheduler/schedule.js b/docs/cocos2d/core/CCScheduler/schedule.js deleted file mode 100644 index 7c07b16f4e4..00000000000 --- a/docs/cocos2d/core/CCScheduler/schedule.js +++ /dev/null @@ -1,2 +0,0 @@ -//register a schedule to scheduler -cc.director.getScheduler().schedule(callback, this, interval, !this._isRunning); diff --git a/docs/cocos2d/core/CCScheduler/scheduleCallbackForTarget.js b/docs/cocos2d/core/CCScheduler/scheduleCallbackForTarget.js deleted file mode 100644 index ac0761b9041..00000000000 --- a/docs/cocos2d/core/CCScheduler/scheduleCallbackForTarget.js +++ /dev/null @@ -1,3 +0,0 @@ -//register a schedule to scheduler -var scheduler = cc.director.getScheduler(); -scheduler.scheduleCallbackForTarget(this, function, interval, repeat, delay, !this._isRunning); diff --git a/docs/cocos2d/core/CCScheduler/scheduleUpdateForTarget.js b/docs/cocos2d/core/CCScheduler/scheduleUpdateForTarget.js deleted file mode 100644 index 6b3f469a538..00000000000 --- a/docs/cocos2d/core/CCScheduler/scheduleUpdateForTarget.js +++ /dev/null @@ -1,3 +0,0 @@ -//register this object to scheduler -var scheduler = cc.director.getScheduler(); -scheduler.scheduleUpdateForTarget(this, priority, !this._isRunning ); diff --git a/docs/cocos2d/core/CCScheduler/unscheduleCallbackForTarget.js b/docs/cocos2d/core/CCScheduler/unscheduleCallbackForTarget.js deleted file mode 100644 index 3db2c55423a..00000000000 --- a/docs/cocos2d/core/CCScheduler/unscheduleCallbackForTarget.js +++ /dev/null @@ -1,3 +0,0 @@ -//unschedule a callback of target -var scheduler = cc.director.getScheduler(); -scheduler.unscheduleCallbackForTarget(this, callback); diff --git a/docs/cocos2d/core/CCScheduler/unscheduleUpdateForTarget.js b/docs/cocos2d/core/CCScheduler/unscheduleUpdateForTarget.js deleted file mode 100644 index cf84c1ce891..00000000000 --- a/docs/cocos2d/core/CCScheduler/unscheduleUpdateForTarget.js +++ /dev/null @@ -1,3 +0,0 @@ -//unschedules the "update" method. -var scheduler = cc.director.getScheduler(); -scheduler.unscheduleUpdateForTarget(this); diff --git a/docs/cocos2d/core/animation-clip/curve-data.js b/docs/cocos2d/core/animation-clip/curve-data.js deleted file mode 100644 index 5ad9672332e..00000000000 --- a/docs/cocos2d/core/animation-clip/curve-data.js +++ /dev/null @@ -1,58 +0,0 @@ -{ - // 根节点不用查找路径 - // root properties - props: { - x: [ - { frame: 0, value: 0, curve: [0,0.5,0.5,1] }, - { frame: 1, value: 200, curve: null } - ] - }, - comps: { - // component - 'comp-1': { - // component properties - 'prop-1': [ - { frame: 0, value: 10, curve: [0,0.5,0.5,1] }, - { frame: 1, value: 20, curve: null } - ] - } - }, - paths: { - // key 为节点到root的路径名, 通过cc.find找到 - 'foo/bar': { - // node properties - props: { - x: [ - { frame: 0, value: 0, curve: [0,0.5,0.5,1] - { frame: 1, value: 200, curve: null } - ] - }, - comps: { - // component - 'comp-1': { - // component property - 'prop-1': [ - { frame: 0, value: 10, curve: [0,0.5,0. - { frame: 1, value: 20, curve: null } - ] - } - } - }, - 'hello': { - props: { - position: [ - { - frame: 0, - value: [0,0], - motionPath: [ - [320, 240, 0, 240, 640, 240], - [640, 0, 400, 0, 1000, 0] - ] - }, - { frame: 5, value: [640, 480] } - ] - } - } - } - } -} \ No newline at end of file diff --git a/docs/cocos2d/core/animation-clip/event-data.js b/docs/cocos2d/core/animation-clip/event-data.js deleted file mode 100644 index 5d0e54c30d2..00000000000 --- a/docs/cocos2d/core/animation-clip/event-data.js +++ /dev/null @@ -1,11 +0,0 @@ -// frame : The exactly time in second. -// func : Callback function name -// params : Callback parameters -[ - { frame: 0, func: 'onAnimationEvent1', params:['param-1', 'param-2'] }, - { frame: 2, func: 'onAnimationEvent3', params:['param-1', 'param-2'] }, - { frame: 3, func: 'onAnimationEvent2', params:['param-1'] }, - // The second event at frame 3 - { frame: 3, func: 'onAnimationEvent4', params:['param-1'] }, - { frame: 4, func: 'onAnimationEvent4', params:['param-1'] } -] \ No newline at end of file diff --git a/docs/cocos2d/core/components/CCSpriteRenerer/initWithSpriteFrameName.js b/docs/cocos2d/core/components/CCSpriteRenerer/initWithSpriteFrameName.js deleted file mode 100644 index a99bc3e9c45..00000000000 --- a/docs/cocos2d/core/components/CCSpriteRenerer/initWithSpriteFrameName.js +++ /dev/null @@ -1,3 +0,0 @@ ---------- -var sprite = new _ccsg.Sprite(); -sprite.initWithSpriteFrameName("grossini_dance_01.png"); diff --git a/docs/cocos2d/core/event/_getCapturingTargets.js b/docs/cocos2d/core/event/_getCapturingTargets.js deleted file mode 100644 index 370be488456..00000000000 --- a/docs/cocos2d/core/event/_getCapturingTargets.js +++ /dev/null @@ -1,8 +0,0 @@ ----------- -Subclasses can override this method to make event propagable -```js -for (var target = this._parent; target; target = target._parent) { - if (target._capturingListeners && target._capturingListeners.hasEventListener(type)) { - array.push(target); - } -} diff --git a/docs/cocos2d/core/platform/CCCommon/KEY.js b/docs/cocos2d/core/platform/CCCommon/KEY.js deleted file mode 100644 index de27a98bb1c..00000000000 --- a/docs/cocos2d/core/platform/CCCommon/KEY.js +++ /dev/null @@ -1,18 +0,0 @@ -cc.Class({ - extends: cc.Component, - onLoad: function () { - cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); - }, - - destroy () { - cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); - }, - - onKeyDown: function (event) { - switch(event.keyCode) { - case cc.macro.KEY['0']: - console.log('Press a key'); - break; - } - } -}); \ No newline at end of file diff --git a/docs/cocos2d/core/platform/CCEnum/Enum.js b/docs/cocos2d/core/platform/CCEnum/Enum.js deleted file mode 100644 index c598263d2e2..00000000000 --- a/docs/cocos2d/core/platform/CCEnum/Enum.js +++ /dev/null @@ -1,46 +0,0 @@ -// JavaScript: - -var WrapMode = cc.Enum({ - Repeat: -1, - Clamp: -1 -}); - -// Texture.WrapMode.Repeat == 0 -// Texture.WrapMode.Clamp == 1 -// Texture.WrapMode[0] == "Repeat" -// Texture.WrapMode[1] == "Clamp" - -var FlagType = cc.Enum({ - Flag1: 1, - Flag2: 2, - Flag3: 4, - Flag4: 8, -}); - -var AtlasSizeList = cc.Enum({ - 128: 128, - 256: 256, - 512: 512, - 1024: 1024, -}); - -// TypeScript: - -// If used in TypeScript, just define a TypeScript enum: -enum Direction { - Up, - Down, - Left, - Right -} - -// If you need to inspect the enum in Properties panel, you can call cc.Enum: -const {ccclass, property} = cc._decorator; - -@ccclass -class NewScript extends cc.Component { - @property({ - type: cc.Enum(Direction) // call cc.Enum - }) - direction: Direction = Direction.Up; -} diff --git a/docs/cocos2d/core/platform/CCMacro/lerp.js b/docs/cocos2d/core/platform/CCMacro/lerp.js deleted file mode 100644 index e0f67441ed3..00000000000 --- a/docs/cocos2d/core/platform/CCMacro/lerp.js +++ /dev/null @@ -1,4 +0,0 @@ ----- -lerp -cc.math.lerp(2,10,0.5)//returns 6 -cc.math.lerp(2,10,0.2)//returns 3.6 diff --git a/docs/cocos2d/core/platform/url/raw.js b/docs/cocos2d/core/platform/url/raw.js deleted file mode 100644 index 88ec9b4c249..00000000000 --- a/docs/cocos2d/core/platform/url/raw.js +++ /dev/null @@ -1,3 +0,0 @@ ---- -var url = cc.url.raw("textures/myTexture.png"); -console.log(url); // "resources/raw/textures/myTexture.png" diff --git a/docs/cocos2d/core/sprites/addSpriteFrames.js b/docs/cocos2d/core/sprites/addSpriteFrames.js deleted file mode 100644 index 44c45c4f466..00000000000 --- a/docs/cocos2d/core/sprites/addSpriteFrames.js +++ /dev/null @@ -1,4 +0,0 @@ ----------------------------------------------------- -// add SpriteFrames to SpriteFrameCache With File -cc.spriteFrameCache.addSpriteFrames(s_grossiniPlist); -cc.spriteFrameCache.addSpriteFrames(s_grossiniJson); diff --git a/docs/cocos2d/core/sprites/getSpriteFrame.js b/docs/cocos2d/core/sprites/getSpriteFrame.js deleted file mode 100644 index 0c37dd966e1..00000000000 --- a/docs/cocos2d/core/sprites/getSpriteFrame.js +++ /dev/null @@ -1,3 +0,0 @@ ----------------------------------------------------- -//get a SpriteFrame by name -var frame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png"); diff --git a/docs/cocos2d/core/textures/TextureAtlas.js b/docs/cocos2d/core/textures/TextureAtlas.js deleted file mode 100644 index e0d4542b39d..00000000000 --- a/docs/cocos2d/core/textures/TextureAtlas.js +++ /dev/null @@ -1,7 +0,0 @@ --------------------------- -1. //creates a TextureAtlas with filename -var textureAtlas = new cc.TextureAtlas("res/hello.png", 3); - -2. //creates a TextureAtlas with texture -var texture = cc.textureCache.addImage("hello.png"); -var textureAtlas = new cc.TextureAtlas(texture, 3); diff --git a/docs/cocos2d/core/textures/addImage.js b/docs/cocos2d/core/textures/addImage.js deleted file mode 100644 index cd3cc39a031..00000000000 --- a/docs/cocos2d/core/textures/addImage.js +++ /dev/null @@ -1,2 +0,0 @@ ----- -cc.textureCache.addImage("hello.png"); diff --git a/docs/cocos2d/core/textures/getKeyByTexture.js b/docs/cocos2d/core/textures/getKeyByTexture.js deleted file mode 100644 index 6617822a860..00000000000 --- a/docs/cocos2d/core/textures/getKeyByTexture.js +++ /dev/null @@ -1,2 +0,0 @@ ---------- -var key = cc.textureCache.getKeyByTexture(texture); diff --git a/docs/cocos2d/core/textures/getTextureColors.js b/docs/cocos2d/core/textures/getTextureColors.js deleted file mode 100644 index 75cc1325505..00000000000 --- a/docs/cocos2d/core/textures/getTextureColors.js +++ /dev/null @@ -1,2 +0,0 @@ ---------------- -var cacheTextureForColor = cc.textureCache.getTextureColors(texture); diff --git a/docs/cocos2d/core/textures/getTextureForKey.js b/docs/cocos2d/core/textures/getTextureForKey.js deleted file mode 100644 index 7ce13d75dee..00000000000 --- a/docs/cocos2d/core/textures/getTextureForKey.js +++ /dev/null @@ -1,2 +0,0 @@ ------------------- -var key = cc.textureCache.getTextureForKey("hello.png"); diff --git a/docs/cocos2d/core/textures/initWithFile.js b/docs/cocos2d/core/textures/initWithFile.js deleted file mode 100644 index e7cfc635fa9..00000000000 --- a/docs/cocos2d/core/textures/initWithFile.js +++ /dev/null @@ -1,3 +0,0 @@ --------------------------------------------------- -var textureAtlas = new cc.TextureAtlas(); -textureAtlas.initWithTexture("hello.png", 3); diff --git a/docs/cocos2d/core/textures/initWithTexture.js b/docs/cocos2d/core/textures/initWithTexture.js deleted file mode 100644 index e1ae8a7282e..00000000000 --- a/docs/cocos2d/core/textures/initWithTexture.js +++ /dev/null @@ -1,4 +0,0 @@ ---------------------------- -var texture = cc.textureCache.addImage("hello.png"); -var textureAtlas = new cc.TextureAtlas(); -textureAtlas.initWithTexture(texture, 3); diff --git a/docs/cocos2d/core/textures/removeAllTextures.js b/docs/cocos2d/core/textures/removeAllTextures.js deleted file mode 100644 index e3e8bcdbebe..00000000000 --- a/docs/cocos2d/core/textures/removeAllTextures.js +++ /dev/null @@ -1,2 +0,0 @@ --------- -cc.textureCache.removeAllTextures(); diff --git a/docs/cocos2d/core/textures/removeTexture.js b/docs/cocos2d/core/textures/removeTexture.js deleted file mode 100644 index e7e4782d871..00000000000 --- a/docs/cocos2d/core/textures/removeTexture.js +++ /dev/null @@ -1,2 +0,0 @@ ------ -cc.textureCache.removeTexture(texture); diff --git a/docs/cocos2d/core/textures/removeTextureForKey.js b/docs/cocos2d/core/textures/removeTextureForKey.js deleted file mode 100644 index 27308cb0547..00000000000 --- a/docs/cocos2d/core/textures/removeTextureForKey.js +++ /dev/null @@ -1,2 +0,0 @@ ------- -cc.textureCache.removeTexture("hello.png"); diff --git a/docs/cocos2d/core/textures/textureForKey.js b/docs/cocos2d/core/textures/textureForKey.js deleted file mode 100644 index 28175de1061..00000000000 --- a/docs/cocos2d/core/textures/textureForKey.js +++ /dev/null @@ -1,2 +0,0 @@ ------------------- -var key = cc.textureCache.textureForKey("hello.png"); diff --git a/docs/cocos2d/core/utils/CCPath/basename.js b/docs/cocos2d/core/utils/CCPath/basename.js deleted file mode 100644 index 31a3db9a876..00000000000 --- a/docs/cocos2d/core/utils/CCPath/basename.js +++ /dev/null @@ -1,6 +0,0 @@ ---------------------------------- -cc.path.basename("a/b.png"); //-->"b.png" -cc.path.basename("a/b.png?a=1&b=2"); //-->"b.png" -cc.path.basename("a/b.png", ".png"); //-->"b" -cc.path.basename("a/b.png?a=1&b=2", ".png"); //-->"b" -cc.path.basename("a/b.png", ".txt"); //-->"b.png" diff --git a/docs/cocos2d/core/utils/CCPath/changeBasename.js b/docs/cocos2d/core/utils/CCPath/changeBasename.js deleted file mode 100644 index 6188cd1ba4c..00000000000 --- a/docs/cocos2d/core/utils/CCPath/changeBasename.js +++ /dev/null @@ -1,6 +0,0 @@ ----------------------------------- -cc.path.changeBasename("a/b/c.plist", "b.plist"); //-->"a/b/b.plist" -cc.path.changeBasename("a/b/c.plist?a=1&b=2", "b.plist"); //-->"a/b/b.plist?a=1&b=2" -cc.path.changeBasename("a/b/c.plist", ".png"); //-->"a/b/c.png" -cc.path.changeBasename("a/b/c.plist", "b"); //-->"a/b/b" -cc.path.changeBasename("a/b/c.plist", "b", true); //-->"a/b/b.plist" diff --git a/docs/cocos2d/core/utils/CCPath/changeExtname.js b/docs/cocos2d/core/utils/CCPath/changeExtname.js deleted file mode 100644 index 8ca43f3bb25..00000000000 --- a/docs/cocos2d/core/utils/CCPath/changeExtname.js +++ /dev/null @@ -1,3 +0,0 @@ ---------------------------------- -cc.path.changeExtname("a/b.png", ".plist"); //-->"a/b.plist" -cc.path.changeExtname("a/b.png?a=1&b=2", ".plist"); //-->"a/b.plist?a=1&b=2" diff --git a/docs/cocos2d/core/utils/CCPath/dirname.js b/docs/cocos2d/core/utils/CCPath/dirname.js deleted file mode 100644 index 3ed94455933..00000000000 --- a/docs/cocos2d/core/utils/CCPath/dirname.js +++ /dev/null @@ -1,9 +0,0 @@ ---------------------------------- -* unix -cc.path.driname("a/b/c.png"); //-->"a/b" -cc.path.driname("a/b/c.png?a=1&b=2"); //-->"a/b" -cc.path.dirname("a/b/"); //-->"a/b" -cc.path.dirname("c.png"); //-->"" -* windows -cc.path.driname("a\\b\\c.png"); //-->"a\b" -cc.path.driname("a\\b\\c.png?a=1&b=2"); //-->"a\b" diff --git a/docs/cocos2d/core/utils/CCPath/extname.js b/docs/cocos2d/core/utils/CCPath/extname.js deleted file mode 100644 index d8718c8af1e..00000000000 --- a/docs/cocos2d/core/utils/CCPath/extname.js +++ /dev/null @@ -1,5 +0,0 @@ ---------------------------- -cc.path.extname("a/b.png"); //-->".png" -cc.path.extname("a/b.png?a=1&b=2"); //-->".png" -cc.path.extname("a/b"); //-->null -cc.path.extname("a/b?a=1&b=2"); //-->null diff --git a/docs/cocos2d/core/utils/CCPath/join.js b/docs/cocos2d/core/utils/CCPath/join.js deleted file mode 100644 index efd2eb1936a..00000000000 --- a/docs/cocos2d/core/utils/CCPath/join.js +++ /dev/null @@ -1,6 +0,0 @@ ------------------------------- -cc.path.join("a", "b.png"); //-->"a/b.png" -cc.path.join("a", "b", "c.png"); //-->"a/b/c.png" -cc.path.join("a", "b"); //-->"a/b" -cc.path.join("a", "b", "/"); //-->"a/b/" -cc.path.join("a", "b/", "/"); //-->"a/b/" diff --git a/docs/cocos2d/core/utils/base-node/setPosition.js b/docs/cocos2d/core/utils/base-node/setPosition.js deleted file mode 100644 index 9fb077b9a75..00000000000 --- a/docs/cocos2d/core/utils/base-node/setPosition.js +++ /dev/null @@ -1,2 +0,0 @@ -node.setPosition(cc.v2(0, 0)); -node.setPosition(0, 0); diff --git a/docs/cocos2d/core/utils/node-wrapper/setPosition.js b/docs/cocos2d/core/utils/node-wrapper/setPosition.js deleted file mode 100644 index c88584e4737..00000000000 --- a/docs/cocos2d/core/utils/node-wrapper/setPosition.js +++ /dev/null @@ -1,3 +0,0 @@ ---------------------------------- -var size = cc.winSize; -node.setPosition(size.width/2, size.height/2); diff --git a/docs/cocos2d/core/value-types/CCColor/color.js b/docs/cocos2d/core/value-types/CCColor/color.js deleted file mode 100644 index 888290d0f5d..00000000000 --- a/docs/cocos2d/core/value-types/CCColor/color.js +++ /dev/null @@ -1,7 +0,0 @@ ------------------------ -// 1. All channels seperately as parameters -var color1 = new cc.Color(255, 255, 255, 255); -// 2. Convert a hex string to a color -var color2 = new cc.Color("#000000"); -// 3. An color object as parameter -var color3 = new cc.Color({r: 255, g: 255, b: 255, a: 255}); diff --git a/docs/cocos2d/core/value-types/CCColor/lerp.js b/docs/cocos2d/core/value-types/CCColor/lerp.js deleted file mode 100644 index e2b7e2d0755..00000000000 --- a/docs/cocos2d/core/value-types/CCColor/lerp.js +++ /dev/null @@ -1,9 +0,0 @@ -// Converts a white color to a black one trough time. -update: function (dt) { - var color = this.node.color; - if (color.equals(cc.Color.BLACK)) { - return; - } - this.ratio += dt * 0.1; - this.node.color = cc.Color.WHITE.lerp(cc.Color.BLACK, ratio); -} diff --git a/docs/cocos2d/core/value-types/CCSize/size.js b/docs/cocos2d/core/value-types/CCSize/size.js deleted file mode 100644 index d7fba0c2d76..00000000000 --- a/docs/cocos2d/core/value-types/CCSize/size.js +++ /dev/null @@ -1,4 +0,0 @@ -var size1 = cc.size(); -var size2 = cc.size(100,100); -var size3 = cc.size(size2); -var size4 = cc.size({width: 100, height: 100}); diff --git a/docs/contribution/experimental.md b/docs/contribution/experimental.md new file mode 100644 index 00000000000..882a5b6ba91 --- /dev/null +++ b/docs/contribution/experimental.md @@ -0,0 +1,45 @@ + +# Experimental API specification + +This section describes what actions you should take to release and recall an experimental Cocos Creator engine API. + +## Release an experimental API + +While developing engine features, you may release an API as experimental, +if you, for example, expect users' feedback before the feature can be formally landed. + +To release an experimental API: + +- You're **REQUIRED** to postfix the API's name with a `_experimental`. + + > The requirement is reasonable since: + + > - In this way, the experimental API does not occupy a "formal" name of + stable API. Make it easy if the stable API differs a lot. + + > - Users clearly know the API is experimental, without inspect any warning or document. + +- An **optional** message(in warn level) can be attached at runtime when this API is used. The message shall be shown at most once. + +## Revise the experimental API + +During evolution of the API, you may revise the experimental API at your discretion. **No backward compatibility is required**. However you should document the change in release note, optionally in document. + +## Recall an experimental API + +When the API settles(no matter if there's a corresponding stable substitution), you're **REQUIRED** to turn the experimental as **deprecated** before you can entirely remove the API from engine. + +In the following, "life time" [`a`, `b`] means the experimental API is released at version `a` and settled at version `b`. + +- If the API's life time spans only patch versions, you're permitted to remove it in **next minor** version. + + > For example, if the API live in [`3.7.0`, `3.7.4`], you can remove it in `3.8.0`. + +- If the API's life time spans only minor versions [`X.Y.*`, `X.Z.*`], you're permitted to remove it only after `Z-Y` minor versions, or in next major version. + + > For example, if the API live in [`3.7.1`,`3.9.0`], you can remove it in `3.11.0`, or `4.0.0` + +- If the API's life time spans major versions. You can remove it in next major version. + + > For example, if the API live in [`3.0.0`, `5.6.7`], you can remove it only in `6.0.0`. + diff --git a/docs/contribution/experimental.zh-CN.md b/docs/contribution/experimental.zh-CN.md new file mode 100644 index 00000000000..7977ed4cd6b --- /dev/null +++ b/docs/contribution/experimental.zh-CN.md @@ -0,0 +1,43 @@ + +# 实验性 API 规范 + +本节描述了在需要发布和召回 Cocos Creator 引擎实验性 API 时应当采取的措施。 + +## 发布实验性 API + +在开发引擎功能时,你可以将一个 API 以实验性质发布。例如,如果你希望在该功能正式落地之前得到用户的反馈。 + +要发布一个实验性的API: + +- 你 **必须** 让该 API 名称的后缀为 `_experimental`. + + > 这个要求合理,因为: + + > - 这样一来,实验性 API 就不会占用稳定 API 的“正式”名称。 + + > - 用户可以清楚地知道这个 API 是实验性的,他们不需要检查任何警告或者查看任何文档。 + +- 当该 API 使用时,**可以** 在运行时附加一个信息(级别应为警告)。该信息应至多展示一次。 + +## 修订实验性 API + +在该 API 的演进过程中,由你自行决定如何对其进行修订。**不需要保持向后兼容**。但是,你应该在发布说明中注明修改,文档中有说明更好。 + +## 召回实验性 API + +当 API 稳定下来后(不管是否有相应的稳定版本),你 **必须** 首先将实验性的 API 变成**废弃** API,然后才能从引擎中完全删除它。 + +在下文中,“生命期”[`a`, `b`] 是指该 API 在版本 `a` 中发布,在版本 `b` 中稳定。 + +- 如果 API 的生命期只跨越了补丁版本,你可以在 **下一个次要** 版本中删除它。 + + > 例如,如果该 API 存在于 [`3.7.0`, `3.7.4`],你可以在 `3.8.0` 中删除它。 + +- 如果 API 的生命期只跨越了次要版本 [`X.Y.*`, `X.Z.*`],你只允许在 `Z-Y`个次要版本之后,或在下一个主要版本中移除它。 + + > 例如,如果该 API 存在于 [`3.7.1`,`3.9.0`],你可以在 `3.11.0` 或 `4.0.0` 中删除它。 + +- 如果 API 的生命期跨越了主要版本。你仅可以在下一个主要版本中删除它。 + + > 例如,如果该 API 存在于 [`3.0.0`, `5.6.7`],你只能在 `6.0.0` 中删除它。 + diff --git a/docs/extensions/ccpool/putInPool.js b/docs/extensions/ccpool/putInPool.js deleted file mode 100644 index f2829171017..00000000000 --- a/docs/extensions/ccpool/putInPool.js +++ /dev/null @@ -1,5 +0,0 @@ ---------------------------------- -var sp = new _ccsg.Sprite("a.png"); -this.addChild(sp); -cc.pool.putInPool(sp); -cc.pool.getFromPool(_ccsg.Sprite, "a.png"); diff --git a/editor/assets/chunks/builtin/functionalities/probe.chunk b/editor/assets/chunks/builtin/functionalities/probe.chunk new file mode 100644 index 00000000000..11b2fc9e5a3 --- /dev/null +++ b/editor/assets/chunks/builtin/functionalities/probe.chunk @@ -0,0 +1,45 @@ +#include +vec4 GetTexData(sampler2D dataMap, float dataMapWidth, float x, float uv_y) +{ + return vec4( + decode32(texture(dataMap, vec2(((x + 0.5)/dataMapWidth), uv_y))), + decode32(texture(dataMap, vec2(((x + 1.5)/dataMapWidth), uv_y))), + decode32(texture(dataMap, vec2(((x + 2.5)/dataMapWidth), uv_y))), + decode32(texture(dataMap, vec2(((x + 3.5)/dataMapWidth), uv_y))) + ); +} +void GetPlanarReflectionProbeData(out vec4 plane, out float planarReflectionDepthScale, out float mipCount, float probeId) +{ + #if USE_INSTANCING + float uv_y = (probeId + 0.5) / cc_probeInfo.x; //align to texel center + float dataMapWidth = 12.0; + vec4 texData1 = GetTexData(cc_reflectionProbeDataMap, dataMapWidth, 0.0, uv_y); + vec4 texData2 = GetTexData(cc_reflectionProbeDataMap, dataMapWidth, 4.0, uv_y); + plane.xyz = texData1.xyz; + plane.w = texData2.x; + planarReflectionDepthScale = texData2.y; + mipCount = texData2.z; + #else + plane = cc_reflectionProbeData1; + planarReflectionDepthScale = cc_reflectionProbeData2.x; + mipCount = cc_reflectionProbeData2.w; + #endif +} + +void GetCubeReflectionProbeData(out vec3 centerPos, out vec3 boxHalfSize, out float mipCount, float probeId) +{ + #if USE_INSTANCING + float uv_y = (probeId + 0.5) / cc_probeInfo.x; //align to texel center + float dataMapWidth = 12.0; + vec4 texData1 = GetTexData(cc_reflectionProbeDataMap, dataMapWidth, 0.0, uv_y); + vec4 texData2 = GetTexData(cc_reflectionProbeDataMap, dataMapWidth, 4.0, uv_y); + vec4 texData3 = GetTexData(cc_reflectionProbeDataMap, dataMapWidth, 8.0, uv_y); + centerPos = texData1.xyz; + boxHalfSize = texData2.xyz; + mipCount = texData3.x; + #else + centerPos = cc_reflectionProbeData1.xyz; + boxHalfSize = cc_reflectionProbeData2.xyz; + mipCount = cc_reflectionProbeData2.w; + #endif +} diff --git a/editor/assets/chunks/builtin/functionalities/probe.chunk.meta b/editor/assets/chunks/builtin/functionalities/probe.chunk.meta new file mode 100644 index 00000000000..b1a48df9bea --- /dev/null +++ b/editor/assets/chunks/builtin/functionalities/probe.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "92ac3587-8a8c-4405-87b0-5cf026196c64", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/builtin/functionalities/sh.chunk b/editor/assets/chunks/builtin/functionalities/sh.chunk new file mode 100644 index 00000000000..7430c4939f4 --- /dev/null +++ b/editor/assets/chunks/builtin/functionalities/sh.chunk @@ -0,0 +1,40 @@ +#pragma define-meta CC_USE_LIGHT_PROBE default(false) + +#if CC_USE_LIGHT_PROBE +vec3 SHEvaluate(vec3 normal) +{ + vec3 result; + +#if USE_INSTANCING + // calculate linear and const terms + vec4 normal4 = vec4(normal, 1.0); + result.r = dot(v_sh_linear_const_r, normal4); + result.g = dot(v_sh_linear_const_g, normal4); + result.b = dot(v_sh_linear_const_b, normal4); + +#else + // calculate linear and const terms + vec4 normal4 = vec4(normal, 1.0); + result.r = dot(cc_sh_linear_const_r, normal4); + result.g = dot(cc_sh_linear_const_g, normal4); + result.b = dot(cc_sh_linear_const_b, normal4); + + // calculate quadratic terms + vec4 n14 = normal.xyzz * normal.yzzx; + float n5 = normal.x * normal.x - normal.y * normal.y; + + result.r += dot(cc_sh_quadratic_r, n14); + result.g += dot(cc_sh_quadratic_g, n14); + result.b += dot(cc_sh_quadratic_b, n14); + result += (cc_sh_quadratic_a.rgb * n5); +#endif + + #if CC_USE_HDR + // convert from standard camera exposure parameters to current exposure value + // baked in LDR scene still regarded as exposured with standard camera parameters + result *= cc_exposure.w * cc_exposure.x; + #endif + + return result; +} +#endif diff --git a/editor/assets/chunks/builtin/functionalities/sh.chunk.meta b/editor/assets/chunks/builtin/functionalities/sh.chunk.meta new file mode 100644 index 00000000000..36708fc9672 --- /dev/null +++ b/editor/assets/chunks/builtin/functionalities/sh.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "c8728e39-6dca-4d22-a4ee-cc1aefb0198a", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/builtin/functionalities/shadow-map.chunk b/editor/assets/chunks/builtin/functionalities/shadow-map.chunk index bce1a85732d..7734d50c91a 100644 --- a/editor/assets/chunks/builtin/functionalities/shadow-map.chunk +++ b/editor/assets/chunks/builtin/functionalities/shadow-map.chunk @@ -37,9 +37,6 @@ float CCGetLinearDepth(vec3 worldPos) { //////////////////////////////////////////////////////////Helper Functions - // When screenSpaceSingY and clipSpaceSignY have different signs, need to flip the uv - #pragma define CC_HANDLE_NDC_SAMPLE_FLIP(uv) uv = cc_cameraPos.w == 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv - bool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias) { shadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5; @@ -48,7 +45,7 @@ float CCGetLinearDepth(vec3 worldPos) { shadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) { return false; } - CC_HANDLE_NDC_SAMPLE_FLIP(shadowNDCPos.xy); + CC_HANDLE_NDC_SAMPLE_FLIP(shadowNDCPos.xy, cc_cameraPos.w); return true; } @@ -76,12 +73,21 @@ float CCGetLinearDepth(vec3 worldPos) { return newShadowPos; } + float GetViewSpaceDepthFromNDCDepth_Orthgraphic(float NDCDepth, float projScaleZ, float projBiasZ) + { + return (NDCDepth - projBiasZ) / projScaleZ; + } + float GetViewSpaceDepthFromNDCDepth_Perspective(float NDCDepth, float homogenousDividW, float invProjScaleZ, float invProjBiasZ) + { + return NDCDepth * invProjScaleZ + homogenousDividW * invProjBiasZ; + } + vec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias) { // Recover the coord in view space: cc_matLightInvProj * shadowPos vec3 viewSpacePos; viewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw; - viewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y; + viewSpacePos.z = GetViewSpaceDepthFromNDCDepth_Perspective(shadowPos.z, shadowPos.w, cc_shadowInvProjDepthInfo.x, cc_shadowInvProjDepthInfo.y); // Apply bias viewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias; @@ -107,7 +113,7 @@ float CCGetLinearDepth(vec3 worldPos) { float coeffB = projBiasZ; // Recover the Z distance in view space: - float viewSpacePos_z = (shadowPos.z - coeffB) / coeffA; + float viewSpacePos_z = GetViewSpaceDepthFromNDCDepth_Orthgraphic(shadowPos.z, projScaleZ, projBiasZ); // Apply bias viewSpacePos_z += viewspaceDepthBias; @@ -195,7 +201,7 @@ float CCGetLinearDepth(vec3 worldPos) { //////////////////////////////////////////////////////////Main Functions - float CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias) + float CCSpotShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 worldPos, vec2 shadowBias) { float pcf = cc_shadowWHPBInfo.z; vec4 pos = vec4(1.0); @@ -205,18 +211,22 @@ float CCGetLinearDepth(vec3 worldPos) { pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x); #endif + float realtimeShadow = 1.0; if (pcf > 2.9) { - return CCGetSpotLightShadowFactorSoft5X(pos, worldPos); + realtimeShadow = CCGetSpotLightShadowFactorSoft5X(pos, worldPos); }else if (pcf > 1.9) { - return CCGetSpotLightShadowFactorSoft3X(pos, worldPos); + realtimeShadow = CCGetSpotLightShadowFactorSoft3X(pos, worldPos); }else if (pcf > 0.9) { - return CCGetSpotLightShadowFactorSoft(pos, worldPos); + realtimeShadow = CCGetSpotLightShadowFactorSoft(pos, worldPos); }else { - return CCGetSpotLightShadowFactorHard(pos, worldPos); + realtimeShadow = CCGetSpotLightShadowFactorHard(pos, worldPos); } + + shadowNDCPosWithBias = pos; + return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w); } - float CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias) + float CCShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 N, vec2 shadowBias) { vec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy); pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y); @@ -235,11 +245,36 @@ float CCGetLinearDepth(vec3 worldPos) { realtimeShadow = CCGetDirLightShadowFactorHard(pos); #endif + shadowNDCPosWithBias = pos; return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w); } #if CC_SUPPORT_CASCADED_SHADOW_MAP - int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) { + bool CCGetCSMLevelWithTransition(out float ratio, vec3 clipPos) { + highp float layerThreshold = cc_csmViewDir0[0].w; + highp float maxRange = 1.0 - cc_csmSplitsInfo.x - layerThreshold; + highp float minRange = cc_csmSplitsInfo.x - layerThreshold; + if (clipPos.x <= minRange || clipPos.x >= maxRange || + clipPos.y <= minRange || clipPos.y >= maxRange) { + if (clipPos.x >= layerThreshold && clipPos.x <= cc_csmSplitsInfo.x) { + ratio = (clipPos.x - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold); + } + if (clipPos.x >= maxRange && clipPos.x <= 1.0 - layerThreshold) { + ratio = (clipPos.x - maxRange) / (cc_csmSplitsInfo.x - layerThreshold); + } + if (clipPos.y >= 0.0 && clipPos.y <= cc_csmSplitsInfo.x) { + ratio = min((clipPos.y - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold), 1.0); + } + if (clipPos.y >= maxRange && clipPos.y <= 1.0 - layerThreshold) { + ratio = (clipPos.y - maxRange) / (cc_csmSplitsInfo.x - layerThreshold); + } + return true; + } + return false; + } + + int CCGetCSMLevel(out bool hasNextTransition, out bool transitionArea, out float transitionRatio, out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos, int nextLayer) + { int layer = -1; highp float layerThreshold = cc_csmViewDir0[0].w; for (int i = 0; i < NUMCASCADES; i++) { @@ -247,30 +282,65 @@ float CCGetLinearDepth(vec3 worldPos) { vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5; if (clipPos.x >= (0.0 + layerThreshold) && clipPos.x <= (1.0 - layerThreshold) && clipPos.y >= (0.0 + layerThreshold) && clipPos.y <= (1.0 - layerThreshold) && - clipPos.z >= 0.0 && clipPos.z <= 1.0 && layer < 0) { - csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0); - csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw; - shadowProjDepthInfo = cc_csmProjDepthInfo[i]; - shadowProjInfo = cc_csmProjInfo[i]; - shadowViewDir0 = cc_csmViewDir0[i].xyz; - shadowViewDir1 = cc_csmViewDir1[i].xyz; - shadowViewDir2 = cc_csmViewDir2[i].xyz; - layer = i; + clipPos.z >= 0.0 && clipPos.z <= 1.0) { + #if CC_CASCADED_LAYERS_TRANSITION + if (layer < 0 || (nextLayer >= 0 && i == nextLayer)) + #else + if (layer < 0) + #endif + { + #if CC_CASCADED_LAYERS_TRANSITION + if (nextLayer < 0) { + transitionArea = CCGetCSMLevelWithTransition(transitionRatio, clipPos); + } + #endif + csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0); + csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw; + shadowProjDepthInfo = cc_csmProjDepthInfo[i]; + shadowProjInfo = cc_csmProjInfo[i]; + shadowViewDir0 = cc_csmViewDir0[i].xyz; + shadowViewDir1 = cc_csmViewDir1[i].xyz; + shadowViewDir2 = cc_csmViewDir2[i].xyz; + layer = i; + + #if CC_CASCADED_LAYERS_TRANSITION + hasNextTransition = true; + #endif + } } } return layer; } - float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) + int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) + { + bool hasNextTransition = false; + bool transitionArea = false; + float transitionRatio = 0.0; + int nextLayer = -1; + return CCGetCSMLevel(hasNextTransition, transitionArea, transitionRatio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, nextLayer); + } + + // output csmPos is non-biased position that can be used for sampling shadow map after homogeneous divid + float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias) { - vec4 csmPos = vec4(1.0); + bool hasNext = false; + bool transitionArea = false; + float ratio = 0.0; + csmPos = vec4(1.0); vec4 shadowProjDepthInfo, shadowProjInfo; vec3 shadowViewDir0, shadowViewDir1, shadowViewDir2; - int level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos); + int level = -1; + #if CC_CASCADED_LAYERS_TRANSITION + level = CCGetCSMLevel(hasNext, transitionArea, ratio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, -1); + #else + level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos); + #endif if (level < 0) { return 1.0; } vec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, shadowViewDir0, shadowViewDir1, shadowViewDir2, shadowProjInfo.xy); pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y); + csmNDCPosWithBias = pos; float realtimeShadow = 1.0; #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_5X @@ -286,17 +356,61 @@ float CCGetLinearDepth(vec3 worldPos) { realtimeShadow = CCGetDirLightShadowFactorHard(pos); #endif - return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w); + #if CC_CASCADED_LAYERS_TRANSITION + vec4 nextCSMPos = vec4(1.0); + vec4 nextShadowProjDepthInfo, nextShadowProjInfo; + vec3 nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2; + float nextRealtimeShadow = 1.0; + CCGetCSMLevel(hasNext, transitionArea, ratio, nextCSMPos, nextShadowProjDepthInfo, nextShadowProjInfo, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, worldPos, level + 1); + if (hasNext && transitionArea) { + vec4 nexPos = ApplyShadowDepthBias_FaceNormal(nextCSMPos, N, shadowBias.y, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, nextShadowProjInfo.xy); + nexPos = ApplyShadowDepthBias_Orthographic(nexPos, shadowBias.x, nextShadowProjDepthInfo.x, nextShadowProjDepthInfo.y); + + #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_5X + nextRealtimeShadow = CCGetDirLightShadowFactorSoft5X(nexPos); + #endif + #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_3X + nextRealtimeShadow = CCGetDirLightShadowFactorSoft3X(nexPos); + #endif + #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT + nextRealtimeShadow = CCGetDirLightShadowFactorSoft(nexPos); + #endif + #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_HARD + nextRealtimeShadow = CCGetDirLightShadowFactorHard(nexPos); + #endif + + return mix(mix(nextRealtimeShadow, realtimeShadow, ratio), 1.0, cc_shadowNFLSInfo.w); + } + return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w); + #else + return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w); + #endif } #else int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) { return -1; } - float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) { - vec4 shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0); - return CCShadowFactorBase(shadowPos, N, shadowBias); + float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias) { + csmPos = cc_matLightViewProj * vec4(worldPos, 1.0); + return CCShadowFactorBase(csmNDCPosWithBias, csmPos, N, shadowBias); } #endif + // compatible version + float CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias) { + vec4 shadowNDCPosWithBias; + return CCShadowFactorBase(shadowNDCPosWithBias, shadowPos, N, shadowBias); + } + + float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) { + vec4 csmPos, csmNDCPosWithBias; + return CCCSMFactorBase(csmPos, csmNDCPosWithBias, worldPos, N, shadowBias); + } + + float CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias) + { + vec4 shadowNDCPosWithBias; + return CCSpotShadowFactorBase(shadowNDCPosWithBias, shadowPos, worldPos, shadowBias); + } #endif diff --git a/editor/assets/chunks/builtin/internal/particle-vs-gpu.chunk b/editor/assets/chunks/builtin/internal/particle-vs-gpu.chunk index d5712eae781..bd886efdc58 100644 --- a/editor/assets/chunks/builtin/internal/particle-vs-gpu.chunk +++ b/editor/assets/chunks/builtin/internal/particle-vs-gpu.chunk @@ -35,15 +35,15 @@ uniform TickConstants { in vec4 a_position_starttime; // center position,particle start time in vec4 a_color; in vec4 a_dir_life; // xyz:particle start velocity,w:particle lifetime +in float a_rndSeed; #if !CC_INSTANCE_PARTICLE in vec4 a_size_uv; // xyz:size, w:uv_0 in vec4 a_rotation_uv; // xyz:rotation, w:uv_1 - in float a_rndSeed; #endif #if CC_INSTANCE_PARTICLE - in vec4 a_size_fid; // xyz:size, w:fid - in vec4 a_rotation_rnd; // xyz:rotation, w:random + in vec4 a_size_fid; // xyz:size, w:fid + in vec3 a_rotation; // xyz:rotation in vec3 a_uv; #endif @@ -178,12 +178,6 @@ vec4 toQuat(vec3 rotation) { } vec4 gpvs_main () { - #if CC_INSTANCE_PARTICLE - float randSeed = a_rotation_rnd.w; - #else - float randSeed = a_rndSeed; - #endif - float activeTime = u_timeDelta.x - a_position_starttime.w; float normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0); @@ -218,7 +212,7 @@ vec4 gpvs_main () { } else { vec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0); vec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1); - float factor_s = pseudoRandom(randSeed + SIZE_OVERTIME_RAND_OFFSET); + float factor_s = pseudoRandom(a_rndSeed + SIZE_OVERTIME_RAND_OFFSET); size *= mix(size_0, size_1, factor_s); } #endif @@ -233,7 +227,7 @@ vec4 gpvs_main () { } else { vec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0); vec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1); - float factor_f = pseudoRandom(randSeed + FORCE_OVERTIME_RAND_OFFSET); + float factor_f = pseudoRandom(a_rndSeed + FORCE_OVERTIME_RAND_OFFSET); forceAnim = mix(force_0, force_1, factor_f); } vec4 forceTrack = vec4(forceAnim, 0.); @@ -253,7 +247,7 @@ vec4 gpvs_main () { } else { vec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0); vec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1); - float factor_v = pseudoRandom(randSeed + VELOCITY_OVERTIME_RAND_OFFSET); + float factor_v = pseudoRandom(a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET); velocityAnim = mix(vectory_0, vectory_1, factor_v); speedModifier0 = mix(speedModifier0, speedModifier1, factor_v); } @@ -279,7 +273,7 @@ vec4 gpvs_main () { vec3 startRotation = a_rotation_uv.xyz; #endif #if CC_INSTANCE_PARTICLE - vec3 startRotation = a_rotation_rnd.xyz; + vec3 startRotation = a_rotation; #endif #if CC_RENDER_MODE != RENDER_MODE_MESH #if CC_RENDER_MODE == RENDER_MODE_BILLBOARD @@ -306,7 +300,7 @@ vec4 gpvs_main () { } else { vec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0); vec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1); - float factor_r = pseudoRandom(randSeed + ROTATION_OVERTIME_RAND_OFFSET); + float factor_r = pseudoRandom(a_rndSeed + ROTATION_OVERTIME_RAND_OFFSET); vec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w; #if CC_RENDER_MODE == RENDER_MODE_VERTICAL_BILLBOARD || CC_RENDER_MODE == RENDER_MODE_HORIZONTAL_BILLBOARD euler = vec3(0.0, 0.0, euler.z); @@ -325,7 +319,7 @@ vec4 gpvs_main () { } else { vec4 color_0 = texture(color_over_time_tex0, timeCoord0); vec4 color_1 = texture(color_over_time_tex0, timeCoord1); - float factor_c = pseudoRandom(randSeed + COLOR_OVERTIME_RAND_OFFSET); + float factor_c = pseudoRandom(a_rndSeed + COLOR_OVERTIME_RAND_OFFSET); color = a_color * mix(color_0, color_1, factor_c); } #endif @@ -382,7 +376,7 @@ vec4 gpvs_main () { } else { vec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0); vec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1); - float factor_t = pseudoRandom(randSeed + TEXTURE_ANIMATION_RAND_OFFSET); + float factor_t = pseudoRandom(a_rndSeed + TEXTURE_ANIMATION_RAND_OFFSET); frameInfo = mix(frameInfo0, frameInfo1, factor_t); } startFrame = frameInfo.x / u_anim_info.y; diff --git a/editor/assets/chunks/builtin/internal/sprite-texture.chunk b/editor/assets/chunks/builtin/internal/sprite-texture.chunk index d51b56d0694..7e53ac974b2 100644 --- a/editor/assets/chunks/builtin/internal/sprite-texture.chunk +++ b/editor/assets/chunks/builtin/internal/sprite-texture.chunk @@ -1,4 +1,4 @@ // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. #pragma builtin(local) -layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture; +layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; diff --git a/editor/assets/chunks/builtin/uniforms/cc-csm.chunk b/editor/assets/chunks/builtin/uniforms/cc-csm.chunk index 809eb9691d5..ed1a70a3c52 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-csm.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-csm.chunk @@ -4,11 +4,11 @@ #pragma builtin(global) layout(set = 0, binding = 3) uniform CCCSM { highp vec4 cc_csmViewDir0[NUMCASCADES]; //[0].w->layer blank threshold - highp vec4 cc_csmViewDir1[NUMCASCADES]; - highp vec4 cc_csmViewDir2[NUMCASCADES]; + highp vec4 cc_csmViewDir1[NUMCASCADES]; //[i].w->layer split camera near + highp vec4 cc_csmViewDir2[NUMCASCADES]; //[i].w->layer split camera far highp vec4 cc_csmAtlas[NUMCASCADES]; highp mat4 cc_matCSMViewProj[NUMCASCADES]; highp vec4 cc_csmProjDepthInfo[NUMCASCADES]; highp vec4 cc_csmProjInfo[NUMCASCADES]; - highp vec4 cc_csmSplitsInfo; // x-> level_1 far, y-> level_2 far, z-> level_3 far, w-> level_4 far + highp vec4 cc_csmSplitsInfo; // x-> Layers.skirtRange }; diff --git a/editor/assets/chunks/builtin/uniforms/cc-forward-light.chunk b/editor/assets/chunks/builtin/uniforms/cc-forward-light.chunk index bc22e41c471..d1654a32782 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-forward-light.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-forward-light.chunk @@ -9,9 +9,10 @@ #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0 #pragma builtin(local) layout(set = 2, binding = 1) uniform CCForwardLight { - highp vec4 cc_lightPos[LIGHTS_PER_PASS]; // xyz: pos, w: isSpotLight + highp vec4 cc_lightPos[LIGHTS_PER_PASS]; // xyz: pos, w: valid light type[0: directional light, 1: sphere light, 2: spot light, 3: point light, 4: ranged dir light, 5: unkonw] vec4 cc_lightColor[LIGHTS_PER_PASS]; // xyz: color, w: intensity - vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS]; // x: size, y: range, z: cos(half outterAngle), w: enable shadow - vec4 cc_lightDir[LIGHTS_PER_PASS]; // xyz: dir, w: valid light count -}; + vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS]; // x: size, y: range, z: cos(half outterAngle), w: enable shadow; ranged dir light: xyz is right + vec4 cc_lightDir[LIGHTS_PER_PASS]; // xyz: dir, w: unused + vec4 cc_lightBoundingSizeVS[LIGHTS_PER_PASS]; //xyz: ranged dir light node half scale +}; #endif diff --git a/editor/assets/chunks/builtin/uniforms/cc-global.chunk b/editor/assets/chunks/builtin/uniforms/cc-global.chunk index 0a4ab4865ee..0962160ff68 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-global.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-global.chunk @@ -4,14 +4,16 @@ // if shared among stages with different precisions #pragma builtin(global) layout(set = 0, binding = 0) uniform CCGlobal { - highp vec4 cc_time; // x: global time since started in seconds, y: delta time for current frame, z: total frames since started + highp vec4 cc_time; // x: global time since started in seconds, y: delta time for current frame, z: total frames since started, w: fractinal part of x, better precious, should be used with uv animation mediump vec4 cc_screenSize; // xy: screen size, zw: inverse screen size mediump vec4 cc_nativeSize; // xy: shading size, zw: inverse shading size + mediump vec4 cc_probeInfo; // x: reflection probe count mediump vec4 cc_debug_view_mode; // x: single mode, y: lighting with albedo, z: csm layer coloration w: unused mediump vec4 cc_debug_view_composite_pack_1; // x: dir diffuse, y: dir specular, z: env diffuse, w: env specular mediump vec4 cc_debug_view_composite_pack_2; // x: emissive, y: lightmap, z: shadow, w: ao mediump vec4 cc_debug_view_composite_pack_3; // x: normalmap, y: fog, z: tonemapping, w: gamma correction + mediump vec4 cc_debug_view_composite_pack_4; // x: fresnel, y: transmit diffuse, z: transmit specular, w: trt }; #pragma builtin(global) @@ -22,8 +24,8 @@ layout(set = 0, binding = 1) uniform CCCamera { highp mat4 cc_matProjInv; // inverse projection matrix highp mat4 cc_matViewProj; // view-projection matrix highp mat4 cc_matViewProjInv; // inverse view-projection matrix - highp vec4 cc_cameraPos; // xyz: camera position - mediump vec4 cc_surfaceTransform; // x: surface transform y: unused zw: skybox rotation angle cos/sin value + highp vec4 cc_cameraPos; // xyz: camera position w: flip NDC sign + mediump vec4 cc_surfaceTransform; // x: surface transform y: camera usage zw: skybox rotation angle cos/sin value mediump vec4 cc_screenScale; // xy: screen scale, zw: inverse screen scale mediump vec4 cc_exposure; // x: exposure, y: inverse exposure, z: HDR flag, w: inverse standard exposure value mediump vec4 cc_mainLitDir; // xyz: main direcitonal light direction, w: enable shadow diff --git a/editor/assets/chunks/builtin/uniforms/cc-light-map.chunk b/editor/assets/chunks/builtin/uniforms/cc-light-map.chunk index c4fc91ed3c2..4df72e67441 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-light-map.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-light-map.chunk @@ -1,2 +1,2 @@ #pragma builtin(local) -layout(set = 2, binding = 10) uniform sampler2D cc_lightingMap; +layout(set = 2, binding = 11) uniform sampler2D cc_lightingMap; diff --git a/editor/assets/chunks/builtin/uniforms/cc-local.chunk b/editor/assets/chunks/builtin/uniforms/cc-local.chunk index a2bfe240716..3e3e763988d 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-local.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-local.chunk @@ -5,5 +5,7 @@ layout(set = 2, binding = 0) uniform CCLocal { highp mat4 cc_matWorld; highp mat4 cc_matWorldIT; highp vec4 cc_lightingMapUVParam; - highp vec4 cc_localShadowBias; // x:shadow bias, y:shadow normal bias. + highp vec4 cc_localShadowBias; // x:shadow bias, y:shadow normal bias, z:unused, w:visibility for dirlight + highp vec4 cc_reflectionProbeData1; // xyzw: plane or xyz: cube center + highp vec4 cc_reflectionProbeData2; // x: planar reflection depth scale or xyz: cube box half size, w: mipCount }; diff --git a/editor/assets/chunks/builtin/uniforms/cc-morph.chunk b/editor/assets/chunks/builtin/uniforms/cc-morph.chunk index 6f0e7691587..11dbfa2d9b3 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-morph.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-morph.chunk @@ -10,15 +10,15 @@ layout(set = 2, binding = 4) uniform CCMorph { #if CC_MORPH_TARGET_HAS_POSITION #pragma builtin(local) - layout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements; + layout(set = 2, binding = 8) uniform sampler2D cc_PositionDisplacements; #endif #if CC_MORPH_TARGET_HAS_NORMAL #pragma builtin(local) - layout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements; + layout(set = 2, binding = 9) uniform sampler2D cc_NormalDisplacements; #endif #if CC_MORPH_TARGET_HAS_TANGENT #pragma builtin(local) - layout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements; + layout(set = 2, binding = 10) uniform sampler2D cc_TangentDisplacements; #endif diff --git a/editor/assets/chunks/builtin/uniforms/cc-reflection-probe.chunk b/editor/assets/chunks/builtin/uniforms/cc-reflection-probe.chunk new file mode 100644 index 00000000000..52e50b97616 --- /dev/null +++ b/editor/assets/chunks/builtin/uniforms/cc-reflection-probe.chunk @@ -0,0 +1,10 @@ +// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + +#pragma builtin(local) +layout(set = 2, binding = 15) uniform samplerCube cc_reflectionProbeCubemap; + +#pragma builtin(local) +layout(set = 2, binding = 16) uniform sampler2D cc_reflectionProbePlanarMap; + +#pragma builtin(local) +layout(set = 2, binding = 17) uniform sampler2D cc_reflectionProbeDataMap; diff --git a/editor/assets/chunks/builtin/uniforms/cc-reflection-probe.chunk.meta b/editor/assets/chunks/builtin/uniforms/cc-reflection-probe.chunk.meta new file mode 100644 index 00000000000..e5b9603c088 --- /dev/null +++ b/editor/assets/chunks/builtin/uniforms/cc-reflection-probe.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "960cff1c-912a-47d1-a3d9-9a25a9568508", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/builtin/uniforms/cc-sh.chunk b/editor/assets/chunks/builtin/uniforms/cc-sh.chunk new file mode 100644 index 00000000000..6f1e80e27fd --- /dev/null +++ b/editor/assets/chunks/builtin/uniforms/cc-sh.chunk @@ -0,0 +1,12 @@ +// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + +#pragma builtin(local) +layout(set = 2, binding = 6) uniform CCSH { + vec4 cc_sh_linear_const_r; + vec4 cc_sh_linear_const_g; + vec4 cc_sh_linear_const_b; + vec4 cc_sh_quadratic_r; + vec4 cc_sh_quadratic_g; + vec4 cc_sh_quadratic_b; + vec4 cc_sh_quadratic_a; +}; diff --git a/editor/assets/chunks/builtin/uniforms/cc-sh.chunk.meta b/editor/assets/chunks/builtin/uniforms/cc-sh.chunk.meta new file mode 100644 index 00000000000..fe5029e8a8e --- /dev/null +++ b/editor/assets/chunks/builtin/uniforms/cc-sh.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "2c62fe23-f1f4-49f1-a08f-e5e6c650682f", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk b/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk index 5a4d4806eeb..c013c898ec9 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk @@ -12,7 +12,7 @@ highp vec4 cc_jointAnimInfo; // frameID }; #pragma builtin(local) - layout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture; + layout(set = 2, binding = 7) uniform highp sampler2D cc_jointTexture; /** * Although tempting, don't opt the offset arithmetics out to CPU (could * be reduced to a single MAD). The enlarged numerical range could require @@ -33,7 +33,7 @@ #else #if CC_USE_REAL_TIME_JOINT_TEXTURE #pragma builtin(local) - layout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint; + layout(set = 2, binding = 7) uniform highp sampler2D cc_realtimeJoint; #else #pragma builtin(local) layout(set = 2, binding = 3) uniform CCSkinning { diff --git a/editor/assets/chunks/common/common-define.chunk b/editor/assets/chunks/common/common-define.chunk index 4d4acc656b7..48d6d2755b9 100644 --- a/editor/assets/chunks/common/common-define.chunk +++ b/editor/assets/chunks/common/common-define.chunk @@ -25,8 +25,9 @@ #define GRAY_VECTOR vec3(0.299, 0.587, 0.114) // common function -#pragma define saturate(a) clamp(a, 0.0, 1.0) #pragma define equalf(data1, data2) (abs(float(data1) - float(data2)) < EPSILON) +#pragma define equalf_lowp(data1, data2) (abs(float(data1) - float(data2)) < EPSILON_LOWP) +#pragma define equalf_epsilon(data1, data2, epsilonValue) (abs(float(data1) - float(data2)) < epsilonValue) // runtime constants #pragma define-meta CC_DEVICE_SUPPORT_FLOAT_TEXTURE default(1) @@ -44,6 +45,24 @@ #pragma define CC_HANDLE_GET_CLIP_FLIP(uv) uv = cc_cameraPos.w == 0.0 ? vec2(uv.x, -uv.y) : uv // CC_USE_LIGHTMAP Values -#define CC_LIGHTMAP_DISABLED 0 -#define CC_LIGHTMAP_ALL_IN_ONE 1 -#define CC_LIGHTMAP_CC_LIGHTMAP_INDIRECT_OCCLUSION 2 +#define LIGHT_MAP_TYPE_DISABLED 0 +#define LIGHT_MAP_TYPE_ALL_IN_ONE 1 +#define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2 + +// CC_USE_REFLECTION_PROBE Values +#define REFLECTION_PROBE_TYPE_NONE 0 +#define REFLECTION_PROBE_TYPE_CUBE 1 +#define REFLECTION_PROBE_TYPE_PLANAR 2 + +// Light Type +#define LIGHT_TYPE_DIRECTIONAL 0.0 +#define LIGHT_TYPE_SPHERE 1.0 +#define LIGHT_TYPE_SPOT 2.0 +#define LIGHT_TYPE_POINT 3.0 +#define LIGHT_TYPE_RANGED_DIRECTIONAL 4.0 + +#define IS_DIRECTIONAL_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_DIRECTIONAL) +#define IS_SPHERE_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_SPHERE) +#define IS_SPOT_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_SPOT) +#define IS_POINT_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_POINT) +#define IS_RANGED_DIRECTIONAL_LIGHT(light_type) equalf_lowp(light_type, LIGHT_TYPE_RANGED_DIRECTIONAL) diff --git a/editor/assets/chunks/common/debug/debug-view-define.chunk b/editor/assets/chunks/common/debug/debug-view-define.chunk index 701aa143eab..ae653b7c3c3 100644 --- a/editor/assets/chunks/common/debug/debug-view-define.chunk +++ b/editor/assets/chunks/common/debug/debug-view-define.chunk @@ -22,9 +22,10 @@ #define CC_SURFACES_DEBUG_VIEW_METALLIC CC_SURFACES_DEBUG_VIEW_TRANSPARENCY + 1 #define CC_SURFACES_DEBUG_VIEW_ROUGHNESS CC_SURFACES_DEBUG_VIEW_METALLIC + 1 #define CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY CC_SURFACES_DEBUG_VIEW_ROUGHNESS + 1 +#define CC_SURFACES_DEBUG_VIEW_IOR CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY + 1 // lighting data -#define CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY + 1 +#define CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE CC_SURFACES_DEBUG_VIEW_IOR + 1 #define CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE + 1 #define CC_SURFACES_DEBUG_VIEW_DIRECT_ALL CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR + 1 #define CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE CC_SURFACES_DEBUG_VIEW_DIRECT_ALL + 1 @@ -35,7 +36,19 @@ #define CC_SURFACES_DEBUG_VIEW_SHADOW CC_SURFACES_DEBUG_VIEW_LIGHT_MAP + 1 #define CC_SURFACES_DEBUG_VIEW_AO CC_SURFACES_DEBUG_VIEW_SHADOW + 1 -#define CC_SURFACES_DEBUG_VIEW_FOG CC_SURFACES_DEBUG_VIEW_AO + 1 +// advanced lighting data +#define CC_SURFACES_DEBUG_VIEW_FRESNEL CC_SURFACES_DEBUG_VIEW_AO + 1 +#define CC_SURFACES_DEBUG_VIEW_TRANSMIT_DIRECT_DIFFUSE CC_SURFACES_DEBUG_VIEW_FRESNEL + 1 +#define CC_SURFACES_DEBUG_VIEW_TRANSMIT_DIRECT_SPECULAR CC_SURFACES_DEBUG_VIEW_TRANSMIT_DIRECT_DIFFUSE + 1 +#define CC_SURFACES_DEBUG_VIEW_TRANSMIT_ENV_DIFFUSE CC_SURFACES_DEBUG_VIEW_TRANSMIT_DIRECT_SPECULAR + 1 +#define CC_SURFACES_DEBUG_VIEW_TRANSMIT_ENV_SPECULAR CC_SURFACES_DEBUG_VIEW_TRANSMIT_ENV_DIFFUSE + 1 +#define CC_SURFACES_DEBUG_VIEW_TRANSMIT_ALL CC_SURFACES_DEBUG_VIEW_TRANSMIT_ENV_SPECULAR + 1 +#define CC_SURFACES_DEBUG_VIEW_TRT_DIRECT CC_SURFACES_DEBUG_VIEW_TRANSMIT_ALL + 1 +#define CC_SURFACES_DEBUG_VIEW_TRT_ENVIRONMENT CC_SURFACES_DEBUG_VIEW_TRT_DIRECT + 1 +#define CC_SURFACES_DEBUG_VIEW_TRT_ALL CC_SURFACES_DEBUG_VIEW_TRT_ENVIRONMENT + 1 + +// misc data +#define CC_SURFACES_DEBUG_VIEW_FOG CC_SURFACES_DEBUG_VIEW_TRT_ALL + 1 // Debug view UI and macros // #pragma define-meta CC_USE_DEBUG_VIEW range([0, 2]) @@ -44,18 +57,23 @@ #define CC_SURFACES_DEBUG_VIEW_SINGLE 1 #define CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC 2 -#pragma define IS_DEBUG_VIEW_SINGLE_MODE(mode) equalf(cc_debug_view_mode.x, mode) -#define IS_DEBUG_VIEW_LIGHTING_ENABLE_WITH_ALBEDO (cc_debug_view_mode.y > 0.0) -#define IS_DEBUG_VIEW_MISC_ENABLE_CSM_LAYER_COLORATION (cc_debug_view_mode.z > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_DIFFUSE (cc_debug_view_composite_pack_1.x > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_SPECULAR (cc_debug_view_composite_pack_1.y > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_DIFFUSE (cc_debug_view_composite_pack_1.z > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_SPECULAR (cc_debug_view_composite_pack_1.w > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_EMISSIVE (cc_debug_view_composite_pack_2.x > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_LIGHT_MAP (cc_debug_view_composite_pack_2.y > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_SHADOW (cc_debug_view_composite_pack_2.z > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_AO (cc_debug_view_composite_pack_2.w > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_NORMAL_MAP (cc_debug_view_composite_pack_3.x > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_FOG (cc_debug_view_composite_pack_3.y > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING (cc_debug_view_composite_pack_3.z > 0.0) -#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION (cc_debug_view_composite_pack_3.w > 0.0) +#define IS_DEBUG_VIEW_ENABLE_WITH_CAMERA (cc_surfaceTransform.y != 3.0) +#pragma define IS_DEBUG_VIEW_SINGLE_MODE(mode) (equalf_lowp(cc_debug_view_mode.x, mode) && (cc_surfaceTransform.y != 3.0)) +#define IS_DEBUG_VIEW_LIGHTING_ENABLE_WITH_ALBEDO ((cc_debug_view_mode.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_MISC_ENABLE_CSM_LAYER_COLORATION ((cc_debug_view_mode.z > 0.0) && IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_DIFFUSE ((cc_debug_view_composite_pack_1.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_SPECULAR ((cc_debug_view_composite_pack_1.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_DIFFUSE ((cc_debug_view_composite_pack_1.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_SPECULAR ((cc_debug_view_composite_pack_1.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_EMISSIVE ((cc_debug_view_composite_pack_2.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_LIGHT_MAP ((cc_debug_view_composite_pack_2.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_SHADOW ((cc_debug_view_composite_pack_2.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_AO ((cc_debug_view_composite_pack_2.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_NORMAL_MAP ((cc_debug_view_composite_pack_3.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_FOG ((cc_debug_view_composite_pack_3.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING ((cc_debug_view_composite_pack_3.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION ((cc_debug_view_composite_pack_3.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_FRESNEL ((cc_debug_view_composite_pack_4.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TRANSMIT_DIFFUSE ((cc_debug_view_composite_pack_4.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TRANSMIT_SPECULAR ((cc_debug_view_composite_pack_4.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) +#define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TRT ((cc_debug_view_composite_pack_4.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) diff --git a/editor/assets/chunks/common/lighting/attenuation.chunk b/editor/assets/chunks/common/lighting/attenuation.chunk index f6ef44e5cd8..44266dc576f 100644 --- a/editor/assets/chunks/common/lighting/attenuation.chunk +++ b/editor/assets/chunks/common/lighting/attenuation.chunk @@ -1,4 +1,4 @@ - +// base float SmoothDistAtt2 (float distSqr, float invSqrAttRadius) { float factor = distSqr * invSqrAttRadius; // ^2 float factor2 = factor * factor; // ^4 @@ -24,3 +24,37 @@ float GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffse float attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0); return (attenuation * attenuation); } + + +float GetOutOfRange (vec3 worldPos, vec3 lightPos, vec3 lookAt, vec3 right, vec3 BoundingHalfSizeVS) { + vec3 v = vec3(0.0); + vec3 up = cross(right, lookAt); + worldPos -= lightPos; + v.x = dot(worldPos, right); + v.y = dot(worldPos, up); + v.z = dot(worldPos, lookAt); + vec3 result = step(abs(v), BoundingHalfSizeVS); + return result.x * result.y * result.z; +} + +// advanced +float CalculateDistanceAttenuation(float distToLightSqr, float lightRadius, float lightRange, float lightType) +{ + // physical attenuation + float attRadiusSqrInv = 1.0 / max(lightRange, 0.01); + attRadiusSqrInv *= attRadiusSqrInv; + + // artical soft edge fading + float litRadiusSqr = lightRadius * lightRadius; + float edgeAttenuation = (IS_POINT_LIGHT(lightType) || IS_RANGED_DIRECTIONAL_LIGHT(lightType)) ? 1.0 : litRadiusSqr / max(litRadiusSqr, distToLightSqr); + + return GetDistAtt(distToLightSqr, attRadiusSqrInv) * edgeAttenuation; +} + +float CalculateAngleAttenuation(vec3 spotLightDir, vec3 L, float cosAngleOuter) +{ + float cosInner = max(dot(spotLightDir, L), 0.01); + float litAngleScale = 1.0 / max(0.001, cosInner - cosAngleOuter); + float litAngleOffset = -cosAngleOuter * litAngleScale; + return GetAngleAtt(L, spotLightDir, litAngleScale, litAngleOffset); +} diff --git a/editor/assets/chunks/common/lighting/brdf.chunk b/editor/assets/chunks/common/lighting/brdf.chunk index 63a70735c1c..abd2d1a24c7 100644 --- a/editor/assets/chunks/common/lighting/brdf.chunk +++ b/editor/assets/chunks/common/lighting/brdf.chunk @@ -1,3 +1,5 @@ +#include + float D_GGX(float roughness, float NoH) { float m = roughness * roughness; @@ -10,7 +12,7 @@ float D_GGXMobile(float roughness, float NoH) { float OneMinusNoHSqr = 1.0 - NoH * NoH; float a = roughness * roughness; float n = NoH * a; - float p = a / (OneMinusNoHSqr + n * n); + float p = a / max(EPSILON, OneMinusNoHSqr + n * n); return p * p; } diff --git a/editor/assets/chunks/common/lighting/bxdf.chunk b/editor/assets/chunks/common/lighting/bxdf.chunk new file mode 100644 index 00000000000..5638c711516 --- /dev/null +++ b/editor/assets/chunks/common/lighting/bxdf.chunk @@ -0,0 +1,14 @@ + +// saturated N dot V +float CalculateFresnelCoefficient(float ior, float NoVSat) +{ + float g, c, n, prev, next; + n = ior; + c = ior * NoVSat; + g = sqrt(1.0 + c * c - c); + prev = (g - c) / (g + c); + next = (c * (g+c) - n*n) / (c * (g-c) + n*n); + prev *= prev; + next *= next; + return 0.5 * prev * (1.0 + next); +} diff --git a/editor/assets/chunks/common/lighting/bxdf.chunk.meta b/editor/assets/chunks/common/lighting/bxdf.chunk.meta new file mode 100644 index 00000000000..9ee68aa2d2d --- /dev/null +++ b/editor/assets/chunks/common/lighting/bxdf.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "5c21fcb9-179d-4081-99f8-b119f1e6176e", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/common/lighting/functions.chunk b/editor/assets/chunks/common/lighting/functions.chunk index 7f48e073f99..18f478f2bb5 100644 --- a/editor/assets/chunks/common/lighting/functions.chunk +++ b/editor/assets/chunks/common/lighting/functions.chunk @@ -1,22 +1,65 @@ -#include - // helper functions for lighting model-functions -float CalculateDistanceAttenuation(float distToLightSqr, float lightRadius, float lightRange) +// return unnormalized vector, support oppo-side +// V from pixel to camera +vec3 CalculateRefractDirection(vec3 N, vec3 V, float NoV, float ior) { - float litRadiusSqr = lightRadius * lightRadius; - float attRadiusSqrInv = 1.0 / max(lightRange, 0.01); - attRadiusSqrInv *= attRadiusSqrInv; - - // soft edge fading - float edgeAttenuation = litRadiusSqr / max(litRadiusSqr, distToLightSqr); - return GetDistAtt(distToLightSqr, attRadiusSqrInv) * edgeAttenuation; + float NoVAbs = abs(NoV); + // two sided + float sideSign = NoV < 0.0 ? -1.0 : 1.0; + N *= sideSign; + NoV *= sideSign; + float sinB = sqrt(1.0 - NoVAbs*NoVAbs) / ior; + vec3 X = normalize(-V + N * NoVAbs); + vec3 R = -N + X * sinB; + return R; } -float CalculateAngleAttenuation(vec3 spotLightDir, vec3 L, float cosAngleOuter) +vec3 CalculateReflectDirection(vec3 N, vec3 V, float NoV) { - float cosInner = max(dot(spotLightDir, L), 0.01); - float litAngleScale = 1.0 / max(0.001, cosInner - cosAngleOuter); - float litAngleOffset = -cosAngleOuter * litAngleScale; - return GetAngleAtt(L, spotLightDir, litAngleScale, litAngleOffset); + // two sided + float sideSign = NoV < 0.0 ? -1.0 : 1.0; + N *= sideSign; + return reflect(-V, N); +} + +// for bumped planar reflection +vec3 CalculatePlanarReflectPositionOnPlane(vec3 N, vec3 V, vec3 worldPos, vec4 plane, vec3 cameraPos, float probeReflectedDepth) +{ + float distPixelToPlane = -dot(plane, vec4(worldPos, 1.0)); + // bring plane to worldPos, avoid artifacts when reflected point away from plane (do not bring worldPos to plane) + plane.w += distPixelToPlane; + float distCameraToPlane = abs(-dot(plane, vec4(cameraPos, 1.0))); + vec3 planeN = plane.xyz; + vec3 virtualCameraPos = cameraPos - 2.0 * distCameraToPlane * planeN; + /*support for two-sided reflections + float sideSignPlaneN = dot(planeN, V) < 0.0 ? -1.0 : 1.0; + float sideSignN = dot(N, V) < 0.0 ? -1.0 : 1.0; + planeN *= sideSignPlaneN; + N *= sideSignN;*/ + vec3 bumpedR = normalize(reflect(-V, N)); //R' + + // actually reflected pos alone bumpedR direction, avoid tracing by specified a fake depth + vec3 reflectedPointPos = worldPos + probeReflectedDepth * bumpedR; + vec3 virtualCameraToReflectedPoint = normalize(reflectedPointPos - virtualCameraPos); + + // the ray from virtual camera to reflected point, will intersect with plane on P' + float y = distCameraToPlane / max(EPSILON_LOWP, dot(planeN, virtualCameraToReflectedPoint)); + return virtualCameraPos + y * virtualCameraToReflectedPoint; } + + + +// fix cubemap direction with box projection +// return unnormalized vector and weight for exceeding +vec4 CalculateBoxProjectedDirection(vec3 R, vec3 worldPos, vec3 cubeCenterPos, vec3 cubeBoxHalfSize) +{ + // point W is the worldPos in the space origin align with cube center + vec3 W = worldPos - cubeCenterPos; + // find point P which intersected with cube box border from W alone R + vec3 projectedLength = (sign(R) * cubeBoxHalfSize - W) / (R + vec3(EPSILON)); + float len = min(min(projectedLength.x, projectedLength.y), projectedLength.z); + vec3 P = W + len * R; + float weight = len < 0.0 ? 0.0 : 1.0; + return vec4(P, weight); +} \ No newline at end of file diff --git a/editor/assets/chunks/common/lighting/light-map.chunk b/editor/assets/chunks/common/lighting/light-map.chunk index e4f4b77ac0d..1e31b5db4b8 100644 --- a/editor/assets/chunks/common/lighting/light-map.chunk +++ b/editor/assets/chunks/common/lighting/light-map.chunk @@ -1,14 +1,34 @@ - -vec4 GetLightMapColor(sampler2D lightingMap, vec2 luv, float lum) +// for legacy effects +void SampleAndDecodeLightMapColor(out vec3 lightmapColor, out float dirShadow, out float ao, sampler2D lightingMap, vec2 luv, float lum, vec3 worldNormal) { + // has radiant basis +#if CC_LIGHT_MAP_VERSION > 2 + // has high precision data +#elif CC_LIGHT_MAP_VERSION > 1 + vec4 dataLow = texture(lightingMap, luv); + vec4 dataHigh = texture(lightingMap, luv + vec2(0.5, 0.0)); + lightmapColor.xyz = dataLow.xyz + dataHigh.xyz * 0.00392156862745098; + lightmapColor.rgb *= lum; + dirShadow = dataLow.a; + ao = dataHigh.a; +#else vec4 lightmap = texture(lightingMap, luv); - lightmap.rgb *= lum; + lightmapColor = lightmap.rgb * lum; + dirShadow = lightmap.a; + ao = 1.0; +#endif +} + +// for surface shader +void GetLightMapColor(out vec3 lightmapColor, out float dirShadow, out float ao, sampler2D lightingMap, vec2 luv, float lum, vec3 worldNormal) +{ + vec4 lightmap; + vec2 occlusion; + SampleAndDecodeLightMapColor(lightmapColor, dirShadow, ao, lightingMap, luv, lum, worldNormal); #if CC_USE_HDR // convert from standard camera exposure parameters to current exposure value // baked in LDR scene still regarded as exposured with standard camera parameters - lightmap.rgb *= cc_exposure.w * cc_exposure.x; + lightmapColor.rgb *= cc_exposure.w * cc_exposure.x; #endif - - return lightmap; } diff --git a/editor/assets/chunks/common/math/coordinates.chunk b/editor/assets/chunks/common/math/coordinates.chunk index 07a32909e80..4e9868d2eac 100644 --- a/editor/assets/chunks/common/math/coordinates.chunk +++ b/editor/assets/chunks/common/math/coordinates.chunk @@ -1,3 +1,26 @@ +// When screenSpaceSingY and clipSpaceSignY have different signs, need to flip the uv +// cc_cameraPos.w is flipNDCSign +#pragma define CC_HANDLE_NDC_SAMPLE_FLIP(uv, flipNDCSign) uv = flipNDCSign == 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv + + +vec2 GetScreenUV(vec3 worldPos, mat4 matViewProj, float flipNDCSign) +{ + vec4 clipPos = matViewProj * vec4(worldPos, 1.0); + vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5; + screenUV = vec2(1.0 - screenUV.x, screenUV.y); + CC_HANDLE_NDC_SAMPLE_FLIP(screenUV, flipNDCSign); + return screenUV; +} + +vec2 GetPlanarReflectScreenUV(vec3 worldPos, mat4 matVirtualCameraViewProj, float flipNDCSign, vec3 viewDir, vec3 reflectDir) +{ + vec4 clipPos = matVirtualCameraViewProj * vec4(worldPos, 1.0); + vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5; + screenUV = vec2(1.0 - screenUV.x, screenUV.y); + CC_HANDLE_NDC_SAMPLE_FLIP(screenUV, flipNDCSign); + return screenUV; +} + // depthHS = ndc depth(-1 ~ +1) float GetCameraDepthRH(float depthHS, mat4 matProj) { diff --git a/editor/assets/chunks/common/math/number.chunk b/editor/assets/chunks/common/math/number.chunk index bf59eb75e24..ac6f76b3352 100644 --- a/editor/assets/chunks/common/math/number.chunk +++ b/editor/assets/chunks/common/math/number.chunk @@ -28,4 +28,33 @@ bool isinfs(vec4 val) { } -// random number \ No newline at end of file +// intrinsic functions +#if __VERSION__ < 300 + float round(float value) + { + float f = fract(value); + return value - f + (f < 0.5 ? 0.0 : 1.0); + } + vec2 round(vec2 value) { return vec2(round(value.x), round(value.y)); } + vec3 round(vec3 value) { return vec3(round(value.x), round(value.y), round(value.z)); } + vec4 round(vec4 value) { return vec4(round(value.x), round(value.y), round(value.z), round(value.w)); } +#endif + +float rsqrt(float value) +{ + return 1.0 / sqrt(value); +} +vec2 rsqrt(vec2 value) { return vec2(rsqrt(value.x), rsqrt(value.y)); } +vec3 rsqrt(vec3 value) { return vec3(rsqrt(value.x), rsqrt(value.y), rsqrt(value.z)); } +vec4 rsqrt(vec4 value) { return vec4(rsqrt(value.x), rsqrt(value.y), rsqrt(value.z), rsqrt(value.w)); } + +float saturate(float value) +{ + return min(max(value, 0.0), 1.0); +} +vec2 saturate(vec2 value) { return vec2(saturate(value.x), saturate(value.y)); } +vec3 saturate(vec3 value) { return vec3(saturate(value.x), saturate(value.y), saturate(value.z)); } +vec4 saturate(vec4 value) { return vec4(saturate(value.x), saturate(value.y), saturate(value.z), saturate(value.w)); } + + +// random number diff --git a/editor/assets/chunks/common/mesh/vat-animation.chunk b/editor/assets/chunks/common/mesh/vat-animation.chunk new file mode 100644 index 00000000000..1d2a20c7a0b --- /dev/null +++ b/editor/assets/chunks/common/mesh/vat-animation.chunk @@ -0,0 +1,272 @@ +#include +#include + +// Vertex Animation Texture (VAT), baked physically simulation result for rigid-body, soft-body and fluid + +// Houdini VAT Plugin Version: + // 1. Soft-body and fluids use 3.0, Select Unity mode, otherwise animation will become crack + // 2. Rigid-body use 2.0, Select UE mode with initialize settings, needs export json for numOfFrames(frameCount) and max/min values + +// Houdini misc export settings: + // 1. Select LDR + // 2. Do not check paddle, two-position textures and pack normals + +// Cocos import settings: + // 1. LUT texture should set filter to "nearest" and uncheck "fix alpha transparency" + // 2. Rigid-body select import normal and tangent + // 3. Rigid-body and soft-body need check HAS_SECOND_UV + // 4. If no sign texture with exr image, use white texture instead + +// For resources exported by UE mode, invoke functions like: + // 1. VATFunction(inout_pos.xzy / VAT_FBX_TO_COCOS_COORDINATE_SCALE, inout_vector.xzy); + // 2. out_pos.xyz = inout_pos.xzy * VAT_FBX_TO_COCOS_COORDINATE_SCALE; + // 2. out_vector.xyz = inout_vector.xzy; + +#define VAT_FBX_TO_COCOS_COORDINATE_SCALE 0.01 +#define VAT_LUT_PRECISION_VALUE_LDR 255.0 +#define VAT_LUT_PRECISION_VALUE_HDR 2048.0 + +float CalculateVATAnimationUV(out vec2 deltaV, float frameCount, float animSpeed, float elapseTime) +{ + float thisFrame = fract(animSpeed * elapseTime); + thisFrame = floor(thisFrame * frameCount); + float thisFrameDeltaV = thisFrame / frameCount; + float nextFrameDeltaV = (thisFrame + 1.0) / frameCount; + deltaV = vec2(thisFrameDeltaV, nextFrameDeltaV); + float frameLerp = fract(thisFrame * frameCount); + return frameLerp; +} + + + +///////////////////////////////////////////// public functions +// auto calculation frame count for fluid +float VATCalculateFrameCount(vec2 lutTexResolution, float meshVertexCount) +{ + float lineCountPerFrame = ceil(meshVertexCount / lutTexResolution.x); + return floor(lutTexResolution.y / lineCountPerFrame); +} + +// meshUV use texCoord0 for fluid +// meshUV use texCoord1 for rigid-body and soft-body +float VATGetAnimUV(out vec2 thisFrameUV, out vec2 nextFrameUV, vec2 meshUV, float frameCount, float animSpeed, float elapseTime) +{ + vec2 frameDeltaV; + float frameLerp = CalculateVATAnimationUV(frameDeltaV, frameCount, animSpeed, elapseTime); + thisFrameUV = meshUV + vec2(0.0, frameDeltaV.x); + nextFrameUV = meshUV + vec2(0.0, frameDeltaV.y); + return frameLerp; +} +// VAT with LUT, fluid only +float VATGetAnimUV(out vec2 thisFrameUV, out vec2 nextFrameUV, vec2 meshUV, float frameCount, float animSpeed, float elapseTime, sampler2D lutTexture) +{ + vec2 frameDeltaV; + float frameLerp = CalculateVATAnimationUV(frameDeltaV, frameCount, animSpeed, elapseTime); + vec4 thisFramelookUpValue = texture(lutTexture, meshUV + vec2(0.0, frameDeltaV.x)); + thisFrameUV = thisFramelookUpValue.xz + thisFramelookUpValue.yw / VAT_LUT_PRECISION_VALUE_LDR; + vec4 nextFramelookUpValue = texture(lutTexture, meshUV + vec2(0.0, frameDeltaV.y)); + nextFrameUV = nextFramelookUpValue.xz + nextFramelookUpValue.yw / VAT_LUT_PRECISION_VALUE_LDR; + return frameLerp; +} + +// return absolute position for fluid +// return position offset for soft-body +vec3 VATGetLocalPosition(vec2 thisFrameUV, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture) +{ + vec3 thisFramePos = SampleTextureExr(vatPositionTexture, vatPositionSignTexture, thisFrameUV); + return thisFramePos * VAT_FBX_TO_COCOS_COORDINATE_SCALE; +} +// meshNormal is up-axis for fluid +vec3 VATGetLocalNormal(vec3 meshNormal, vec2 thisFrameUV, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture) +{ + vec4 thisFrameData = SampleTextureExrWithAlpha(vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, thisFrameUV); + rotateVecFromQuat(meshNormal, thisFrameData); + return meshNormal; +} + +// for smooth animation +vec3 VATGetLocalPosition(vec2 thisFrameUV, vec2 nextFrameUV, float frameLerp, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture) +{ + vec3 thisFramePos = SampleTextureExr(vatPositionTexture, vatPositionSignTexture, thisFrameUV); + vec3 nextFramePos = SampleTextureExr(vatPositionTexture, vatPositionSignTexture, nextFrameUV); + return mix(thisFramePos, nextFramePos, frameLerp) * VAT_FBX_TO_COCOS_COORDINATE_SCALE; +} +vec3 VATGetLocalNormal(vec3 meshNormal, vec2 thisFrameUV, vec2 nextFrameUV, float frameLerp, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture) +{ + vec4 thisFrameData = SampleTextureExrWithAlpha(vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, thisFrameUV); + vec4 nextFrameData = SampleTextureExrWithAlpha(vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, nextFrameUV); + vec4 data = mix(thisFrameData, nextFrameData, frameLerp); + + rotateVecFromQuat(meshNormal, data); + return meshNormal; +} + +// calculate simulation voxel coordinates +vec3 VATCalculateFluidVoxelUV(vec3 vatBoundingBoxMin, vec3 vatBoundingBoxMax, vec3 localPos) +{ + // bounding box in exported json is unscaled + vatBoundingBoxMin *= VAT_FBX_TO_COCOS_COORDINATE_SCALE; + vatBoundingBoxMax *= VAT_FBX_TO_COCOS_COORDINATE_SCALE; + + vec3 size = vatBoundingBoxMax - vatBoundingBoxMin; + vec3 coef = (localPos - vatBoundingBoxMin) / size; + return coef; +} + + + + + +////////////////////////////////////////////////////////////////Rigid-body +void VATGetLocalPositionRigidBody20(inout vec3 meshLocalPos, inout vec3 meshLocalNormal, inout vec3 meshLocalTangent, in vec4 meshVertexColor, vec2 thisFrameUV, float pivMax, float pivMin, float posMax, float posMin, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture, sampler2D vatPositionAlphaTexture, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture) +{ + // pivot + float pivExpand = pivMax - pivMin; + float posExpand = posMax - posMin; + + vec3 pivot = meshVertexColor.xyz; + pivot.xyz *= pivExpand; + pivot.xyz += vec3(pivMin); + + // anim pos + vec3 posData = SampleTextureExr(vatPositionTexture, vatPositionSignTexture, thisFrameUV); + vec3 texturePos = posData; + texturePos.xyz *= posExpand; + texturePos.xyz += posMin; + + // rotate pos + vec4 quat = SampleTextureExrWithAlpha(vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, thisFrameUV); + quat = quat * 2.0 - vec4(1.0); + + vec3 originPos = meshLocalPos - pivot; + vec3 rotatedPos; + rotatedPos = 2.0 * cross(quat.xyz, cross(quat.xyz, originPos.xyz) + quat.w * originPos.xyz); + + // result + meshLocalPos = meshLocalPos + rotatedPos + texturePos; + rotateVecFromQuat(meshLocalNormal, quat); + rotateVecFromQuat(meshLocalTangent, quat); +} + +void VATGetLocalPositionRigidBody20_UE(inout vec3 meshLocalPos, inout vec3 meshLocalNormal, inout vec3 meshLocalTangent, in vec4 meshVertexColor, vec2 thisFrameUV, float pivMax, float pivMin, float posMax, float posMin, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture, sampler2D vatPositionAlphaTexture, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture) +{ + // input + vec3 preSkinnedPos = meshLocalPos.xzy / VAT_FBX_TO_COCOS_COORDINATE_SCALE; + vec3 preSkinnedNorm = meshLocalNormal.xzy; + vec3 preSkinnedTangent = meshLocalTangent.xzy; + + VATGetLocalPositionRigidBody20(preSkinnedPos, preSkinnedNorm, preSkinnedTangent, meshVertexColor, thisFrameUV, pivMax, pivMin, posMax, posMin, vatPositionTexture, vatPositionSignTexture, vatPositionAlphaTexture, vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture); + + // output + meshLocalPos.xyz = preSkinnedPos.xzy * VAT_FBX_TO_COCOS_COORDINATE_SCALE; + meshLocalNormal.xyz = preSkinnedNorm.xzy; + meshLocalTangent.xyz = preSkinnedTangent.xzy; +} + + +// Experimental +float CalculateVATDecodeUV(float A, float B) +{ +#if __VERSION__ >= 110 + uint a = floatBitsToUint(A); //asuint(A) + uint b = floatBitsToUint(B); + a = ((a >> 16u) & 0x8000u) | + ((((a >> 23u) & 0xFFu) - 112u) << 10u) | + ((a >> 13u) & 0x3FFu); + b = ((b >> 16u) & 0x8000u) | + ((((b >> 23u) & 0xFFu) - 112u) << 10u) | + ((b >> 13u) & 0x3FFu); + a = (a & 0x8000u) | ((a << 2u) & 0x7FF8u); + b = (b & 0x8000u) | ((b << 2u) & 0x7FF8u); + a = (a << 16u) | (b << 3u); + return uintBitsToFloat(a); //asfloat(a); +#endif + return 0.0; +} +void VATGetLocalPositionRigidBody30(inout vec3 meshLocalPos, inout vec3 meshLocalNormal, inout vec3 meshLocalTangent, in vec2 meshUV2, in vec2 meshUV3, vec2 thisFrameUV, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture, sampler2D vatPositionAlphaTexture, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture, bool isZUp) +{ + // pivot offset + vec3 direction; + direction.x = meshUV2.x; + direction.y = sqrt(1.0 - (meshUV2.x*meshUV2.x + meshUV3.x*meshUV3.x)); + direction.z = meshUV3.x; + float Magnitude = CalculateVATDecodeUV(meshUV2.y, meshUV3.y); + float Up = Magnitude; + + vec3 org, pivot; + org = vec3(meshUV2.x, Up, meshUV3.x); + if(abs(meshUV3.y) > 2.0) + pivot = direction.xyz * Magnitude; + else + pivot = org.xyz; + + if(isZUp) + pivot.xyz = pivot.xzy / VAT_FBX_TO_COCOS_COORDINATE_SCALE; + vec3 originPos = meshLocalPos - pivot; + + // rotation offset + vec4 posData = SampleTextureExrWithAlpha(vatPositionTexture, vatPositionSignTexture, vatPositionAlphaTexture, thisFrameUV); + vec4 XYZW = SampleTextureExrWithAlpha(vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, thisFrameUV); + float w = sqrt(1.0 - dot(XYZW.xyz, XYZW.xyz)); //sqrt(1.0 - quat.x*quat.x - quat.y*quat.y - quat.z*quat.z); //r + // restore origin quaternion for slerp between frames + // float cycle_count = XYZW.w; // rotation cycle count for slerp between frames + // float rot_angle = cycle_count * PI2 + acos(w); + // w = cos(rot_angle); + vec4 quat = vec4(0.0, 0.0, 0.0, 1.0); + + // upper is UE, lower is Houdini + float maxComponent = floor(posData.a * 4.0); + if(equalf_epsilon(maxComponent, 1.0, 0.01)) { + quat = vec4(-w, XYZW.yzx); + quat = vec4(w, XYZW.yzx); + } + else if(equalf_epsilon(maxComponent, 2.0, 0.01)) { + quat = vec4(XYZW.xy, -w, -XYZW.z); + quat = vec4(XYZW.x, w, XYZW.zy); + } + else if(equalf_epsilon(maxComponent, 3.0, 0.01)) { + quat = vec4(XYZW.x, -w, -XYZW.zy); + quat = vec4(XYZW.xy, w, XYZW.z); + } + else + quat = vec4(XYZW.xyz, w); + + // quat = quat.xzyw; + + vec3 rotatedPos; + rotatedPos = 2.0 * cross(quat.xyz, cross(quat.xyz, originPos.xyz) + quat.w * originPos.xyz); + + // result + meshLocalPos = originPos + rotatedPos + posData.xyz; + meshLocalNormal = 2.0 * cross(quat.xyz, cross(quat.xyz, meshLocalNormal.xyz)+ quat.w * meshLocalNormal.xyz); + meshLocalTangent = 2.0 * cross(quat.xyz, cross(quat.xyz, meshLocalTangent.xyz)+ quat.w * meshLocalTangent.xyz); +} + +void VATGetLocalPositionRigidBody30_UE(inout vec3 meshLocalPos, inout vec3 meshLocalNormal, inout vec3 meshLocalTangent, in vec2 meshUV2, in vec2 meshUV3, vec2 thisFrameUV, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture, sampler2D vatPositionAlphaTexture, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture) +{ + // input + vec3 preSkinnedPos = meshLocalPos.xzy / VAT_FBX_TO_COCOS_COORDINATE_SCALE; + vec3 preSkinnedNorm = meshLocalNormal.xzy; + vec3 preSkinnedTangent = meshLocalTangent.xzy; + + VATGetLocalPositionRigidBody30(preSkinnedPos, preSkinnedNorm, preSkinnedTangent, meshUV2, meshUV3, thisFrameUV, vatPositionTexture, vatPositionSignTexture, vatPositionAlphaTexture, vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, true); + + // output + meshLocalPos = preSkinnedPos.xzy * VAT_FBX_TO_COCOS_COORDINATE_SCALE; + meshLocalNormal = preSkinnedNorm.xzy; + meshLocalTangent = preSkinnedTangent.xzy; +} +void VATGetLocalPositionRigidBody30_Cocos(inout vec3 meshLocalPos, inout vec3 meshLocalNormal, inout vec3 meshLocalTangent, in vec2 meshUV2, in vec2 meshUV3, vec2 thisFrameUV, sampler2D vatPositionTexture, sampler2D vatPositionSignTexture, sampler2D vatPositionAlphaTexture, sampler2D vatRotationTexture, sampler2D vatRotationSignTexture, sampler2D vatRotationAlphaTexture) +{ + // input + vec3 preSkinnedPos = meshLocalPos.xyz / VAT_FBX_TO_COCOS_COORDINATE_SCALE; + vec3 preSkinnedNorm = meshLocalNormal.xyz; + vec3 preSkinnedTangent = meshLocalTangent.xyz; + + VATGetLocalPositionRigidBody30(preSkinnedPos, preSkinnedNorm, preSkinnedTangent, meshUV2, meshUV3, thisFrameUV, vatPositionTexture, vatPositionSignTexture, vatPositionAlphaTexture, vatRotationTexture, vatRotationSignTexture, vatRotationAlphaTexture, false); + + // output + meshLocalPos = preSkinnedPos.xyz * VAT_FBX_TO_COCOS_COORDINATE_SCALE; + meshLocalNormal = preSkinnedNorm.xyz; + meshLocalTangent = preSkinnedTangent.xyz; +} diff --git a/editor/assets/chunks/common/mesh/vat-animation.chunk.meta b/editor/assets/chunks/common/mesh/vat-animation.chunk.meta new file mode 100644 index 00000000000..dabf944e485 --- /dev/null +++ b/editor/assets/chunks/common/mesh/vat-animation.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "1f9087ef-e3eb-44f2-8520-cfb117e8d618", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/common/shadow/native-pcf.chunk b/editor/assets/chunks/common/shadow/native-pcf.chunk index bc0e41a15d4..5b5167e89ce 100644 --- a/editor/assets/chunks/common/shadow/native-pcf.chunk +++ b/editor/assets/chunks/common/shadow/native-pcf.chunk @@ -5,7 +5,16 @@ #pragma define CC_SHADOW_PCF_SOFT_3X 2 #pragma define CC_SHADOW_PCF_SOFT_5X 3 -float NativePCFShadowFactorHard (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution) +float SampleShadowMap (vec3 shadowNDCPos, highp sampler2D shadowMap) +{ + #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 + return unpackRGBAToDepth(texture(shadowMap, shadowNDCPos.xy)); + #else + return texture(shadowMap, shadowNDCPos.xy).x; + #endif +} + +float NativePCFShadowFactorHard (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution) { #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 return step(shadowNDCPos.z, unpackRGBAToDepth(texture(shadowMap, shadowNDCPos.xy))); @@ -14,7 +23,7 @@ float NativePCFShadowFactorHard (vec3 shadowNDCPos, sampler2D shadowMap, vec2 sh #endif } -float NativePCFShadowFactorSoft (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution) +float NativePCFShadowFactorSoft (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution) { vec2 oneTap = 1.0 / shadowMapResolution; vec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap; @@ -40,7 +49,7 @@ float NativePCFShadowFactorSoft (vec3 shadowNDCPos, sampler2D shadowMap, vec2 sh return mix(resultX, resultY, coefY); } -float NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution) +float NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution) { vec2 oneTap = 1.0 / shadowMapResolution; float shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x; @@ -94,7 +103,7 @@ float NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 return shadow * 0.25; } -float NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution) +float NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution) { vec2 oneTap = 1.0 / shadowMapResolution; vec2 twoTap = oneTap * 2.0; diff --git a/editor/assets/chunks/common/texture/cubemap.chunk b/editor/assets/chunks/common/texture/cubemap.chunk index 7c36653a7d0..14f5f736ae1 100644 --- a/editor/assets/chunks/common/texture/cubemap.chunk +++ b/editor/assets/chunks/common/texture/cubemap.chunk @@ -1,3 +1,4 @@ +// for legacy only #pragma extension([GL_OES_standard_derivatives, __VERSION__ < 110]) vec3 EnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) { #if CC_USE_IBL @@ -29,22 +30,18 @@ #endif } - vec3 EnvReflection(vec3 R, float roughness, float mipCount) { - #if CC_USE_IBL - // simulate GGX convolution - #if !CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING && !CC_IBL_CONVOLUTED - roughness = pow(roughness, 0.5); - #endif + vec3 EnvReflection(samplerCube tex, vec3 R, float roughness, float mipCount) { + // simulate GGX convolution + #if !CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING && !CC_IBL_CONVOLUTED + roughness = pow(roughness, 0.5); + #endif - vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w); - vec4 envmap = fragTextureLod(cc_environment, rotationDir, roughness * (mipCount - 1.0)); + vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w); + vec4 envmap = fragTextureLod(tex, rotationDir, roughness * (mipCount - 1.0)); - #if CC_USE_IBL == IBL_RGBE - return unpackRGBE(envmap); - #else - return SRGBToLinear(envmap.rgb); - #endif + #if CC_USE_IBL == IBL_RGBE || CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_NONE + return unpackRGBE(envmap); #else - return vec3(0.0, 0.0, 0.0); + return SRGBToLinear(envmap.rgb); #endif } diff --git a/editor/assets/chunks/common/texture/texture-misc.chunk b/editor/assets/chunks/common/texture/texture-misc.chunk new file mode 100644 index 00000000000..acf1bb6ed8c --- /dev/null +++ b/editor/assets/chunks/common/texture/texture-misc.chunk @@ -0,0 +1,24 @@ + +// for exr data texture and sub resources +vec3 SampleTextureExr(sampler2D exrRGBE, vec2 uv) +{ + vec3 data = unpackRGBE(texture(exrRGBE, uv)); + return data; +} + +vec3 SampleTextureExr(sampler2D exrRGBE, sampler2D exrSign, vec2 uv) +{ + vec3 data = unpackRGBE(texture(exrRGBE, uv)); + vec4 signValue = sign(texture(exrSign, uv) - vec4(0.5)); + return data * signValue.xyz; +} + +vec4 SampleTextureExrWithAlpha(sampler2D exrRGBE, sampler2D exrSign, sampler2D exrAlpha, vec2 uv) +{ + vec3 data = unpackRGBE(texture(exrRGBE, uv)); + vec4 alphaTex = texture(exrAlpha, uv); + float alpha = unpackRGBE(alphaTex).x; + + vec4 signValue = sign(texture(exrSign, uv) - vec4(0.5)); + return vec4(data, alpha) * signValue; +} diff --git a/editor/assets/chunks/common/texture/texture-misc.chunk.meta b/editor/assets/chunks/common/texture/texture-misc.chunk.meta new file mode 100644 index 00000000000..4de83ca1cc7 --- /dev/null +++ b/editor/assets/chunks/common/texture/texture-misc.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "47e68d9d-c7b2-4cdf-adf9-faaeff9cb61a", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/legacy/decode-base.chunk b/editor/assets/chunks/legacy/decode-base.chunk index 7d6db0d9aef..4d768cc3462 100644 --- a/editor/assets/chunks/legacy/decode-base.chunk +++ b/editor/assets/chunks/legacy/decode-base.chunk @@ -39,8 +39,13 @@ layout(location = 3) in vec4 a_tangent; #if CC_USE_LIGHTMAP in vec4 a_lightingMapUVParam; #endif - #if CC_RECEIVE_SHADOW - in vec2 a_localShadowBias; // x:shadow bias, y:shadow normal bias. + #if CC_USE_REFLECTION_PROBE || CC_RECEIVE_SHADOW + in vec4 a_localShadowBiasAndProbeId; // x:shadow bias, y:shadow normal bias, z: reflection probe id, w: reserved for blend reflection probe id + #endif + #if CC_USE_LIGHT_PROBE + in vec4 a_sh_linear_const_r; + in vec4 a_sh_linear_const_g; + in vec4 a_sh_linear_const_b; #endif #endif diff --git a/editor/assets/chunks/legacy/lightingmap-fs.chunk b/editor/assets/chunks/legacy/lightingmap-fs.chunk index ce6dcc9419c..e95b0cfe0ab 100644 --- a/editor/assets/chunks/legacy/lightingmap-fs.chunk +++ b/editor/assets/chunks/legacy/lightingmap-fs.chunk @@ -1,2 +1,3 @@ in vec3 v_luv; -#include \ No newline at end of file +#include +#include diff --git a/editor/assets/chunks/legacy/output-standard.chunk b/editor/assets/chunks/legacy/output-standard.chunk index 7e15576c575..f8472da6c6e 100644 --- a/editor/assets/chunks/legacy/output-standard.chunk +++ b/editor/assets/chunks/legacy/output-standard.chunk @@ -3,9 +3,11 @@ #include vec4 CCFragOutput (vec4 color) { - #if CC_USE_HDR - color.rgb = ACESToneMap(color.rgb); + #if !CC_USE_RGBE_OUTPUT + #if CC_USE_HDR + color.rgb = ACESToneMap(color.rgb); + #endif + color.rgb = LinearToSRGB(color.rgb); #endif - color.rgb = LinearToSRGB(color.rgb); return color; } diff --git a/editor/assets/chunks/legacy/sh-fs.chunk b/editor/assets/chunks/legacy/sh-fs.chunk new file mode 100644 index 00000000000..57d226b31af --- /dev/null +++ b/editor/assets/chunks/legacy/sh-fs.chunk @@ -0,0 +1,10 @@ +#if CC_USE_LIGHT_PROBE + #if USE_INSTANCING + in mediump vec4 v_sh_linear_const_r; + in mediump vec4 v_sh_linear_const_g; + in mediump vec4 v_sh_linear_const_b; + #else + #include + #endif + #include +#endif diff --git a/editor/assets/chunks/legacy/sh-fs.chunk.meta b/editor/assets/chunks/legacy/sh-fs.chunk.meta new file mode 100644 index 00000000000..53e55e97028 --- /dev/null +++ b/editor/assets/chunks/legacy/sh-fs.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "fa7a90a4-9aa6-45b2-ad63-ec46c9826569", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/legacy/sh-vs.chunk b/editor/assets/chunks/legacy/sh-vs.chunk new file mode 100644 index 00000000000..f0cdaed5017 --- /dev/null +++ b/editor/assets/chunks/legacy/sh-vs.chunk @@ -0,0 +1,20 @@ +#if CC_USE_LIGHT_PROBE + #if USE_INSTANCING + out mediump vec4 v_sh_linear_const_r; + out mediump vec4 v_sh_linear_const_g; + out mediump vec4 v_sh_linear_const_b; + #endif +#endif + +//define function to transfer + +void CC_TRANSFER_SH() { +#if CC_USE_LIGHT_PROBE + #if USE_INSTANCING + v_sh_linear_const_r = a_sh_linear_const_r; + v_sh_linear_const_g = a_sh_linear_const_g; + v_sh_linear_const_b = a_sh_linear_const_b; + #endif +#endif +} + diff --git a/editor/assets/chunks/legacy/sh-vs.chunk.meta b/editor/assets/chunks/legacy/sh-vs.chunk.meta new file mode 100644 index 00000000000..eff4737c663 --- /dev/null +++ b/editor/assets/chunks/legacy/sh-vs.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "ea51061e-deb7-48b9-a35a-c91be103f636", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/legacy/shading-cluster-additive.chunk b/editor/assets/chunks/legacy/shading-cluster-additive.chunk index 6e413e66849..3dc7965ca65 100644 --- a/editor/assets/chunks/legacy/shading-cluster-additive.chunk +++ b/editor/assets/chunks/legacy/shading-cluster-additive.chunk @@ -121,7 +121,7 @@ vec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) { float att = GetDistAtt(distSqr, attRadiusSqrInv); vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N); - if (light.cc_lightPos.w > 0.0) { + if (IS_SPOT_LIGHT(light.cc_lightPos.w)) { float cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01); float cosOuter = light.cc_lightSizeRangeAngle.z; float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter); @@ -133,7 +133,7 @@ vec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) { float shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP - if (light.cc_lightPos.w > 0.0) { + if (IS_SPOT_LIGHT(light.cc_lightPos.w) && cc_lightSizeRangeAngle.w > 0.0) { shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias); } #endif diff --git a/editor/assets/chunks/legacy/shading-standard-additive.chunk b/editor/assets/chunks/legacy/shading-standard-additive.chunk index 62455a3da7f..11097cf635c 100644 --- a/editor/assets/chunks/legacy/shading-standard-additive.chunk +++ b/editor/assets/chunks/legacy/shading-standard-additive.chunk @@ -21,40 +21,47 @@ vec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) { for (int i = 0; i < LIGHTS_PER_PASS; i++) { if (i >= numLights) break; - vec3 SLU = cc_lightPos[i].xyz - position; + + // lighting + vec3 SLU = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -cc_lightDir[i].xyz : cc_lightPos[i].xyz - position; vec3 SL = normalize(SLU); vec3 SH = normalize(SL + V); float SNL = max(dot(N, SL), 0.0); float SNH = max(dot(N, SH), 0.0); - - float distSqr = dot(SLU, SLU); - float litRadius = cc_lightSizeRangeAngle[i].x; - float litRadiusSqr = litRadius * litRadius; - float illum = litRadiusSqr / max(litRadiusSqr, distSqr); - float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01); - attRadiusSqrInv *= attRadiusSqrInv; - float att = GetDistAtt(distSqr, attRadiusSqrInv); vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N); - if (cc_lightPos[i].w > 0.0) { - float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01); - float cosOuter = cc_lightSizeRangeAngle[i].z; - float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter); - float litAngleOffset = -cosOuter * litAngleScale; - att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset); - } + // attenuations + float illum = 1.0; + float att = 1.0; + if (IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) { + att = GetOutOfRange(position, cc_lightPos[i].xyz, cc_lightDir[i].xyz, cc_lightSizeRangeAngle[i].xyz, cc_lightBoundingSizeVS[i].xyz); + } else { + float distSqr = dot(SLU, SLU); + float litRadius = cc_lightSizeRangeAngle[i].x; + float litRadiusSqr = litRadius * litRadius; + illum = (IS_POINT_LIGHT(cc_lightPos[i].w) || IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) ? 1.0 : litRadiusSqr / max(litRadiusSqr, distSqr); + float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01); + attRadiusSqrInv *= attRadiusSqrInv; + att = GetDistAtt(distSqr, attRadiusSqrInv); - vec3 lightColor = cc_lightColor[i].rgb; + if (IS_SPOT_LIGHT(cc_lightPos[i].w)) { + float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01); + float cosOuter = cc_lightSizeRangeAngle[i].z; + float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter); + float litAngleOffset = -cosOuter * litAngleScale; + att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset); + } + } + // shadows float shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP - if (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) { + if (IS_SPOT_LIGHT(cc_lightPos[i].w) && cc_lightSizeRangeAngle[i].w > 0.0) { shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias); } #endif - lightColor *= shadow; - finalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec); + finalColor += SNL * cc_lightColor[i].rgb * shadow * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec); } return vec4(finalColor, 0.0); diff --git a/editor/assets/chunks/legacy/shading-standard-base.chunk b/editor/assets/chunks/legacy/shading-standard-base.chunk index 9808cddb1da..9db9b66d67a 100644 --- a/editor/assets/chunks/legacy/shading-standard-base.chunk +++ b/editor/assets/chunks/legacy/shading-standard-base.chunk @@ -5,23 +5,30 @@ #include #include #include - +#include +#include +#include +#include #if CC_USE_IBL - #include - #include - #include - #if CC_USE_DIFFUSEMAP #include #endif #endif +#if CC_USE_REFLECTION_PROBE + #include + #include +#endif +#if CC_USE_LIGHT_PROBE +#include +#endif + float GGXMobile (float roughness, float NoH, vec3 H, vec3 N) { vec3 NxH = cross(N, H); float OneMinusNoHSqr = dot(NxH, NxH); float a = roughness * roughness; float n = NoH * a; - float p = a / (OneMinusNoHSqr + n * n); + float p = a / max(EPSILON, OneMinusNoHSqr + n * n); return p * p; } @@ -41,17 +48,26 @@ vec3 BRDFApprox (vec3 specular, float roughness, float NoV) { #if USE_REFLECTION_DENOISE #pragma extension([GL_OES_standard_derivatives, __VERSION__ < 110]) - vec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) { + vec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity, vec2 screenUV) { #if CC_USE_IBL float mip = roughness * (mipCount - 1.0); float delta = (dot(dFdx(R), dFdy(R))) * 1000.0; float mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0)); - vec4 biased = fragTextureLod(cc_environment, R, mip + mipBias); - vec4 filtered = texture(cc_environment, R); - #if CC_USE_IBL == IBL_RGBE - biased.rgb = unpackRGBE(biased); + #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE + vec4 biased = fragTextureLod(cc_reflectionProbeCubemap, R, mip + mipBias); + vec4 filtered = texture(cc_reflectionProbeCubemap, R); + #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR + vec4 biased = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mip + mipBias); + vec4 filtered = texture(cc_reflectionProbePlanarMap, screenUV); + #else + vec4 biased = fragTextureLod(cc_environment, R, mip + mipBias); + vec4 filtered = texture(cc_environment, R); + #endif + + #if CC_USE_IBL == IBL_RGBE || CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_NONE + biased.rgb = unpackRGBE(biased); filtered.rgb = unpackRGBE(filtered); #else biased.rgb = SRGBToLinear(biased.rgb); @@ -75,7 +91,7 @@ struct StandardSurface { // emissive vec3 emissive; // light map - vec3 lightmap; + vec4 lightmap; float lightmap_test; // PBR params float roughness; @@ -86,6 +102,9 @@ struct StandardSurface { #if CC_RECEIVE_SHADOW vec2 shadowBias; #endif + #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + float reflectionProbeId; + #endif }; vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) { @@ -105,18 +124,16 @@ vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) { float shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP if (NL > 0.0 && cc_mainLitDir.w > 0.0) { - if (cc_shadowLPNNInfo.w > 0.0) { - #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED - shadow = CCCSMFactorBase(position, N, s.shadowBias); - #endif - } else { - #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM - shadow = CCShadowFactorBase(shadowPos, N, s.shadowBias); - #endif - } + #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED + shadow = CCCSMFactorBase(position, N, s.shadowBias); + #endif + #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM + shadow = CCShadowFactorBase(shadowPos, N, s.shadowBias); + #endif } #endif + vec3 finalColor = vec3(0.0); #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD vec3 lightmap = s.lightmap.rgb; #if CC_USE_HDR @@ -124,14 +141,22 @@ vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) { // baked in LDR scene still regarded as exposured with standard camera parameters lightmap.rgb *= cc_exposure.w * cc_exposure.x; #endif - vec3 finalColor = diffuse * lightmap.rgb * shadow; - #else + #if CC_USE_LIGHTMAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION + shadow *= s.lightmap.a; // apply baked shadows for real-time lighting + s.occlusion *= s.lightmap_test; + finalColor += diffuse * lightmap.rgb; + #else + finalColor += diffuse * lightmap.rgb * shadow; // apply real-time shadows for baked color + #endif + #endif + + #if CC_RECEIVE_DIRECTIONAL_LIGHT float NV = max(abs(dot(N, V)), 0.0); specular = BRDFApprox(specular, s.roughness, NV); vec3 H = normalize(L + V); float NH = max(dot(N, H), 0.0); - vec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w; + vec3 lightingColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w; vec3 diffuseContrib = diffuse / PI; // Cook-Torrance Microfacet Specular BRDF @@ -139,15 +164,15 @@ vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) { vec3 dirlightContrib = (diffuseContrib + specularContrib); dirlightContrib *= shadow; - finalColor *= dirlightContrib; + finalColor += lightingColor * dirlightContrib; #endif - float fAmb = 0.5 - N.y * 0.5; + float fAmb = max(EPSILON, 0.5 - N.y * 0.5); vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb); - + vec3 env = vec3(0.0); #if CC_USE_IBL - #if CC_USE_DIFFUSEMAP + #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE // Diffuse reflection irradiance vec4 diffuseMap = texture(cc_diffuseMap, N); #if CC_USE_DIFFUSEMAP == IBL_RGBE @@ -157,26 +182,64 @@ vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) { #endif #endif - vec3 R = normalize(reflect(-V, N)); + #if !CC_USE_REFLECTION_PROBE + vec3 R = normalize(reflect(-V, N)); - vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w); - #if USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED - vec3 env = GetEnvReflectionWithMipFiltering(rotationDir, s.roughness, cc_ambientGround.w, 0.6); - #else - vec4 envmap = fragTextureLod(cc_environment, rotationDir, s.roughness * (cc_ambientGround.w - 1.0)); - - #if CC_USE_IBL == IBL_RGBE - vec3 env = unpackRGBE(envmap); + vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w); + #if USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED + env = GetEnvReflectionWithMipFiltering(rotationDir, s.roughness, cc_ambientGround.w, 0.6, vec2(0.0)); #else - vec3 env = SRGBToLinear(envmap.rgb); + vec4 envmap = fragTextureLod(cc_environment, rotationDir, s.roughness * (cc_ambientGround.w - 1.0)); + + #if CC_USE_IBL == IBL_RGBE + env = unpackRGBE(envmap); + #else + env = SRGBToLinear(envmap.rgb); + #endif #endif #endif + #endif - finalColor += env * cc_ambientSky.w * specular * s.occlusion; + #if CC_USE_REFLECTION_PROBE + vec4 probe = vec4(0.0); + vec3 R = normalize(reflect(-V, N)); + #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE + if(s.reflectionProbeId < 0.0){ + probe = fragTextureLod(cc_reflectionProbeCubemap, R, s.roughness * (cc_ambientGround.w - 1.0)); + }else{ + vec3 centerPos, boxHalfSize; + float mipCount; + GetCubeReflectionProbeData(centerPos, boxHalfSize, mipCount, s.reflectionProbeId); + vec4 fixedR = CalculateBoxProjectedDirection(R, position, centerPos, boxHalfSize); + probe = mix(fragTextureLod(cc_environment, R, s.roughness * (cc_ambientGround.w - 1.0)), + fragTextureLod(cc_reflectionProbeCubemap, fixedR.xyz, s.roughness * (mipCount - 1.0)), fixedR.w); + } + #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR + if(s.reflectionProbeId < 0.0){ + vec2 screenUV = GetPlanarReflectScreenUV(s.position, cc_matViewProj, cc_cameraPos.w, V, R); + probe = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, 1.0); + }else{ + vec4 plane; + float planarReflectionDepthScale, mipCount; + GetPlanarReflectionProbeData(plane, planarReflectionDepthScale, mipCount, s.reflectionProbeId); + R = normalize(CalculateReflectDirection(N, V, max(abs(dot(N, V)), 0.0))); + vec3 worldPosOffset = CalculatePlanarReflectPositionOnPlane(N, V, s.position, plane, cc_cameraPos.xyz, planarReflectionDepthScale); + vec2 screenUV = GetPlanarReflectScreenUV(worldPosOffset, cc_matViewProj, cc_cameraPos.w, V, R); + probe = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mipCount); + } + #endif + env = unpackRGBE(probe); #endif + finalColor += env * cc_ambientSky.w * specular * s.occlusion; + + +#if CC_USE_LIGHT_PROBE + finalColor += SHEvaluate(N) * diffuse * s.occlusion; +#endif finalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion; + finalColor += s.emissive; return vec4(finalColor, s.albedo.a); diff --git a/editor/assets/chunks/legacy/shading-toon.chunk b/editor/assets/chunks/legacy/shading-toon.chunk index 2aa7b6e54c9..655b72018a3 100644 --- a/editor/assets/chunks/legacy/shading-toon.chunk +++ b/editor/assets/chunks/legacy/shading-toon.chunk @@ -37,19 +37,13 @@ struct ToonSurface { vec3 finalColor = vec3(0.0); for (int i = 0; i < LIGHTS_PER_PASS; i++) { - vec3 SLU = cc_lightPos[i].xyz - position; + // lighting + vec3 SLU = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -cc_lightDir[i].xyz : cc_lightPos[i].xyz - position; vec3 SL = normalize(SLU); vec3 SH = normalize(SL + V); float SNL = 0.5 * dot(N, SL) + 0.5; float SNH = 0.5 * dot(N, SH) + 0.5; - - float distSqr = dot(SLU, SLU); - float litRadius = cc_lightSizeRangeAngle[i].x; - float litRadiusSqr = litRadius * litRadius; - float illum = litRadiusSqr / max(litRadiusSqr , distSqr); - float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01); - attRadiusSqrInv *= attRadiusSqrInv; - float att = GetDistAtt(distSqr, attRadiusSqrInv); + vec3 diffuse = mix(s.shade1, s.shade2, clamp(1.0 + (s.shadeStep - s.shadeFeather - SNL) / s.shadeFeather, 0.0, 1.0)); diffuse = mix(s.baseColor.rgb, diffuse, @@ -57,12 +51,27 @@ struct ToonSurface { float specularMask = step(specularWeight, SNH); vec3 specular = s.specular.rgb * specularMask; - if (cc_lightPos[i].w > 0.0) { - float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01); - float cosOuter = cc_lightSizeRangeAngle[i].z; - float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter); - float litAngleOffset = -cosOuter * litAngleScale; - att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset); + // attenuations + float illum = 1.0; + float att = 1.0; + if (IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) { + att = GetOutOfRange(position, cc_lightPos[i].xyz, cc_lightDir[i].xyz, cc_lightSizeRangeAngle[i].xyz, cc_lightBoundingSizeVS[i].xyz); + } else { + float distSqr = dot(SLU, SLU); + float litRadius = cc_lightSizeRangeAngle[i].x; + float litRadiusSqr = litRadius * litRadius; + illum = (IS_POINT_LIGHT(cc_lightPos[i].w) || IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) ? 1.0 : litRadiusSqr / max(litRadiusSqr , distSqr); + float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01); + attRadiusSqrInv *= attRadiusSqrInv; + att = GetDistAtt(distSqr, attRadiusSqrInv); + + if (IS_SPOT_LIGHT(cc_lightPos[i].w)) { + float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01); + float cosOuter = cc_lightSizeRangeAngle[i].z; + float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter); + float litAngleOffset = -cosOuter * litAngleScale; + att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset); + } } finalColor += SNL * cc_lightColor[i].rgb * cc_lightColor[i].a * illum * att * s.baseStep * (diffuse + specular); @@ -94,7 +103,7 @@ struct ToonSurface { clamp(1.0 + (s.baseStep - s.baseFeather - NL) / s.baseFeather, 0.0, 1.0)); float specularWeight = 1.0 - pow(s.specular.a, 5.0); - float specularMask = step(specularWeight, NH); + float specularMask = step(specularWeight + EPSILON_LOWP, NH); vec3 specular = s.specular.rgb * specularMask; vec3 dirlightContrib = diffuse + specular; @@ -102,15 +111,12 @@ struct ToonSurface { float shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP if(s.shadowCover < NL && cc_mainLitDir.w > 0.0) { - if (cc_shadowLPNNInfo.w > 0.0) { - #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED - shadow = CCCSMFactorBase(position, N, s.shadowBias); - #endif - } else { - #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM - shadow = CCShadowFactorBase(CC_SHADOW_POSITION, N, s.shadowBias); - #endif - } + #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED + shadow = CCCSMFactorBase(position, N, s.shadowBias); + #endif + #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM + shadow = CCShadowFactorBase(CC_SHADOW_POSITION, N, s.shadowBias); + #endif } #endif diff --git a/editor/assets/chunks/legacy/shadow-map-vs.chunk b/editor/assets/chunks/legacy/shadow-map-vs.chunk index fa32af28a31..85c5209302d 100644 --- a/editor/assets/chunks/legacy/shadow-map-vs.chunk +++ b/editor/assets/chunks/legacy/shadow-map-vs.chunk @@ -12,7 +12,7 @@ out highp vec4 v_shadowPos; vec2 CCGetShadowBias() { #if USE_INSTANCING - return vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z); + return vec2(a_localShadowBiasAndProbeId.x + cc_shadowWHPBInfo.w, a_localShadowBiasAndProbeId.y + cc_shadowLPNNInfo.z); #else return vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z); #endif diff --git a/editor/assets/chunks/legacy/standard-surface-entry.chunk b/editor/assets/chunks/legacy/standard-surface-entry.chunk index 78f968872df..b42a39c4596 100644 --- a/editor/assets/chunks/legacy/standard-surface-entry.chunk +++ b/editor/assets/chunks/legacy/standard-surface-entry.chunk @@ -35,6 +35,9 @@ #if CC_USE_FOG != CC_FOG_NONE \ CC_APPLY_FOG(color, s.position.xyz); \ #endif \ + #if CC_USE_RGBE_OUTPUT \ + color = packRGBE(color.rgb); \ + #endif \ fragColorX = color; \ } \ \ diff --git a/editor/assets/chunks/lighting-models/data-structures/lighting-intermediate-data.chunk b/editor/assets/chunks/lighting-models/data-structures/lighting-intermediate-data.chunk index 1da0b3f96dc..33f4e81de20 100644 --- a/editor/assets/chunks/lighting-models/data-structures/lighting-intermediate-data.chunk +++ b/editor/assets/chunks/lighting-models/data-structures/lighting-intermediate-data.chunk @@ -8,21 +8,28 @@ struct LightingIntermediateData float NoLSat, NoVSat, NoHSat;//, VoHSat; // clamped to 0-1 float NoVAbsSat; // abs and clamped to 1 + HIGHP_VALUE_STRUCT_DEFINE(vec3, worldPosition); + // for advanced material vec3 T, B; // material data float specularParam; // roughness or specular power + float ior; + #if CC_SURFACES_LIGHTING_ANISOTROPIC float anisotropyShape; #endif - // #if CC_SURFACES_LIGHTING_SPECULAR_2ND - // float specularParam2nd, specularIntensity2nd, specularRotation2nd; // for hair - // vec3 specularColor2nd; - // #endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + vec4 shadowPosAndDepth; //xy: shadowmap uv, z: camera depth from pixel LVP, w: camera depth from shadowmap + vec4 transmitDiffuseParams; //zw: min/max DepthWS for shadowmap and 0 means disable shadow transmit, x: transmit irradiance apply shadow, y: additional transmit depth mask, 可补充shadowmap cover不到的地方,也可以在minmax屏蔽掉shadowmap之后给专门的薄片穿透 +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR || CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + vec4 transmitParams; // xy: extinction coef for out/in-scattering, z: in-scattering coef, w: transmit distance(water depth, leaf thickness) + vec3 inScatteringLightColor; +#endif // #if CC_SURFACES_LIGHTING_CLEAR_COAT - // float ior; // float roughnessClearCoat; // for clear coat or multi-layer pbr // #endif }; @@ -46,12 +53,20 @@ void CCSurfacesLightingGetIntermediateData_PerPixel(inout LightingIntermediateDa data.NoVSat = max(data.NoV, 0.0); data.NoVAbsSat = max(abs(data.NoV), 0.0); + HIGHP_VALUE_TO_STRUCT_DEFINED(worldPos, data.worldPosition); data.T = worldTangent; data.B = worldBinormal; #if CC_SURFACES_LIGHTING_ANISOTROPIC data.anisotropyShape = anisotropyShape; #endif +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR || CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + data.inScatteringLightColor = vec3(0.0); + data.transmitParams = vec4(0.0); +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + data.shadowPosAndDepth = vec4(0.0, 0.0, 999999.0, 999999.0); +#endif } void CCSurfacesLightingGetIntermediateData_PerLight(inout LightingIntermediateData data, vec3 lightDirWithDist) diff --git a/editor/assets/chunks/lighting-models/data-structures/lighting-misc-data.chunk b/editor/assets/chunks/lighting-models/data-structures/lighting-misc-data.chunk new file mode 100644 index 00000000000..93b6a9e507c --- /dev/null +++ b/editor/assets/chunks/lighting-models/data-structures/lighting-misc-data.chunk @@ -0,0 +1,9 @@ +// for user modified lighting result +struct LightingMiscData +{ + // local light source attributes, like CCForwardLight + float lightType; + vec3 lightPos, lightDir; + vec4 lightColorAndIntensity; + vec4 lightSizeRangeAngle; +}; diff --git a/editor/assets/chunks/lighting-models/data-structures/lighting-misc-data.chunk.meta b/editor/assets/chunks/lighting-models/data-structures/lighting-misc-data.chunk.meta new file mode 100644 index 00000000000..f0d6c190d37 --- /dev/null +++ b/editor/assets/chunks/lighting-models/data-structures/lighting-misc-data.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "f5326068-1588-43b4-9f15-c190688fc7c0", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/lighting-models/data-structures/lighting-result.chunk b/editor/assets/chunks/lighting-models/data-structures/lighting-result.chunk index 97fdda2eb76..b87dedc244a 100644 --- a/editor/assets/chunks/lighting-models/data-structures/lighting-result.chunk +++ b/editor/assets/chunks/lighting-models/data-structures/lighting-result.chunk @@ -9,5 +9,20 @@ struct LightingResult float shadow, ao; vec3 lightmapColor; vec3 emissive; - //vec3 transmittance, scattered; + + // advanced +#if CC_SURFACES_LIGHTING_USE_FRESNEL + float fresnel; +#endif + +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + vec3 directTransmitSpecular, environmentTransmitSpecular; +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + vec3 directTransmitDiffuse, environmentTransmitDiffuse; +#endif +#if CC_SURFACES_LIGHTING_TRT + vec3 directTRT, environmentTRT; +#endif + //vec3 scattered; }; diff --git a/editor/assets/chunks/lighting-models/default-functions/simple-skin.chunk b/editor/assets/chunks/lighting-models/default-functions/simple-skin.chunk index 6691d26cdba..4a94b9ff493 100644 --- a/editor/assets/chunks/lighting-models/default-functions/simple-skin.chunk +++ b/editor/assets/chunks/lighting-models/default-functions/simple-skin.chunk @@ -1,3 +1,4 @@ +// invoked by lighting-models/model-functions/XXX #ifndef CC_SURFACES_LIGHTING_MODIFY_SKIN_DIFFUSE_LIGHTING vec3 SurfacesLightingModifySkinDiffuseLighting(in LightingIntermediateData lightingData, in float ssssCurvature) { diff --git a/editor/assets/chunks/lighting-models/default-functions/standard.chunk b/editor/assets/chunks/lighting-models/default-functions/standard.chunk new file mode 100644 index 00000000000..0dbbc3ffb35 --- /dev/null +++ b/editor/assets/chunks/lighting-models/default-functions/standard.chunk @@ -0,0 +1,11 @@ +// modify final lighting result for user-defined lighting models +// this function invokes at end of lighting flow +// should use common lighting-model and corresponding shading-model header before function define + //#include + //#include + +// #define CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT +// void SurfacesLightingModifyFinalResult(inout LightingResult result, in LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData, in LightingMiscData miscData) +// { +// } + diff --git a/editor/assets/chunks/lighting-models/default-functions/standard.chunk.meta b/editor/assets/chunks/lighting-models/default-functions/standard.chunk.meta new file mode 100644 index 00000000000..205d6d5899d --- /dev/null +++ b/editor/assets/chunks/lighting-models/default-functions/standard.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "eec6f0f1-607d-4613-9285-e5ab22a89e87", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/lighting-models/default-functions/toon.chunk b/editor/assets/chunks/lighting-models/default-functions/toon.chunk new file mode 100644 index 00000000000..dcd24eddb61 --- /dev/null +++ b/editor/assets/chunks/lighting-models/default-functions/toon.chunk @@ -0,0 +1,11 @@ +// modify final lighting result for user-defined lighting models +// this function invokes at end of lighting flow +// should use common lighting-model and corresponding shading-model header before function define + //#include + //#include + +// #define CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT +// void SurfacesLightingModifyFinalResult(inout LightingResult result, in LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData) +// { +// } + diff --git a/editor/assets/chunks/lighting-models/default-functions/toon.chunk.meta b/editor/assets/chunks/lighting-models/default-functions/toon.chunk.meta new file mode 100644 index 00000000000..1fa604c35f2 --- /dev/null +++ b/editor/assets/chunks/lighting-models/default-functions/toon.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "6845eadb-c3d5-4485-9699-de3361cf7aaa", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/lighting-models/includes/common.chunk b/editor/assets/chunks/lighting-models/includes/common.chunk new file mode 100644 index 00000000000..fa0b70b11aa --- /dev/null +++ b/editor/assets/chunks/lighting-models/includes/common.chunk @@ -0,0 +1,5 @@ +// Lighting-model common includes +#include +#include +#include + diff --git a/editor/assets/chunks/lighting-models/includes/common.chunk.meta b/editor/assets/chunks/lighting-models/includes/common.chunk.meta new file mode 100644 index 00000000000..300e150008d --- /dev/null +++ b/editor/assets/chunks/lighting-models/includes/common.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "e0e29596-7cc0-45b0-80bc-5193f81e818f", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/lighting-models/includes/standard.chunk b/editor/assets/chunks/lighting-models/includes/standard.chunk index 1da559d1322..a1911caef29 100644 --- a/editor/assets/chunks/lighting-models/includes/standard.chunk +++ b/editor/assets/chunks/lighting-models/includes/standard.chunk @@ -1,4 +1,4 @@ // Lighting-model includes -#include -#include +#include +#include #include diff --git a/editor/assets/chunks/lighting-models/includes/toon.chunk b/editor/assets/chunks/lighting-models/includes/toon.chunk index 90a13e1dc87..ce47e8e804c 100644 --- a/editor/assets/chunks/lighting-models/includes/toon.chunk +++ b/editor/assets/chunks/lighting-models/includes/toon.chunk @@ -1,4 +1,4 @@ // Lighting-model includes -#include -#include +#include +#include #include diff --git a/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk b/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk index 2d95d922994..b7d1aa52a1f 100644 --- a/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk +++ b/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk @@ -1,34 +1,54 @@ #if (CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_FORWARD || CC_FORCE_FORWARD_SHADING) #if CC_FORWARD_ADD && !CC_ENABLE_CLUSTERED_LIGHT_CULLING - void CCSurfacesLighting(inout LightingResult lightingResult, in SurfacesMaterialData surfaceData, in vec2 shadowBias) + void CCSurfacesLighting(inout LightingResult lightingResultAccumulated, in SurfacesMaterialData surfaceData, in vec2 shadowBias) { vec3 worldPos; HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, surfaceData.worldPos); + CCSurfacesInitializeLightingResult(lightingResultAccumulated); + LightingIntermediateData lightingData; CCSurfacesInitializeLightingIntermediateData(lightingData, surfaceData); + LightingResult lightingResult; CCSurfacesLightingInitializeColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData); - - lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0); + lightingResultAccumulated.diffuseColorWithLighting = lightingResult.diffuseColorWithLighting; + lightingResultAccumulated.specularColorWithLighting = lightingResult.specularColorWithLighting; int numLights = CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_FORWARD ? LIGHTS_PER_PASS : int(cc_lightDir[0].w); for (int i = 0; i < LIGHTS_PER_PASS; i++) { if (i >= numLights) break; - CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData, surfaceData, cc_lightPos[i].xyz - worldPos); + vec3 lightDirWithLength = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -normalize(cc_lightDir[i].xyz) : cc_lightPos[i].xyz - worldPos; + CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData, surfaceData, lightDirWithLength); CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData); vec3 diffuseLighting, specularLighting; CCSurfacesLightingCalculateDirect(diffuseLighting, specularLighting, lightingData, cc_lightColor[i]); - + + float fresnel = 1.0; + #if CC_SURFACES_LIGHTING_USE_FRESNEL + fresnel = lightingResult.fresnel = CCSurfaceLightingCalculateFresnel(lightingData); + #endif + + // shadows float shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP - if (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) { + if (IS_SPOT_LIGHT(cc_lightPos[i].w) && cc_lightSizeRangeAngle[i].w > 0.0) { + vec4 shadowPos = vec4(0.0), shadowNDCPosWithBias = vec4(0.0); if (CCSurfacesLightingEnableShadow(lightingData.NoL)) { - vec4 shadowPos = cc_matLightViewProj * vec4(surfaceData.worldPos, 1.0); - shadow = CCSpotShadowFactorBase(shadowPos, worldPos, shadowBias); + shadowPos = cc_matLightViewProj * vec4(surfaceData.worldPos, 1.0); + shadow = CCSpotShadowFactorBase(shadowNDCPosWithBias, shadowPos, worldPos, shadowBias); } + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + #if CC_SURFACES_LIGHTING_USE_SHADOWMAP_TRANSMIT + lightingData.shadowPosAndDepth.xy = shadowNDCPosWithBias.xy; + lightingData.shadowPosAndDepth.z = shadowPos.z; + lightingData.shadowPosAndDepth.w = GetViewSpaceDepthFromNDCDepth_Perspective(SampleShadowMap(shadowNDCPosWithBias.xyz, cc_spotShadowMap), shadowNDCPosWithBias.w, cc_shadowInvProjDepthInfo.x, cc_shadowInvProjDepthInfo.y); + #else + lightingData.transmitDiffuseParams.zw = vec2(0.0); + #endif + #endif } #endif @@ -38,17 +58,59 @@ } #endif - float distAtt = CCSurfacesLightingCalculateDistanceAttenuation(lightingData, cc_lightSizeRangeAngle[i]); + lightingResult.shadow = shadow; + + // attenuations + float distAtt = 1.0; + if(IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) { + distAtt = GetOutOfRange(worldPos, cc_lightPos[i].xyz, cc_lightDir[i].xyz, cc_lightSizeRangeAngle[i].xyz, cc_lightBoundingSizeVS[i].xyz); + } else { + distAtt = CCSurfacesLightingCalculateDistanceAttenuation(lightingData, cc_lightSizeRangeAngle[i], cc_lightPos[i].w); + } float angleAtt = 1.0; - if (cc_lightPos[i].w > 0.0) { + if (IS_SPOT_LIGHT(cc_lightPos[i].w)) { angleAtt = CCSurfacesLightingCalculateAngleAttenuation(lightingData, cc_lightSizeRangeAngle[i], -cc_lightDir[i].xyz); } - float multiplier = distAtt * angleAtt * shadow; - - lightingResult.directDiffuse += diffuseLighting * multiplier; - lightingResult.directSpecular += specularLighting * multiplier; + float multiplier = distAtt * angleAtt; + + // output + lightingResult.directDiffuse = diffuseLighting * multiplier; + lightingResult.directSpecular = specularLighting * multiplier * fresnel; + + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + vec3 transmitSpecularLighting; + CCSurfacesLightingCalculateDirectTransmitSpecular(transmitSpecularLighting, lightingData, cc_lightColor[i]); + lightingResult.directTransmitSpecular = transmitSpecularLighting * multiplier * (1.0 - fresnel); + #endif + + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + lightingResult.directTransmitDiffuse = CCSurfacesLightingCalculateDirectTransmitDiffuse(lightingResult, lightingData, cc_lightColor[i]); + #endif + + #if CC_SURFACES_LIGHTING_TRT + vec3 TRTLighting; + LightingIntermediateData lightingDataTRT; + CCSurfacesGetLightingIntermediateDataTRT(lightingDataTRT, lightingData, surfaceData); + CCSurfacesLightingCalculateDirectTRT(TRTLighting, lightingDataTRT, cc_lightColor[i]); + lightingResult.directTRT = TRTLighting; + #endif + + + // user-defined lighting model + #ifdef CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT + LightingMiscData miscData; + miscData.lightType = cc_lightPos[i].w; + miscData.lightPos = cc_lightPos[i].xyz; + miscData.lightDir = cc_lightDir[i].xyz; + miscData.lightColorAndIntensity = cc_lightColor[i]; + miscData.lightSizeRangeAngle = cc_lightSizeRangeAngle[i]; + SurfacesLightingModifyFinalResult(lightingResult, lightingData, surfaceData, miscData); + #endif + + // accumulate per-light results + CCSurfacesAccumulateLightingResult(lightingResultAccumulated, lightingResult); } } #else @@ -66,51 +128,91 @@ lightingResult.shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP if (cc_mainLitDir.w > 0.0) { + vec4 shadowPos = vec4(0.0), shadowNDCPosWithBias = vec4(0.0); if (CCSurfacesLightingEnableShadow(lightingData.NoL)) { - if (cc_shadowLPNNInfo.w > 0.0) { - #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED - lightingResult.shadow = CCCSMFactorBase(surfaceData.worldPos, lightingData.N, shadowBias); - #endif - } else { - #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM - vec4 shadowPos = cc_matLightViewProj * vec4(surfaceData.worldPos, 1.0); - lightingResult.shadow = CCShadowFactorBase(shadowPos, lightingData.N, shadowBias); - #endif - } + #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED + lightingResult.shadow = CCCSMFactorBase(shadowPos, shadowNDCPosWithBias, surfaceData.worldPos, lightingData.N, shadowBias); + #endif + #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM + shadowPos = cc_matLightViewProj * vec4(surfaceData.worldPos, 1.0); + lightingResult.shadow = CCShadowFactorBase(shadowPos, lightingData.N, shadowBias); + #endif } + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + #if CC_SURFACES_LIGHTING_USE_SHADOWMAP_TRANSMIT + lightingData.shadowPosAndDepth.xy = shadowNDCPosWithBias.xy; + lightingData.shadowPosAndDepth.z = shadowPos.z; + lightingData.shadowPosAndDepth.w = GetViewSpaceDepthFromNDCDepth_Orthgraphic(SampleShadowMap(shadowNDCPosWithBias.xyz, cc_shadowMap), cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y); + #else + lightingData.transmitDiffuseParams.zw = vec2(0.0); + #endif + #endif } #endif // CCSurfacesLightingCalculateBaked: lightingResult.lightmapColor = vec3(0.0); #if CC_SURFACES_USE_LIGHT_MAP && !CC_FORWARD_ADD - vec4 lightmap = GetLightMapColor(cc_lightingMap, FSInput_lightMapUV.xy, FSInput_lightMapUV.z); - lightingResult.lightmapColor = lightmap.rgb; - // lightingResult.shadow/ao *= lightmap.a; + float lightmapShadow, lightmapAO; + GetLightMapColor(lightingResult.lightmapColor, lightmapShadow, lightmapAO, cc_lightingMap, FSInput_lightMapUV.xy, FSInput_lightMapUV.z, surfaceData.worldNormal); + + #if CC_SURFACES_USE_LIGHT_MAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION + lightingResult.shadow *= lightmapShadow; + lightingResult.ao *= lightmapAO; + #endif + #endif - // static dir light - lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0); // dynamic & stationary dir light - #else + lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0); + #if CC_RECEIVE_DIRECTIONAL_LIGHT && !CC_FORWARD_ADD CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData); CCSurfacesLightingCalculateDirect(lightingResult.directDiffuse, lightingResult.directSpecular, lightingData, cc_mainLitColor); #endif // apply SSR, local probe & global probe - CCSurfacesLightingCalculateEnvironment(lightingResult, lightingData); + CCSurfacesLightingCalculateEnvironment(lightingResult.environmentDiffuse, lightingResult.environmentSpecular, lightingData, cc_ambientSky.w); + + #if CC_SURFACES_LIGHTING_USE_FRESNEL + lightingResult.fresnel = CCSurfaceLightingCalculateFresnel(lightingData); + #endif + + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + CCSurfacesLightingCalculateDirectTransmitSpecular(lightingResult.directTransmitSpecular, lightingData, cc_mainLitColor); + CCSurfacesLightingCalculateEnvironmentTransmitSpecular(lightingResult.environmentTransmitSpecular, lightingData, cc_ambientSky.w); + #endif - // CCSurfacesLightingCalculateTransmittence(lightingResult, lightingData, shadowPos); + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + CCSurfacesLightingCalculateDirectTransmitDiffuse(lightingResult.directTransmitDiffuse, lightingResult, lightingData, cc_mainLitColor); + CCSurfacesLightingCalculateEnvironmentTransmitDiffuse(lightingResult.environmentTransmitDiffuse, lightingResult, lightingData, cc_ambientSky.w); + #endif + #if CC_SURFACES_LIGHTING_TRT + LightingIntermediateData lightingDataTRT; + CCSurfacesGetLightingIntermediateDataTRT(lightingDataTRT, lightingData, surfaceData); + CCSurfacesLightingCalculateDirectTRT(lightingResult.directTRT, lightingDataTRT, cc_mainLitColor); + CCSurfacesLightingCalculateEnvironmentTRT(lightingResult.environmentTRT, lightingDataTRT, cc_ambientSky.w); + #endif // apply screen-space shadow and ao // lightingResult.shadow/ao *= XXX; - - - //#todo: cluster related lighting flow - #if CC_ENABLE_CLUSTERED_LIGHT_CULLING - //#include - #endif + // user-defined lighting model + #ifdef CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT + LightingMiscData miscData; + miscData.lightType = LIGHT_TYPE_DIRECTIONAL; + miscData.lightPos = vec3(0.0); + miscData.lightDir = cc_mainLitDir.xyz; + miscData.lightColorAndIntensity = cc_mainLitColor; + miscData.lightSizeRangeAngle = vec4(0.0, 0.0, 0.0, 0.0); + SurfacesLightingModifyFinalResult(lightingResult, lightingData, surfaceData, miscData); + #endif } - #endif -#endif + #if CC_ENABLE_CLUSTERED_LIGHT_CULLING + // #todo: cluster related lighting flow, invoke after CCSurfacesLighting + // use same code as additive-pass + // void CCSurfacesLighting_Cluster(inout LightingResult lightingResult, in SurfacesMaterialData surfaceData, in vec2 shadowBias) + // { + // } + #endif // cluster lighting + #endif // base pass +#endif // forward shading diff --git a/editor/assets/chunks/lighting-models/model-functions/standard-common.chunk b/editor/assets/chunks/lighting-models/model-functions/standard-common.chunk new file mode 100644 index 00000000000..0d7ac87701f --- /dev/null +++ b/editor/assets/chunks/lighting-models/model-functions/standard-common.chunk @@ -0,0 +1,184 @@ +#include +#include + +void LightingCalculateDirect(out vec3 lightingDiffuse, out vec3 lightingSpecular, in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity) +{ + vec3 irradiance = vec3(lightingData.NoLSat) * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w; + +#if CC_SURFACES_LIGHTING_CALCULATE_DIFFUSE + lightingDiffuse = irradiance * DiffuseCoefficient_EnergyConservation; +#else + lightingDiffuse = vec3(0.0); +#endif + +#if CC_SURFACES_LIGHTING_CALCULATE_SPECULAR + float roughness = lightingData.specularParam; + #if CC_SURFACES_LIGHTING_ANISOTROPIC + float rT, rB; + GetAnisotropicRoughness(roughness, lightingData.anisotropyShape, rT, rB); + float calcSpec = D_GGXAniso(rT, rB, lightingData.NoHSat, lightingData.H, lightingData.T, lightingData.B); + #else + #if CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING + float calcSpec = (roughness * 0.25 + 0.25) * D_GGXMobile(roughness, lightingData.NoHSat); + #else + float calcSpec = D_GGX(roughness, lightingData.NoHSat); + #endif + #endif + lightingSpecular = irradiance * calcSpec; +#else + lightingSpecular = vec3(0.0); +#endif +} + + +#if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT + vec3 EnvAnisotropicReflection(samplerCube tex, vec3 R, float roughness, float mipCount, float anisotropyShape, vec3 V, vec3 N, vec3 T, vec3 B) { + R = normalize(R); + float integratedBRDF = 0.0; + vec3 envSpec = vec3(0.0); + // One direction sample count + const int SAMPLE_STEP_COUNT = CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT; + float sampleAngleRange = PI * abs(anisotropyShape); + vec3 anisoDirection = anisotropyShape < 0.0 ? T : B; + vec3 ROnNormalPlane = normalize(R - anisoDirection * dot(R, anisoDirection)); + //ROnTangentPlane = R; //for example: cross-style + vec3 stepOffset = normalize(ROnNormalPlane - N) * (sampleAngleRange / float(SAMPLE_STEP_COUNT * 2)); + + for (int i = -SAMPLE_STEP_COUNT; i <= SAMPLE_STEP_COUNT; ++i) + { + float rT, rB; + GetAnisotropicRoughness(roughness, anisotropyShape, rT, rB); + #if CC_IBL_CONVOLUTED + float coef = abs(float(i)) / float(SAMPLE_STEP_COUNT) * float(SAMPLE_STEP_COUNT); + #else + float coef = pow(abs(float(i)) / float(SAMPLE_STEP_COUNT), 1.3) * float(SAMPLE_STEP_COUNT); + #endif + vec3 H = normalize(N + stepOffset * sign(float(i)) * coef); + vec3 L = reflect(-V, H); + float NoHSat = saturate(dot(N, H)); + float calcSpec = D_GGXAniso(rT, rB, NoHSat, H, T, B); + + envSpec += calcSpec * EnvReflection(tex, L, roughness, mipCount); + integratedBRDF += calcSpec; + } + envSpec /= integratedBRDF; + return envSpec; + } +#endif + +vec3 SampleEnvironmentSpecular(samplerCube tex, in LightingIntermediateData lightingData, float mipCount) +{ + vec3 envSpec = vec3(0.0); + float roughness = lightingData.specularParam; + #if CC_SURFACES_LIGHTING_ANISOTROPIC && !CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT + vec3 R = GetAnisotropicReflect(roughness, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B); + #else + vec3 R = CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV); + #endif + + #if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT + envSpec = EnvAnisotropicReflection(tex, R, roughness, mipCount, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B); + #else + #if CC_SURFACES_USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED + envSpec = EnvReflectionWithMipFiltering(normalize(R), roughness, mipCount, 0.6); + #else + envSpec = EnvReflection(tex, R, roughness, mipCount); + #endif + #endif + return envSpec; +} + +vec3 SampleEnvironmentSpecular(samplerCube tex, in LightingIntermediateData lightingData, float mipCount, vec3 worldPos, vec3 cubeCenterPos, vec3 boxHalfSize) +{ + vec3 envSpec = vec3(0.0); + float roughness = lightingData.specularParam; + #if CC_SURFACES_LIGHTING_ANISOTROPIC && !CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT + vec3 R = GetAnisotropicReflect(roughness, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B); + #else + vec3 R = CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV); + #endif + + vec4 fixedR = CalculateBoxProjectedDirection(R, worldPos, cubeCenterPos, boxHalfSize); + R = fixedR.xyz; + + vec3 envmap = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w).xyz; + #if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT + envSpec = EnvAnisotropicReflection(tex, fixedR.xyz, roughness, mipCount, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B); + envSpec = mix(envmap, envSpec, fixedR.w); + #else + #if CC_SURFACES_USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED + envSpec = EnvReflectionWithMipFiltering(normalize(R), roughness, mipCount, 0.6); + #else + envSpec = mix(envmap, EnvReflection(tex, R, roughness, mipCount), fixedR.w); + #endif + #endif + return envSpec; +} + + +vec3 CalculateEnvironmentDiffuse(in LightingIntermediateData lightingData, float lightIntensity) +{ + // Hemisphere Lighting + float fAmb = max(EPSILON, 0.5 - lightingData.N.y * 0.5); + vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb); + + // Diffuse Map + #if CC_USE_IBL + #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE + // Diffuse irradiance + vec4 diffuseMap = texture(cc_diffuseMap, lightingData.N); + #if CC_USE_DIFFUSEMAP == IBL_RGBE + ambDiff = unpackRGBE(diffuseMap); + #else + ambDiff = SRGBToLinear(diffuseMap.rgb); + #endif + #endif + #endif + + ambDiff.rgb *= lightIntensity; + + // Probe + #if CC_USE_LIGHT_PROBE + ambDiff.rgb += SHEvaluate(lightingData.N); + #endif + + return ambDiff.rgb; +} + +vec3 CalculateEnvironmentSpecular(in LightingIntermediateData lightingData, float lightIntensity) +{ + vec3 envSpec = vec3(0.0); + +#if CC_USE_REFLECTION_PROBE + vec3 worldPos; + HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, lightingData.worldPosition); + + #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE + if(FSInput_reflectionProbeId < 0.0){ + envSpec = SampleEnvironmentSpecular(cc_reflectionProbeCubemap, lightingData, cc_ambientGround.w); + }else{ + vec3 centerPos, boxHalfSize; + float mipCount; + GetCubeReflectionProbeData(centerPos, boxHalfSize, mipCount, FSInput_reflectionProbeId); + envSpec = SampleEnvironmentSpecular(cc_reflectionProbeCubemap, lightingData, mipCount, worldPos, centerPos, boxHalfSize); + } + #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR + vec3 R = normalize(CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV)); + if(FSInput_reflectionProbeId < 0.0){ + vec2 screenUV = GetPlanarReflectScreenUV(worldPos, cc_matViewProj, cc_cameraPos.w, lightingData.V, R); + envSpec = unpackRGBE(fragTextureLod(cc_reflectionProbePlanarMap, screenUV, 1.0)).xyz; + }else{ + vec4 plane; + float planarReflectionDepthScale, mipCount; + GetPlanarReflectionProbeData(plane, planarReflectionDepthScale, mipCount, FSInput_reflectionProbeId); + vec3 worldPosOffset = CalculatePlanarReflectPositionOnPlane(lightingData.N, lightingData.V, worldPos, plane, cc_cameraPos.xyz, planarReflectionDepthScale); + vec2 screenUV = GetPlanarReflectScreenUV(worldPosOffset, cc_matViewProj, cc_cameraPos.w, lightingData.V, R); + envSpec = unpackRGBE(fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mipCount)).xyz; + } + #endif +#elif CC_USE_IBL + envSpec = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w); +#endif + + return envSpec * lightIntensity; +} diff --git a/editor/assets/chunks/lighting-models/model-functions/standard-common.chunk.meta b/editor/assets/chunks/lighting-models/model-functions/standard-common.chunk.meta new file mode 100644 index 00000000000..9f6bf2cc31d --- /dev/null +++ b/editor/assets/chunks/lighting-models/model-functions/standard-common.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "5e057755-d68b-41d1-b089-ed7f7f65f2b8", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/lighting-models/model-functions/standard.chunk b/editor/assets/chunks/lighting-models/model-functions/standard.chunk index 9ee80346a55..ef3c96fd6e9 100644 --- a/editor/assets/chunks/lighting-models/model-functions/standard.chunk +++ b/editor/assets/chunks/lighting-models/model-functions/standard.chunk @@ -1,14 +1,17 @@ #include +#include +#include #include +#include bool CCSurfacesLightingEnableShadow(in float NoL) { return NoL > 0.0; } -float CCSurfacesLightingCalculateDistanceAttenuation(in LightingIntermediateData lightingData, in vec4 lightSizeRangeAngle) +float CCSurfacesLightingCalculateDistanceAttenuation(in LightingIntermediateData lightingData, in vec4 lightSizeRangeAngle, in float lightType) { - return CalculateDistanceAttenuation(lightingData.distToLightSqr, lightSizeRangeAngle.x, lightSizeRangeAngle.y); + return CalculateDistanceAttenuation(lightingData.distToLightSqr, lightSizeRangeAngle.x, lightSizeRangeAngle.y, lightType); } float CCSurfacesLightingCalculateAngleAttenuation(in LightingIntermediateData lightingData, in vec4 lightSizeRangeAngle, in vec3 spotLightDir) @@ -18,104 +21,125 @@ float CCSurfacesLightingCalculateAngleAttenuation(in LightingIntermediateData li void CCSurfacesLightingCalculateDirect(out vec3 lightingDiffuse, out vec3 lightingSpecular, in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity) { - vec3 irradiance = vec3(lightingData.NoLSat) * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w; - - lightingDiffuse = irradiance * DiffuseCoefficient_EnergyConservation; + LightingCalculateDirect(lightingDiffuse, lightingSpecular, lightingData, lightSourceColorAndIntensity); +} - float roughness = lightingData.specularParam; -#if CC_SURFACES_LIGHTING_ANISOTROPIC - float rT, rB; - GetAnisotropicRoughness(roughness, lightingData.anisotropyShape, rT, rB); - float calcSpec = D_GGXAniso(rT, rB, lightingData.NoHSat, lightingData.H, lightingData.T, lightingData.B); + +void CCSurfacesLightingCalculateEnvironment(out vec3 lightingDiffuse, out vec3 lightingSpecular, in LightingIntermediateData lightingData, float lightIntensity) +{ +#if CC_SURFACES_LIGHTING_CALCULATE_DIFFUSE + lightingDiffuse = CalculateEnvironmentDiffuse(lightingData, lightIntensity); #else - #if CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING - float calcSpec = (roughness * 0.25 + 0.25) * D_GGXMobile(roughness, lightingData.NoHSat); - #else - float calcSpec = D_GGX(roughness, lightingData.NoHSat); - #endif + lightingDiffuse = vec3(0.0); #endif - lightingSpecular = irradiance * calcSpec; -} +#if CC_SURFACES_LIGHTING_CALCULATE_SPECULAR + lightingSpecular = CalculateEnvironmentSpecular(lightingData, lightIntensity); +#else + lightingSpecular = vec3(0.0); +#endif +} -#if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT - vec3 EnvAnisotropicReflection(vec3 R, float roughness, float mipCount, float anisotropyShape, vec3 V, vec3 N, vec3 T, vec3 B) { - R = normalize(R); - float integratedBRDF = 0.0; - vec3 envSpec = vec3(0.0); - // One direction sample count - const int SAMPLE_STEP_COUNT = CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT; - float sampleAngleRange = PI * abs(anisotropyShape); - vec3 anisoDirection = anisotropyShape < 0.0 ? T : B; - vec3 ROnNormalPlane = normalize(R - anisoDirection * dot(R, anisoDirection)); - //ROnTangentPlane = R; //for example: cross-style - vec3 stepOffset = normalize(ROnNormalPlane - N) * (sampleAngleRange / float(SAMPLE_STEP_COUNT * 2)); - - for (int i = -SAMPLE_STEP_COUNT; i <= SAMPLE_STEP_COUNT; ++i) - { - float rT, rB; - GetAnisotropicRoughness(roughness, anisotropyShape, rT, rB); - #if CC_IBL_CONVOLUTED - float coef = abs(float(i)) / float(SAMPLE_STEP_COUNT) * float(SAMPLE_STEP_COUNT); - #else - float coef = pow(abs(float(i)) / float(SAMPLE_STEP_COUNT), 1.3) * float(SAMPLE_STEP_COUNT); - #endif - vec3 H = normalize(N + stepOffset * sign(float(i)) * coef); - vec3 L = reflect(-V, H); - float NoHSat = saturate(dot(N, H)); - float calcSpec = D_GGXAniso(rT, rB, NoHSat, H, T, B); - - envSpec += calcSpec * EnvReflection(L, roughness, mipCount); - integratedBRDF += calcSpec; - } - envSpec /= integratedBRDF; - return envSpec; +#if CC_SURFACES_LIGHTING_USE_FRESNEL + float CCSurfaceLightingCalculateFresnel(in LightingIntermediateData lightingData) + { + return CalculateFresnelCoefficient(lightingData.ior, abs(lightingData.NoV)); //NoVSat for single side, and NoVAbs for two sided } #endif +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + // do not support anisotropy + void CCSurfacesLightingCalculateDirectTransmitSpecular(out vec3 lightingSpecular, in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity) + { + float roughness = lightingData.specularParam; + float NoLSat = saturate(dot(lightingData.N, -lightingData.L)); + vec3 irradiance = NoLSat * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w; -void CCSurfacesLightingCalculateEnvironment(inout LightingResult lightingResult, in LightingIntermediateData lightingData) -{ - float roughness = lightingData.specularParam; - float fAmb = 0.5 - lightingData.N.y * 0.5; - vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb); - vec3 envSpec = vec3(0.0); - - #if CC_USE_IBL - #if CC_USE_DIFFUSEMAP - // Diffuse irradiance - vec4 diffuseMap = texture(cc_diffuseMap, lightingData.N); - #if CC_USE_DIFFUSEMAP == IBL_RGBE - ambDiff = unpackRGBE(diffuseMap); - #else - ambDiff = SRGBToLinear(diffuseMap.rgb); - #endif - #endif - - #if CC_SURFACES_LIGHTING_ANISOTROPIC && !CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT - vec3 R = GetAnisotropicReflect(roughness, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B); - #else - vec3 R = reflect(-lightingData.V, lightingData.N); + vec3 R = CalculateRefractDirection(lightingData.N, lightingData.V, lightingData.NoV, lightingData.ior); + float RoL = dot(lightingData.L, normalize(R)); + float calcSpec = D_GGX(roughness, saturate(RoL)); + + lightingSpecular = irradiance * calcSpec; + } + void CCSurfacesLightingCalculateEnvironmentTransmitSpecular(out vec3 lightingSpecular, in LightingIntermediateData lightingData, float lightIntensity) + { + vec3 envSpec = vec3(0.0); + vec3 R = CalculateRefractDirection(lightingData.N, lightingData.V, lightingData.NoV, lightingData.ior); + float roughness = lightingData.specularParam; + + #if CC_USE_REFLECTION_PROBE + #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE + envSpec = EnvReflection(cc_reflectionProbeCubemap, R, roughness, cc_ambientGround.w); #endif + //todo: planar refraction from scene color + #endif - #if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT - envSpec = EnvAnisotropicReflection(R, roughness, cc_ambientGround.w, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B); - #else - #if CC_SURFACES_USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED - envSpec = EnvReflectionWithMipFiltering(normalize(R), roughness, cc_ambientGround.w, 0.6); - #else - envSpec = EnvReflection(R, roughness, cc_ambientGround.w); - #endif - #endif + #if CC_USE_IBL && CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_CUBE + envSpec = EnvReflection(cc_environment, R, roughness, cc_ambientGround.w); #endif - lightingResult.environmentDiffuse = ambDiff.rgb * cc_ambientSky.w; - lightingResult.environmentSpecular = envSpec * cc_ambientSky.w; -} + lightingSpecular = envSpec * lightIntensity; -void CCSurfacesLightingCalculateTransmittence(inout LightingResult lightingResult, in LightingIntermediateData lightingData, vec3 shadowPos) -{ - vec3 irradiance = vec3(lightingData.NoLSat);// * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w; + // scattering + float distance = lightingData.transmitParams.w, inScatterCoef = lightingData.transmitParams.z; + vec2 e = lightingData.transmitParams.xy; + vec2 extinction = exp(-e * distance * vec2(1.0, inScatterCoef)); + vec3 inScattered = (1.0 - extinction.y) * lightingData.inScatteringLightColor.rgb; + lightingSpecular = lightingSpecular * extinction.x + inScattered; + } +#endif + +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + void CCSurfacesLightingCalculateDirectTransmitDiffuse(out vec3 transmitDiffuse, in LightingResult lightingResult, in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity) + { + vec3 backIrradiance = vec3(saturate(-lightingData.NoL)) * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w; + vec3 transmitDiffuse = backIrradiance * DiffuseCoefficient_EnergyConservation; + //todo: add some + lightingData.transmitParams; + lightingData.transmitDiffuseParams; + transmitDiffuse = vec3(0.0); + } + void CCSurfacesLightingCalculateEnvironmentTransmitDiffuse(out vec3 transmitDiffuse, in LightingResult lightingResult, in LightingIntermediateData lightingData, float lightIntensity) + { + // negativate lightingData.N before invoking CalculateEnvironmentDiffuse + lightingData.N *= -1.0; + vec3 backIrradiance = CalculateEnvironmentDiffuse(lightingData, lightIntensity); + lightingData.transmitParams; + lightingData.transmitDiffuseParams; + transmitDiffuse = vec3(0.0); //backIrradiance * lightingResult.ao; + } +#endif + +#if CC_SURFACES_LIGHTING_TRT + // this surface function used for adjust TRT color with brdf lighting, input are lighting result and surface data + // the default function can only be defined here + #ifndef CC_SURFACES_FRAGMENT_MODIFY_TRT_SPECULAR_COLOR + vec3 SurfacesLightingGetTRTSpecularColor(float specBRDF, bool isSaturated) + { + return vec3(specBRDF); + } + #endif + + void CCSurfacesLightingCalculateDirectTRT(out vec3 TRTLighting, in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity) + { + vec3 unused; + // light color has less influence + CCSurfacesLightingCalculateDirect(unused, TRTLighting, lightingData, vec4(1.0)); + float brdf = TRTLighting.x; + vec3 Color = SurfacesLightingGetTRTSpecularColor(brdf, true); + // todo: modify Color to add some light color influence + TRTLighting *= Color * lightSourceColorAndIntensity.w; + } + + void CCSurfacesLightingCalculateEnvironmentTRT(out vec3 TRTLighting, in LightingIntermediateData lightingData, float lightIntensity) + { + vec3 unused; + // light color has less influence + TRTLighting = CalculateEnvironmentSpecular(lightingData, 1.0); + float brdf = length(TRTLighting); + vec3 Color = SurfacesLightingGetTRTSpecularColor(brdf, false); + // todo: modify Color to add some light color influence + TRTLighting *= Color * lightIntensity; + } - vec3 transmittence = irradiance * DiffuseCoefficient_EnergyConservation; -} +#endif diff --git a/editor/assets/chunks/lighting-models/model-functions/toon.chunk b/editor/assets/chunks/lighting-models/model-functions/toon.chunk index 4e6be6f9c47..505a62cce24 100644 --- a/editor/assets/chunks/lighting-models/model-functions/toon.chunk +++ b/editor/assets/chunks/lighting-models/model-functions/toon.chunk @@ -1,4 +1,5 @@ #include +#include #include bool CCSurfacesLightingEnableShadow(in float NoL) @@ -6,9 +7,9 @@ bool CCSurfacesLightingEnableShadow(in float NoL) return NoL > 0.0; } -float CCSurfacesLightingCalculateDistanceAttenuation(in LightingIntermediateData lightingData, in vec4 lightSizeRangeAngle) +float CCSurfacesLightingCalculateDistanceAttenuation(in LightingIntermediateData lightingData, in vec4 lightSizeRangeAngle, in float lightType) { - return CalculateDistanceAttenuation(lightingData.distToLightSqr, lightSizeRangeAngle.x, lightSizeRangeAngle.y); + return CalculateDistanceAttenuation(lightingData.distToLightSqr, lightSizeRangeAngle.x, lightSizeRangeAngle.y, lightType); } float CCSurfacesLightingCalculateAngleAttenuation(in LightingIntermediateData lightingData, in vec4 lightSizeRangeAngle, in vec3 spotLightDir) @@ -30,13 +31,13 @@ void CCSurfacesLightingCalculateDirect(out vec3 lightingDiffuse, out vec3 lighti float NH = 0.5 * lightingData.NoH + 0.5; float specularWeight = 1.0 - pow(lightingData.specularParam, 5.0); - float specularMask = step(specularWeight, NH); + float specularMask = step(specularWeight + EPSILON_LOWP, NH); lightingSpecular = irradiance * specularMask; } -void CCSurfacesLightingCalculateEnvironment(inout LightingResult lightingResult, in LightingIntermediateData lightingData) +void CCSurfacesLightingCalculateEnvironment(out vec3 lightingDiffuse, out vec3 lightingSpecular, in LightingIntermediateData lightingData, float lightIntensity) { - lightingResult.environmentDiffuse = vec3(0.0); - lightingResult.environmentSpecular = vec3(0.0); + lightingDiffuse = vec3(0.0); + lightingSpecular = vec3(0.0); } diff --git a/editor/assets/chunks/post-process/anti-aliasing.chunk b/editor/assets/chunks/post-process/anti-aliasing.chunk index ae778139546..6e84354b7b2 100644 --- a/editor/assets/chunks/post-process/anti-aliasing.chunk +++ b/editor/assets/chunks/post-process/anti-aliasing.chunk @@ -3,3 +3,7 @@ #if ANTIALIAS_TYPE == 1 #include #endif +#if ANTIALIAS_TYPE == 2 + // #define FXAA_PRESET 5 + #include +#endif diff --git a/editor/assets/chunks/post-process/fxaa-hq.chunk b/editor/assets/chunks/post-process/fxaa-hq.chunk new file mode 100644 index 00000000000..0480aaadae4 --- /dev/null +++ b/editor/assets/chunks/post-process/fxaa-hq.chunk @@ -0,0 +1,294 @@ + +#include + +#define FxaaTex sampler2D + +#define int2 vec2 +#define float2 vec2 +#define float3 vec3 +#define float4 vec4 +#define FxaaBool3 bvec3 +#define FxaaInt2 vec2 +#define FxaaFloat2 vec2 +#define FxaaFloat3 vec3 +#define FxaaFloat4 vec4 +#define FxaaBool2Float(a) mix(0.0, 1.0, (a)) +#define FxaaPow3(x, y) pow(x, y) +#define FxaaSel3(f, t, b) mix((f), (t), (b)) +#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a)) +float4 FxaaTexLod0(FxaaTex tex, float2 pos) { + return texture(tex, pos.xy); + // return fragTextureLod(tex, pos.xy, 0.0); +} +float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) { + return fragTextureGrad(tex, pos.xy, grad, grad); +} +float4 FxaaTexOff(FxaaTex tex, float2 pos, int2 off, float2 rcpFrame) { + return FxaaTexLod0(tex, pos.xy + vec2(off.x, off.y) * rcpFrame); +} + +#define FXAA_SRGB_ROP 0 + + +#ifndef FXAA_PRESET + #define FXAA_PRESET 3 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_PRESET == 0) + #define FXAA_EDGE_THRESHOLD (1.0/4.0) + #define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0) + #define FXAA_SEARCH_STEPS 2 + #define FXAA_SEARCH_ACCELERATION 4 + #define FXAA_SEARCH_THRESHOLD (1.0/4.0) + #define FXAA_SUBPIX 1 + #define FXAA_SUBPIX_FASTER 1 + #define FXAA_SUBPIX_CAP (2.0/3.0) + #define FXAA_SUBPIX_TRIM (1.0/4.0) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_PRESET == 1) + #define FXAA_EDGE_THRESHOLD (1.0/8.0) + #define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0) + #define FXAA_SEARCH_STEPS 4 + #define FXAA_SEARCH_ACCELERATION 3 + #define FXAA_SEARCH_THRESHOLD (1.0/4.0) + #define FXAA_SUBPIX 1 + #define FXAA_SUBPIX_FASTER 0 + #define FXAA_SUBPIX_CAP (3.0/4.0) + #define FXAA_SUBPIX_TRIM (1.0/4.0) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_PRESET == 2) + #define FXAA_EDGE_THRESHOLD (1.0/8.0) + #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) + #define FXAA_SEARCH_STEPS 8 + #define FXAA_SEARCH_ACCELERATION 2 + #define FXAA_SEARCH_THRESHOLD (1.0/4.0) + #define FXAA_SUBPIX 1 + #define FXAA_SUBPIX_FASTER 0 + #define FXAA_SUBPIX_CAP (3.0/4.0) + #define FXAA_SUBPIX_TRIM (1.0/4.0) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_PRESET == 3) + #define FXAA_EDGE_THRESHOLD (1.0/8.0) + #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) + #define FXAA_SEARCH_STEPS 16 + #define FXAA_SEARCH_ACCELERATION 1 + #define FXAA_SEARCH_THRESHOLD (1.0/4.0) + #define FXAA_SUBPIX 1 + #define FXAA_SUBPIX_FASTER 0 + #define FXAA_SUBPIX_CAP (3.0/4.0) + #define FXAA_SUBPIX_TRIM (1.0/4.0) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_PRESET == 4) + #define FXAA_EDGE_THRESHOLD (1.0/8.0) + #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) + #define FXAA_SEARCH_STEPS 24 + #define FXAA_SEARCH_ACCELERATION 1 + #define FXAA_SEARCH_THRESHOLD (1.0/4.0) + #define FXAA_SUBPIX 1 + #define FXAA_SUBPIX_FASTER 0 + #define FXAA_SUBPIX_CAP (3.0/4.0) + #define FXAA_SUBPIX_TRIM (1.0/4.0) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_PRESET == 5) + #define FXAA_EDGE_THRESHOLD (1.0/8.0) + #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) + #define FXAA_SEARCH_STEPS 32 + #define FXAA_SEARCH_ACCELERATION 1 + #define FXAA_SEARCH_THRESHOLD (1.0/4.0) + #define FXAA_SUBPIX 1 + #define FXAA_SUBPIX_FASTER 0 + #define FXAA_SUBPIX_CAP (3.0/4.0) + #define FXAA_SUBPIX_TRIM (1.0/4.0) +#endif +/*--------------------------------------------------------------------------*/ +#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM)) + + +float FxaaLuma(float3 rgb) { + return rgb.y * (0.587/0.299) + rgb.x; } +float3 FxaaLerp3(float3 a, float3 b, float amountOfA) { + return (FxaaToFloat3(-amountOfA) * b) + + ((a * FxaaToFloat3(amountOfA)) + b); } +float3 FxaaFilterReturn(float3 rgb) { + #if FXAA_SRGB_ROP + return FxaaSel3( + rgb * FxaaToFloat3(1.0/12.92), + FxaaPow3( + rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055), + FxaaToFloat3(2.4)), + rgb > FxaaToFloat3(0.04045)); + #else + return rgb; + #endif +} + + +float3 FxaaPixelShader( +float2 pos, +FxaaTex tex, +float2 rcpFrame) { + float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz; + float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz; + float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz; + float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz; + float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz; + float lumaN = FxaaLuma(rgbN); + float lumaW = FxaaLuma(rgbW); + float lumaM = FxaaLuma(rgbM); + float lumaE = FxaaLuma(rgbE); + float lumaS = FxaaLuma(rgbS); + float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE))); + float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE))); + float range = rangeMax - rangeMin; + #if FXAA_DEBUG + float lumaO = lumaM / (1.0 + (0.587/0.299)); + #endif + if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) { + #if FXAA_DEBUG + return FxaaFilterReturn(FxaaToFloat3(lumaO)); + #endif + return FxaaFilterReturn(rgbM); } + #if FXAA_SUBPIX > 0 + #if FXAA_SUBPIX_FASTER + float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) * + FxaaToFloat3(1.0/5.0); + #else + float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS; + #endif + #endif + + + #if FXAA_SUBPIX != 0 + float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25; + float rangeL = abs(lumaL - lumaM); + #endif + #if FXAA_SUBPIX == 1 + float blendL = max(0.0, + (rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE; + blendL = min(FXAA_SUBPIX_CAP, blendL); + #endif + #if FXAA_SUBPIX == 2 + float blendL = rangeL / range; + #endif + + + + float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz; + float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz; + float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz; + float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz; + #if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0) + rgbL += (rgbNW + rgbNE + rgbSW + rgbSE); + rgbL *= FxaaToFloat3(1.0/9.0); + #endif + float lumaNW = FxaaLuma(rgbNW); + float lumaNE = FxaaLuma(rgbNE); + float lumaSW = FxaaLuma(rgbSW); + float lumaSE = FxaaLuma(rgbSE); + float edgeVert = + abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) + + abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) + + abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE)); + float edgeHorz = + abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) + + abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) + + abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE)); + bool horzSpan = edgeHorz >= edgeVert; + float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x; + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + float gradientN = abs(lumaN - lumaM); + float gradientS = abs(lumaS - lumaM); + lumaN = (lumaN + lumaM) * 0.5; + lumaS = (lumaS + lumaM) * 0.5; + + + + bool pairN = gradientN >= gradientS; + if(!pairN) lumaN = lumaS; + if(!pairN) gradientN = gradientS; + if(!pairN) lengthSign *= -1.0; + float2 posN; + posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5); + posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0); + + + gradientN *= FXAA_SEARCH_THRESHOLD; + + + float2 posP = posN; + float2 offNP = horzSpan ? + FxaaFloat2(rcpFrame.x, 0.0) : + FxaaFloat2(0.0, rcpFrame.y); + float lumaEndN = lumaN; + float lumaEndP = lumaN; + bool doneN = false; + bool doneP = false; + #if FXAA_SEARCH_ACCELERATION == 1 + posN += offNP * FxaaFloat2(-1.0, -1.0); + posP += offNP * FxaaFloat2( 1.0, 1.0); + #endif + #if FXAA_SEARCH_ACCELERATION == 2 + posN += offNP * FxaaFloat2(-1.5, -1.5); + posP += offNP * FxaaFloat2( 1.5, 1.5); + offNP *= FxaaFloat2(2.0, 2.0); + #endif + #if FXAA_SEARCH_ACCELERATION == 3 + posN += offNP * FxaaFloat2(-2.0, -2.0); + posP += offNP * FxaaFloat2( 2.0, 2.0); + offNP *= FxaaFloat2(3.0, 3.0); + #endif + #if FXAA_SEARCH_ACCELERATION == 4 + posN += offNP * FxaaFloat2(-2.5, -2.5); + posP += offNP * FxaaFloat2( 2.5, 2.5); + offNP *= FxaaFloat2(4.0, 4.0); + #endif + for(int i = 0; i < FXAA_SEARCH_STEPS; i++) { + #if FXAA_SEARCH_ACCELERATION == 1 + if(!doneN) lumaEndN = + FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz); + if(!doneP) lumaEndP = + FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz); + #else + if(!doneN) lumaEndN = + FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz); + if(!doneP) lumaEndP = + FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz); + #endif + doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN); + doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN); + if(doneN && doneP) break; + if(!doneN) posN -= offNP; + if(!doneP) posP += offNP; } + + + + float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y; + float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y; + bool directionN = dstN < dstP; + lumaEndN = directionN ? lumaEndN : lumaEndP; + + + + if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0)) + lengthSign = 0.0; + + + + float spanLength = (dstP + dstN); + dstN = directionN ? dstN : dstP; + float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign; + float3 rgbF = FxaaTexLod0(tex, FxaaFloat2( + pos.x + (horzSpan ? 0.0 : subPixelOffset), + pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz; + #if FXAA_SUBPIX == 0 + return FxaaFilterReturn(rgbF); + #else + return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL)); + #endif +} diff --git a/editor/assets/chunks/post-process/fxaa-hq.chunk.meta b/editor/assets/chunks/post-process/fxaa-hq.chunk.meta new file mode 100644 index 00000000000..d359883dc4e --- /dev/null +++ b/editor/assets/chunks/post-process/fxaa-hq.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "7dd16c65-64a1-48c0-a335-f613807810b4", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk b/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk index bf9bba7d5ad..72b184a5297 100644 --- a/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk +++ b/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk @@ -35,7 +35,7 @@ void CCSurfacesGetFragmentInput(out SurfacesStandardFragmentInput fsInput) #define FSInput_mirrorNormal 1.0 #endif -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP +#if CC_SURFACES_USE_SECOND_UV #define FSInput_texcoord1 v_uv1 #else #define FSInput_texcoord1 vec2(0.0, 0.0) @@ -46,7 +46,10 @@ void CCSurfacesGetFragmentInput(out SurfacesStandardFragmentInput fsInput) #endif #if CC_RECEIVE_SHADOW - #define FSInput_shadowBias v_shadowBias + #define FSInput_shadowBias v_shadowBiasAndProbeId.xy +#endif +#if CC_USE_REFLECTION_PROBE + #define FSInput_reflectionProbeId v_shadowBiasAndProbeId.z #endif #if CC_USE_FOG != CC_FOG_NONE && !CC_USE_ACCURATE_FOG diff --git a/editor/assets/chunks/shading-entries/data-structures/vs-fs.chunk b/editor/assets/chunks/shading-entries/data-structures/vs-fs.chunk index 5d4e0d3c1dc..0f9aadd732d 100644 --- a/editor/assets/chunks/shading-entries/data-structures/vs-fs.chunk +++ b/editor/assets/chunks/shading-entries/data-structures/vs-fs.chunk @@ -11,7 +11,7 @@ CC_SURFACES_VARING_MODIFIER vec2 v_uv; CC_SURFACES_VARING_MODIFIER mediump vec4 v_tangent; #endif -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP +#if CC_SURFACES_USE_SECOND_UV CC_SURFACES_VARING_MODIFIER mediump vec2 v_uv1; #endif @@ -19,8 +19,8 @@ CC_SURFACES_VARING_MODIFIER vec2 v_uv; CC_SURFACES_VARING_MODIFIER mediump vec3 v_luv; #endif -#if CC_RECEIVE_SHADOW - CC_SURFACES_VARING_MODIFIER mediump vec2 v_shadowBias; +#if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + CC_SURFACES_VARING_MODIFIER mediump vec4 v_shadowBiasAndProbeId; #endif #if CC_USE_FOG != CC_FOG_NONE && !CC_USE_ACCURATE_FOG @@ -30,3 +30,11 @@ CC_SURFACES_VARING_MODIFIER vec2 v_uv; #if CC_SURFACES_TRANSFER_LOCAL_POS CC_SURFACES_VARING_MODIFIER highp vec4 v_localPos; #endif + +#if CC_USE_LIGHT_PROBE + #if USE_INSTANCING + CC_SURFACES_VARING_MODIFIER mediump vec4 v_sh_linear_const_r; + CC_SURFACES_VARING_MODIFIER mediump vec4 v_sh_linear_const_g; + CC_SURFACES_VARING_MODIFIER mediump vec4 v_sh_linear_const_b; + #endif +#endif \ No newline at end of file diff --git a/editor/assets/chunks/shading-entries/data-structures/vs-input.chunk b/editor/assets/chunks/shading-entries/data-structures/vs-input.chunk index 293aa34cef6..21f540250d4 100644 --- a/editor/assets/chunks/shading-entries/data-structures/vs-input.chunk +++ b/editor/assets/chunks/shading-entries/data-structures/vs-input.chunk @@ -38,12 +38,16 @@ layout(location = 2) in vec2 a_texCoord; #if CC_USE_LIGHTMAP in vec4 a_lightingMapUVParam; #endif - #if CC_RECEIVE_SHADOW - in vec2 a_localShadowBias; // x:shadow bias, y:shadow normal bias. + #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + in vec4 a_localShadowBiasAndProbeId; // x:shadow bias, y:shadow normal bias, z: reflection probe id, w: reserved for blend reflection probe id + #endif + #if CC_USE_LIGHT_PROBE + in vec4 a_sh_linear_const_r; + in vec4 a_sh_linear_const_g; + in vec4 a_sh_linear_const_b; #endif #endif - #if CC_USE_MORPH #if __VERSION__ < 450 in float a_vertexId; diff --git a/editor/assets/chunks/shading-entries/data-structures/vs-intermediate.chunk b/editor/assets/chunks/shading-entries/data-structures/vs-intermediate.chunk index c5b740c109b..c97b12c37de 100644 --- a/editor/assets/chunks/shading-entries/data-structures/vs-intermediate.chunk +++ b/editor/assets/chunks/shading-entries/data-structures/vs-intermediate.chunk @@ -13,7 +13,7 @@ struct SurfacesStandardVertexIntermediate #endif vec2 texCoord; -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP +#if CC_SURFACES_USE_SECOND_UV vec2 texCoord1; #endif @@ -26,8 +26,8 @@ struct SurfacesStandardVertexIntermediate #endif //transfered -#if CC_RECEIVE_SHADOW - vec2 shadowBias; +#if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + vec4 shadowBiasAndProbeId; #endif #if CC_USE_FOG != CC_FOG_NONE && !CC_USE_ACCURATE_FOG diff --git a/editor/assets/chunks/shading-entries/data-structures/vs-output.chunk b/editor/assets/chunks/shading-entries/data-structures/vs-output.chunk index c777938ce8e..ea9593b4daa 100644 --- a/editor/assets/chunks/shading-entries/data-structures/vs-output.chunk +++ b/editor/assets/chunks/shading-entries/data-structures/vs-output.chunk @@ -22,7 +22,7 @@ #define VSOutput_mirrorNormal v_tangent.w #endif -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP +#if CC_SURFACES_USE_SECOND_UV #define VSOutput_texcoord1 v_uv1 #endif @@ -31,7 +31,10 @@ #endif #if CC_RECEIVE_SHADOW - #define VSOutput_shadowBias v_shadowBias + #define VSOutput_shadowBias v_shadowBiasAndProbeId.xy +#endif +#if CC_USE_REFLECTION_PROBE + #define VSOutput_reflectionProbeId v_shadowBiasAndProbeId.z #endif #if CC_USE_FOG != CC_FOG_NONE && !CC_USE_ACCURATE_FOG diff --git a/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk b/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk index ed9e54a4f8c..baeb8b05393 100644 --- a/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk @@ -26,5 +26,9 @@ void main() { #endif color.rgb = LinearToSRGB(color.rgb); + #if CC_USE_RGBE_OUTPUT + color = packRGBE(color.rgb); + #endif + fragColorX = color; } diff --git a/editor/assets/chunks/shading-entries/main-functions/render-to-reflectmap/fs.chunk b/editor/assets/chunks/shading-entries/main-functions/render-to-reflectmap/fs.chunk index 750c21b903b..0c749cd325c 100644 --- a/editor/assets/chunks/shading-entries/main-functions/render-to-reflectmap/fs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/render-to-reflectmap/fs.chunk @@ -1,46 +1,50 @@ layout(location = 0) out vec4 fragColorX; - -void main() { -#if CC_DISABLE_STRUCTURE_IN_FRAGMENT_SHADER - float NoL = dot(-cc_mainLitDir.xyz, FSInput_worldNormal.xyz); //trigger ubo binding - vec4 color = SurfacesFragmentModifyBaseColorAndTransparency(); -#else - // Surface - SurfacesMaterialData surfaceData; - CCSurfacesFragmentGetMaterialData(surfaceData); - - // Shadow parameters - vec2 shadowBias = vec2(0.0); - #if CC_RECEIVE_SHADOW - shadowBias = FSInput_shadowBias; - #endif - - // Fog factor - #if !CC_FORWARD_ADD - float fogFactor = 1.0; - #if CC_USE_FOG != CC_FOG_NONE - #if !CC_USE_ACCURATE_FOG - fogFactor = FSInput_fogFactor; - #else - CC_TRANSFER_FOG_BASE(vec4(FSInput_worldPos, 1.0), fogFactor); +#if CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED && !CC_FORCE_FORWARD_SHADING + void main() { fragColorX = vec4(0.0, 1.0, 0.0, 1.0); } +#else + void main() { + #if CC_DISABLE_STRUCTURE_IN_FRAGMENT_SHADER + float NoL = dot(-cc_mainLitDir.xyz, FSInput_worldNormal.xyz); //trigger ubo binding + vec4 color = SurfacesFragmentModifyBaseColorAndTransparency(); + #else + // Surface + SurfacesMaterialData surfaceData; + CCSurfacesFragmentGetMaterialData(surfaceData); + + // Shadow parameters + vec2 shadowBias = vec2(0.0); + #if CC_RECEIVE_SHADOW + shadowBias = FSInput_shadowBias; + #endif + + + // Fog factor + #if !CC_FORWARD_ADD + float fogFactor = 1.0; + #if CC_USE_FOG != CC_FOG_NONE + #if !CC_USE_ACCURATE_FOG + fogFactor = FSInput_fogFactor; + #else + CC_TRANSFER_FOG_BASE(vec4(FSInput_worldPos, 1.0), fogFactor); + #endif #endif #endif + + + // Lighting + LightingResult lightingResult; + CCSurfacesLighting(lightingResult, surfaceData, shadowBias); + + // Shading + vec4 color = CCSurfacesShading(surfaceData, lightingResult); + + #if !CC_FORWARD_ADD + CC_APPLY_FOG_BASE(color, fogFactor); + #endif #endif - - - // Lighting - LightingResult lightingResult; - CCSurfacesLighting(lightingResult, surfaceData, shadowBias); - - // Shading - vec4 color = CCSurfacesShading(surfaceData, lightingResult); - - #if !CC_FORWARD_ADD - CC_APPLY_FOG_BASE(color, fogFactor); - #endif + + // Color output (RGBE) + fragColorX = packRGBE(color.rgb); + } #endif - - // Color output (RGBE) - fragColorX = packRGBE(color.rgb); -} diff --git a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk index 60ad5b178c1..239974e6851 100644 --- a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk @@ -21,7 +21,8 @@ void main() { vec4 csmPos; vec4 shadowProjDepthInfo, shadowProjInfo; vec3 shadowViewDir0, shadowViewDir1, shadowViewDir2; - int csmLayer = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, surfaceData.worldPos); + int csmLayer = -1; + csmLayer = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, surfaceData.worldPos); bool OutOfRange = csmLayer < 0; if (OutOfRange) colDebugCSMLayer = vec3(1.0); @@ -92,9 +93,10 @@ void main() { debugColor.rgb = LinearToSRGB(debugColor.rgb); } } - - fragColorX = debugColor; - return; + if (IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) { + fragColorX = debugColor; + return; + } #elif CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC && CC_SURFACES_ENABLE_DEBUG_VIEW CCSurfacesDebugViewCompositeLightingResult(lightingResult); @@ -117,6 +119,11 @@ void main() { #endif // Color output + #if CC_USE_RGBE_OUTPUT + fragColorX = packRGBE(color.rgb); // for reflection-map + return; + #endif + #if CC_USE_HDR #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC && CC_SURFACES_ENABLE_DEBUG_VIEW if (IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING) diff --git a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/vs.chunk b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/vs.chunk index 6d9239e75d2..392f91b91a9 100644 --- a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/vs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/vs.chunk @@ -6,6 +6,11 @@ void main() CCSurfacesVertexInput(In); CCSurfacesVertexAnimation(In); In.position.xyz = SurfacesVertexModifyLocalPos(In); + In.normal.xyz = SurfacesVertexModifyLocalNormal(In); + #if CC_SURFACES_USE_TANGENT_SPACE + In.tangent = SurfacesVertexModifyLocalTangent(In); + #endif + SurfacesVertexModifyLocalSharedData(In); // World Space CCSurfacesVertexWorldTransform(In); @@ -16,12 +21,13 @@ void main() In.clipPos = SurfacesVertexModifyClipPos(In); // Other Surfaces Function - SurfacesVertexModifyUV(In); - vec3 viewDirect = normalize(cc_cameraPos.xyz - In.worldPos); In.worldNormal.w = dot(In.worldNormal.xyz, viewDirect) < 0.0 ? -1.0 : 1.0; In.worldNormal.xyz = SurfacesVertexModifyWorldNormal(In); + SurfacesVertexModifyUV(In); + SurfacesVertexModifySharedData(In); + // Other Data CCSurfacesVertexTransformUV(In); CCSurfacesVertexTransferFog(In); diff --git a/editor/assets/chunks/shading-entries/main-functions/render-to-shadowmap/vs.chunk b/editor/assets/chunks/shading-entries/main-functions/render-to-shadowmap/vs.chunk index d5dcceaaf2b..cecd57a617e 100644 --- a/editor/assets/chunks/shading-entries/main-functions/render-to-shadowmap/vs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/render-to-shadowmap/vs.chunk @@ -11,6 +11,7 @@ void main() CCSurfacesVertexInput(In); CCSurfacesVertexAnimation(In); In.position.xyz = SurfacesVertexModifyLocalPos(In); + SurfacesVertexModifyLocalSharedData(In); // World Space CCSurfacesVertexWorldTransform(In); @@ -22,6 +23,7 @@ void main() // Other Surfaces Function SurfacesVertexModifyUV(In); + SurfacesVertexModifySharedData(In); // Other Data CCSurfacesVertexTransformUV(In); diff --git a/editor/assets/chunks/surfaces/data-structures/standard.chunk b/editor/assets/chunks/surfaces/data-structures/standard.chunk index 62711411f62..40d83496a7f 100644 --- a/editor/assets/chunks/surfaces/data-structures/standard.chunk +++ b/editor/assets/chunks/surfaces/data-structures/standard.chunk @@ -13,9 +13,21 @@ struct SurfacesMaterialData // for advanced PBR vec3 worldTangent, worldBinormal; + float ior; + #if CC_SURFACES_LIGHTING_ANISOTROPIC float anisotropyShape; #endif - // float transmittanceFactor; + +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR || CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + vec3 inScatteringLightColor; + vec4 transmitParams; +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + vec4 transmitDiffuseParams; +#endif +#if CC_SURFACES_LIGHTING_TRT + float roughnessTRT; +#endif // float sssCurvature; }; diff --git a/editor/assets/chunks/surfaces/default-functions/common-vs.chunk b/editor/assets/chunks/surfaces/default-functions/common-vs.chunk index b6252172acf..794b3dfeacc 100644 --- a/editor/assets/chunks/surfaces/default-functions/common-vs.chunk +++ b/editor/assets/chunks/surfaces/default-functions/common-vs.chunk @@ -5,6 +5,31 @@ vec3 SurfacesVertexModifyLocalPos(in SurfacesStandardVertexIntermediate In) } #endif +#ifndef CC_SURFACES_VERTEX_MODIFY_LOCAL_NORMAL +vec3 SurfacesVertexModifyLocalNormal(in SurfacesStandardVertexIntermediate In) +{ + return In.normal.xyz; +} +#endif + +#ifndef CC_SURFACES_VERTEX_MODIFY_LOCAL_TANGENT + #if CC_SURFACES_USE_TANGENT_SPACE + vec4 SurfacesVertexModifyLocalTangent(in SurfacesStandardVertexIntermediate In) + { + return In.tangent; + } + #endif +#endif + +// some vertex datas use shared raw data, avoid sample / calculate same raw data multiply times, use this function for better performance +// this function invokes before world transform +#ifndef CC_SURFACES_VERTEX_MODIFY_LOCAL_SHARED_DATA +void SurfacesVertexModifyLocalSharedData(inout SurfacesStandardVertexIntermediate In) +{ +} +#endif + + #ifndef CC_SURFACES_VERTEX_MODIFY_WORLD_POS vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In) { @@ -22,10 +47,10 @@ vec4 SurfacesVertexModifyClipPos(in SurfacesStandardVertexIntermediate In) #ifndef CC_SURFACES_VERTEX_MODIFY_UV void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) { - In.texCoord = In.texCoord; -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP - In.texCoord1 = In.texCoord1; -#endif +// In.texCoord = In.texCoord; +// #if CC_SURFACES_USE_SECOND_UV +// In.texCoord1 = In.texCoord1; +// #endif } #endif @@ -39,3 +64,11 @@ vec3 SurfacesVertexModifyWorldNormal(in SurfacesStandardVertexIntermediate In) return worldNormal; } #endif + +// some vertex datas use shared raw data, avoid sample / calculate same raw data multiply times, use this function for better performance +// this function invokes at last +#ifndef CC_SURFACES_VERTEX_MODIFY_SHARED_DATA +void SurfacesVertexModifySharedData(inout SurfacesStandardVertexIntermediate In) +{ +} +#endif diff --git a/editor/assets/chunks/surfaces/default-functions/standard-fs.chunk b/editor/assets/chunks/surfaces/default-functions/standard-fs.chunk index 0930f7d185c..e4e6961a985 100644 --- a/editor/assets/chunks/surfaces/default-functions/standard-fs.chunk +++ b/editor/assets/chunks/surfaces/default-functions/standard-fs.chunk @@ -37,6 +37,13 @@ void SurfacesFragmentModifyWorldTangentAndBinormal(inout vec3 worldTangent, inou } #endif +#ifndef CC_SURFACES_FRAGMENT_MODIFY_IOR +float SurfacesFragmentModifyIOR() +{ + return 1.0; +} +#endif + #ifndef CC_SURFACES_FRAGMENT_MODIFY_ANISOTROPY_PARAMS // isRotation=1.0: shape(0~1), rotation(0~2PI), 0.0, 0.0 // or @@ -63,6 +70,35 @@ vec4 SurfacesFragmentModifyPBRParams() } #endif +#ifndef CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_PARAMS +void SurfacesFragmentModifyTransmitParams(out vec4 transmitParams, out vec3 inScatteringLightColor) +{ + // xy: extinction coef for out/in-scattering (should be same) + // z: in-scattering coef (constant phase function) + // w: transmit distance(water depth, leaf thickness) + transmitParams = vec4(0.0, 0.0, 0.0, 0.0); + inScatteringLightColor = vec3(0.0); +} +#endif + +#ifndef CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_DIFFUSE_PARAMS +vec4 SurfacesFragmentModifyTransmitDiffuseParams() +{ + // x: transmit irradiance apply shadow + // y: additional transmit depth mask, add light transport for area which cannot be covered by shadowmap transmittance, or stand for thin transmittance + // zw: min/max DepthWS for shadowmap, 0 means disable shadow transmit + return vec4(1.0, 0.0, 0.0, 0.0); +} +#endif + +#ifndef CC_SURFACES_FRAGMENT_MODIFY_TRT_PARAMS +vec4 SurfacesFragmentModifyTRTParams() +{ + //x: roughness + return vec4(0.5, 0.0, 0.0, 0.0); +} +#endif + // some material datas use shared raw data, avoid sample / calculate same raw data multiply times, use this function for better performance // this function invokes at last // should use corresponding shading-model header: #include before function define diff --git a/editor/assets/chunks/surfaces/effect-macros/common-macros.chunk b/editor/assets/chunks/surfaces/effect-macros/common-macros.chunk index 6939253d73e..e0b2c4f7b66 100644 --- a/editor/assets/chunks/surfaces/effect-macros/common-macros.chunk +++ b/editor/assets/chunks/surfaces/effect-macros/common-macros.chunk @@ -22,13 +22,11 @@ #define CC_SURFACES_TRANSFER_LOCAL_POS 0 #endif -// Can force CC_SURFACES_USE_LIGHT_MAP to 0, can not force to 1 -#if CC_USE_LIGHTMAP - #ifndef CC_SURFACES_USE_LIGHT_MAP - #define CC_SURFACES_USE_LIGHT_MAP 1 - #endif -#else - #ifndef CC_SURFACES_USE_LIGHT_MAP +// force CC_SURFACES_USE_LIGHT_MAP to 0 is valid, force to 1 is invalid +#ifndef CC_SURFACES_USE_LIGHT_MAP + #ifdef CC_USE_LIGHTMAP + #define CC_SURFACES_USE_LIGHT_MAP CC_USE_LIGHTMAP + #else #define CC_SURFACES_USE_LIGHT_MAP 0 #endif #endif @@ -52,8 +50,31 @@ #ifndef CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING #define CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING 0 #endif +#ifndef CC_SURFACES_LIGHTING_USE_FRESNEL + #define CC_SURFACES_LIGHTING_USE_FRESNEL 0 +#endif +#ifndef CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + #define CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR 0 +#endif +#ifndef CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + #define CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE 0 +#endif +#ifndef CC_SURFACES_LIGHTING_USE_SHADOWMAP_TRANSMIT + #define CC_SURFACES_LIGHTING_USE_SHADOWMAP_TRANSMIT 0 +#endif +#ifndef CC_SURFACES_LIGHTING_TRT + #define CC_SURFACES_LIGHTING_TRT 0 +#endif // render-to-color-map can disable functionality to avoid error data map #ifndef CC_SURFACES_ENABLE_DEBUG_VIEW #define CC_SURFACES_ENABLE_DEBUG_VIEW 1 #endif + +// for skin +#ifndef CC_SURFACES_LIGHTING_CALCULATE_DIFFUSE + #define CC_SURFACES_LIGHTING_CALCULATE_DIFFUSE 1 +#endif +#ifndef CC_SURFACES_LIGHTING_CALCULATE_SPECULAR + #define CC_SURFACES_LIGHTING_CALCULATE_SPECULAR 1 +#endif diff --git a/editor/assets/chunks/surfaces/effect-macros/terrain.chunk b/editor/assets/chunks/surfaces/effect-macros/terrain.chunk index a76e9b677ee..7c4818d7487 100644 --- a/editor/assets/chunks/surfaces/effect-macros/terrain.chunk +++ b/editor/assets/chunks/surfaces/effect-macros/terrain.chunk @@ -6,8 +6,6 @@ #define CC_SURFACES_USE_SECOND_UV 0 #define CC_SURFACES_USE_TWO_SIDED 0 -#define CC_SURFACES_USE_LIGHT_MAP CC_USE_LIGHTMAP - // vs-fs varing addon data #define CC_SURFACES_TRANSFER_LOCAL_POS 1 diff --git a/editor/assets/chunks/surfaces/includes/common-fs.chunk b/editor/assets/chunks/surfaces/includes/common-fs.chunk index 2d967c0cec4..e99bf8f895a 100644 --- a/editor/assets/chunks/surfaces/includes/common-fs.chunk +++ b/editor/assets/chunks/surfaces/includes/common-fs.chunk @@ -21,17 +21,27 @@ #endif #endif +#if CC_USE_LIGHT_PROBE + #if !USE_INSTANCING + #include + #endif +#endif + // Uniforms--Tex #include #if CC_SUPPORT_CASCADED_SHADOW_MAP #include #endif + +#include #if CC_USE_IBL - #include #if CC_USE_DIFFUSEMAP #include #endif #endif +#if CC_USE_REFLECTION_PROBE + #include +#endif // Base #include @@ -49,6 +59,12 @@ // Functional #include #include +#if CC_USE_LIGHT_PROBE + #include +#endif +#if CC_USE_REFLECTION_PROBE + #include +#endif // Uniform should depend on system macro, not surface macro #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD diff --git a/editor/assets/chunks/surfaces/module-functions/common-vs.chunk b/editor/assets/chunks/surfaces/module-functions/common-vs.chunk index bf5d875629f..21b4bff405f 100644 --- a/editor/assets/chunks/surfaces/module-functions/common-vs.chunk +++ b/editor/assets/chunks/surfaces/module-functions/common-vs.chunk @@ -13,7 +13,7 @@ void CCSurfacesVertexInput(out SurfacesStandardVertexIntermediate In) #endif In.texCoord = a_texCoord; -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP +#if CC_SURFACES_USE_SECOND_UV In.texCoord1 = a_texCoord1; #endif } @@ -28,7 +28,7 @@ void CCSurfacesVertexOutput(in SurfacesStandardVertexIntermediate In) #if CC_SURFACES_USE_TANGENT_SPACE VSOutput_worldTangent = In.worldTangent.xyz; // VSOutput_worldBitangent = In.worldBinormal; - VSOutput_mirrorNormal = In.tangent.w; + VSOutput_mirrorNormal = In.tangent.w > 0.0 ? 1.0 : -1.0; // for compatibility #14121 #endif #if CC_SURFACES_USE_VERTEX_COLOR @@ -36,7 +36,7 @@ void CCSurfacesVertexOutput(in SurfacesStandardVertexIntermediate In) #endif VSOutput_texcoord = In.texCoord; -#if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP +#if CC_SURFACES_USE_SECOND_UV VSOutput_texcoord1 = In.texCoord1; #endif @@ -45,7 +45,11 @@ void CCSurfacesVertexOutput(in SurfacesStandardVertexIntermediate In) #endif #if CC_RECEIVE_SHADOW - VSOutput_shadowBias = In.shadowBias; + VSOutput_shadowBias = In.shadowBiasAndProbeId.xy; +#endif + +#if CC_USE_REFLECTION_PROBE + VSOutput_reflectionProbeId = In.shadowBiasAndProbeId.z; #endif #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD @@ -55,6 +59,14 @@ void CCSurfacesVertexOutput(in SurfacesStandardVertexIntermediate In) #if CC_SURFACES_TRANSFER_LOCAL_POS VSOutput_localPos = In.position; #endif + +#if CC_USE_LIGHT_PROBE + #if USE_INSTANCING + v_sh_linear_const_r = a_sh_linear_const_r; + v_sh_linear_const_g = a_sh_linear_const_g; + v_sh_linear_const_b = a_sh_linear_const_b; + #endif +#endif } // Morph & Skinning @@ -97,7 +109,7 @@ void CCSurfacesVertexTransformUV(inout SurfacesStandardVertexIntermediate In) { #if CC_SURFACES_FLIP_UV CC_HANDLE_RT_SAMPLE_FLIP(In.texCoord); - #if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP + #if CC_SURFACES_USE_SECOND_UV CC_HANDLE_RT_SAMPLE_FLIP(In.texCoord1); #endif #endif @@ -113,12 +125,23 @@ void CCSurfacesVertexTransferFog(inout SurfacesStandardVertexIntermediate In) void CCSurfacesVertexTransferShadow(inout SurfacesStandardVertexIntermediate In) { + #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + In.shadowBiasAndProbeId = vec4(0.0); + #endif #if CC_RECEIVE_SHADOW - In.shadowBias = vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z); + In.shadowBiasAndProbeId.xy = vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z); + #if USE_INSTANCING + In.shadowBiasAndProbeId.xy += a_localShadowBiasAndProbeId.xy; + #else + In.shadowBiasAndProbeId.xy += cc_localShadowBias.xy; + #endif + #endif + + #if CC_USE_REFLECTION_PROBE #if USE_INSTANCING - In.shadowBias += a_localShadowBias.xy; + In.shadowBiasAndProbeId.zw = a_localShadowBiasAndProbeId.zw; #else - In.shadowBias += cc_localShadowBias.xy; + In.shadowBiasAndProbeId.zw = cc_localShadowBias.zw; #endif #endif } diff --git a/editor/assets/chunks/surfaces/module-functions/debug-view.chunk b/editor/assets/chunks/surfaces/module-functions/debug-view.chunk index 1aff7c17172..e25d8c9ce23 100644 --- a/editor/assets/chunks/surfaces/module-functions/debug-view.chunk +++ b/editor/assets/chunks/surfaces/module-functions/debug-view.chunk @@ -100,68 +100,139 @@ vec4 CCSurfacesDebugDisplayInvalidInputData(vec4 color, vec3 data) #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_SINGLE bool CCSurfacesDebugViewLightingResult(inout vec4 color, in LightingResult lightingResult) { - bool isDebugMatched = false; + // whether need tone mapping & LinearToSRGB + bool isSRGBColor = false; if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE)) { color.rgb = lightingResult.directDiffuse * lightingResult.diffuseColorWithLighting; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR)) { color.rgb = lightingResult.directSpecular * lightingResult.specularColorWithLighting; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_DIRECT_ALL)) { color.rgb = lightingResult.directDiffuse * lightingResult.diffuseColorWithLighting + lightingResult.directSpecular * lightingResult.specularColorWithLighting; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE)) { color.rgb = lightingResult.environmentDiffuse * lightingResult.diffuseColorWithLighting; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR)) { color.rgb = lightingResult.environmentSpecular * lightingResult.specularColorWithLighting; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_ENV_ALL)) { color.rgb = lightingResult.environmentDiffuse * lightingResult.diffuseColorWithLighting + lightingResult.environmentSpecular * lightingResult.specularColorWithLighting; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_LIGHT_MAP)) { color.rgb = lightingResult.lightmapColor; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_EMISSIVE)) { color.rgb = lightingResult.emissive; - isDebugMatched = true; + isSRGBColor = true; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_AO)) { color.rgb = vec3(lightingResult.ao); - isDebugMatched = true; + isSRGBColor = false; } if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_SHADOW)) { color.rgb = vec3(lightingResult.shadow); - isDebugMatched = true; + isSRGBColor = false; } - return isDebugMatched; + float fresnel = 0.0; + vec3 directTransmitSpecular = vec3(0.0), environmentTransmitSpecular = vec3(0.0); + vec3 directTransmitDiffuse = vec3(0.0), environmentTransmitDiffuse = vec3(0.0); + vec3 directTRT = vec3(0.0), environmentTRT = vec3(0.0); + #if CC_SURFACES_LIGHTING_USE_FRESNEL + fresnel = lightingResult.fresnel; + #endif + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + directTransmitSpecular = lightingResult.directTransmitSpecular; + environmentTransmitSpecular = lightingResult.environmentTransmitSpecular; + #endif + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + directTransmitDiffuse = lightingResult.directTransmitDiffuse; + environmentTransmitDiffuse = lightingResult.environmentTransmitDiffuse; + #endif + #if CC_SURFACES_LIGHTING_TRT + directTRT = lightingResult.directTRT; + environmentTRT = lightingResult.environmentTRT; + #endif + + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_FRESNEL)) + { + color.rgb = vec3(fresnel); + isSRGBColor = false; + } + + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRANSMIT_DIRECT_SPECULAR)) + { + color.rgb = directTransmitSpecular; + isSRGBColor = true; + } + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRANSMIT_ENV_SPECULAR)) + { + color.rgb = environmentTransmitSpecular; + isSRGBColor = true; + } + + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRANSMIT_DIRECT_DIFFUSE)) + { + color.rgb = directTransmitDiffuse; + isSRGBColor = true; + } + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRANSMIT_ENV_DIFFUSE)) + { + color.rgb = environmentTransmitDiffuse; + isSRGBColor = true; + } + + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRANSMIT_ALL)) + { + color.rgb = directTransmitSpecular + environmentTransmitSpecular + directTransmitDiffuse + environmentTransmitDiffuse; + isSRGBColor = true; + } + + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRT_DIRECT)) + { + color.rgb = directTRT; + isSRGBColor = true; + } + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRT_ENVIRONMENT)) + { + color.rgb = environmentTRT; + isSRGBColor = true; + } + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_TRT_ALL)) + { + color.rgb = directTRT + environmentTRT; + isSRGBColor = true; + } + + return isSRGBColor; } #endif @@ -182,6 +253,21 @@ vec4 CCSurfacesDebugDisplayInvalidInputData(vec4 color, vec3 data) if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_SPECULAR) lightingResult.environmentSpecular = vec3(0.0); + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_TRANSMIT_DIFFUSE) + lightingResult.directTransmitDiffuse = lightingResult.environmentTransmitDiffuse = vec3(0.0); + #endif + + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_TRANSMIT_SPECULAR) + lightingResult.directTransmitSpecular = lightingResult.environmentTransmitSpecular = vec3(0.0); + #endif + + #if CC_SURFACES_LIGHTING_TRT + if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_TRT) + lightingResult.directTRT = lightingResult.environmentTRT = vec3(0.0); + #endif + if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_EMISSIVE) lightingResult.emissive = vec3(0.0); @@ -193,5 +279,10 @@ vec4 CCSurfacesDebugDisplayInvalidInputData(vec4 color, vec3 data) if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_AO) lightingResult.ao = 1.0; + + #if CC_SURFACES_LIGHTING_USE_FRESNEL + if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_FRESNEL) + lightingResult.fresnel = 1.0; + #endif } #endif diff --git a/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk b/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk index e8f097fe96e..e65c9035b28 100644 --- a/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk +++ b/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk @@ -9,6 +9,9 @@ void CCSurfacesFragmentGetMaterialData(inout SurfacesMaterialData surfaceData) surfaceData.worldNormal = SurfacesFragmentModifyWorldNormal(); SurfacesFragmentModifyWorldTangentAndBinormal(surfaceData.worldTangent, surfaceData.worldBinormal, surfaceData.worldNormal); + + surfaceData.ior = SurfacesFragmentModifyIOR(); + #if CC_SURFACES_LIGHTING_ANISOTROPIC float isRotation; vec4 anisotropyParams = SurfacesFragmentModifyAnisotropyParams(isRotation); @@ -31,6 +34,17 @@ void CCSurfacesFragmentGetMaterialData(inout SurfacesMaterialData surfaceData) surfaceData.metallic = pbr.z; surfaceData.specularIntensity = pbr.w; +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR || CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + SurfacesFragmentModifyTransmitParams(surfaceData.transmitParams, surfaceData.inScatteringLightColor); +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + surfaceData.transmitDiffuseParams = SurfacesFragmentModifyTransmitDiffuseParams(); +#endif +#if CC_SURFACES_LIGHTING_TRT + vec4 trt = SurfacesFragmentModifyTRTParams(); + surfaceData.roughnessTRT = trt.x; +#endif + SurfacesFragmentModifySharedData(surfaceData); #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC @@ -82,19 +96,71 @@ void CCSurfacesInitializeLightingIntermediateData(inout LightingIntermediateData #endif ); lightingData.specularParam = surfaceData.roughness; + lightingData.ior = surfaceData.ior; +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR || CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + lightingData.transmitParams = surfaceData.transmitParams; + lightingData.inScatteringLightColor = surfaceData.inScatteringLightColor; +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + lightingData.transmitDiffuseParams = surfaceData.transmitDiffuseParams; +#endif } + void CCSurfacesLightingCalculateIntermediateData_PerLight(inout LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData, vec3 lightDirWithDist) { CCSurfacesLightingGetIntermediateData_PerLight(lightingData, lightDirWithDist); } -// Copy material data to lighting results +// pass original lightingData, get TRT lightingData +#if CC_SURFACES_LIGHTING_TRT +void CCSurfacesGetLightingIntermediateDataTRT(out LightingIntermediateData lightingDataTRT, in LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData) +{ + lightingDataTRT = lightingData; + lightingDataTRT.specularParam = surfaceData.roughnessTRT; +} +#endif + + +// Copy material data to lighting results for base pass void CCSurfacesInitializeLightingResult(inout LightingResult lightingResult, in SurfacesMaterialData surfaceData) { lightingResult.ao = surfaceData.ao; lightingResult.emissive = surfaceData.emissive; } +// Init accumulated lighting results for additive pass +void CCSurfacesInitializeLightingResult(inout LightingResult lightingResult) +{ + lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0); + +#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + lightingResult.directTransmitSpecular = vec3(0.0); +#endif +#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + lightingResult.directTransmitDiffuse = vec3(0.0); +#endif +#if CC_SURFACES_LIGHTING_TRT + lightingResult.directTRT = vec3(0.0); +#endif +} + +// Accumulated lighting results for additive pass +void CCSurfacesAccumulateLightingResult(inout LightingResult lightingResultAccumulated, in LightingResult lightingResult) +{ + lightingResultAccumulated.directDiffuse += lightingResult.directDiffuse * lightingResult.shadow; + lightingResultAccumulated.directSpecular += lightingResult.directSpecular * lightingResult.shadow; + + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + lightingResultAccumulated.directTransmitSpecular += lightingResult.directTransmitSpecular; + #endif + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + lightingResultAccumulated.directTransmitDiffuse += lightingResult.directTransmitDiffuse; + #endif + #if CC_SURFACES_LIGHTING_TRT + lightingResultAccumulated.directTRT += lightingResult.directTRT; + #endif +} + #if CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED @@ -117,24 +183,62 @@ void CCSurfacesInitializeLightingResult(inout LightingResult lightingResult, in vec4 CCSurfacesShading(in SurfacesMaterialData surfaceData, in LightingResult lightingResult) { vec4 color = vec4(0.0, 0.0, 0.0, surfaceData.baseColor.a); + #if CC_FORWARD_ADD - color.xyz += lightingResult.directDiffuse * lightingResult.diffuseColorWithLighting; - color.xyz += lightingResult.directSpecular * lightingResult.specularColorWithLighting; + // shadow and fresnel has already been applied with common flow + color.xyz += lightingResult.directDiffuse * lightingResult.diffuseColorWithLighting + + lightingResult.directSpecular * lightingResult.specularColorWithLighting; + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + + lightingResult.directTransmitSpecular * lightingResult.specularColorWithLighting + #endif + ; + #else + float fresnel = 1.0; + #if CC_SURFACES_LIGHTING_USE_FRESNEL + fresnel = lightingResult.fresnel; + #endif + float invFresnel = 1.0 - fresnel; + color.xyz += - ( lightingResult.lightmapColor * lightingResult.diffuseColorWithLighting - + lightingResult.directDiffuse * lightingResult.diffuseColorWithLighting - + lightingResult.directSpecular * lightingResult.specularColorWithLighting) + ( lightingResult.directDiffuse * lightingResult.diffuseColorWithLighting + + lightingResult.directSpecular * lightingResult.specularColorWithLighting * fresnel + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + + lightingResult.directTransmitSpecular * lightingResult.specularColorWithLighting * invFresnel + #endif + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + + lightingResult.directTransmitDiffuse + #endif + #if CC_SURFACES_LIGHTING_TRT + + lightingResult.directTRT * lightingResult.specularColorWithLighting + #endif + ) * lightingResult.shadow; + #if CC_SURFACES_USE_LIGHT_MAP == LIGHT_MAP_TYPE_ALL_IN_ONE + color.xyz += lightingResult.lightmapColor * lightingResult.diffuseColorWithLighting * lightingResult.shadow; //apply real-time shadows + #elif CC_SURFACES_USE_LIGHT_MAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION + color.xyz += lightingResult.lightmapColor * lightingResult.diffuseColorWithLighting; + #endif + color.xyz += ( lightingResult.environmentDiffuse * lightingResult.diffuseColorWithLighting - + lightingResult.environmentSpecular * lightingResult.specularColorWithLighting) + + lightingResult.environmentSpecular * lightingResult.specularColorWithLighting * fresnel + #if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR + + lightingResult.environmentTransmitSpecular * lightingResult.specularColorWithLighting * invFresnel + #endif + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE + + lightingResult.environmentTransmitDiffuse + #endif + #if CC_SURFACES_LIGHTING_TRT + + lightingResult.environmentTRT * lightingResult.specularColorWithLighting + #endif + ) * lightingResult.ao; color.xyz += lightingResult.emissive; #endif - + return color; } @@ -191,6 +295,10 @@ void CCSurfacesDebugViewSurfaceData(inout vec4 color, in SurfacesMaterialData su scalar = surfaceData.specularIntensity; color = vec4(scalar, scalar, scalar, 1.0); } + if (IS_DEBUG_VIEW_SINGLE_MODE(CC_SURFACES_DEBUG_VIEW_IOR)) { + scalar = surfaceData.ior - 1.0; + color = vec4(scalar, scalar, scalar, 1.0); + } } #endif diff --git a/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk b/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk index 2cf4b605080..43becca4b6e 100644 --- a/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk +++ b/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk @@ -76,18 +76,32 @@ void CCSurfacesInitializeLightingIntermediateData(inout LightingIntermediateData HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, surfaceData.worldPos); CCSurfacesLightingGetIntermediateData_PerPixel(lightingData, surfaceData.worldNormal, worldPos, vec3(0.0), vec3(0.0)); lightingData.specularParam = surfaceData.specular.a; + lightingData.ior = 1.0; } void CCSurfacesLightingCalculateIntermediateData_PerLight(inout LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData, vec3 lightDirWithDist) { CCSurfacesLightingGetIntermediateData_PerLight(lightingData, lightDirWithDist); } -// Copy material data to lighting results +// Copy material data to lighting results for base pass void CCSurfacesInitializeLightingResult(inout LightingResult lightingResult, in SurfacesMaterialData surfaceData) { lightingResult.emissive = surfaceData.emissive; } +// Init accumulated lighting results for additive pass +void CCSurfacesInitializeLightingResult(inout LightingResult lightingResult) +{ + lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0); +} + +// Accumulated lighting results for additive pass +void CCSurfacesAccumulateLightingResult(inout LightingResult lightingResultAccumulated, in LightingResult lightingResult) +{ + lightingResultAccumulated.directDiffuse += lightingResult.directDiffuse * lightingResult.shadow; + lightingResultAccumulated.directSpecular += lightingResult.directSpecular * lightingResult.shadow; +} + // Lighting #if CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED vec4 CCSurfacesDeferredOutput0(in SurfacesMaterialData surfaceData) diff --git a/editor/assets/default_file_content/animgraphvari b/editor/assets/default_file_content/animgraphvari new file mode 100644 index 00000000000..2c5c080a94d --- /dev/null +++ b/editor/assets/default_file_content/animgraphvari @@ -0,0 +1,16 @@ +[ + { + "__type__": "cc.animation.AnimationGraphVariant", + "_name": "", + "_objFlags": 0, + "_native": "", + "_graph": null, + "_clipOverrides": { + "__id__": 1 + } + }, + { + "__type__": "cc.animation.ClipOverrideMap", + "_entries": [] + } +] \ No newline at end of file diff --git a/editor/assets/default_file_content/animgraphvari.meta b/editor/assets/default_file_content/animgraphvari.meta new file mode 100644 index 00000000000..c5462ef1f14 --- /dev/null +++ b/editor/assets/default_file_content/animgraphvari.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.0.0", + "importer": "*", + "imported": true, + "uuid": "eb9a3479-6087-45cb-82bc-d72e2aa6e9ef", + "files": [ + "", + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/default_file_content/mtl b/editor/assets/default_file_content/mtl index a0b0debbb0f..a674cc2a3e3 100644 --- a/editor/assets/default_file_content/mtl +++ b/editor/assets/default_file_content/mtl @@ -4,7 +4,7 @@ "_objFlags": 0, "_native": "", "_effectAsset": { - "__uuid__": "1baf0fc9-befa-459c-8bdd-af1a450a0319" + "__uuid__": "c8f66d17-351a-48da-a12c-0212d28575c4" }, "_techIdx": 0, "_defines": [], diff --git a/editor/assets/default_file_content/scene b/editor/assets/default_file_content/scene index 2f66237e49f..5e93f306e5d 100644 --- a/editor/assets/default_file_content/scene +++ b/editor/assets/default_file_content/scene @@ -209,33 +209,33 @@ "__type__": "cc.AmbientInfo", "_skyColorHDR": { "__type__": "cc.Vec4", - "x": 0.21465, - "y": 0.34977, - "z": 0.576641, - "w": 0.520833125 + "x": 0.365754, + "y": 0.568107, + "z": 0.9080791, + "w": 0 }, "_skyIllumHDR": 20000, "_skyIllum": 20000, "_groundAlbedoHDR": { "__type__": "cc.Vec4", - "x": 0.245603, - "y": 0.246646, - "z": 0.251197, + "x": 0.455624, + "y": 0.403274, + "z": 0.370948, "w": 0 }, "_skyColorLDR": { "__type__": "cc.Vec4", - "x": 0.36244, - "y": 0.486029, - "z": 0.632565, - "w": 0.5208 + "x": 0.452588, + "y": 0.607642, + "z": 0.755699, + "w": 0 }, - "_skyIllumLDR": 0.5208, + "_skyIllumLDR": 0.8, "_groundAlbedoLDR": { "__type__": "cc.Vec4", - "x": 0.437391, - "y": 0.436011, - "z": 0.436589, + "x": 0.618555, + "y": 0.577848, + "z": 0.544564, "w": 0 } }, diff --git a/editor/assets/default_file_content/scene-2d b/editor/assets/default_file_content/scene-2d index 3b3ac017bb3..63da4dbe2b1 100644 --- a/editor/assets/default_file_content/scene-2d +++ b/editor/assets/default_file_content/scene-2d @@ -133,12 +133,12 @@ "_enabled": true, "__prefab": null, "_projection": 0, - "_priority": 1073741824, + "_priority": 0, "_fov": 45, "_fovAxis": 0, - "_orthoHeight": 393.04773561811504, + "_orthoHeight": 10, "_near": 0, - "_far": 2000, + "_far": 1000, "_color": { "__type__": "cc.Color", "r": 0, @@ -160,7 +160,7 @@ "_shutter": 7, "_iso": 0, "_screenScale": 1, - "_visibility": 41943040, + "_visibility": 1108344832, "_targetTexture": null, "_id": "63WIch3o5BEYRlXzTT0oWc" }, diff --git a/editor/assets/default_file_content/scene-quality b/editor/assets/default_file_content/scene-quality new file mode 100644 index 00000000000..604045e426e --- /dev/null +++ b/editor/assets/default_file_content/scene-quality @@ -0,0 +1,393 @@ +[ + { + "__type__": "cc.SceneAsset", + "_name": "", + "_objFlags": 0, + "_native": "", + "scene": { + "__id__": 1 + } + }, + { + "__type__": "cc.Scene", + "_name": "scene-quality", + "_objFlags": 0, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 5 + } + ], + "_active": true, + "_components": [], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "autoReleaseAssets": false, + "_globals": { + "__id__": 7 + }, + "_reflectionProbeId": 0, + "_id": "19323c5d-5d36-438a-86ee-8288c690e5b0" + }, + { + "__type__": "cc.Node", + "_name": "Main Light", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": -0.06397656665577071, + "y": -0.44608233363525845, + "z": -0.8239028751062036, + "w": -0.3436591377065261 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": -117.894, + "y": -194.909, + "z": 38.562 + }, + "_id": "c0y6F5f+pAvI805TdmxIjx" + }, + { + "__type__": "cc.DirectionalLight", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": null, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 250, + "b": 240, + "a": 255 + }, + "_useColorTemperature": false, + "_colorTemperature": 6550, + "_staticSettings": { + "__id__": 4 + }, + "_visibility": -325058561, + "_illuminanceHDR": 65000, + "_illuminance": 65000, + "_illuminanceLDR": 1.6927083333333335, + "_shadowEnabled": true, + "_shadowPcf": 2, + "_shadowBias": 0.00001, + "_shadowNormalBias": 0, + "_shadowSaturation": 1, + "_shadowDistance": 50, + "_shadowInvisibleOcclusionRange": 200, + "_csmLevel": 4, + "_csmLayerLambda": 0.75, + "_csmOptimizationMode": 2, + "_shadowFixedArea": false, + "_shadowNear": 0.1, + "_shadowFar": 10, + "_shadowOrthoSize": 5, + "_id": "597uMYCbhEtJQc0ffJlcgA" + }, + { + "__type__": "cc.StaticLightSettings", + "_baked": false, + "_editorOnly": false, + "_bakeable": true, + "_castShadow": true + }, + { + "__type__": "cc.Node", + "_name": "Main Camera", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 6 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -10, + "y": 10, + "z": 10 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": -0.27781593346944056, + "y": -0.36497167621709875, + "z": -0.11507512748638377, + "w": 0.8811195706053617 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": -35, + "y": -45, + "z": 0 + }, + "_id": "c9DMICJLFO5IeO07EPon7U" + }, + { + "__type__": "cc.Camera", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 5 + }, + "_enabled": true, + "__prefab": null, + "_projection": 1, + "_priority": 0, + "_fov": 45, + "_fovAxis": 0, + "_orthoHeight": 10, + "_near": 1, + "_far": 1000, + "_color": { + "__type__": "cc.Color", + "r": 51, + "g": 51, + "b": 51, + "a": 255 + }, + "_depth": 1, + "_stencil": 0, + "_clearFlags": 14, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_aperture": 19, + "_shutter": 7, + "_iso": 0, + "_screenScale": 1, + "_visibility": 1822425087, + "_targetTexture": null, + "_cameraType": -1, + "_trackingType": 0, + "_id": "7dWQTpwS5LrIHnc1zAPUtf" + }, + { + "__type__": "cc.SceneGlobals", + "ambient": { + "__id__": 8 + }, + "shadows": { + "__id__": 9 + }, + "_skybox": { + "__id__": 10 + }, + "fog": { + "__id__": 11 + }, + "octree": { + "__id__": 12 + }, + "lightProbeInfo": { + "__id__": 13 + } + }, + { + "__type__": "cc.AmbientInfo", + "_skyColorHDR": { + "__type__": "cc.Vec4", + "x": 0.365754, + "y": 0.568107, + "z": 0.9080791, + "w": 0 + }, + "_skyIllumHDR": 20000, + "_skyIllum": 20000, + "_groundAlbedoHDR": { + "__type__": "cc.Vec4", + "x": 0.455624, + "y": 0.403274, + "z": 0.370948, + "w": 0 + }, + "_skyColorLDR": { + "__type__": "cc.Vec4", + "x": 0.452588, + "y": 0.607642, + "z": 0.755699, + "w": 0 + }, + "_skyIllumLDR": 0.8, + "_groundAlbedoLDR": { + "__type__": "cc.Vec4", + "x": 0.618555, + "y": 0.577848, + "z": 0.544564, + "w": 0 + } + }, + { + "__type__": "cc.ShadowsInfo", + "_enabled": true, + "_type": 1, + "_normal": { + "__type__": "cc.Vec3", + "x": 0, + "y": 1, + "z": 0 + }, + "_distance": 0, + "_shadowColor": { + "__type__": "cc.Color", + "r": 76, + "g": 76, + "b": 76, + "a": 255 + }, + "_maxReceived": 4, + "_size": { + "__type__": "cc.Vec2", + "x": 2048, + "y": 2048 + } + }, + { + "__type__": "cc.SkyboxInfo", + "_envLightingType": 1, + "_envmapHDR": { + "__uuid__": "d032ac98-05e1-4090-88bb-eb640dcb5fc1@b47c0", + "__expectedType__": "cc.TextureCube" + }, + "_envmap": { + "__uuid__": "d032ac98-05e1-4090-88bb-eb640dcb5fc1@b47c0", + "__expectedType__": "cc.TextureCube" + }, + "_envmapLDR": { + "__uuid__": "6f01cf7f-81bf-4a7e-bd5d-0afc19696480@b47c0", + "__expectedType__": "cc.TextureCube" + }, + "_diffuseMapHDR": null, + "_diffuseMapLDR": null, + "_enabled": true, + "_useHDR": true, + "_editableMaterial": null, + "_reflectionHDR": null, + "_reflectionLDR": null, + "_rotationAngle": 0 + }, + { + "__type__": "cc.FogInfo", + "_type": 0, + "_fogColor": { + "__type__": "cc.Color", + "r": 200, + "g": 200, + "b": 200, + "a": 255 + }, + "_enabled": false, + "_fogDensity": 0.3, + "_fogStart": 0.5, + "_fogEnd": 300, + "_fogAtten": 5, + "_fogTop": 1.5, + "_fogRange": 1.2, + "_accurate": false + }, + { + "__type__": "cc.OctreeInfo", + "_enabled": false, + "_minPos": { + "__type__": "cc.Vec3", + "x": -1024, + "y": -1024, + "z": -1024 + }, + "_maxPos": { + "__type__": "cc.Vec3", + "x": 1024, + "y": 1024, + "z": 1024 + }, + "_depth": 8 + }, + { + "__type__": "cc.LightProbeInfo", + "_enabled": false, + "_giScale": 1, + "_giSamples": 1024, + "_bounces": 2, + "_reduceRinging": 0, + "_showProbe": true, + "_showWireframe": true, + "_showConvex": false, + "_data": null, + "_lightProbeGroups": [] + } + ] diff --git a/editor/assets/default_file_content/scene-quality.meta b/editor/assets/default_file_content/scene-quality.meta new file mode 100644 index 00000000000..cc1028935a9 --- /dev/null +++ b/editor/assets/default_file_content/scene-quality.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.0.0", + "importer": "*", + "imported": true, + "uuid": "1d5e3139-1826-4b4a-8c4c-2e7b6874a474", + "files": [ + "", + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/default_materials/default-billboard-material.mtl.meta b/editor/assets/default_materials/default-billboard-material.mtl.meta index 2f9e10255c4..97c632b971a 100644 --- a/editor/assets/default_materials/default-billboard-material.mtl.meta +++ b/editor/assets/default_materials/default-billboard-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "78e0584a-4343-4727-8f37-e14e65c2a2db", diff --git a/editor/assets/default_materials/default-clear-stencil.mtl.meta b/editor/assets/default_materials/default-clear-stencil.mtl.meta index 69df2017cbe..59957ce2d90 100644 --- a/editor/assets/default_materials/default-clear-stencil.mtl.meta +++ b/editor/assets/default_materials/default-clear-stencil.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "8bbdbcdd-5cd4-4100-b6d5-b7c9625b6107", diff --git a/editor/assets/default_materials/default-material-transparent.mtl b/editor/assets/default_materials/default-material-transparent.mtl index 5a9b7fac6d9..4725bb86961 100644 --- a/editor/assets/default_materials/default-material-transparent.mtl +++ b/editor/assets/default_materials/default-material-transparent.mtl @@ -49,7 +49,9 @@ "g": 255, "b": 255, "a": 99 - } + }, + "roughness": 0.8, + "metallic": 0.6 }, {}, {} diff --git a/editor/assets/default_materials/default-material-transparent.mtl.meta b/editor/assets/default_materials/default-material-transparent.mtl.meta index 2064bf7a4b5..3004bebb7e1 100644 --- a/editor/assets/default_materials/default-material-transparent.mtl.meta +++ b/editor/assets/default_materials/default-material-transparent.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "c31a901b-671b-4c3d-9246-f9a6e5f14b90", diff --git a/editor/assets/default_materials/default-material.mtl b/editor/assets/default_materials/default-material.mtl index e9937ac8a2e..ca9628324ad 100644 --- a/editor/assets/default_materials/default-material.mtl +++ b/editor/assets/default_materials/default-material.mtl @@ -11,6 +11,9 @@ {} ], "_props": [ - {} + { + "roughness": 0.8, + "metallic": 0.6 + } ] } \ No newline at end of file diff --git a/editor/assets/default_materials/default-material.mtl.meta b/editor/assets/default_materials/default-material.mtl.meta index b3e86cf9938..83e5e18ca35 100644 --- a/editor/assets/default_materials/default-material.mtl.meta +++ b/editor/assets/default_materials/default-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "d3c7820c-2a98-4429-8bc7-b8453bc9ac41", diff --git a/editor/assets/default_materials/default-particle-gpu-material.mtl.meta b/editor/assets/default_materials/default-particle-gpu-material.mtl.meta index c273d265ad2..3101eed10c6 100644 --- a/editor/assets/default_materials/default-particle-gpu-material.mtl.meta +++ b/editor/assets/default_materials/default-particle-gpu-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "14da1725-c4c2-42b4-ab08-ee0aeb6898b3", diff --git a/editor/assets/default_materials/default-particle-material.mtl.meta b/editor/assets/default_materials/default-particle-material.mtl.meta index 3bb67cd5704..27adeff5d1f 100644 --- a/editor/assets/default_materials/default-particle-material.mtl.meta +++ b/editor/assets/default_materials/default-particle-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "c0143906-9aed-447e-9436-2ae8512d1b6e", diff --git a/editor/assets/default_materials/default-spine-material.mtl.meta b/editor/assets/default_materials/default-spine-material.mtl.meta index e38d1569173..239ea622378 100644 --- a/editor/assets/default_materials/default-spine-material.mtl.meta +++ b/editor/assets/default_materials/default-spine-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "b5d6115f-0370-4d7c-aad3-c194cc71cf98", diff --git a/editor/assets/default_materials/default-sprite-renderer-material.mtl.meta b/editor/assets/default_materials/default-sprite-renderer-material.mtl.meta index 02351b73e4e..36d4b1b9d7d 100644 --- a/editor/assets/default_materials/default-sprite-renderer-material.mtl.meta +++ b/editor/assets/default_materials/default-sprite-renderer-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "ade8a15a-dcca-4b3c-84c6-f6476ac875bb", diff --git a/editor/assets/default_materials/default-trail-material.mtl.meta b/editor/assets/default_materials/default-trail-material.mtl.meta index a9c72ed1ea0..ca98959efa5 100644 --- a/editor/assets/default_materials/default-trail-material.mtl.meta +++ b/editor/assets/default_materials/default-trail-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "081cab31-dccd-428e-8652-f2404cc81c47", diff --git a/editor/assets/default_materials/missing-effect-material.mtl.meta b/editor/assets/default_materials/missing-effect-material.mtl.meta index 81b59406511..0d6c0175c70 100644 --- a/editor/assets/default_materials/missing-effect-material.mtl.meta +++ b/editor/assets/default_materials/missing-effect-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "bcd64cc6-2dd9-43f6-abbe-66318d332032", diff --git a/editor/assets/default_materials/missing-material.mtl.meta b/editor/assets/default_materials/missing-material.mtl.meta index 7ce8228abef..c0eca933e1d 100644 --- a/editor/assets/default_materials/missing-material.mtl.meta +++ b/editor/assets/default_materials/missing-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "d930590d-bb92-4cc8-8bd1-23cd027f9edf", diff --git a/editor/assets/default_materials/particle-add.mtl.meta b/editor/assets/default_materials/particle-add.mtl.meta index f1c732cb5c6..f39079d5941 100644 --- a/editor/assets/default_materials/particle-add.mtl.meta +++ b/editor/assets/default_materials/particle-add.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "ea7478b0-408d-4052-b703-f0d2355e095f", diff --git a/editor/assets/default_materials/standard-material.mtl b/editor/assets/default_materials/standard-material.mtl index 75533e95d7e..76908ad4a9b 100644 --- a/editor/assets/default_materials/standard-material.mtl +++ b/editor/assets/default_materials/standard-material.mtl @@ -9,6 +9,9 @@ "_techIdx": 0, "_defines": [], "_props": [ - {} + { + "roughness": 0.8, + "metallic": 0.6 + } ] } \ No newline at end of file diff --git a/editor/assets/default_materials/standard-material.mtl.meta b/editor/assets/default_materials/standard-material.mtl.meta index 3d3c11b1b62..efa764a77fb 100644 --- a/editor/assets/default_materials/standard-material.mtl.meta +++ b/editor/assets/default_materials/standard-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "620b6bf3-0369-4560-837f-2a2c00b73c26", diff --git a/editor/assets/default_materials/ui-alpha-test-material.mtl.meta b/editor/assets/default_materials/ui-alpha-test-material.mtl.meta index 04831cad104..9668081cb8c 100644 --- a/editor/assets/default_materials/ui-alpha-test-material.mtl.meta +++ b/editor/assets/default_materials/ui-alpha-test-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "50f4348b-c883-4e2f-8f11-ce233b859fa1", diff --git a/editor/assets/default_materials/ui-base-material.mtl.meta b/editor/assets/default_materials/ui-base-material.mtl.meta index baa0914269f..3868077a162 100644 --- a/editor/assets/default_materials/ui-base-material.mtl.meta +++ b/editor/assets/default_materials/ui-base-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "e9aa9a3e-5b2b-4ac7-a2c7-073de2b2b24f", diff --git a/editor/assets/default_materials/ui-graphics-material.mtl.meta b/editor/assets/default_materials/ui-graphics-material.mtl.meta index b80ffb29eb6..e675d6d4285 100644 --- a/editor/assets/default_materials/ui-graphics-material.mtl.meta +++ b/editor/assets/default_materials/ui-graphics-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "f0416e68-0200-4b77-a926-4f9d16e494da", diff --git a/editor/assets/default_materials/ui-sprite-alpha-sep-material.mtl.meta b/editor/assets/default_materials/ui-sprite-alpha-sep-material.mtl.meta index 7f8a21ff158..3daa36ec41a 100644 --- a/editor/assets/default_materials/ui-sprite-alpha-sep-material.mtl.meta +++ b/editor/assets/default_materials/ui-sprite-alpha-sep-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "f92806d7-1768-443f-afe8-12bcde84d0f0", diff --git a/editor/assets/default_materials/ui-sprite-gray-alpha-sep-material.mtl.meta b/editor/assets/default_materials/ui-sprite-gray-alpha-sep-material.mtl.meta index f72090c94cd..bd23e805167 100644 --- a/editor/assets/default_materials/ui-sprite-gray-alpha-sep-material.mtl.meta +++ b/editor/assets/default_materials/ui-sprite-gray-alpha-sep-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "dd3a144d-ab7f-41f0-82b8-2e43a090d496", diff --git a/editor/assets/default_materials/ui-sprite-gray-material.mtl.meta b/editor/assets/default_materials/ui-sprite-gray-material.mtl.meta index 2b7ad486e6e..27b4f4eaf2b 100644 --- a/editor/assets/default_materials/ui-sprite-gray-material.mtl.meta +++ b/editor/assets/default_materials/ui-sprite-gray-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "efe8e2a3-eace-427b-b4f1-cb8a937ec77d", diff --git a/editor/assets/default_materials/ui-sprite-material.mtl.meta b/editor/assets/default_materials/ui-sprite-material.mtl.meta index b08a8b2e92e..bbcc1cf1853 100644 --- a/editor/assets/default_materials/ui-sprite-material.mtl.meta +++ b/editor/assets/default_materials/ui-sprite-material.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "fda095cb-831d-4601-ad94-846013963de8", diff --git a/editor/assets/default_prefab/2d/Camera.prefab b/editor/assets/default_prefab/2d/Camera.prefab index 19bdc3a8a19..c8f6141b384 100644 --- a/editor/assets/default_prefab/2d/Camera.prefab +++ b/editor/assets/default_prefab/2d/Camera.prefab @@ -75,9 +75,9 @@ "_far": 1000, "_color": { "__type__": "cc.Color", - "r": 51, - "g": 76, - "b": 120, + "r": 0, + "g": 0, + "b": 0, "a": 255 }, "_depth": 1, diff --git a/editor/assets/default_prefab/2d/Camera.prefab.meta b/editor/assets/default_prefab/2d/Camera.prefab.meta index 0f464abf21e..ee4929bb098 100644 --- a/editor/assets/default_prefab/2d/Camera.prefab.meta +++ b/editor/assets/default_prefab/2d/Camera.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "3487d118-0158-4983-93fe-c3822790e7c5", diff --git a/editor/assets/default_prefab/2d/ui.meta b/editor/assets/default_prefab/2d/ui.meta new file mode 100644 index 00000000000..4a8f95398ac --- /dev/null +++ b/editor/assets/default_prefab/2d/ui.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "f81bb320-88da-4db8-b210-75e4d7544f3e", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/editor/assets/default_prefab/2d/ui/Canvas.prefab b/editor/assets/default_prefab/2d/ui/Canvas.prefab new file mode 100644 index 00000000000..5098aea4804 --- /dev/null +++ b/editor/assets/default_prefab/2d/ui/Canvas.prefab @@ -0,0 +1,245 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "Canvas", + "_objFlags": 0, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "asyncLoadAssets": false, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "Canvas", + "_objFlags": 0, + "_parent": null, + "_children": [ + { + "__id__": 2 + } + ], + "_active": true, + "_components": [ + { + "__id__": 4 + }, + { + "__id__": 6 + }, + { + "__id__": 8 + } + ], + "_prefab": { + "__id__": 10 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 480, + "y": 320, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Camera", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 1000 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Camera", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": null, + "_projection": 0, + "_priority": 0, + "_fov": 45, + "_fovAxis": 0, + "_orthoHeight": 10, + "_near": 0, + "_far": 1000, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_depth": 1, + "_stencil": 0, + "_clearFlags": 6, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_aperture": 19, + "_shutter": 7, + "_iso": 0, + "_screenScale": 1, + "_visibility": 1108344832, + "_targetTexture": null, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 5 + }, + "_priority": 0, + "_contentSize": { + "__type__": "cc.Size", + "width": 960, + "height": 640 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "0dngp/9gNO34wUQjZfN/CX" + }, + { + "__type__": "cc.Canvas", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 7 + }, + "_cameraComponent": { + "__id__": 3 + }, + "_alignCanvasWithScreen": true, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3f2oTdCepERZdpmIfLsrhd" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 9 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e8a+bU/8dPDbbJguUzLdoF" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__uuid__": "f773db21-62b8-4540-956a-29bacf5ddbf5" + }, + "fileId": "5f6AJl30pDQId35UqIfQJ/" + } +] \ No newline at end of file diff --git a/editor/assets/default_prefab/2d/ui/Canvas.prefab.meta b/editor/assets/default_prefab/2d/ui/Canvas.prefab.meta new file mode 100644 index 00000000000..7d5aae062b8 --- /dev/null +++ b/editor/assets/default_prefab/2d/ui/Canvas.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.43", + "importer": "prefab", + "imported": true, + "uuid": "4c33600e-9ca9-483b-b734-946008261697", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "Canvas" + } +} diff --git a/editor/assets/default_prefab/3d/Capsule.prefab b/editor/assets/default_prefab/3d/Capsule.prefab index 92d815dbe28..7bc7aef6c6c 100644 --- a/editor/assets/default_prefab/3d/Capsule.prefab +++ b/editor/assets/default_prefab/3d/Capsule.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@801ec" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Capsule.prefab.meta b/editor/assets/default_prefab/3d/Capsule.prefab.meta index 9bef03cba5f..6f0f1bbda9e 100644 --- a/editor/assets/default_prefab/3d/Capsule.prefab.meta +++ b/editor/assets/default_prefab/3d/Capsule.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "73ce1f7f-d1f4-4942-ad93-66ca3b3041ab", diff --git a/editor/assets/default_prefab/3d/Cone.prefab b/editor/assets/default_prefab/3d/Cone.prefab index f32877f4e23..5c7faa37381 100644 --- a/editor/assets/default_prefab/3d/Cone.prefab +++ b/editor/assets/default_prefab/3d/Cone.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@38fd2" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Cone.prefab.meta b/editor/assets/default_prefab/3d/Cone.prefab.meta index 11140900cf1..fbe3dd42a96 100644 --- a/editor/assets/default_prefab/3d/Cone.prefab.meta +++ b/editor/assets/default_prefab/3d/Cone.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "6350d660-e888-4acf-a552-f3b719ae9110", diff --git a/editor/assets/default_prefab/3d/Cube.prefab b/editor/assets/default_prefab/3d/Cube.prefab index 8cfafe37dc0..261c5516e89 100644 --- a/editor/assets/default_prefab/3d/Cube.prefab +++ b/editor/assets/default_prefab/3d/Cube.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@a804a" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Cube.prefab.meta b/editor/assets/default_prefab/3d/Cube.prefab.meta index 2d427d2b95e..871c9f0d144 100644 --- a/editor/assets/default_prefab/3d/Cube.prefab.meta +++ b/editor/assets/default_prefab/3d/Cube.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "30da77a1-f02d-4ede-aa56-403452ee7fde", diff --git a/editor/assets/default_prefab/3d/Cylinder.prefab b/editor/assets/default_prefab/3d/Cylinder.prefab index 09c69323e6d..95e5deb511b 100644 --- a/editor/assets/default_prefab/3d/Cylinder.prefab +++ b/editor/assets/default_prefab/3d/Cylinder.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@8abdc" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Cylinder.prefab.meta b/editor/assets/default_prefab/3d/Cylinder.prefab.meta index 2d67ac60750..32a4fe0a7ae 100644 --- a/editor/assets/default_prefab/3d/Cylinder.prefab.meta +++ b/editor/assets/default_prefab/3d/Cylinder.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "ab3e16f9-671e-48a7-90b7-d0884d9cbb85", diff --git a/editor/assets/default_prefab/3d/Plane.prefab b/editor/assets/default_prefab/3d/Plane.prefab index b7ce0dd2d34..c1b44541659 100644 --- a/editor/assets/default_prefab/3d/Plane.prefab +++ b/editor/assets/default_prefab/3d/Plane.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@2e76e" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Plane.prefab.meta b/editor/assets/default_prefab/3d/Plane.prefab.meta index 7d4d2e262d1..6027b7ab8f1 100644 --- a/editor/assets/default_prefab/3d/Plane.prefab.meta +++ b/editor/assets/default_prefab/3d/Plane.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "40563723-f8fc-4216-99ea-a81636435c10", diff --git a/editor/assets/default_prefab/3d/Quad.prefab b/editor/assets/default_prefab/3d/Quad.prefab index 83a6831b00a..18bc650da28 100644 --- a/editor/assets/default_prefab/3d/Quad.prefab +++ b/editor/assets/default_prefab/3d/Quad.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@fc873" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Quad.prefab.meta b/editor/assets/default_prefab/3d/Quad.prefab.meta index 85ec1471d9a..a81ac6603cb 100644 --- a/editor/assets/default_prefab/3d/Quad.prefab.meta +++ b/editor/assets/default_prefab/3d/Quad.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "34a07346-9f62-4a84-90ae-cb83f7a426c1", diff --git a/editor/assets/default_prefab/3d/Sphere.prefab b/editor/assets/default_prefab/3d/Sphere.prefab index 1dce4bfef3b..1ae12daae66 100644 --- a/editor/assets/default_prefab/3d/Sphere.prefab +++ b/editor/assets/default_prefab/3d/Sphere.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@17020" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Sphere.prefab.meta b/editor/assets/default_prefab/3d/Sphere.prefab.meta index 7c4a1d4e9a2..0bfaf961ba9 100644 --- a/editor/assets/default_prefab/3d/Sphere.prefab.meta +++ b/editor/assets/default_prefab/3d/Sphere.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "655c9519-1a37-472b-bae6-29fefac0b550", diff --git a/editor/assets/default_prefab/3d/Torus.prefab b/editor/assets/default_prefab/3d/Torus.prefab index 9e4f480e14f..509b9eba8f6 100644 --- a/editor/assets/default_prefab/3d/Torus.prefab +++ b/editor/assets/default_prefab/3d/Torus.prefab @@ -71,8 +71,6 @@ "_mesh": { "__uuid__": "1263d74c-8167-4928-91a6-4e2672411f47@40ece" }, - "_shadowCastingMode": 0, - "_receiveShadows": false, "_id": "", "__prefab": { "__id__": 3 diff --git a/editor/assets/default_prefab/3d/Torus.prefab.meta b/editor/assets/default_prefab/3d/Torus.prefab.meta index 7481a2b0a5d..18e0e15ea85 100644 --- a/editor/assets/default_prefab/3d/Torus.prefab.meta +++ b/editor/assets/default_prefab/3d/Torus.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "d47f5d5e-c931-4ff4-987b-cc818a728b82", diff --git a/editor/assets/default_prefab/Camera.prefab.meta b/editor/assets/default_prefab/Camera.prefab.meta index 7cf2aca3be9..c4b4549afd6 100644 --- a/editor/assets/default_prefab/Camera.prefab.meta +++ b/editor/assets/default_prefab/Camera.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "bb0a6472-cd67-4afb-a031-94fca8f4cc92", diff --git a/editor/assets/default_prefab/Terrain.prefab.meta b/editor/assets/default_prefab/Terrain.prefab.meta index bb7b0c1f7c8..70906c5f24c 100644 --- a/editor/assets/default_prefab/Terrain.prefab.meta +++ b/editor/assets/default_prefab/Terrain.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "90e8b0d4-12dc-412d-9156-ea1fdb18c15b", diff --git a/editor/assets/default_prefab/effects/Particle System.prefab.meta b/editor/assets/default_prefab/effects/Particle System.prefab.meta index 3293783829a..e037aa29efb 100644 --- a/editor/assets/default_prefab/effects/Particle System.prefab.meta +++ b/editor/assets/default_prefab/effects/Particle System.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "f09a0597-10e6-49e5-8759-a148b5e85395", diff --git a/editor/assets/default_prefab/light/Directional Light.prefab.meta b/editor/assets/default_prefab/light/Directional Light.prefab.meta index 6b9b01a1c79..75380f558d2 100644 --- a/editor/assets/default_prefab/light/Directional Light.prefab.meta +++ b/editor/assets/default_prefab/light/Directional Light.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "a0e9756d-9128-4f49-8097-e041c8b733b8", diff --git a/editor/assets/default_prefab/light/Light Probe Group.prefab b/editor/assets/default_prefab/light/Light Probe Group.prefab new file mode 100644 index 00000000000..822cbb900e2 --- /dev/null +++ b/editor/assets/default_prefab/light/Light Probe Group.prefab @@ -0,0 +1,103 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "Light Probe Group", + "_objFlags": 0, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false, + "asyncLoadAssets": false + }, + { + "__type__": "cc.Node", + "_name": "Light Probe Group", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 2 + } + ], + "_prefab": { + "__id__": 4 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.LightProbeGroup", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 3 + }, + "_probes": [], + "_method": 0, + "_minPos": { + "__type__": "cc.Vec3", + "x": -5, + "y": -5, + "z": -5 + }, + "_maxPos": { + "__type__": "cc.Vec3", + "x": 5, + "y": 5, + "z": 5 + }, + "_nProbesX": 3, + "_nProbesY": 3, + "_nProbesZ": 3, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "17bqOQpnFHppFmHaK/y+jI" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "71lH762IZI7qrxgIM9ikao" + } +] \ No newline at end of file diff --git a/editor/assets/default_prefab/light/Light Probe Group.prefab.meta b/editor/assets/default_prefab/light/Light Probe Group.prefab.meta new file mode 100644 index 00000000000..c41ca31b2c9 --- /dev/null +++ b/editor/assets/default_prefab/light/Light Probe Group.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.43", + "importer": "prefab", + "imported": true, + "uuid": "50dfda40-7c45-4868-a876-2fe2a4c782f4", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "Light Probe Group" + } +} diff --git a/editor/assets/default_prefab/light/Point Light.prefab b/editor/assets/default_prefab/light/Point Light.prefab new file mode 100644 index 00000000000..cb555e0070c --- /dev/null +++ b/editor/assets/default_prefab/light/Point Light.prefab @@ -0,0 +1,97 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "Point Light", + "_objFlags": 0, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "asyncLoadAssets": false, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "Point Light", + "_objFlags": 0, + "_parent": null, + "_children": [], + "_active": true, + "_level": 1, + "_components": [ + { + "__id__": 2 + } + ], + "_prefab": { + "__id__": 4 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.PointLight", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_useColorTemperature": false, + "_colorTemperature": 6550, + "_intensity": 1700, + "_size": 0.15, + "_range": 2, + "_id": "", + "__prefab": { + "__id__": 3 + } + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "5b6a86+adN0IKor4mk41YN" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "59eikBZx5K9aR06hUuVC37" + } +] diff --git a/editor/assets/default_prefab/light/Point Light.prefab.meta b/editor/assets/default_prefab/light/Point Light.prefab.meta new file mode 100644 index 00000000000..9228573f806 --- /dev/null +++ b/editor/assets/default_prefab/light/Point Light.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.43", + "importer": "prefab", + "imported": true, + "uuid": "03029371-ee64-4f14-820a-d495ad7cdc29", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "Point Light" + } +} diff --git a/editor/assets/default_prefab/light/Ranged Directional Light.prefab b/editor/assets/default_prefab/light/Ranged Directional Light.prefab new file mode 100644 index 00000000000..73afa3b15ff --- /dev/null +++ b/editor/assets/default_prefab/light/Ranged Directional Light.prefab @@ -0,0 +1,95 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "Ranged Directional Light", + "_objFlags": 0, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "asyncLoadAssets": false, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "Ranged Directional Light", + "_objFlags": 0, + "_parent": null, + "_children": [], + "_active": true, + "_level": 1, + "_components": [ + { + "__id__": 2 + } + ], + "_prefab": { + "__id__": 4 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.RangedDirectionalLight", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_useColorTemperature": false, + "_colorTemperature": 6550, + "_intensity": 65000, + "_id": "", + "__prefab": { + "__id__": 3 + } + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1fmNgOipdOha90C8NNkXEN" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "aeyMch0nJBEbV/mk9CXYkW" + } +] diff --git a/editor/assets/default_prefab/light/Ranged Directional Light.prefab.meta b/editor/assets/default_prefab/light/Ranged Directional Light.prefab.meta new file mode 100644 index 00000000000..2355e5c5611 --- /dev/null +++ b/editor/assets/default_prefab/light/Ranged Directional Light.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.43", + "importer": "prefab", + "imported": true, + "uuid": "df72d0f6-49d3-452a-b082-8b23d38b33af", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "Ranged Directional Light" + } +} diff --git a/editor/assets/default_prefab/light/Reflection Probe.prefab b/editor/assets/default_prefab/light/Reflection Probe.prefab new file mode 100644 index 00000000000..f8f47c404aa --- /dev/null +++ b/editor/assets/default_prefab/light/Reflection Probe.prefab @@ -0,0 +1,106 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "Reflection Probe", + "_objFlags": 0, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false, + "asyncLoadAssets": false + }, + { + "__type__": "cc.Node", + "_name": "Reflection Probe", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 2 + } + ], + "_prefab": { + "__id__": 4 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.ReflectionProbe", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 3 + }, + "_resolution": 256, + "_clearFlag": 14, + "_backgroundColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_visibility": 1083179008, + "_probeType": 0, + "_cubemap": null, + "_size": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_sourceCamera": null, + "_probeId": -1, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "19F7YKQTZB17IO5txxISws" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "e0JfJQZohBa5oXEZWTaEi2" + } +] \ No newline at end of file diff --git a/editor/assets/default_prefab/light/Reflection Probe.prefab.meta b/editor/assets/default_prefab/light/Reflection Probe.prefab.meta new file mode 100644 index 00000000000..11840c47e45 --- /dev/null +++ b/editor/assets/default_prefab/light/Reflection Probe.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.43", + "importer": "prefab", + "imported": true, + "uuid": "d8b49b64-cfba-4cfa-be53-1e469547b28b", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "Reflection Probe" + } +} diff --git a/editor/assets/default_prefab/light/Sphere Light.prefab b/editor/assets/default_prefab/light/Sphere Light.prefab index 8b2f8bc5bf6..a42c4ef0d30 100644 --- a/editor/assets/default_prefab/light/Sphere Light.prefab +++ b/editor/assets/default_prefab/light/Sphere Light.prefab @@ -73,7 +73,6 @@ "_useColorTemperature": false, "_colorTemperature": 6550, "_intensity": 1700, - "_size": 0.15, "_range": 2, "_id": "", "__prefab": { diff --git a/editor/assets/default_prefab/light/Sphere Light.prefab.meta b/editor/assets/default_prefab/light/Sphere Light.prefab.meta index 611742c5d21..c1e2fc257a6 100644 --- a/editor/assets/default_prefab/light/Sphere Light.prefab.meta +++ b/editor/assets/default_prefab/light/Sphere Light.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "4182ee46-ffa0-4de2-b66b-c93cc6c7e9b8", diff --git a/editor/assets/default_prefab/light/Spot Light.prefab.meta b/editor/assets/default_prefab/light/Spot Light.prefab.meta index 8b3c0693829..83d0f68f7e8 100644 --- a/editor/assets/default_prefab/light/Spot Light.prefab.meta +++ b/editor/assets/default_prefab/light/Spot Light.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "7a49aa24-bd7a-40a8-b31a-b2a9da85abcd", diff --git a/editor/assets/default_prefab/ui/Button.prefab.meta b/editor/assets/default_prefab/ui/Button.prefab.meta index 2c32c912f5f..eaedac7d2d2 100644 --- a/editor/assets/default_prefab/ui/Button.prefab.meta +++ b/editor/assets/default_prefab/ui/Button.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "90bdd2a9-2838-4888-b66c-e94c8b7a5169", diff --git a/editor/assets/default_prefab/ui/Canvas.prefab.meta b/editor/assets/default_prefab/ui/Canvas.prefab.meta index b54eb40b6a5..59c12a8383b 100644 --- a/editor/assets/default_prefab/ui/Canvas.prefab.meta +++ b/editor/assets/default_prefab/ui/Canvas.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "f773db21-62b8-4540-956a-29bacf5ddbf5", diff --git a/editor/assets/default_prefab/ui/EditBox.prefab.meta b/editor/assets/default_prefab/ui/EditBox.prefab.meta index 6f1ea23f0fe..b90498533a3 100644 --- a/editor/assets/default_prefab/ui/EditBox.prefab.meta +++ b/editor/assets/default_prefab/ui/EditBox.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "05e79121-8675-4551-9ad7-1b901a4025db", diff --git a/editor/assets/default_prefab/ui/Graphics.prefab.meta b/editor/assets/default_prefab/ui/Graphics.prefab.meta index f47e3f55843..2bf58cfb456 100644 --- a/editor/assets/default_prefab/ui/Graphics.prefab.meta +++ b/editor/assets/default_prefab/ui/Graphics.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "c96e159e-43ea-4a16-8279-05bc39119d1a", diff --git a/editor/assets/default_prefab/ui/Label.prefab.meta b/editor/assets/default_prefab/ui/Label.prefab.meta index c2e581395ab..680f3ca02f7 100644 --- a/editor/assets/default_prefab/ui/Label.prefab.meta +++ b/editor/assets/default_prefab/ui/Label.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "36008810-7ad3-47c0-8112-e30aee089e45", diff --git a/editor/assets/default_prefab/ui/Layout.prefab.meta b/editor/assets/default_prefab/ui/Layout.prefab.meta index bf9fec85ea0..eb3e329a4db 100644 --- a/editor/assets/default_prefab/ui/Layout.prefab.meta +++ b/editor/assets/default_prefab/ui/Layout.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "a9ef7dfc-ea8b-4cf8-918e-36da948c4de0", diff --git a/editor/assets/default_prefab/ui/Mask.prefab.meta b/editor/assets/default_prefab/ui/Mask.prefab.meta index ff5366e4c11..a3a5eebb181 100644 --- a/editor/assets/default_prefab/ui/Mask.prefab.meta +++ b/editor/assets/default_prefab/ui/Mask.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "7fa63aed-f3e2-46a5-8a7c-c1a1adf6cea6", diff --git a/editor/assets/default_prefab/ui/ParticleSystem2D.prefab b/editor/assets/default_prefab/ui/ParticleSystem2D.prefab index cfa9cb68c2b..673afadd40f 100644 --- a/editor/assets/default_prefab/ui/ParticleSystem2D.prefab +++ b/editor/assets/default_prefab/ui/ParticleSystem2D.prefab @@ -155,7 +155,7 @@ "autoRemoveOnFinish": false, "_custom": false, "_file": { - "__uuid__": "86f25d5c-9de5-454f-a5f9-ee16603e6701" + "__uuid__": "e17b4526-57a2-48d3-acc9-cf09f30aa138" }, "_spriteFrame": { "__uuid__": "24c419ea-63a8-4ea1-a9d0-7fc469489bbc@f9941" diff --git a/editor/assets/default_prefab/ui/ParticleSystem2D.prefab.meta b/editor/assets/default_prefab/ui/ParticleSystem2D.prefab.meta index 9e459bc5ed8..96dd0e1130e 100644 --- a/editor/assets/default_prefab/ui/ParticleSystem2D.prefab.meta +++ b/editor/assets/default_prefab/ui/ParticleSystem2D.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "f396261e-3e06-41ec-bdd6-9a8b6d99026f", diff --git a/editor/assets/default_prefab/ui/ProgressBar.prefab.meta b/editor/assets/default_prefab/ui/ProgressBar.prefab.meta index b9720cb6da7..b23f6fc7049 100644 --- a/editor/assets/default_prefab/ui/ProgressBar.prefab.meta +++ b/editor/assets/default_prefab/ui/ProgressBar.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "0d9353c4-6fb9-49bb-bc62-77f1750078c2", diff --git a/editor/assets/default_prefab/ui/RichText.prefab.meta b/editor/assets/default_prefab/ui/RichText.prefab.meta index 46eef95adb1..0e6c16a13b1 100644 --- a/editor/assets/default_prefab/ui/RichText.prefab.meta +++ b/editor/assets/default_prefab/ui/RichText.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "fc6bfcfa-8086-4326-809b-0ba1226bac7d", diff --git a/editor/assets/default_prefab/ui/ScrollView.prefab.meta b/editor/assets/default_prefab/ui/ScrollView.prefab.meta index 34fe466c901..d5dc710ba75 100644 --- a/editor/assets/default_prefab/ui/ScrollView.prefab.meta +++ b/editor/assets/default_prefab/ui/ScrollView.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "c1baa707-78d6-4b89-8d5d-0b7fdf0c39bc", diff --git a/editor/assets/default_prefab/ui/Slider.prefab.meta b/editor/assets/default_prefab/ui/Slider.prefab.meta index 15b96e18ab2..6e815ec0742 100644 --- a/editor/assets/default_prefab/ui/Slider.prefab.meta +++ b/editor/assets/default_prefab/ui/Slider.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "2bd7e5b6-cd8c-41a1-8136-ddb8efbf6326", diff --git a/editor/assets/default_prefab/ui/Sprite.prefab.meta b/editor/assets/default_prefab/ui/Sprite.prefab.meta index 6cdad31d566..52607136b9a 100644 --- a/editor/assets/default_prefab/ui/Sprite.prefab.meta +++ b/editor/assets/default_prefab/ui/Sprite.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "9db8cd0b-cbe4-42e7-96a9-a239620c0a9d", diff --git a/editor/assets/default_prefab/ui/SpriteRenderer.prefab.meta b/editor/assets/default_prefab/ui/SpriteRenderer.prefab.meta index 27ae8ce476d..f77888a3751 100644 --- a/editor/assets/default_prefab/ui/SpriteRenderer.prefab.meta +++ b/editor/assets/default_prefab/ui/SpriteRenderer.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "279ed042-5a65-4efe-9afb-2fc23c61e15a", diff --git a/editor/assets/default_prefab/ui/SpriteSplash.prefab.meta b/editor/assets/default_prefab/ui/SpriteSplash.prefab.meta index 0578f6665ee..316ebde3d5d 100644 --- a/editor/assets/default_prefab/ui/SpriteSplash.prefab.meta +++ b/editor/assets/default_prefab/ui/SpriteSplash.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "e5f21aad-3a69-4011-ac62-b74352ac025e", diff --git a/editor/assets/default_prefab/ui/TiledMap.prefab.meta b/editor/assets/default_prefab/ui/TiledMap.prefab.meta index f50f5502ae2..e8e6edf3224 100644 --- a/editor/assets/default_prefab/ui/TiledMap.prefab.meta +++ b/editor/assets/default_prefab/ui/TiledMap.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "3139fa4f-8c42-4ce6-98be-15e848d9734c", diff --git a/editor/assets/default_prefab/ui/Toggle.prefab.meta b/editor/assets/default_prefab/ui/Toggle.prefab.meta index be08fd508f3..0f66dc60a1f 100644 --- a/editor/assets/default_prefab/ui/Toggle.prefab.meta +++ b/editor/assets/default_prefab/ui/Toggle.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "0e89afe7-56de-4f99-96a1-cba8a75bedd2", diff --git a/editor/assets/default_prefab/ui/ToggleContainer.prefab.meta b/editor/assets/default_prefab/ui/ToggleContainer.prefab.meta index 305e3456737..d29cda49fd8 100644 --- a/editor/assets/default_prefab/ui/ToggleContainer.prefab.meta +++ b/editor/assets/default_prefab/ui/ToggleContainer.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "2af73429-41d1-4346-9062-7798e42945dd", diff --git a/editor/assets/default_prefab/ui/VideoPlayer.prefab.meta b/editor/assets/default_prefab/ui/VideoPlayer.prefab.meta index e1fcf13ddeb..b9b19356dbb 100644 --- a/editor/assets/default_prefab/ui/VideoPlayer.prefab.meta +++ b/editor/assets/default_prefab/ui/VideoPlayer.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "7e089eaf-fa97-40d7-8a20-741a152585df", diff --git a/editor/assets/default_prefab/ui/WebView.prefab.meta b/editor/assets/default_prefab/ui/WebView.prefab.meta index fb0944f27ca..3436befb8d8 100644 --- a/editor/assets/default_prefab/ui/WebView.prefab.meta +++ b/editor/assets/default_prefab/ui/WebView.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "9c541fa2-1dc8-4d8b-813a-aec89133f5b1", diff --git a/editor/assets/default_prefab/ui/Widget.prefab.meta b/editor/assets/default_prefab/ui/Widget.prefab.meta index 88c5b2828a2..59e0fa45615 100644 --- a/editor/assets/default_prefab/ui/Widget.prefab.meta +++ b/editor/assets/default_prefab/ui/Widget.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "36ed4422-3542-4cc4-bf02-dc4bfc590836", diff --git a/editor/assets/default_prefab/ui/pageView.prefab.meta b/editor/assets/default_prefab/ui/pageView.prefab.meta index cec5d685d73..c55ac35b5b0 100644 --- a/editor/assets/default_prefab/ui/pageView.prefab.meta +++ b/editor/assets/default_prefab/ui/pageView.prefab.meta @@ -1,5 +1,5 @@ { - "ver": "1.1.40", + "ver": "1.1.43", "importer": "prefab", "imported": true, "uuid": "20a5d8cb-ccad-4543-a937-fccd98c9f3de", diff --git a/editor/assets/default_renderpipeline/deferred-lighting.mtl.meta b/editor/assets/default_renderpipeline/deferred-lighting.mtl.meta index 238baedfcca..c696d8160c3 100644 --- a/editor/assets/default_renderpipeline/deferred-lighting.mtl.meta +++ b/editor/assets/default_renderpipeline/deferred-lighting.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "016951c5-5a09-4dd0-9bb7-f4958a82d690", diff --git a/editor/assets/default_renderpipeline/post-process.mtl.meta b/editor/assets/default_renderpipeline/post-process.mtl.meta index ee2862b3d4f..9fc995df587 100644 --- a/editor/assets/default_renderpipeline/post-process.mtl.meta +++ b/editor/assets/default_renderpipeline/post-process.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "85c4d630-c264-4b18-90a4-c52d594e6099", diff --git a/editor/assets/default_renderpipeline/tonemap.mtl.meta b/editor/assets/default_renderpipeline/tonemap.mtl.meta index fb77aca3c05..544c5e13089 100644 --- a/editor/assets/default_renderpipeline/tonemap.mtl.meta +++ b/editor/assets/default_renderpipeline/tonemap.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "9d9704d8-08b4-4917-ba47-9d778bc77ac6", diff --git a/editor/assets/default_skybox/default_skybox.hdr b/editor/assets/default_skybox/default_skybox.hdr index 87457129cfe..8b92b77ae84 100644 Binary files a/editor/assets/default_skybox/default_skybox.hdr and b/editor/assets/default_skybox/default_skybox.hdr differ diff --git a/editor/assets/default_skybox/default_skybox.hdr.meta b/editor/assets/default_skybox/default_skybox.hdr.meta index f13fcadb14e..f7458ac2859 100644 --- a/editor/assets/default_skybox/default_skybox.hdr.meta +++ b/editor/assets/default_skybox/default_skybox.hdr.meta @@ -22,7 +22,7 @@ "mipfilter": "linear", "anisotropy": 0, "isRGBE": true, - "imageDatabaseUri": "db://internal/default_skybox/default_skybox.hdr" + "imageDatabaseUri": "d032ac98-05e1-4090-88bb-eb640dcb5fc1" }, "ver": "1.0.10", "imported": true, diff --git a/editor/assets/default_skybox/default_skybox.png b/editor/assets/default_skybox/default_skybox.png index 78e3311c4c3..5637bef2ebe 100644 Binary files a/editor/assets/default_skybox/default_skybox.png and b/editor/assets/default_skybox/default_skybox.png differ diff --git a/editor/assets/default_skybox/default_skybox.png.meta b/editor/assets/default_skybox/default_skybox.png.meta index ed28be6c3c2..7617e4789da 100644 --- a/editor/assets/default_skybox/default_skybox.png.meta +++ b/editor/assets/default_skybox/default_skybox.png.meta @@ -22,7 +22,7 @@ "mipfilter": "linear", "anisotropy": 0, "isRGBE": false, - "imageDatabaseUri": "db://internal/default_skybox/default_skybox.png" + "imageDatabaseUri": "6f01cf7f-81bf-4a7e-bd5d-0afc19696480" }, "ver": "1.0.10", "imported": true, diff --git a/editor/assets/default_ui/atom_new.plist b/editor/assets/default_ui/atom_new.plist new file mode 100644 index 00000000000..9392b28eeeb --- /dev/null +++ b/editor/assets/default_ui/atom_new.plist @@ -0,0 +1,108 @@ + + + + + angle + 360 + angleVariance + 360 + blendFuncDestination + 1 + blendFuncSource + 2 + duration + -1 + emitterType + 0.0 + finishColorAlpha + 0.8399999737739563 + finishColorBlue + 0.0771484375 + finishColorGreen + 0.63492840528488159 + finishColorRed + 0.68082684278488159 + finishColorVarianceAlpha + 0.0 + finishColorVarianceBlue + 0.0 + finishColorVarianceGreen + 0.0 + finishColorVarianceRed + 0.0 + finishParticleSize + 30.319999694824219 + finishParticleSizeVariance + 0.0 + gravityx + 0.25 + gravityy + 0.86000001430511475 + maxParticles + 200 + maxRadius + 100 + maxRadiusVariance + 0.0 + minRadius + 0.0 + particleLifespan + 0.20000000298023224 + particleLifespanVariance + 0.5 + radialAccelVariance + 65.790000915527344 + radialAcceleration + -671.04998779296875 + rotatePerSecond + 0.0 + rotatePerSecondVariance + 0.0 + rotationEnd + -47.369998931884766 + rotationEndVariance + -142.11000061035156 + rotationStart + -47.369998931884766 + rotationStartVariance + 0.0 + sourcePositionVariancex + 7 + sourcePositionVariancey + 7 + sourcePositionx + 373.72775268554688 + sourcePositiony + 478.40472412109375 + speed + 0.0 + speedVariance + 190.78999328613281 + startColorAlpha + 0.63999998569488525 + startColorBlue + 0.3375650942325592 + startColorGreen + 0.78792315721511841 + startColorRed + 0.794921875 + startColorVarianceAlpha + 0.0 + startColorVarianceBlue + 0.0 + startColorVarianceGreen + 0.0 + startColorVarianceRed + 0.0 + startParticleSize + 3.369999885559082 + startParticleSizeVariance + 50 + tangentialAccelVariance + 65.790000915527344 + tangentialAcceleration + -92.110000610351562 + textureFileName + atom.png + + diff --git a/editor/assets/default_ui/atom_new.plist.meta b/editor/assets/default_ui/atom_new.plist.meta new file mode 100644 index 00000000000..75c03cb70d8 --- /dev/null +++ b/editor/assets/default_ui/atom_new.plist.meta @@ -0,0 +1,70 @@ +{ + "ver": "1.0.2", + "importer": "particle", + "imported": true, + "uuid": "e17b4526-57a2-48d3-acc9-cf09f30aa138", + "files": [ + ".json", + ".plist" + ], + "subMetas": {}, + "userData": { + "totalParticles": 200, + "life": 0.20000000298023224, + "lifeVar": 0.5, + "emissionRate": 999.999985098839, + "duration": -1, + "srcBlendFactor": 2, + "dstBlendFactor": 1, + "startColor": { + "_val": 2740373706 + }, + "startColorVar": { + "_val": 0 + }, + "endColor": { + "_val": 3591610797 + }, + "endColorVar": { + "_val": 0 + }, + "startSize": 3.369999885559082, + "startSizeVar": 50, + "endSize": 30.31999969482422, + "endSizeVar": 0, + "positionType": 0, + "sourcePos": { + "x": 0, + "y": 0 + }, + "posVar": { + "x": 7, + "y": 7 + }, + "angle": 360, + "angleVar": 360, + "startSpin": -47.369998931884766, + "startSpinVar": 0, + "endSpin": -47.369998931884766, + "endSpinVar": -142.11000061035156, + "emitterMode": 0, + "gravity": { + "x": 0.25, + "y": 0.8600000143051147 + }, + "speed": 0, + "speedVar": 190.7899932861328, + "radialAccel": -671.0499877929688, + "radialAccelVar": 65.79000091552734, + "tangentialAccel": -92.11000061035156, + "tangentialAccelVar": 65.79000091552734, + "rotationIsDir": false, + "startRadius": 0, + "startRadiusVar": 0, + "endRadius": 0, + "endRadiusVar": 0, + "rotatePerS": 0, + "rotatePerSVar": 0, + "spriteFrameUuid": "24c419ea-63a8-4ea1-a9d0-7fc469489bbc@f9941" + } +} diff --git a/editor/assets/effects/surfaces.meta b/editor/assets/effects/advanced.meta similarity index 100% rename from editor/assets/effects/surfaces.meta rename to editor/assets/effects/advanced.meta diff --git a/editor/assets/effects/surfaces/sky.effect b/editor/assets/effects/advanced/sky.effect similarity index 100% rename from editor/assets/effects/surfaces/sky.effect rename to editor/assets/effects/advanced/sky.effect diff --git a/editor/assets/effects/surfaces/sky.effect.meta b/editor/assets/effects/advanced/sky.effect.meta similarity index 90% rename from editor/assets/effects/surfaces/sky.effect.meta rename to editor/assets/effects/advanced/sky.effect.meta index 2fdf69ce740..f7b9f2c2d37 100644 --- a/editor/assets/effects/surfaces/sky.effect.meta +++ b/editor/assets/effects/advanced/sky.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "6308c013-7d49-4160-9516-562dd205b480", diff --git a/editor/assets/effects/advanced/water.effect b/editor/assets/effects/advanced/water.effect new file mode 100644 index 00000000000..0f75f926c6a --- /dev/null +++ b/editor/assets/effects/advanced/water.effect @@ -0,0 +1,293 @@ +// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. + +CCEffect %{ + techniques: + - name: opaque + passes: + - vert: standard-vs + frag: standard-fs + properties: &props + mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: Albedo, type: color } } + normalStrength: { value: 1.0, target: pbrParams.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } + mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } + roughness: { value: 0.5, target: pbrParams.y, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + fresnelIntensity: { value: 1.5, target: pbrParams.z, editor: { slide: true, range: [0, 3.0], step: 0.001 } } + normalMap: { value: normal } + normalMapDetailed: { value: normal } + baseTiling: { value: 100.0, target: pbrParams.x, editor: { parent: USE_NORMAL_MAP, range: [1.0, 10000.0] } } + waterSpeed: { value: 0.2, target: waterParam.x, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 1.0], step: 0.001 } } + detailedSpeed: { value: 0.2, target: waterParam.y, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 1.0], step: 0.001 } } + detailedTiling: { value: 0.2, target: waterParam.z, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 1.0], step: 0.001 } } + detailedIntensity: { value: 0.5, target: waterParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 1.0], step: 0.001 } } + waterInScatterColor: { value: [0.07, 0.13, 0.087, 1.0], target: waterColor, linear: true, editor: { parent: USE_WATER_SCATTERING, type: color } } + waterScatterCoef: { value: 3.0, target: waterColor.w, editor: { parent: USE_WATER_SCATTERING, range: [0, 10.0] } } + rasterizerState: + cullMode: none + - &forward-add + vert: standard-vs + frag: standard-fs + phase: forward-add + propertyIndex: 0 + embeddedMacros: { CC_FORWARD_ADD: true } + rasterizerState: + cullMode: none + depthStencilState: + depthFunc: equal + depthTest: true + depthWrite: false + blendState: + targets: + - blend: true + blendSrc: one + blendDst: one + blendSrcAlpha: zero + blendDstAlpha: one + - &shadow-caster + vert: shadow-caster-vs + frag: shadow-caster-fs + phase: shadow-caster + propertyIndex: 0 + rasterizerState: + cullMode: front + properties: + mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, editor: { displayName: Albedo, type: color } } + mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } + - &reflect-map + vert: standard-vs + frag: reflect-map-fs + phase: reflect-map + propertyIndex: 0 + - name: transparent + passes: + - vert: standard-vs + frag: standard-fs + embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } + depthStencilState: + depthTest: true + depthWrite: false + blendState: + targets: + - blend: true + blendSrc: src_alpha + blendDst: one_minus_src_alpha + blendDstAlpha: one_minus_src_alpha + properties: *props + - *forward-add + - *shadow-caster +}% + +CCProgram shared-ubos %{ + uniform Constants { + vec4 albedo; + vec4 pbrParams; + vec4 waterParam; + vec4 waterColor; + }; +}% + +CCProgram macro-remapping %{ + // ui displayed macros + #pragma define-meta HAS_SECOND_UV + #pragma define-meta USE_TWOSIDE + #define CC_SURFACES_USE_SECOND_UV HAS_SECOND_UV + #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE + #define CC_SURFACES_LIGHTING_USE_FRESNEL 1 + #define CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR 1 + + // depend on UI macros +#if USE_NORMAL_MAP + #define CC_SURFACES_USE_TANGENT_SPACE 1 +#endif +}% + +CCProgram surface-vertex %{ +}% + +CCProgram surface-fragment %{ + #if USE_ALBEDO_MAP + uniform sampler2D albedoMap; + #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) + #endif + #if USE_NORMAL_MAP + uniform sampler2D normalMap; + uniform sampler2D normalMapDetailed; + #pragma define-meta NORMAL_UV options([v_uv, v_uv1]) + #endif + #pragma define-meta DEFAULT_UV options([v_uv, v_uv1]) + + + #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TRANSPARENCY + vec4 SurfacesFragmentModifyBaseColorAndTransparency() + { + vec4 baseColor = albedo; + + #if USE_VERTEX_COLOR + baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear + baseColor.a *= FSInput_vertexColor.a; + #endif + + #if USE_ALBEDO_MAP + vec4 texColor = texture(albedoMap, ALBEDO_UV); + texColor.rgb = SRGBToLinear(texColor.rgb); + baseColor *= texColor; + #endif + + return baseColor; + } + + #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY + void SurfacesFragmentAlphaClipOnly() + { + } + + + vec3 GetDetailedNormal(vec2 texCoord, float tiling, sampler2D normalMap, sampler2D normalMapDetailed, vec3 N, vec3 T) + { + float waterSpeed = waterParam.x; + float detailedSpeed = waterParam.y; + float detailedTiling = waterParam.z * tiling; + float detailedIntensity = waterParam.w; + float normalIntensity = pbrParams.w; + + vec2 uv = texCoord * tiling + vec2(cc_time.w, cc_time.w) * waterSpeed; + vec3 nmmp = texture(normalMap, uv).xyz - vec3(0.5); + vec2 uvDetailed = texCoord * detailedTiling + vec2(0.0, cc_time.w) * detailedSpeed; + vec3 nmmpDetailed = texture(normalMapDetailed, uvDetailed).xyz - vec3(0.5); + // normal blending + nmmp = normalize(vec3(nmmp.xy + nmmpDetailed.xy * detailedIntensity, nmmp.z)); + return normalize(CalculateNormalFromTangentSpace(nmmp, normalIntensity, N, T, FSInput_mirrorNormal)); + } + + + #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL + vec3 SurfacesFragmentModifyWorldNormal() + { + vec3 normal = FSInput_worldNormal; + #if USE_NORMAL_MAP + normal = GetDetailedNormal(NORMAL_UV, pbrParams.x, normalMap, normalMapDetailed, normal, FSInput_worldTangent); + #endif + + return normalize(normal); + } + + #define CC_SURFACES_FRAGMENT_MODIFY_IOR + float SurfacesFragmentModifyIOR() + { + return 1.33; + } +#define CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_PARAMS +void SurfacesFragmentModifyTransmitParams(out vec4 transmitParams, out vec3 inScatteringLightColor) +{ + #if USE_WATER_SCATTERING + float depth = max(abs(FSInput_texcoord.x - 0.5), abs(FSInput_texcoord.y - 0.5)) * 2.0; + depth = saturate(1.0 - depth); + transmitParams = vec4(waterColor.ww, 1.0, depth); + #else + transmitParams = vec4(0.0, 0.0, 0.0, 0.0); + #endif + + inScatteringLightColor = waterColor.rgb; +} + + #include + #include + #define CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT + void SurfacesLightingModifyFinalResult(inout LightingResult result, in LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData, in LightingMiscData miscData) + { + #if CC_SURFACES_LIGHTING_USE_FRESNEL + result.fresnel = saturate(result.fresnel * pbrParams.z); + #endif + } + + #define CC_SURFACES_FRAGMENT_MODIFY_PBRPARAMS + vec4 SurfacesFragmentModifyPBRParams() + { + // ao, roughness, metallic, specularIntensity + return vec4(1.0, pbrParams.y, 1.0, 0.5); + } +}% + +CCProgram standard-vs %{ + precision highp float; + + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include + + // 2. common include with corresponding shader stage, include before surface functions + #include + + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include + + // 4. surface include with corresponding shader stage and shading-model (optional) + #include + + // 5. shader entry with corresponding shader stage and technique usage/type + #include +}% + + +CCProgram shadow-caster-vs %{ + precision highp float; + #include + #include + #include + #include + #include +}% + + + +CCProgram standard-fs %{ + // shading-model : standard + // lighting-model : standard (isotropy / anisotropy pbr) + // shader stage : fs + // technique usage/type : render-to-scene + + precision highp float; + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include + + // 2. common include with corresponding shader stage, include before surface functions + #include + + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include + + // 4. lighting-model (optional) + #include + + // 5. surface include with corresponding shader stage and shading-model (optional) + #include + + // 6. shader entry with corresponding shader stage and technique usage/type + #include +}% + +CCProgram shadow-caster-fs %{ + precision highp float; + #include + #include + #include + #include + #include +}% + + +CCProgram reflect-map-fs %{ + precision highp float; + #include + #include + #include + #include + #include + #include + #include + #include +}% diff --git a/editor/assets/effects/dcc/surfaces-imported-metallic-roughness.effect.meta b/editor/assets/effects/advanced/water.effect.meta similarity index 62% rename from editor/assets/effects/dcc/surfaces-imported-metallic-roughness.effect.meta rename to editor/assets/effects/advanced/water.effect.meta index 20280ed61c2..6e5efdd6a2c 100644 --- a/editor/assets/effects/dcc/surfaces-imported-metallic-roughness.effect.meta +++ b/editor/assets/effects/advanced/water.effect.meta @@ -1,8 +1,8 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "994bae8e-8bfc-4bc4-a32d-ad924f9917d0", + "uuid": "113a72d8-20cd-42cd-ba96-37cc1046971a", "files": [ ".json" ], diff --git a/editor/assets/effects/builtin-standard.effect b/editor/assets/effects/builtin-standard.effect index 22f9a4ba2f2..241f7923954 100644 --- a/editor/assets/effects/builtin-standard.effect +++ b/editor/assets/effects/builtin-standard.effect @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. CCEffect %{ techniques: @@ -7,23 +7,27 @@ CCEffect %{ - vert: standard-vs frag: standard-fs properties: &props - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: Albedo, type: color } } - albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } - alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } - occlusion: { value: 0.0, target: pbrParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - roughness: { value: 0.8, target: pbrParams.y, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - metallic: { value: 0.6, target: pbrParams.z, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - specularIntensity: { value: 0.5, target: pbrParams.w, editor: { slide: true, range: [0.0, 1.0], step: 0.001 } } - emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } - emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleParam.xyz } - normalStrength: { value: 1.0, target: emissiveScaleParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } - mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - normalMap: { value: normal } - pbrMap: { value: grey } - metallicRoughnessMap: { value: grey } - occlusionMap: { value: white } - emissiveMap: { value: grey } + tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } + mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: Albedo, type: color } } + albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } + alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } + occlusion: { value: 0.0, target: pbrParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + roughness: { value: 0.5, target: pbrParams.y, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + metallic: { value: 0.0, target: pbrParams.z, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + specularIntensity: { value: 0.5, target: pbrParams.w, editor: { slide: true, range: [0.0, 1.0], step: 0.001 } } + emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } + emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleParam.xyz } + normalStrength: { value: 1.0, target: emissiveScaleParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } + anisotropyIntensity: { value: 1.0, target: anisotropyParam.x, editor: { parent: IS_ANISOTROPY, slide : true, range : [0.0, 1.0] , step : 0.0001 } } + anisotropyRotation: { value: 0.0, target: anisotropyParam.y, editor: { parent: IS_ANISOTROPY, slide : true, range : [0, 1.0] , step : 0.0001 } } + anisotropyMapResolutionHeight: { value: 0.0, target: anisotropyParam.w, editor: { parent: FIX_ANISOTROPIC_ROTATION_MAP } } + mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } + normalMap: { value: normal } + pbrMap: { value: grey } + occlusionMap: { value: white } + emissiveMap: { value: grey } + anisotropyMap: { value: black, editor : { parent: IS_ANISOTROPY } } + anisotropyMapNearestFilter: { value: black, editor : { parent: FIX_ANISOTROPIC_ROTATION_MAP } } - &forward-add vert: standard-vs frag: standard-fs @@ -42,8 +46,8 @@ CCEffect %{ blendSrcAlpha: zero blendDstAlpha: one - &shadow-caster - vert: shadow-caster-vs:vert - frag: shadow-caster-fs:frag + vert: shadow-caster-vs + frag: shadow-caster-fs phase: shadow-caster propertyIndex: 0 rasterizerState: @@ -54,6 +58,11 @@ CCEffect %{ albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } + - &reflect-map + vert: standard-vs + frag: reflect-map-fs + phase: reflect-map + propertyIndex: 0 - name: transparent passes: - vert: standard-vs @@ -81,140 +90,83 @@ CCProgram shared-ubos %{ vec4 pbrParams; vec4 emissive; vec4 emissiveScaleParam; + vec4 anisotropyParam; }; }% -CCProgram standard-vs %{ - precision highp float; - #include - #include - #include - #include - #include - #include - #include - - #if USE_VERTEX_COLOR - in vec4 a_color; - out lowp vec4 v_color; - #endif - - out vec3 v_position; - out mediump vec3 v_normal; - out vec2 v_uv; - #if HAS_SECOND_UV - out mediump vec2 v_uv1; - #endif - - #if CC_RECEIVE_SHADOW - out mediump vec2 v_shadowBias; - #endif - - #if USE_NORMAL_MAP - out mediump vec4 v_tangent; - #endif +CCProgram macro-remapping %{ + // ui displayed macros + #pragma define-meta HAS_SECOND_UV + #pragma define-meta USE_TWOSIDE + #pragma define-meta IS_ANISOTROPY + #pragma define-meta USE_VERTEX_COLOR + + #define CC_SURFACES_USE_SECOND_UV HAS_SECOND_UV + #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE + #define CC_SURFACES_LIGHTING_ANISOTROPIC IS_ANISOTROPY + #define CC_SURFACES_USE_VERTEX_COLOR USE_VERTEX_COLOR + + // depend on UI macros +#if IS_ANISOTROPY || USE_NORMAL_MAP + #define CC_SURFACES_USE_TANGENT_SPACE 1 +#endif + + // functionality for each effect + #define CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT 31 +}% - #if HAS_SECOND_UV || CC_USE_LIGHTMAP - in vec2 a_texCoord1; +CCProgram surface-vertex %{ + /*#define CC_SURFACES_VERTEX_MODIFY_WORLD_POS + vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In) + { + vec3 worldPos = In.worldPos; + worldPos.x += sin(cc_time.x * worldPos.z); + worldPos.y += cos(cc_time.x * worldPos.z); + return worldPos; + } + + #define CC_SURFACES_VERTEX_MODIFY_WORLD_NORMAL + vec3 SurfacesVertexModifyWorldNormal(in SurfacesStandardVertexIntermediate In) + { + vec3 worldNormal = In.worldNormal.xyz; + worldNormal.x += sin(cc_time.x * 3.0); + worldNormal.y += cos(cc_time.x * 3.0); + #if CC_SURFACES_USE_TWO_SIDED + worldNormal.xyz *= In.worldNormal.w; #endif - - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - #include + return normalize(worldNormal); + } + + // see for more overrided functions + #define CC_SURFACES_VERTEX_MODIFY_SHARED_DATA + void SurfacesVertexModifySharedData(inout SurfacesStandardVertexIntermediate In) + { + } +*/ + + #define CC_SURFACES_VERTEX_MODIFY_UV + void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) + { + In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; + #if CC_SURFACES_USE_SECOND_UV + In.texCoord1 = In.texCoord1 * tilingOffset.xy + tilingOffset.zw; #endif - - void main () { - StandardVertInput In; - CCVertInput(In); - - mat4 matWorld, matWorldIT; - CCGetWorldMatrixFull(matWorld, matWorldIT); - - vec4 pos = matWorld * In.position; - - v_position = pos.xyz; - v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz); - - #if CC_RECEIVE_SHADOW - v_shadowBias = CCGetShadowBias(); - #endif - - #if USE_TWOSIDE - vec3 viewDirect = normalize(cc_cameraPos.xyz - v_position); - v_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0; - #endif - - #if USE_NORMAL_MAP - v_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); - v_tangent.w = In.tangent.w; - #endif - - v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; - #if SAMPLE_FROM_RT - CC_HANDLE_RT_SAMPLE_FLIP(v_uv); - #endif - #if HAS_SECOND_UV - v_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw; - #if SAMPLE_FROM_RT - CC_HANDLE_RT_SAMPLE_FLIP(v_uv1); - #endif - #endif - - #if USE_VERTEX_COLOR - v_color = a_color; - #endif - - CC_TRANSFER_FOG(pos); - CC_TRANSFER_SHADOW(pos); - - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - CCLightingMapCaclUV(); - #endif - - gl_Position = cc_matProj * (cc_matView * matWorld) * In.position; } }% -CCProgram standard-fs %{ - precision highp float; - #include - #include - #include - #include - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - #include - #endif - - in vec3 v_position; - in vec2 v_uv; - #if HAS_SECOND_UV - in mediump vec2 v_uv1; - #endif - in mediump vec3 v_normal; - - #if CC_RECEIVE_SHADOW - in mediump vec2 v_shadowBias; - #endif - - #if USE_VERTEX_COLOR - in lowp vec4 v_color; - #endif - +CCProgram surface-fragment %{ #if USE_ALBEDO_MAP uniform sampler2D albedoMap; #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) #endif #if USE_NORMAL_MAP - in mediump vec4 v_tangent; uniform sampler2D normalMap; #pragma define-meta NORMAL_UV options([v_uv, v_uv1]) #endif - #pragma define-meta PBR_UV options([v_uv, v_uv1]) + #pragma define-meta DEFAULT_UV options([v_uv, v_uv1]) #if USE_PBR_MAP uniform sampler2D pbrMap; #endif - #if USE_METALLIC_ROUGHNESS_MAP - uniform sampler2D metallicRoughnessMap; - #endif #if USE_OCCLUSION_MAP uniform sampler2D occlusionMap; #endif @@ -222,6 +174,10 @@ CCProgram standard-fs %{ uniform sampler2D emissiveMap; #pragma define-meta EMISSIVE_UV options([v_uv, v_uv1]) #endif + #if IS_ANISOTROPY && USE_ANISOTROPY_MAP + uniform sampler2D anisotropyMap; + uniform sampler2D anisotropyMapNearestFilter; + #endif #pragma define OCCLUSION_CHANNEL r #pragma define ROUGHNESS_CHANNEL g @@ -232,163 +188,220 @@ CCProgram standard-fs %{ #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) #endif - void surf (out StandardSurface s) { + + #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TRANSPARENCY + vec4 SurfacesFragmentModifyBaseColorAndTransparency() + { vec4 baseColor = albedo; + #if USE_VERTEX_COLOR - baseColor.rgb *= SRGBToLinear(v_color.rgb); // use linear - baseColor.a *= v_color.a; + baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear + baseColor.a *= FSInput_vertexColor.a; #endif + #if USE_ALBEDO_MAP vec4 texColor = texture(albedoMap, ALBEDO_UV); texColor.rgb = SRGBToLinear(texColor.rgb); baseColor *= texColor; #endif - s.albedo = baseColor; - s.albedo.rgb *= albedoScaleAndCutoff.xyz; #if USE_ALPHA_TEST - if (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; - #endif - - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - vec4 lightColor = texture(cc_lightingMap, v_luv.xy); - s.lightmap = lightColor.xyz * v_luv.z; - s.lightmap_test = v_luv.z; /*lum*/ + if (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; #endif - s.normal = v_normal; + baseColor.rgb *= albedoScaleAndCutoff.xyz; + return baseColor; + } - #if CC_RECEIVE_SHADOW - s.shadowBias = v_shadowBias; + #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY + void SurfacesFragmentAlphaClipOnly() + { + #if USE_ALPHA_TEST + float alpha = albedo.ALPHA_TEST_CHANNEL; + #if USE_VERTEX_COLOR + alpha *= FSInput_vertexColor.a; + #endif + #if USE_ALBEDO_MAP + alpha = texture(albedoMap, ALBEDO_UV).ALPHA_TEST_CHANNEL; + #endif + + if (alpha < albedoScaleAndCutoff.w) discard; #endif + } + #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL + vec3 SurfacesFragmentModifyWorldNormal() + { + vec3 normal = FSInput_worldNormal; #if USE_NORMAL_MAP vec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5); - vec3 bitangent = cross(v_normal, v_tangent.xyz) * v_tangent.w; // note the cross order - s.normal = - (nmmp.x * emissiveScaleParam.w) * normalize(v_tangent.xyz) + - (nmmp.y * emissiveScaleParam.w) * normalize(bitangent) + - nmmp.z * normalize(s.normal); + normal = CalculateNormalFromTangentSpace(nmmp, emissiveScaleParam.w, normal.xyz, FSInput_worldTangent, FSInput_mirrorNormal); + #endif + + return normalize(normal); + } + + #define CC_SURFACES_FRAGMENT_MODIFY_ANISOTROPY_PARAMS + vec4 SurfacesFragmentModifyAnisotropyParams(out float isRotation) + { + float anisotropyRotation = anisotropyParam.y * PI; + float anisotropyShape = anisotropyParam.x; + #if IS_ANISOTROPY && USE_ANISOTROPY_MAP + // Rotation angle should disable trilinear filtering + vec4 tex = texture(anisotropyMap, DEFAULT_UV); + anisotropyRotation = fract(anisotropyRotation * 0.5 + tex.y) * PI2; + // less value is better for SP exported shape + anisotropyShape *= tex.x; + #endif + + // fix rotation map seam line of black and white + #if FIX_ANISOTROPIC_ROTATION_MAP + #if IS_ANISOTROPY && USE_ANISOTROPY_MAP + vec4 reference = texture(anisotropyMapNearestFilter, DEFAULT_UV); + vec2 oneTap = vec2(0.0, 1.0 / anisotropyParam.w); + float threshold = 0.2; + // scan more taps for stable result + vec4 sample1 = texture(anisotropyMapNearestFilter, DEFAULT_UV + oneTap); + vec4 sample2 = texture(anisotropyMapNearestFilter, DEFAULT_UV - oneTap); + if (abs(sample1.y - reference.y) > threshold || abs(sample2.y - reference.y) > threshold) { + tex.y = reference.y; + } + anisotropyRotation = fract(anisotropyParam.y * PI * 0.5 + tex.y) * PI2; + #endif #endif - HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); + isRotation = 1.0; + return vec4(anisotropyShape, anisotropyRotation, 0.0, 0.0); + } + + #define CC_SURFACES_FRAGMENT_MODIFY_EMISSIVE + vec3 SurfacesFragmentModifyEmissive() + { + vec3 emissive = emissive.rgb; + #if USE_EMISSIVE_MAP + emissive = SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb); + #endif + return emissive * emissiveScaleParam.xyz; + } + #define CC_SURFACES_FRAGMENT_MODIFY_PBRPARAMS + vec4 SurfacesFragmentModifyPBRParams() + { vec4 pbr = pbrParams; - pbr.x = 1.0 - pbr.x; + pbr.x = 1.0; #if USE_PBR_MAP - vec4 res = texture(pbrMap, PBR_UV); + vec4 res = texture(pbrMap, DEFAULT_UV); pbr.x *= res.OCCLUSION_CHANNEL; pbr.y *= res.ROUGHNESS_CHANNEL; pbr.z *= res.METALLIC_CHANNEL; pbr.w *= res.SPECULAR_INTENSITY_CHANNEL; #endif - #if USE_METALLIC_ROUGHNESS_MAP - vec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV); - pbr.z *= metallicRoughness.METALLIC_CHANNEL; - pbr.y *= metallicRoughness.ROUGHNESS_CHANNEL; - #endif #if USE_OCCLUSION_MAP - pbr.x *= texture(occlusionMap, PBR_UV).OCCLUSION_CHANNEL; + pbr.x = mix(1.0, texture(occlusionMap, DEFAULT_UV).OCCLUSION_CHANNEL, pbrParams.x); #endif - s.occlusion = pbr.x; - s.roughness = pbr.y; - s.metallic = pbr.z; - s.specularIntensity = pbr.w; - s.emissive = emissive.rgb * emissiveScaleParam.xyz; - #if USE_EMISSIVE_MAP - s.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb); - #endif + return pbr; } - CC_STANDARD_SURFACE_ENTRY() + /* + // definition of SurfacesMaterialData structure with corresponding shading-model + #include + + //see for more overrided functions, XXXX is shading-model name + #define CC_SURFACES_FRAGMENT_MODIFY_SHARED_DATA + void SurfacesFragmentModifySharedData(inout SurfacesMaterialData surfaceData) + { + } + + // see for more overrided functions, XXXX is lighting-model name + #include + #define CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT + void SurfacesLightingModifyFinalResult(inout LightingResult result, in LightingIntermediateData lightingData, in SurfacesMaterialData surfaceData, in LightingMiscData miscData) + { + }*/ }% -CCProgram shadow-caster-vs %{ +CCProgram standard-vs %{ precision highp float; - #include - #include - #include - #include - #include - - #if HAS_SECOND_UV || CC_USE_LIGHTMAP - in vec2 a_texCoord1; - #endif - out vec2 v_uv; - #if HAS_SECOND_UV - out vec2 v_uv1; - #endif - out vec4 v_worldPos; - out highp vec2 v_clip_depth; + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include - vec4 vert () { - StandardVertInput In; - CCVertInput(In); + // 2. common include with corresponding shader stage, include before surface functions + #include - mat4 matWorld, matWorldIT; - CCGetWorldMatrixFull(matWorld, matWorldIT); + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include - v_worldPos = matWorld * In.position; - vec4 clipPos = cc_matLightViewProj * v_worldPos; + // 4. surface include with corresponding shader stage and shading-model (optional) + #include - v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; - #if HAS_SECOND_UV - v_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw; - #endif + // 5. shader entry with corresponding shader stage and technique usage/type + #include +}% - v_clip_depth = clipPos.zw; - return clipPos; - } +CCProgram shadow-caster-vs %{ + precision highp float; + #include + #include + #include + #include + #include }% -CCProgram shadow-caster-fs %{ + + +CCProgram standard-fs %{ + // shading-model : standard + // lighting-model : standard (isotropy / anisotropy pbr) + // shader stage : fs + // technique usage/type : render-to-scene + precision highp float; - #include - #include - #include + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include - in vec2 v_uv; - #if HAS_SECOND_UV - in vec2 v_uv1; - #endif - in vec4 v_worldPos; - in highp vec2 v_clip_depth; + // 2. common include with corresponding shader stage, include before surface functions + #include - #if USE_ALBEDO_MAP - uniform sampler2D albedoMap; - #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) - #endif + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include - #if USE_ALPHA_TEST - #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) - #endif + // 4. lighting-model (optional) + #include - vec4 frag () { - vec4 baseColor = albedo; + // 5. surface include with corresponding shader stage and shading-model (optional) + #include - #if USE_ALPHA_TEST - #if USE_ALBEDO_MAP - baseColor *= texture(albedoMap, ALBEDO_UV); - #endif - if (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; - #endif + // 6. shader entry with corresponding shader stage and technique usage/type + #include +}% - highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; - // spot use linear - if(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) { - // enabled linear depth - #if CC_SHADOWMAP_USE_LINEAR_DEPTH - clipDepth = CCGetLinearDepth(v_worldPos.xyz); - #endif - } +CCProgram shadow-caster-fs %{ + precision highp float; + #include + #include + #include + #include + #include +}% - #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 - return packDepthToRGBA(clipDepth); - #else - return vec4(clipDepth, 1.0, 1.0, 1.0); - #endif - } + +CCProgram reflect-map-fs %{ + precision highp float; + #include + #include + #include + #include + #include + #include + #include + #include }% diff --git a/editor/assets/effects/builtin-standard.effect.meta b/editor/assets/effects/builtin-standard.effect.meta index eb92874cc1d..8fb201da478 100644 --- a/editor/assets/effects/builtin-standard.effect.meta +++ b/editor/assets/effects/builtin-standard.effect.meta @@ -1,11 +1,17 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "1baf0fc9-befa-459c-8bdd-af1a450a0319", + "uuid": "c8f66d17-351a-48da-a12c-0212d28575c4", "files": [ ".json" ], "subMetas": {}, - "userData": {} + "userData": { + "combinations": [ + {}, + {}, + {} + ] + } } diff --git a/editor/assets/effects/builtin-terrain.effect b/editor/assets/effects/builtin-terrain.effect index 6c0ce9285da..75361284200 100644 --- a/editor/assets/effects/builtin-terrain.effect +++ b/editor/assets/effects/builtin-terrain.effect @@ -1,4 +1,5 @@ -// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. + CCEffect %{ techniques: - name: opaque @@ -6,18 +7,18 @@ CCEffect %{ - vert: terrain-vs frag: terrain-fs properties: &props - UVScale: { value: [1, 1, 1, 1] } - metallic: { value: [0, 0, 0, 0] } - roughness: { value: [1, 1, 1, 1] } - weightMap: { value: black } - detailMap0: { value: grey } - detailMap1: { value: grey } - detailMap2: { value: grey } - detailMap3: { value: grey } - normalMap0: { value: normal } - normalMap1: { value: normal } - normalMap2: { value: normal } - normalMap3: { value: normal } + UVScale: { value: [1, 1, 1, 1] } + metallic: { value: [0, 0, 0, 0] } + roughness: { value: [1, 1, 1, 1] } + weightMap: { value: black } + detailMap0: { value: grey } + detailMap1: { value: grey } + detailMap2: { value: grey } + detailMap3: { value: grey } + normalMap0: { value: normal } + normalMap1: { value: normal } + normalMap2: { value: normal } + normalMap3: { value: normal } - vert: terrain-vs frag: terrain-fs phase: forward-add @@ -35,107 +36,54 @@ CCEffect %{ blendSrcAlpha: zero blendDstAlpha: one properties: *props - - vert: shadow-caster-vs:vert - frag: shadow-caster-fs:frag + - vert: shadow-caster-vs + frag: shadow-caster-fs phase: shadow-add propertyIndex: 0 rasterizerState: cullMode: back + - &reflect-map + vert: terrain-vs + frag: reflect-map-fs + phase: reflect-map + propertyIndex: 0 }% -CCProgram terrain-vs %{ - precision mediump float; - #include - #include - #include - #include - - in vec3 a_position; - in vec3 a_normal; - in vec2 a_texCoord; - - #if CC_RECEIVE_SHADOW - out vec2 v_shadowBias; - #endif - - out highp vec3 v_position; - out mediump vec3 v_normal; - out mediump vec2 uvw; - out mediump vec2 uv0; - out mediump vec2 uv1; - out mediump vec2 uv2; - out mediump vec2 uv3; - out mediump vec3 luv; - out mediump vec3 diffuse; - - uniform TexCoords { +CCProgram shared-ubos %{ + uniform Constants { vec4 UVScale; - vec4 lightMapUVParam; + vec4 metallic; + vec4 roughness; }; +}% + +CCProgram macro-remapping %{ + #pragma define-meta USE_NORMALMAP + #define CC_SURFACES_USE_TANGENT_SPACE USE_NORMALMAP +}% - void main () { +CCProgram surface-vertex %{ + #define CC_SURFACES_VERTEX_MODIFY_WORLD_POS + vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In) + { vec3 worldPos; - worldPos.x = cc_matWorld[3][0] + a_position.x; - worldPos.y = cc_matWorld[3][1] + a_position.y; - worldPos.z = cc_matWorld[3][2] + a_position.z; + worldPos.x = cc_matWorld[3][0] + In.position.x; + worldPos.y = cc_matWorld[3][1] + In.position.y; + worldPos.z = cc_matWorld[3][2] + In.position.z; + return worldPos; + } - vec4 pos = vec4(worldPos, 1.0); + #define CC_SURFACES_VERTEX_MODIFY_CLIP_POS + vec4 SurfacesVertexModifyClipPos(in SurfacesStandardVertexIntermediate In) + { + vec4 pos = vec4(In.worldPos, 1.0); pos = cc_matViewProj * pos; - - uvw = a_texCoord; - uv0 = a_position.xz * UVScale.x; - uv1 = a_position.xz * UVScale.y; - uv2 = a_position.xz * UVScale.z; - uv3 = a_position.xz * UVScale.w; - #if CC_USE_LIGHTMAP - luv.xy = cc_lightingMapUVParam.xy + a_texCoord * cc_lightingMapUVParam.z; - luv.z = cc_lightingMapUVParam.w; - #endif - - v_position = worldPos; - v_normal = a_normal; - CC_TRANSFER_FOG(vec4(worldPos, 1.0)); - - #if CC_RECEIVE_SHADOW - v_shadowBias = vec2(0.0, 0.0); - #endif - - CC_TRANSFER_SHADOW(vec4(worldPos, 1.0)); - - gl_Position = pos; + return pos; } }% -CCProgram terrain-fs %{ - precision highp float; - #include - #include - #include - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - #include - #endif +CCProgram surface-fragment %{ #pragma define-meta LAYERS range([0, 4]) - - in highp vec3 v_position; - in mediump vec3 v_normal; - - #if CC_RECEIVE_SHADOW - in vec2 v_shadowBias; - #endif - - in mediump vec2 uvw; - in mediump vec2 uv0; - in mediump vec2 uv1; - in mediump vec2 uv2; - in mediump vec2 uv3; - in mediump vec3 diffuse; - in mediump vec3 luv; - - uniform PbrParams { - vec4 metallic; - vec4 roughness; - }; - uniform sampler2D weightMap; uniform sampler2D detailMap0; uniform sampler2D detailMap1; @@ -146,11 +94,25 @@ CCProgram terrain-fs %{ uniform sampler2D normalMap2; uniform sampler2D normalMap3; - void surf (out StandardSurface s) { + #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY + void SurfacesFragmentAlphaClipOnly(){} + + #define CC_SURFACES_FRAGMENT_MODIFY_SHARED_DATA + #include + void SurfacesFragmentModifySharedData(inout SurfacesMaterialData surfaceData) + { + vec2 uvw = FSInput_texcoord; + vec2 uv0, uv1, uv2, uv3; + #if CC_SURFACES_TRANSFER_LOCAL_POS + uv0 = FSInput_localPos.xz * UVScale.x; + uv1 = FSInput_localPos.xz * UVScale.y; + uv2 = FSInput_localPos.xz * UVScale.z; + uv3 = FSInput_localPos.xz * UVScale.w; + #endif + vec4 w = vec4(0.0); #if LAYERS > 1 - vec4 w = texture(weightMap, uvw); + w = texture(weightMap, uvw); #endif - vec4 baseColor = vec4(0, 0, 0, 0); #if LAYERS == 1 baseColor = texture(detailMap0, uv0); @@ -169,10 +131,10 @@ CCProgram terrain-fs %{ #else baseColor = texture(detailMap0, uv0); #endif + surfaceData.baseColor = vec4(SRGBToLinear(baseColor.rgb), 1.0); - HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); + vec4 baseNormal = vec4(0, 0, 0, 0); #if USE_NORMALMAP - vec4 baseNormal = vec4(0, 0, 0, 0); #if LAYERS == 1 baseNormal = texture(normalMap0, uv0); #elif LAYERS == 2 @@ -194,128 +156,136 @@ CCProgram terrain-fs %{ vec3 tangent = vec3(1.0, 0.0, 0.0); vec3 binormal = vec3(0.0, 0.0, 1.0); - binormal = cross(tangent, v_normal); - tangent = cross(v_normal, binormal); + binormal = cross(tangent, FSInput_worldNormal); + tangent = cross(FSInput_worldNormal, binormal); vec3 nmmp = baseNormal.xyz - vec3(0.5); - s.normal = + surfaceData.worldNormal = nmmp.x * normalize(tangent) + nmmp.y * normalize(binormal) + - nmmp.z * normalize(v_normal); + nmmp.z * normalize(FSInput_worldNormal); #else - s.normal = v_normal; - #endif - - #if CC_RECEIVE_SHADOW - s.shadowBias = v_shadowBias; + surfaceData.worldNormal = FSInput_worldNormal; #endif - s.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0); - s.occlusion = 1.0; + float roughnessValue = 1.0; + float metallicValue = 0.0; #if USE_PBR - s.roughness = 0.0; #if LAYERS == 1 - s.roughness = roughness.x; + roughnessValue = roughness.x; #elif LAYERS == 2 - s.roughness += roughness.x * w.r; - s.roughness += roughness.y * w.g; + roughnessValue += roughness.x * w.r; + roughnessValue += roughness.y * w.g; #elif LAYERS == 3 - s.roughness += roughness.x * w.r; - s.roughness += roughness.y * w.g; - s.roughness += roughness.z * w.b; + roughnessValue += roughness.x * w.r; + roughnessValue += roughness.y * w.g; + roughnessValue += roughness.z * w.b; #elif LAYERS == 4 - s.roughness += roughness.x * w.r; - s.roughness += roughness.y * w.g; - s.roughness += roughness.z * w.b; - s.roughness += roughness.w * w.a; - #else - s.roughness = 1.0; + roughnessValue += roughness.x * w.r; + roughnessValue += roughness.y * w.g; + roughnessValue += roughness.z * w.b; + roughnessValue += roughness.w * w.a; #endif - - s.specularIntensity = 0.5; - - s.metallic = 0.0; #if LAYERS == 1 - s.specularIntensity = 0.5; - s.metallic = metallic.x; + metallicValue = metallic.x; #elif LAYERS == 2 - s.metallic += metallic.x * w.r; - s.metallic += metallic.y * w.g; + metallicValue += metallic.x * w.r; + metallicValue += metallic.y * w.g; #elif LAYERS == 3 - s.metallic += metallic.x * w.r; - s.metallic += metallic.y * w.g; - s.metallic += metallic.z * w.b; + metallicValue += metallic.x * w.r; + metallicValue += metallic.y * w.g; + metallicValue += metallic.z * w.b; #elif LAYERS == 4 - s.metallic += metallic.x * w.r; - s.metallic += metallic.y * w.g; - s.metallic += metallic.z * w.b; - s.metallic += metallic.w * w.a; - #else - s.specularIntensity = 0.5; - s.metallic = 0.0; + metallicValue += metallic.x * w.r; + metallicValue += metallic.y * w.g; + metallicValue += metallic.z * w.b; + metallicValue += metallic.w * w.a; #endif - #else - s.roughness = 1.0; - s.specularIntensity = 0.5; - s.metallic = 0.0; #endif - s.emissive = vec3(0.0, 0.0, 0.0); - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - vec4 lightColor = texture(cc_lightingMap, luv.xy); - s.lightmap = lightColor.xyz * luv.z; - s.lightmap_test = luv.z; /*lum*/ - #endif + surfaceData.ao = 1.0; + surfaceData.roughness = roughnessValue; + surfaceData.metallic = metallicValue; + surfaceData.specularIntensity = 0.5; + surfaceData.emissive = vec3(0.0); } - - CC_STANDARD_SURFACE_ENTRY() }% -CCProgram shadow-caster-vs %{ +CCProgram terrain-vs %{ precision highp float; - #include #include - #include + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include - in vec3 a_position; - in vec3 a_normal; - in vec2 a_texCoord; + // 2. common include with corresponding shader stage, include before surface functions + #include - out highp vec2 v_clip_depth; + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include - vec4 vert () { - vec4 worldPos; - worldPos.x = cc_matWorld[3][0] + a_position.x; - worldPos.y = cc_matWorld[3][1] + a_position.y; - worldPos.z = cc_matWorld[3][2] + a_position.z; - worldPos.w = 1.0; + // 4. surface include with corresponding shader stage and shading-model (optional) + #include - vec4 clipPos = cc_matLightViewProj * worldPos; + // 5. shader entry with corresponding shader stage and technique usage/type + #include +}% - v_clip_depth = clipPos.zw; - return clipPos; - } +CCProgram shadow-caster-vs %{ + precision highp float; + #include + #include + #include + #include + #include + #include }% -CCProgram shadow-caster-fs %{ +CCProgram terrain-fs %{ + precision highp float; - #include + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include - #pragma define SHADOWMAP_FORMAT_RGBA8 1 - #pragma define SHADOWMAP_FORMAT_FLOAT 0 + // 2. common include with corresponding shader stage, include before surface functions + #include - in highp vec2 v_clip_depth; + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include - vec4 frag () { - highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; + // 4. lighting-model (optional) + #include - //todo: do not support linear mode spot shadow - - #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 - return packDepthToRGBA(clipDepth); - #else - return vec4(clipDepth, 1.0, 1.0, 1.0); - #endif - } + // 5. surface include with corresponding shader stage and shading-model (optional) + #include + + // 6. shader entry with corresponding shader stage and technique usage/type + #include +}% + +CCProgram shadow-caster-fs %{ + precision highp float; + #include + #include + #include + #include + #include +}% + +CCProgram reflect-map-fs %{ + precision highp float; + #include + #include + #include + #include + #include + #include + #include + #include }% diff --git a/editor/assets/effects/builtin-terrain.effect.meta b/editor/assets/effects/builtin-terrain.effect.meta index f6fced1f2bf..5ccc4f2e8fc 100644 --- a/editor/assets/effects/builtin-terrain.effect.meta +++ b/editor/assets/effects/builtin-terrain.effect.meta @@ -1,8 +1,8 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "1d08ef62-a503-4ce2-8b9a-46c90873f7d3", + "uuid": "a0fd9f76-74fe-423c-92d9-298906c189ba", "files": [ ".json" ], diff --git a/editor/assets/effects/builtin-toon.effect b/editor/assets/effects/builtin-toon.effect index a36b279efcf..d88e7e1c8e0 100644 --- a/editor/assets/effects/builtin-toon.effect +++ b/editor/assets/effects/builtin-toon.effect @@ -1,11 +1,11 @@ -// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. CCEffect %{ techniques: - passes: - switch: USE_OUTLINE_PASS - vert: legacy/main-functions/outline-vs:vert - frag: legacy/main-functions/outline-fs:frag + vert: silhouette-edge-vs + frag: silhouette-edge-fs rasterizerState: cullMode: front depthStencilState: @@ -17,8 +17,8 @@ CCEffect %{ depthBias: { value: 0, target: outlineParams.y } baseColor: { editor: { type: color } } baseColorMap: { value: grey } - - vert: toon-vs:vert - frag: toon-fs:frag + - vert: toon-vs + frag: toon-fs properties: &props tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, linear: true, editor: { displayName: BaseColor, type: color } } @@ -41,8 +41,8 @@ CCEffect %{ shadeMap2: { value: white } specularMap: { value: white } emissiveMap: { value: grey } - - vert: toon-vs:vert - frag: toon-fs:frag + - vert: toon-vs + frag: toon-fs phase: forward-add propertyIndex: 1 embeddedMacros: { CC_FORWARD_ADD: true } @@ -58,8 +58,8 @@ CCEffect %{ blendSrcAlpha: zero blendDstAlpha: one properties: *props - - vert: shadow-caster-vs:vert - frag: shadow-caster-fs:frag + - vert: shadow-caster-vs + frag: shadow-caster-fs phase: shadow-caster propertyIndex: 1 rasterizerState: @@ -94,79 +94,31 @@ CCProgram shared-ubos %{ vec4 miscParams; vec4 emissive; vec4 emissiveScaleAndStrenth; - }; -}% - -CCProgram toon-vs %{ - precision highp float; - #include - #include - #include - #include - #include - #include - - out vec3 v_position; - out vec2 v_uv; - out mediump vec3 v_normal; - - #if CC_RECEIVE_SHADOW - out mediump vec2 v_shadowBias; - #endif - - #if USE_NORMAL_MAP - out mediump vec4 v_tangent; - #endif - - vec4 vert () { - StandardVertInput In; - CCVertInput(In); - - mat4 matWorld, matWorldIT; - CCGetWorldMatrixFull(matWorld, matWorldIT); + };}% - vec4 pos = matWorld * In.position; - v_position = pos.xyz; - v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; +CCProgram macro-remapping %{ + // if enabled, shadowed area is very dark + #pragma define-meta USE_COMPATIBLE_LIGHTING + #define CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING USE_COMPATIBLE_LIGHTING - #if CC_RECEIVE_SHADOW - v_shadowBias = CCGetShadowBias(); - #endif - - v_normal = (matWorldIT * vec4(In.normal, 0.0)).xyz; - #if USE_NORMAL_MAP - v_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); - v_tangent.w = In.tangent.w; - #endif - - CC_TRANSFER_SHADOW(pos); + #pragma define-meta USE_NORMAL_MAP + #define CC_SURFACES_USE_TANGENT_SPACE USE_NORMAL_MAP +}% - return cc_matProj * (cc_matView * matWorld) * In.position; +CCProgram surface-vertex %{ + #define CC_SURFACES_VERTEX_MODIFY_UV + void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) + { + In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; } }% -CCProgram toon-fs %{ - precision highp float; - #include - #include - #include - #include - #include - - in vec3 v_position; - in vec2 v_uv; - - #if CC_RECEIVE_SHADOW - in mediump vec2 v_shadowBias; - #endif - +CCProgram surface-fragment %{ #if USE_BASE_COLOR_MAP uniform sampler2D baseColorMap; #endif - in mediump vec3 v_normal; #if USE_NORMAL_MAP - in mediump vec4 v_tangent; uniform sampler2D normalMap; #endif @@ -187,149 +139,253 @@ CCProgram toon-fs %{ #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b]) #endif - void surf (out ToonSurface s) { - s.shade2 = shadeColor2.rgb * colorScaleAndCutoff.rgb; + + #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TOONSHADE + void SurfacesFragmentModifyBaseColorAndToonShade(out vec4 baseColorAndTransparency, out vec3 shade1, out vec3 shade2) + { + shade2 = shadeColor2.rgb * colorScaleAndCutoff.rgb; #if USE_2ND_SHADE_MAP - s.shade2 *= SRGBToLinear(texture(shadeMap2, v_uv).rgb); + shade2 *= SRGBToLinear(texture(shadeMap2, FSInput_texcoord).rgb); #endif - s.shade1 = shadeColor1.rgb * colorScaleAndCutoff.rgb; + shade1 = shadeColor1.rgb * colorScaleAndCutoff.rgb; #if USE_1ST_SHADE_MAP - s.shade1 *= SRGBToLinear(texture(shadeMap1, v_uv).rgb); + shade1 *= SRGBToLinear(texture(shadeMap1, FSInput_texcoord).rgb); #if SHADE_MAP_1_AS_SHADE_MAP_2 - s.shade2 *= s.shade1.rgb; + shade2 *= shade1.rgb; #endif #endif - vec4 baseColor = baseColor; + vec4 color = baseColor; #if USE_BASE_COLOR_MAP - vec4 baseColorMap = texture(baseColorMap, v_uv); - baseColorMap.rgb = SRGBToLinear(baseColorMap.rgb); - baseColor *= baseColorMap; + vec4 texColor = texture(baseColorMap, FSInput_texcoord); + texColor.rgb = SRGBToLinear(texColor.rgb); + color *= texColor; #if BASE_COLOR_MAP_AS_SHADE_MAP_1 - s.shade1 *= baseColorMap.rgb; + shade1 *= texColor.rgb; #endif #if BASE_COLOR_MAP_AS_SHADE_MAP_2 - s.shade2 *= baseColorMap.rgb; + shade2 *= texColor.rgb; #endif #endif - s.baseColor = baseColor; - s.baseColor.rgb *= colorScaleAndCutoff.xyz; + baseColorAndTransparency = color; + baseColorAndTransparency.rgb *= colorScaleAndCutoff.xyz; #if USE_ALPHA_TEST - if (s.baseColor.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; + if (baseColorAndTransparency.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; #endif + } - s.normal = v_normal; - - #if CC_RECEIVE_SHADOW - s.shadowBias = v_shadowBias; + #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY + void SurfacesFragmentAlphaClipOnly() + { + #if USE_ALPHA_TEST + float alpha = baseColor.ALPHA_TEST_CHANNEL; + #if USE_BASE_COLOR_MAP + alpha = texture(baseColorMap, FSInput_texcoord).ALPHA_TEST_CHANNEL; + #endif + + if (alpha < colorScaleAndCutoff.w) discard; #endif + } + #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL + vec3 SurfacesFragmentModifyWorldNormal() + { + vec3 normal = FSInput_worldNormal; #if USE_NORMAL_MAP - vec3 nmmp = texture(normalMap, v_uv).xyz - vec3(0.5); - vec3 bitangent = cross(v_normal, v_tangent.xyz) * v_tangent.w; // note the cross order - s.normal = - (nmmp.x * emissiveScaleAndStrenth.w) * normalize(v_tangent.xyz) + - (nmmp.y * emissiveScaleAndStrenth.w) * normalize(bitangent) + - nmmp.z * normalize(s.normal); + vec3 nmmp = texture(normalMap, FSInput_texcoord).xyz - vec3(0.5); + normal = CalculateNormalFromTangentSpace(nmmp, emissiveScaleAndStrenth.w, normal.xyz, FSInput_worldTangent, FSInput_mirrorNormal); #endif - HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); - - s.specular = specular; - #if USE_SPECULAR_MAP - s.specular.rgb *= SRGBToLinear(texture(specularMap, v_uv).rgb); - #endif + return normalize(normal); + } - s.emissive = emissive.rgb * emissiveScaleAndStrenth.xyz; + #define CC_SURFACES_FRAGMENT_MODIFY_EMISSIVE + vec3 SurfacesFragmentModifyEmissive() + { + vec3 emissive = emissive.rgb * emissiveScaleAndStrenth.xyz; #if USE_EMISSIVE_MAP - s.emissive *= SRGBToLinear(texture(emissiveMap, v_uv).rgb); + emissive *= SRGBToLinear(texture(emissiveMap, FSInput_texcoord).rgb); #endif + return emissive; + } - s.baseStep = shadeParams.x; - s.baseFeather = shadeParams.y; - s.shadeStep = shadeParams.z; - s.shadeFeather = shadeParams.w; - s.shadowCover = miscParams.x; + #define CC_SURFACES_FRAGMENT_MODIFY_TOON_STEP_AND_FEATHER + vec4 SurfacesFragmentModifyToonStepAndFeather() + { + return shadeParams; } - vec4 frag () { - ToonSurface s; surf(s); - vec4 color = CCToonShading(s); - return CCFragOutput(color); + #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SHADOW_COVER + float SurfacesFragmentModifyToonShadowCover() + { + return miscParams.x; } + + #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SPECULAR + vec4 SurfacesFragmentModifyToonSpecular() + { + vec4 specularParam = specular; + #if USE_SPECULAR_MAP + specularParam.rgb *= SRGBToLinear(texture(specularMap, FSInput_texcoord).rgb); + #endif + return specularParam; + } +}% + +CCProgram toon-vs %{ + precision highp float; + + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include + + // 2. common include with corresponding shader stage + #include + + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include + + // 4. surface include with corresponding shader stage and shading-model (optional) + #include + + // 5. shader entry with corresponding shader stage and technique usage/type + #include }% + CCProgram shadow-caster-vs %{ precision highp float; - #include - #include - #include + #include + #include #include - #include + #include + #include +}% - out vec2 v_uv; - out vec4 v_worldPos; - out highp vec2 v_clip_depth; +CCProgram toon-fs %{ + // shading-model : toon + // lighting-model : toon + // shader stage : fs + // technique usage/type : render-to-scene - vec4 vert () { - StandardVertInput In; - CCVertInput(In); + precision highp float; + // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros + #include + #include - mat4 matWorld, matWorldIT; - CCGetWorldMatrixFull(matWorld, matWorldIT); + // 2. common include with corresponding shader stage + #include - v_worldPos = matWorld * In.position; - vec4 clipPos = cc_matLightViewProj * v_worldPos; - v_clip_depth = clipPos.zw; + // 3. user surface functions that can use user (effect) parameters (ubo Constants) + // see surfaces/default-functions/xxx.chunk + #include + #include - v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; + // 4. lighting-model (optional) + #include - return clipPos; - } + // 5. surface include with corresponding shader stage and shading-model (optional) + #include + + // 6. shader entry with corresponding shader stage and technique usage/type + #include }% CCProgram shadow-caster-fs %{ precision highp float; + #include + #include #include - #include - #include - - in vec2 v_uv; - in vec4 v_worldPos; - in highp vec2 v_clip_depth; + #include + #include +}% + + + + + + - #if USE_BASE_COLOR_MAP - uniform sampler2D baseColorMap; - #endif - #if USE_ALPHA_TEST - #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b]) - #endif - vec4 frag () { - vec4 baseColor = baseColor; - #if USE_ALPHA_TEST - #if USE_BASE_COLOR_MAP - baseColor *= texture(baseColorMap, v_uv); - #endif - if (baseColor.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; - #endif - highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; - // spot use linear - if(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) { - // enabled linear depth - #if CC_SHADOWMAP_USE_LINEAR_DEPTH - clipDepth = CCGetLinearDepth(v_worldPos.xyz); - #endif - } - #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 - return packDepthToRGBA(clipDepth); - #else - return vec4(clipDepth, 1.0, 1.0, 1.0); + + + +////////////////////////////////////////////////silhouette-edge sample +// how to write a simple surface material +// change technique outline-vs/fs:vert/frag to silhouette-edge-vs/fs +CCProgram surface-vertex-silhouette-edge %{ + uniform OutlineVert { + vec4 outlineParams; // x: line width, y: depth hack +}; + + #define CC_SURFACES_VERTEX_MODIFY_LOCAL_POS + vec3 SurfacesVertexModifyLocalPos(in SurfacesStandardVertexIntermediate In) + { + float width = outlineParams.x * 0.001; + vec3 localPos = In.position.xyz; + + #if USE_POSITION_SCALING + vec3 dir = normalize(localPos); + float flip = dot(dir, normalize(In.normal)) < 0.0 ? -1.0 : 1.0; + localPos += flip * dir * width * 2.0; + #else + localPos += normalize(In.normal) * width; + #endif + return localPos; + } + + #define CC_SURFACES_VERTEX_MODIFY_CLIP_POS + vec4 SurfacesVertexModifyClipPos(in SurfacesStandardVertexIntermediate In) + { + vec4 clipPos = In.clipPos; + clipPos.z -= outlineParams.y * 0.002; + return clipPos; + } +}% + +CCProgram surface-fragment-silhouette-edge %{ + uniform OutlineFrag { + vec4 baseColor; + }; + #if USE_BASE_COLOR_MAP + uniform sampler2D baseColorMap; + #endif + + // only for render-to-shadow-map or misc usage + #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TRANSPARENCY + vec4 SurfacesFragmentModifyBaseColorAndTransparency() + { + vec4 color = vec4(cc_mainLitColor.rgb, 1.0); + color.rgb = SRGBToLinear(baseColor.rgb); + #if USE_BASE_COLOR_MAP + vec4 texColor = texture(baseColorMap, FSInput_texcoord); + texColor.rgb = SRGBToLinear(texColor.rgb); + color *= texColor; #endif + + return color; } }% + +CCProgram silhouette-edge-vs %{ + precision highp float; + #include + #include + #include + #include +}% + +CCProgram silhouette-edge-fs %{ + precision highp float; + #include + #include + #include + #include +}% diff --git a/editor/assets/effects/builtin-toon.effect.meta b/editor/assets/effects/builtin-toon.effect.meta index 0be5a1524e1..0594320d022 100644 --- a/editor/assets/effects/builtin-toon.effect.meta +++ b/editor/assets/effects/builtin-toon.effect.meta @@ -1,8 +1,8 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "a7612b54-35e3-4238-a1a9-4a7b54635839", + "uuid": "9b20a514-6cc3-49de-b216-b6b863046249", "files": [ ".json" ], diff --git a/editor/assets/effects/builtin-unlit.effect b/editor/assets/effects/builtin-unlit.effect index 89eff207d60..d291ad980f7 100644 --- a/editor/assets/effects/builtin-unlit.effect +++ b/editor/assets/effects/builtin-unlit.effect @@ -109,6 +109,7 @@ CCProgram unlit-vs %{ CCProgram unlit-fs %{ precision highp float; #include + #include #include #if USE_ALPHA_TEST @@ -149,6 +150,9 @@ CCProgram unlit-fs %{ #endif CC_APPLY_FOG(o); + #if CC_USE_RGBE_OUTPUT + o = packRGBE(o.rgb); + #endif return CCFragOutput(o); } }% diff --git a/editor/assets/effects/builtin-unlit.effect.meta b/editor/assets/effects/builtin-unlit.effect.meta index c093a2552d3..721bafd6389 100644 --- a/editor/assets/effects/builtin-unlit.effect.meta +++ b/editor/assets/effects/builtin-unlit.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "a3cd009f-0ab0-420d-9278-b9fdab939bbc", diff --git a/editor/assets/effects/dcc/imported-specular-glossiness.effect b/editor/assets/effects/dcc/imported-specular-glossiness.effect deleted file mode 100644 index 785de584d97..00000000000 --- a/editor/assets/effects/dcc/imported-specular-glossiness.effect +++ /dev/null @@ -1,508 +0,0 @@ -// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. - -CCEffect %{ - techniques: - - name: opaque - passes: - - vert: standard-vs - frag: standard-fs - properties: &props - mainTexture: { value: grey, target: albedoMap, editor: { displayName: DiffuseMap } } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: diffuseColor, linear: true, editor: { displayName: DiffuseColor, type: color } } - albedoScale: { value: 1.0, target: diffuseFactor, editor: { displayName: diffuseFactor } } - alphaThreshold: { value: 0.5, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } - emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } - emissiveMap: { value: grey } - shininessExponentMap: { value: grey, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } - shininessExponent: { value: 100.0, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } - specularGlossinessMap: { value: grey, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } - specularColor: { value: [0.0, 0.0, 0.0, 0.0], linear: true, editor: { displayName: SpecularColor, type: color } } - specularMap: { value: grey, editor: { parent: '!HAS_EXPORTED_METALLIC' } } - specularFactor: { value: 1.0, editor: { parent: '!HAS_EXPORTED_METALLIC' } } - transparencyMap: { value: grey, editor: { displayName: TransparencyMap } } - transparencyFactor: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - normalStrength: { value: 1.0, target: normalScale, editor: { displayName: bumpFactor, parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } - normalMap: { value: normal } - glossiness: { value: 0.0, editor: { parent: HAS_EXPORTED_GLOSSINESS, slide: true, range: [0, 1.0], step: 0.001 } } - metallic: { value: 0.0, editor: { parent: HAS_EXPORTED_METALLIC, slide: true, range: [0, 1.0], step: 0.001 } } - metallicMap: { value: grey, editor: { parent: HAS_EXPORTED_METALLIC } } - - &forward-add - vert: standard-vs - frag: standard-fs - phase: forward-add - propertyIndex: 0 - embeddedMacros: { CC_FORWARD_ADD: true } - depthStencilState: - depthFunc: equal - depthTest: true - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: one - blendDst: one - blendSrcAlpha: zero - blendDstAlpha: one - - &shadow-caster - vert: shadow-caster-vs:vert - frag: shadow-caster-fs:frag - phase: shadow-caster - propertyIndex: 0 - rasterizerState: - cullMode: front - properties: - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: diffuseColor, editor: { displayName: Albedo, type: color } } - albedoScale: { value: 1.0, target: diffuseFactor, editor: { displayName: diffuseFactor } } - alphaThreshold: { value: 0.5, editor: { parent: USE_ALPHA_TEST } } - mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - transparencyMap: { value: grey, editor: { displayName: TransparencyMap } } - transparencyFactor: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - - name: transparent - passes: - - vert: standard-vs - frag: standard-fs - embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: - depthTest: true - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: src_alpha - blendDst: one_minus_src_alpha - blendDstAlpha: one_minus_src_alpha - properties: *props - - *forward-add - - *shadow-caster -}% - -CCProgram shared-ubos %{ - uniform Constants { - vec4 tilingOffset; - vec4 diffuseColor; - vec4 specularColor; - vec4 emissive; - float alphaThreshold; - float shininessExponent; - float glossiness; - float metallic; - float normalScale; - float transparencyFactor; - float diffuseFactor; - float specularFactor; - }; -}% - -CCProgram standard-vs %{ - precision highp float; - #include - #include - #include - #include - #include - #include - - #if USE_VERTEX_COLOR - in vec4 a_color; - out vec4 v_color; - #endif - - out vec3 v_position; - out vec3 v_normal; - out vec2 v_uv; - out vec2 v_uv1; - - #if USE_NORMAL_MAP - out vec3 v_tangent; - out vec3 v_bitangent; - #endif - - #if CC_RECEIVE_SHADOW - out mediump vec2 v_shadowBias; - #endif - - #if HAS_SECOND_UV || CC_USE_LIGHTMAP - in vec2 a_texCoord1; - #endif - - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - #include - #endif - - void main () { - StandardVertInput In; - CCVertInput(In); - - mat4 matWorld, matWorldIT; - CCGetWorldMatrixFull(matWorld, matWorldIT); - - vec4 pos = matWorld * In.position; - - v_position = pos.xyz; - v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz); - - #if USE_TWOSIDE - vec3 viewDirect = normalize(cc_cameraPos.xyz - v_position); - v_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0; - #endif - - #if USE_NORMAL_MAP - v_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); - v_bitangent = cross(v_normal, v_tangent) * In.tangent.w; // note the cross order - #endif - - v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; - - #if HAS_SECOND_UV - v_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw; - #endif - - #if USE_VERTEX_COLOR - v_color = a_color; - #endif - - CC_TRANSFER_FOG(pos); - CC_TRANSFER_SHADOW(pos); - - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - CCLightingMapCaclUV(); - #endif - - #if CC_RECEIVE_SHADOW - v_shadowBias = CCGetShadowBias(); - #endif - - gl_Position = cc_matProj * (cc_matView * matWorld) * In.position; - } -}% - -CCProgram standard-fs %{ - precision highp float; - #include - #include - #include - #include - #include - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - #include - #endif - - in vec3 v_position; - in vec2 v_uv; - in vec2 v_uv1; - in vec3 v_normal; - - #if CC_RECEIVE_SHADOW - in mediump vec2 v_shadowBias; - #endif - - - #pragma define-meta TEXTURE_UV options([v_uv, v_uv1]) - #pragma define-meta DCC_APP_NAME range([0, 5]) - #define DCC_APP_OTHERS 0 - #define DCC_APP_MAX 1 - #define DCC_APP_BLENDER 2 - #define DCC_APP_CINEMA4D 3 - #define DCC_APP_GLTF 4 - #define DCC_APP_MAYA 5 - - #if USE_SHININESS_MAP - uniform sampler2D shininessExponentMap; - #pragma define-meta SHININESS_MAP_CHANNEL options([a,r,g,b]) - #endif - #if USE_SPECULAR_GLOSSINESS_MAP - uniform sampler2D specularGlossinessMap; - #endif - #if USE_SPECULAR_MAP - uniform sampler2D specularMap; - #endif - #if USE_METALLIC_MAP - uniform sampler2D metallicMap; - #endif - - #if USE_VERTEX_COLOR - in vec4 v_color; - #endif - - #if USE_ALBEDO_MAP - uniform sampler2D albedoMap; - #endif - #if USE_TRANSPARENCY_MAP - uniform sampler2D transparencyMap; - #pragma define-meta TRANSPARENCY_MAP_CHANNEL options([a, r, g, b]) - #endif - - #if USE_NORMAL_MAP - in vec3 v_tangent; - in vec3 v_bitangent; - uniform sampler2D normalMap; - #endif - - #if USE_EMISSIVE_MAP - uniform sampler2D emissiveMap; - #endif - - float discolor(vec3 srcColor) { - return dot(GRAY_VECTOR, srcColor); - } - float convertShininessExponent(float shininessExp) - { - #if DCC_APP_NAME == DCC_APP_BLENDER - // 2-100 - float glossiness = clamp(sqrt(shininessExp) * 0.1/*/10.0*/, 0.0, 0.95); // glossiness=1 may leads to specular disappear - #elif DCC_APP_NAME == DCC_APP_MAX || DCC_APP_NAME == DCC_APP_MAYA - // 2-1024 - float l2 = clamp(log(shininessExp + EPSILON) * 0.1442695 /*/log(2.0)/10.0*/, 0.0, 1.0); - float glossiness = pow(l2, 0.5); - #else // DCC_APP_NAME == DCC_APP_CINEMA4D / DCC_APP_GLTF / DCC_APP_OTHERS - // 2-1024 - float glossiness = clamp(log(shininessExp + EPSILON) * 0.1442695 /*/log(2.0)/10.0*/, 0.0, 1.0); - #endif - return glossiness; - } - float getSpecularIntensityFromRoughness(float roughness) - { - #if DCC_APP_NAME == DCC_APP_BLENDER - float specularIntensityMultiplier = mix(1.0, 5.0, roughness); - #elif DCC_APP_NAME == DCC_APP_CINEMA4D - float specularIntensityMultiplier = mix(1.0, 50.0, roughness); - #elif DCC_APP_NAME == DCC_APP_MAX || DCC_APP_NAME == DCC_APP_MAYA - float specularIntensityMultiplier = mix(1.0, 20.0, roughness); - #else // DCC_APP_NAME == DCC_APP_GLTF / DCC_APP_OTHERS - float specularIntensityMultiplier = 1.0; - #endif - return specularIntensityMultiplier; - } - - vec4 getSpecularColorAndFactor() - { - vec3 inSpecular = specularColor.rgb * specularFactor; - float inFactor = 1.0; //reserved - #if USE_SPECULAR_GLOSSINESS_MAP - inSpecular = SRGBToLinear(texture(specularGlossinessMap, TEXTURE_UV).rgb); - #endif - #if USE_SPECULAR_MAP - vec4 specularTex = texture(specularMap, TEXTURE_UV); - specularTex.rgb = SRGBToLinear(specularTex.rgb); - inSpecular = specularTex.rgb; - #endif - return vec4(inSpecular, inFactor); - } - void surf (out StandardSurface s) { - //diffuse - vec4 baseColor = vec4(1.0); - #if USE_VERTEX_COLOR - baseColor.rgb *= SRGBToLinear(v_color.rgb); - baseColor.a *= v_color.a; - #endif - #if USE_ALBEDO_MAP - vec4 texColor = texture(albedoMap, TEXTURE_UV); - texColor.rgb = SRGBToLinear(texColor.rgb); - texColor.a *= transparencyFactor; - baseColor *= texColor; - #else - baseColor *= diffuseColor; - #endif - baseColor.rgb *= diffuseFactor; - - #if USE_TRANSPARENCY_MAP - baseColor.a = texture(transparencyMap, TEXTURE_UV).TRANSPARENCY_MAP_CHANNEL; - #if DCC_APP_NAME == DCC_APP_MAYA - baseColor.a = 1.0 - baseColor.a; - #endif - #endif - - #if USE_ALPHA_TEST - if (baseColor.a < alphaThreshold) discard; - #endif - - #if CC_RECEIVE_SHADOW - s.shadowBias = v_shadowBias; - #endif - - vec4 specularColorAndFactor = getSpecularColorAndFactor(); - - //glossiness - float inGlossiness = 0.0, inSpecularIntensity = 1.0; - #if HAS_EXPORTED_GLOSSINESS - #if USE_SPECULAR_GLOSSINESS_MAP - inGlossiness = 1.0 - texture(specularGlossinessMap, TEXTURE_UV).a; - #else - inGlossiness = glossiness; - #endif - #else - #if USE_SHININESS_MAP - #if USE_SHININESS_MAP_CHANNEL - inGlossiness = 1.0 - texture(shininessExponentMap, TEXTURE_UV).SHININESS_MAP_CHANNEL; - #else - inGlossiness = 1.0 - discolor(texture(shininessExponentMap, TEXTURE_UV).rgb); - #endif - #else - inGlossiness = convertShininessExponent(shininessExponent); - #endif - - inSpecularIntensity *= getSpecularIntensityFromRoughness(1.0 - inGlossiness); - #endif - - //metallic - float inMetallic = 0.0; - vec4 albedo = baseColor; - #if HAS_EXPORTED_METALLIC - inMetallic = metallic; - float spec = specularFactor; - #if USE_SPECULAR_MAP - spec = dot(GRAY_VECTOR, texture(specularMap, TEXTURE_UV).rgb); - #endif - inSpecularIntensity *= spec * 0.5; - #else - GetMetallicAlbedoFromDiffuseSpecularWithoutColor(inMetallic, albedo.rgb, baseColor.rgb, specularColorAndFactor.rgb, 0.04); - inSpecularIntensity *= inMetallic; //simulate specular color is black - #endif - - s.normal = v_normal; - #if USE_NORMAL_MAP - vec3 nmmp = texture(normalMap, TEXTURE_UV).xyz - vec3(0.5); - s.normal = - (nmmp.x * normalScale) * normalize(v_tangent) + - (nmmp.y * normalScale) * normalize(v_bitangent) + - nmmp.z * normalize(s.normal); - #endif - - HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); - - s.albedo = albedo; - s.occlusion = 1.0; - s.roughness = 1.0 - inGlossiness; - s.metallic = inMetallic; - s.specularIntensity = inSpecularIntensity * 0.5; - s.emissive = emissive.rgb; - #if USE_EMISSIVE_MAP - s.emissive = texture(emissiveMap, TEXTURE_UV).xyz; - #endif - - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - vec4 lightColor = texture(cc_lightingMap, v_luv.xy); - s.lightmap = lightColor.xyz * v_luv.z; - s.lightmap_test = v_luv.z; /*lum*/ - #endif - } - - CC_STANDARD_SURFACE_ENTRY() -}% - -CCProgram shadow-caster-vs %{ - precision highp float; - #include - #include - #include - #include - - #if HAS_SECOND_UV || CC_USE_LIGHTMAP - in vec2 a_texCoord1; - #endif - - out vec2 v_uv; - out vec2 v_uv1; - out vec4 v_worldPos; - - out highp vec2 v_clip_depth; - - #if USE_VERTEX_COLOR - in vec4 a_color; - out lowp vec4 v_color; - #endif - - vec4 vert () { - StandardVertInput In; - CCVertInput(In); - - mat4 matWorld, matWorldIT; - CCGetWorldMatrixFull(matWorld, matWorldIT); - - v_worldPos = matWorld * In.position; - vec4 clipPos = cc_matLightViewProj * v_worldPos; - - v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; - #if HAS_SECOND_UV - v_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw; - #endif - - #if USE_VERTEX_COLOR - v_color = a_color; - #endif - - v_clip_depth = clipPos.zw; - - return clipPos; - } -}% - -CCProgram shadow-caster-fs %{ - precision highp float; - #include - #include - #include - - in vec2 v_uv; - in vec2 v_uv1; - in vec4 v_worldPos; - in highp vec2 v_clip_depth; - - #pragma define-meta TEXTURE_UV options([v_uv, v_uv1]) - #pragma define-meta DCC_APP_NAME range([0, 5]) - #define DCC_APP_OTHERS 0 - #define DCC_APP_MAX 1 - #define DCC_APP_BLENDER 2 - #define DCC_APP_CINEMA4D 3 - #define DCC_APP_GLTF 4 - #define DCC_APP_MAYA 5 - - #if USE_ALBEDO_MAP - uniform sampler2D albedoMap; - #endif - - #if USE_TRANSPARENCY_MAP - uniform sampler2D transparencyMap; - #pragma define-meta TRANSPARENCY_MAP_CHANNEL options([a, r, g, b]) - #endif - - #if USE_VERTEX_COLOR - in lowp vec4 v_color; - #endif - - vec4 frag () { - #if USE_ALPHA_TEST - float alpha = diffuseColor.a; - #if USE_VERTEX_COLOR - alpha *= v_color.a; - #endif - #if USE_ALBEDO_MAP - alpha *= texture(albedoMap, TEXTURE_UV).a * transparencyFactor; - #endif - #if USE_TRANSPARENCY_MAP - alpha = texture(transparencyMap, TEXTURE_UV).TRANSPARENCY_MAP_CHANNEL; - #if DCC_APP_NAME == DCC_APP_MAYA - alpha = 1.0 - alpha; - #endif - #endif - if (alpha < alphaThreshold) discard; - #endif - - highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; - // spot use linear - if(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) { - // enabled linear depth - #if CC_SHADOWMAP_USE_LINEAR_DEPTH - clipDepth = CCGetLinearDepth(v_worldPos.xyz); - #endif - } - - #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 - return packDepthToRGBA(clipDepth); - #else - return vec4(clipDepth, 1.0, 1.0, 1.0); - #endif - } -}% diff --git a/editor/assets/effects/for2d.meta b/editor/assets/effects/for2d.meta new file mode 100644 index 00000000000..0619f1ad518 --- /dev/null +++ b/editor/assets/effects/for2d.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "c183505b-b5a7-4984-b335-f0e72576ca78", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/editor/assets/effects/builtin-spine.effect b/editor/assets/effects/for2d/builtin-spine.effect similarity index 96% rename from editor/assets/effects/builtin-spine.effect rename to editor/assets/effects/for2d/builtin-spine.effect index c355817e2c2..eeddef1f187 100644 --- a/editor/assets/effects/builtin-spine.effect +++ b/editor/assets/effects/for2d/builtin-spine.effect @@ -68,7 +68,7 @@ CCProgram sprite-fs %{ #endif in vec2 uv0; #pragma builtin(local) - layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture; + layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; vec4 frag () { diff --git a/editor/assets/effects/builtin-spine.effect.meta b/editor/assets/effects/for2d/builtin-spine.effect.meta similarity index 90% rename from editor/assets/effects/builtin-spine.effect.meta rename to editor/assets/effects/for2d/builtin-spine.effect.meta index cbbda5a7016..da37e86b89d 100644 --- a/editor/assets/effects/builtin-spine.effect.meta +++ b/editor/assets/effects/for2d/builtin-spine.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "c27215d8-6835-4b68-bfbb-bdeac6100c04", diff --git a/editor/assets/effects/builtin-sprite-renderer.effect b/editor/assets/effects/for2d/builtin-sprite-renderer.effect similarity index 94% rename from editor/assets/effects/builtin-sprite-renderer.effect rename to editor/assets/effects/for2d/builtin-sprite-renderer.effect index 376c6b5c928..3f962912e64 100644 --- a/editor/assets/effects/builtin-sprite-renderer.effect +++ b/editor/assets/effects/for2d/builtin-sprite-renderer.effect @@ -44,7 +44,7 @@ CCProgram spriteRender-fs %{ in vec2 uv0; #pragma builtin(local) - layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture; + layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; vec4 frag () { vec4 o = vec4(1, 1, 1, 1); diff --git a/editor/assets/effects/builtin-sprite-renderer.effect.meta b/editor/assets/effects/for2d/builtin-sprite-renderer.effect.meta similarity index 90% rename from editor/assets/effects/builtin-sprite-renderer.effect.meta rename to editor/assets/effects/for2d/builtin-sprite-renderer.effect.meta index c4ff4ad5eb1..7bc53c37e83 100644 --- a/editor/assets/effects/builtin-sprite-renderer.effect.meta +++ b/editor/assets/effects/for2d/builtin-sprite-renderer.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "6ef1defe-7997-477a-9b35-c18859ff8066", diff --git a/editor/assets/effects/builtin-sprite.effect b/editor/assets/effects/for2d/builtin-sprite.effect similarity index 96% rename from editor/assets/effects/builtin-sprite.effect rename to editor/assets/effects/for2d/builtin-sprite.effect index 86e1d95d05e..c3ce0e2d6e1 100644 --- a/editor/assets/effects/builtin-sprite.effect +++ b/editor/assets/effects/for2d/builtin-sprite.effect @@ -70,7 +70,7 @@ CCProgram sprite-fs %{ #if USE_TEXTURE in vec2 uv0; #pragma builtin(local) - layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture; + layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; #endif vec4 frag () { diff --git a/editor/assets/effects/builtin-sprite.effect.meta b/editor/assets/effects/for2d/builtin-sprite.effect.meta similarity index 91% rename from editor/assets/effects/builtin-sprite.effect.meta rename to editor/assets/effects/for2d/builtin-sprite.effect.meta index 2feaea8bf43..2f49f3e83ed 100644 --- a/editor/assets/effects/builtin-sprite.effect.meta +++ b/editor/assets/effects/for2d/builtin-sprite.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "60f7195c-ec2a-45eb-ba94-8955f60e81d0", diff --git a/editor/assets/effects/internal.meta b/editor/assets/effects/internal.meta new file mode 100644 index 00000000000..6a52cf0aeee --- /dev/null +++ b/editor/assets/effects/internal.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "0961841a-d572-45ff-af75-1a8f9c1a470c", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/editor/assets/effects/builtin-camera-texture.effect b/editor/assets/effects/internal/builtin-camera-texture.effect similarity index 100% rename from editor/assets/effects/builtin-camera-texture.effect rename to editor/assets/effects/internal/builtin-camera-texture.effect diff --git a/editor/assets/effects/builtin-camera-texture.effect.meta b/editor/assets/effects/internal/builtin-camera-texture.effect.meta similarity index 90% rename from editor/assets/effects/builtin-camera-texture.effect.meta rename to editor/assets/effects/internal/builtin-camera-texture.effect.meta index 786625a5351..81df8e137b8 100644 --- a/editor/assets/effects/builtin-camera-texture.effect.meta +++ b/editor/assets/effects/internal/builtin-camera-texture.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "bf4078d6-d2d7-4073-83bb-cd6f1802e880", diff --git a/editor/assets/effects/builtin-clear-stencil.effect b/editor/assets/effects/internal/builtin-clear-stencil.effect similarity index 100% rename from editor/assets/effects/builtin-clear-stencil.effect rename to editor/assets/effects/internal/builtin-clear-stencil.effect diff --git a/editor/assets/effects/builtin-clear-stencil.effect.meta b/editor/assets/effects/internal/builtin-clear-stencil.effect.meta similarity index 91% rename from editor/assets/effects/builtin-clear-stencil.effect.meta rename to editor/assets/effects/internal/builtin-clear-stencil.effect.meta index 262a33ae5b8..0e71c13fcba 100644 --- a/editor/assets/effects/builtin-clear-stencil.effect.meta +++ b/editor/assets/effects/internal/builtin-clear-stencil.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "810e96e4-e456-4468-9b59-f4e8f39732c0", diff --git a/editor/assets/effects/builtin-debug-renderer.effect b/editor/assets/effects/internal/builtin-debug-renderer.effect similarity index 100% rename from editor/assets/effects/builtin-debug-renderer.effect rename to editor/assets/effects/internal/builtin-debug-renderer.effect diff --git a/editor/assets/effects/builtin-debug-renderer.effect.meta b/editor/assets/effects/internal/builtin-debug-renderer.effect.meta similarity index 90% rename from editor/assets/effects/builtin-debug-renderer.effect.meta rename to editor/assets/effects/internal/builtin-debug-renderer.effect.meta index 656d058e12d..80b3427e7fd 100644 --- a/editor/assets/effects/builtin-debug-renderer.effect.meta +++ b/editor/assets/effects/internal/builtin-debug-renderer.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "ff9be190-20a4-4e48-b68c-76e3c7cff085", diff --git a/editor/assets/effects/builtin-geometry-renderer.effect b/editor/assets/effects/internal/builtin-geometry-renderer.effect similarity index 100% rename from editor/assets/effects/builtin-geometry-renderer.effect rename to editor/assets/effects/internal/builtin-geometry-renderer.effect diff --git a/editor/assets/effects/builtin-geometry-renderer.effect.meta b/editor/assets/effects/internal/builtin-geometry-renderer.effect.meta similarity index 90% rename from editor/assets/effects/builtin-geometry-renderer.effect.meta rename to editor/assets/effects/internal/builtin-geometry-renderer.effect.meta index a45df37642a..e508b77a840 100644 --- a/editor/assets/effects/builtin-geometry-renderer.effect.meta +++ b/editor/assets/effects/internal/builtin-geometry-renderer.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "4bb480dd-8384-4bc9-987f-de67cc53052a", diff --git a/editor/assets/effects/builtin-graphics.effect b/editor/assets/effects/internal/builtin-graphics.effect similarity index 100% rename from editor/assets/effects/builtin-graphics.effect rename to editor/assets/effects/internal/builtin-graphics.effect diff --git a/editor/assets/effects/builtin-graphics.effect.meta b/editor/assets/effects/internal/builtin-graphics.effect.meta similarity index 90% rename from editor/assets/effects/builtin-graphics.effect.meta rename to editor/assets/effects/internal/builtin-graphics.effect.meta index d864f60ed15..58823c94d64 100644 --- a/editor/assets/effects/builtin-graphics.effect.meta +++ b/editor/assets/effects/internal/builtin-graphics.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "1c02ae6f-4492-4915-b8f8-7492a3b1e4cd", diff --git a/editor/assets/effects/builtin-occlusion-query.effect b/editor/assets/effects/internal/builtin-occlusion-query.effect similarity index 100% rename from editor/assets/effects/builtin-occlusion-query.effect rename to editor/assets/effects/internal/builtin-occlusion-query.effect diff --git a/editor/assets/effects/builtin-occlusion-query.effect.meta b/editor/assets/effects/internal/builtin-occlusion-query.effect.meta similarity index 90% rename from editor/assets/effects/builtin-occlusion-query.effect.meta rename to editor/assets/effects/internal/builtin-occlusion-query.effect.meta index e8417588f1a..7b3e47f18cb 100644 --- a/editor/assets/effects/builtin-occlusion-query.effect.meta +++ b/editor/assets/effects/internal/builtin-occlusion-query.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "d9937e59-61fe-4ec6-92ab-7ac5a19c89b0", diff --git a/editor/assets/effects/builtin-reflection-deferred.effect b/editor/assets/effects/internal/builtin-reflection-deferred.effect similarity index 96% rename from editor/assets/effects/builtin-reflection-deferred.effect rename to editor/assets/effects/internal/builtin-reflection-deferred.effect index 79bb8e86957..3757d607777 100644 --- a/editor/assets/effects/builtin-reflection-deferred.effect +++ b/editor/assets/effects/internal/builtin-reflection-deferred.effect @@ -54,6 +54,7 @@ CCProgram standard-vs %{ #include #include #include + #include #if USE_VERTEX_COLOR in vec4 a_color; @@ -105,6 +106,7 @@ CCProgram standard-vs %{ CC_TRANSFER_FOG(pos); CC_TRANSFER_SHADOW(pos); + CC_TRANSFER_SH(); #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD CCLightingMapCaclUV(); @@ -184,10 +186,6 @@ CCProgram standard-fs %{ if (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; #endif - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - s.lightmap = texture(cc_lightingMap, v_luv); - #endif - s.normal = v_normal; #if USE_NORMAL_MAP vec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5); @@ -197,6 +195,10 @@ CCProgram standard-fs %{ nmmp.z * normalize(s.normal); #endif + #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD + SampleAndDecodeLightMapColor(s.lightmap.rgb, s.lightmap.a, s.lightmap_test, cc_lightingMap, v_luv.xy, v_luv.z, s.normal); + #endif + HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); vec4 pbr = pbrParams; @@ -227,7 +229,7 @@ CCProgram standard-fs %{ } #pragma builtin(local) - layout(set = 2, binding = 12) uniform sampler2D cc_reflectionTexture; + layout(set = 2, binding = 13) uniform sampler2D cc_reflectionTexture; layout(location = 0) out vec4 fragColorX; diff --git a/editor/assets/effects/builtin-reflection-deferred.effect.meta b/editor/assets/effects/internal/builtin-reflection-deferred.effect.meta similarity index 90% rename from editor/assets/effects/builtin-reflection-deferred.effect.meta rename to editor/assets/effects/internal/builtin-reflection-deferred.effect.meta index 159e446037b..15a79f4424a 100644 --- a/editor/assets/effects/builtin-reflection-deferred.effect.meta +++ b/editor/assets/effects/internal/builtin-reflection-deferred.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "99498f84-efe6-43a6-a9a7-e6e93eb845c1", diff --git a/editor/assets/effects/builtin-wireframe.effect b/editor/assets/effects/internal/builtin-wireframe.effect similarity index 100% rename from editor/assets/effects/builtin-wireframe.effect rename to editor/assets/effects/internal/builtin-wireframe.effect diff --git a/editor/assets/effects/builtin-wireframe.effect.meta b/editor/assets/effects/internal/builtin-wireframe.effect.meta similarity index 90% rename from editor/assets/effects/builtin-wireframe.effect.meta rename to editor/assets/effects/internal/builtin-wireframe.effect.meta index e07c27a38c2..b3d6b45cf15 100644 --- a/editor/assets/effects/builtin-wireframe.effect.meta +++ b/editor/assets/effects/internal/builtin-wireframe.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "81127eb0-7556-453c-b147-670782dd5e53", diff --git a/editor/assets/effects/editor.meta b/editor/assets/effects/internal/editor.meta similarity index 100% rename from editor/assets/effects/editor.meta rename to editor/assets/effects/internal/editor.meta diff --git a/editor/assets/effects/editor/gizmo.effect b/editor/assets/effects/internal/editor/gizmo.effect similarity index 64% rename from editor/assets/effects/editor/gizmo.effect rename to editor/assets/effects/internal/editor/gizmo.effect index a55cfccb3f8..f43d1f25f31 100644 --- a/editor/assets/effects/editor/gizmo.effect +++ b/editor/assets/effects/internal/editor/gizmo.effect @@ -4,7 +4,7 @@ CCEffect %{ techniques: - passes: - vert: gizmo-vs:vert - frag: gizmo-fs:frag + frag: gizmo-fs:front priority: max - 10 rasterizerState: cullMode: none @@ -52,6 +52,27 @@ CCEffect %{ cullMode: none depthStencilState: *disable_depth blendState: *enable_blend + + - passes: + - vert: gizmo-vs:vert + frag: gizmo-fs:front + priority: max - 10 + rasterizerState: + cullMode: none + depthStencilState: + depthTest: true + depthWrite: false + blendState: *enable_blend + - vert: gizmo-vs:vert + frag: gizmo-fs:back + priority: max - 10 + rasterizerState: + cullMode: none + depthStencilState: + depthTest: true + depthWrite: false + depthFunc: greater + blendState: *enable_blend }% CCProgram gizmo-vs %{ @@ -88,7 +109,11 @@ CCProgram gizmo-fs %{ #include #include #include - #include + #if CC_USE_LIGHT_PROBE + #include + #else + #include + #endif in vec3 normal_w; in vec3 pos_w; @@ -99,28 +124,60 @@ CCProgram gizmo-fs %{ uniform Constant { vec4 mainColor; + + // SH coefficents used for light probe visualization + vec4 cc_sh_linear_const_r; + vec4 cc_sh_linear_const_g; + vec4 cc_sh_linear_const_b; + vec4 cc_sh_quadratic_r; + vec4 cc_sh_quadratic_g; + vec4 cc_sh_quadratic_b; + vec4 cc_sh_quadratic_a; }; - vec4 frag () { - vec3 N = normalize(normal_w) * (float(gl_FrontFacing) * 2.0 - 1.0); - vec3 V = normalize(cc_cameraPos.xyz - pos_w); - - // vec3 L = normalize(cross(forward, vec3(0, 1, 0))); - // vec3 diffuse = color.rgb * (0.2 + max(0.0, dot(N, L)) * 0.8); - - vec3 points [4]; - //vec3 up = vec3(0, 1, 0); - points[0] = (forward * 3.0 + right + up) * 40.0; - points[1] = (forward * 3.0 - right + up) * 40.0; - points[2] = (forward * 3.0 - right - up) * 40.0; - points[3] = (forward * 3.0 + right - up) * 40.0; - vec3 diffuse = LinearToSRGB(mainColor.rgb * LTC_Evaluate(N, V, pos_l, mat3(1), points)); - #if USE_FORWARD_PIPELINE - return CCFragOutput(vec4(diffuse, mainColor.a)); + #if CC_USE_LIGHT_PROBE + #include + #endif + + vec4 gizmo_fs (float alpha) { + #if CC_USE_LIGHT_PROBE + vec3 N = normalize(normal_w) * (float(gl_FrontFacing) * 2.0 - 1.0); + vec3 diffuse = SHEvaluate(N); + + #if USE_FORWARD_PIPELINE + return CCFragOutput(vec4(diffuse, mainColor.a * alpha)); + #else + return vec4(diffuse, mainColor.a * alpha); + #endif #else - return vec4(diffuse, mainColor.a); + vec3 N = normalize(normal_w) * (float(gl_FrontFacing) * 2.0 - 1.0); + vec3 V = normalize(cc_cameraPos.xyz - pos_w); + + // vec3 L = normalize(cross(forward, vec3(0, 1, 0))); + // vec3 diffuse = color.rgb * (0.2 + max(0.0, dot(N, L)) * 0.8); + + vec3 points [4]; + //vec3 up = vec3(0, 1, 0); + points[0] = (forward * 3.0 + right + up) * 40.0; + points[1] = (forward * 3.0 - right + up) * 40.0; + points[2] = (forward * 3.0 - right - up) * 40.0; + points[3] = (forward * 3.0 + right - up) * 40.0; + vec3 diffuse = LinearToSRGB(mainColor.rgb * LTC_Evaluate(N, V, pos_l, mat3(1), points)); + #if USE_FORWARD_PIPELINE + return CCFragOutput(vec4(diffuse, mainColor.a * alpha)); + #else + return vec4(diffuse, mainColor.a * alpha); + #endif #endif } + + vec4 front () { + return gizmo_fs(1.0); + } + + vec4 back () { + return gizmo_fs(0.2); + } }% CCProgram line-vs %{ diff --git a/editor/assets/effects/editor/gizmo.effect.meta b/editor/assets/effects/internal/editor/gizmo.effect.meta similarity index 92% rename from editor/assets/effects/editor/gizmo.effect.meta rename to editor/assets/effects/internal/editor/gizmo.effect.meta index 0e59e7f2b26..9d63a97d2de 100644 --- a/editor/assets/effects/editor/gizmo.effect.meta +++ b/editor/assets/effects/internal/editor/gizmo.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "9d6c6bde-2fe2-44ee-883b-909608948b04", diff --git a/editor/assets/effects/editor/grid-2d.effect b/editor/assets/effects/internal/editor/grid-2d.effect similarity index 100% rename from editor/assets/effects/editor/grid-2d.effect rename to editor/assets/effects/internal/editor/grid-2d.effect diff --git a/editor/assets/effects/editor/grid-2d.effect.meta b/editor/assets/effects/internal/editor/grid-2d.effect.meta similarity index 92% rename from editor/assets/effects/editor/grid-2d.effect.meta rename to editor/assets/effects/internal/editor/grid-2d.effect.meta index 1f4b776d6ef..235a74c0035 100644 --- a/editor/assets/effects/editor/grid-2d.effect.meta +++ b/editor/assets/effects/internal/editor/grid-2d.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "cb2c332a-fa5e-4235-a129-f011634bb7ad", diff --git a/editor/assets/effects/editor/grid-stroke.effect b/editor/assets/effects/internal/editor/grid-stroke.effect similarity index 100% rename from editor/assets/effects/editor/grid-stroke.effect rename to editor/assets/effects/internal/editor/grid-stroke.effect diff --git a/editor/assets/effects/editor/grid-stroke.effect.meta b/editor/assets/effects/internal/editor/grid-stroke.effect.meta similarity index 92% rename from editor/assets/effects/editor/grid-stroke.effect.meta rename to editor/assets/effects/internal/editor/grid-stroke.effect.meta index 8f3614a270d..44c1e070cf8 100644 --- a/editor/assets/effects/editor/grid-stroke.effect.meta +++ b/editor/assets/effects/internal/editor/grid-stroke.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "4736e978-c8fa-449f-9cf6-fe0158ded9d7", diff --git a/editor/assets/effects/editor/grid.effect b/editor/assets/effects/internal/editor/grid.effect similarity index 100% rename from editor/assets/effects/editor/grid.effect rename to editor/assets/effects/internal/editor/grid.effect diff --git a/editor/assets/effects/editor/grid.effect.meta b/editor/assets/effects/internal/editor/grid.effect.meta similarity index 92% rename from editor/assets/effects/editor/grid.effect.meta rename to editor/assets/effects/internal/editor/grid.effect.meta index 5927bf6fec0..71ae430943e 100644 --- a/editor/assets/effects/editor/grid.effect.meta +++ b/editor/assets/effects/internal/editor/grid.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "ba35f02e-a81c-464c-bfc5-c788328da667", diff --git a/editor/assets/effects/editor/light.effect b/editor/assets/effects/internal/editor/light.effect similarity index 100% rename from editor/assets/effects/editor/light.effect rename to editor/assets/effects/internal/editor/light.effect diff --git a/editor/assets/effects/editor/light.effect.meta b/editor/assets/effects/internal/editor/light.effect.meta similarity index 92% rename from editor/assets/effects/editor/light.effect.meta rename to editor/assets/effects/internal/editor/light.effect.meta index a20a6e0612f..b74bb7eaea5 100644 --- a/editor/assets/effects/editor/light.effect.meta +++ b/editor/assets/effects/internal/editor/light.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "e4e4cb19-8dd2-450d-ad20-1a818263b8d3", diff --git a/editor/assets/effects/editor/terrain-circle-brush.effect b/editor/assets/effects/internal/editor/terrain-circle-brush.effect similarity index 100% rename from editor/assets/effects/editor/terrain-circle-brush.effect rename to editor/assets/effects/internal/editor/terrain-circle-brush.effect diff --git a/editor/assets/effects/editor/terrain-circle-brush.effect.meta b/editor/assets/effects/internal/editor/terrain-circle-brush.effect.meta similarity index 92% rename from editor/assets/effects/editor/terrain-circle-brush.effect.meta rename to editor/assets/effects/internal/editor/terrain-circle-brush.effect.meta index 8313ee63083..3ffd47e2618 100644 --- a/editor/assets/effects/editor/terrain-circle-brush.effect.meta +++ b/editor/assets/effects/internal/editor/terrain-circle-brush.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "a3e72674-c38f-4336-a285-1826b1799cd7", diff --git a/editor/assets/effects/editor/terrain-image-brush.effect b/editor/assets/effects/internal/editor/terrain-image-brush.effect similarity index 100% rename from editor/assets/effects/editor/terrain-image-brush.effect rename to editor/assets/effects/internal/editor/terrain-image-brush.effect diff --git a/editor/assets/effects/editor/terrain-image-brush.effect.meta b/editor/assets/effects/internal/editor/terrain-image-brush.effect.meta similarity index 92% rename from editor/assets/effects/editor/terrain-image-brush.effect.meta rename to editor/assets/effects/internal/editor/terrain-image-brush.effect.meta index 089e42d2d13..af676e5a5ed 100644 --- a/editor/assets/effects/editor/terrain-image-brush.effect.meta +++ b/editor/assets/effects/internal/editor/terrain-image-brush.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "7a115de7-2d94-4620-8b89-766d7f8cbff9", diff --git a/editor/assets/effects/editor/terrain-select-brush.effect b/editor/assets/effects/internal/editor/terrain-select-brush.effect similarity index 100% rename from editor/assets/effects/editor/terrain-select-brush.effect rename to editor/assets/effects/internal/editor/terrain-select-brush.effect diff --git a/editor/assets/effects/editor/terrain-select-brush.effect.meta b/editor/assets/effects/internal/editor/terrain-select-brush.effect.meta similarity index 90% rename from editor/assets/effects/editor/terrain-select-brush.effect.meta rename to editor/assets/effects/internal/editor/terrain-select-brush.effect.meta index 92a953e711b..5a154a31f7c 100644 --- a/editor/assets/effects/editor/terrain-select-brush.effect.meta +++ b/editor/assets/effects/internal/editor/terrain-select-brush.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "9b4d3fa5-89bf-4715-b69a-dbbd1efaf6a5", diff --git a/editor/assets/effects/legacy.meta b/editor/assets/effects/legacy.meta new file mode 100644 index 00000000000..7044f41c232 --- /dev/null +++ b/editor/assets/effects/legacy.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "542f159e-9817-4290-8be0-3682570a3d7f", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/editor/assets/effects/dcc/imported-metallic-roughness.effect b/editor/assets/effects/legacy/standard.effect similarity index 53% rename from editor/assets/effects/dcc/imported-metallic-roughness.effect rename to editor/assets/effects/legacy/standard.effect index c704fc96cea..033c19442d2 100644 --- a/editor/assets/effects/dcc/imported-metallic-roughness.effect +++ b/editor/assets/effects/legacy/standard.effect @@ -8,25 +8,22 @@ CCEffect %{ frag: standard-fs properties: &props tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: BaseColor, type: color } } - mainTexture: { value: grey, target: albedoMap, editor: { displayName: BaseColorMap } } - baseWeightMap: { value: grey } - albedoScale: { value: 1.0, editor: { displayName: BaseWeight } } - roughness: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - roughnessMap: { value: grey } - metallic: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - metallicMap: { value: grey } - occlusion: { value: 0.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - occlusionMap: { value: white } - emissiveScale: { value: 1.0, editor: { displayName: Emissive } } - emissiveScaleMap: { value: grey, editor: { displayName: EmissiveMap } } - emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { displayName: EmissiveColor, type: color} } - emissiveMap: { value: grey, editor: { displayName: EmissiveColorMap } } - alphaSource: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - alphaSourceMap: { value: grey, editor: { parent: USE_OPACITY_MAP } } + mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: Albedo, type: color } } + albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } - normalStrength: { value: 1.0, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 1.0], step: 0.001 } } + occlusion: { value: 0.0, target: pbrParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + roughness: { value: 0.5, target: pbrParams.y, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + metallic: { value: 0.0, target: pbrParams.z, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + specularIntensity: { value: 0.5, target: pbrParams.w, editor: { slide: true, range: [0.0, 1.0], step: 0.001 } } + emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } + emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleParam.xyz } + normalStrength: { value: 1.0, target: emissiveScaleParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } + mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } normalMap: { value: normal } + pbrMap: { value: grey } + metallicRoughnessMap: { value: grey } + occlusionMap: { value: white } + emissiveMap: { value: grey } - &forward-add vert: standard-vs frag: standard-fs @@ -57,8 +54,6 @@ CCEffect %{ albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - alphaSource: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - alphaSourceMap: { value: grey, editor: { parent: USE_OPACITY_MAP } } - name: transparent passes: - vert: standard-vs @@ -83,14 +78,9 @@ CCProgram shared-ubos %{ vec4 tilingOffset; vec4 albedo; vec4 albedoScaleAndCutoff; + vec4 pbrParams; vec4 emissive; - float emissiveScale; - float occlusion; - float roughness; - float metallic; - float normalStrength; - float alphaSource; - float albedoScale; + vec4 emissiveScaleParam; }; }% @@ -103,24 +93,26 @@ CCProgram standard-vs %{ #include #include #include + #include #if USE_VERTEX_COLOR in vec4 a_color; - out vec4 v_color; + out lowp vec4 v_color; #endif out vec3 v_position; - out vec3 v_normal; + out mediump vec3 v_normal; out vec2 v_uv; - out vec2 v_uv1; + #if HAS_SECOND_UV + out mediump vec2 v_uv1; + #endif - #if CC_RECEIVE_SHADOW - out vec2 v_shadowBias; + #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + out mediump vec4 v_shadowBiasAndProbeId; #endif #if USE_NORMAL_MAP - out vec3 v_tangent; - out vec3 v_bitangent; + out mediump vec4 v_tangent; #endif #if HAS_SECOND_UV || CC_USE_LIGHTMAP @@ -144,7 +136,14 @@ CCProgram standard-vs %{ v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz); #if CC_RECEIVE_SHADOW - v_shadowBias = CCGetShadowBias(); + v_shadowBiasAndProbeId.xy = CCGetShadowBias(); + #endif + #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + #if USE_INSTANCING + v_shadowBiasAndProbeId.zw = a_localShadowBiasAndProbeId.zw; + #else + v_shadowBiasAndProbeId.zw = cc_localShadowBias.zw; + #endif #endif #if USE_TWOSIDE @@ -153,8 +152,8 @@ CCProgram standard-vs %{ #endif #if USE_NORMAL_MAP - v_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); - v_bitangent = cross(v_normal, v_tangent) * In.tangent.w; // note the cross order + v_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); + v_tangent.w = In.tangent.w; #endif v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; @@ -174,6 +173,7 @@ CCProgram standard-vs %{ CC_TRANSFER_FOG(pos); CC_TRANSFER_SHADOW(pos); + CC_TRANSFER_SH(); #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD CCLightingMapCaclUV(); @@ -195,72 +195,51 @@ CCProgram standard-fs %{ in vec3 v_position; in vec2 v_uv; - in vec2 v_uv1; - in vec3 v_normal; + #if HAS_SECOND_UV + in mediump vec2 v_uv1; + #endif + in mediump vec3 v_normal; - #if CC_RECEIVE_SHADOW - in vec2 v_shadowBias; + #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE + in mediump vec4 v_shadowBiasAndProbeId; #endif #if USE_VERTEX_COLOR - in vec4 v_color; + in lowp vec4 v_color; #endif - #pragma define-meta TEXTURE_UV options([v_uv, v_uv1]) - #if USE_ALBEDO_MAP uniform sampler2D albedoMap; + #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) #endif - - #if USE_WEIGHT_MAP - uniform sampler2D baseWeightMap; - #endif - #if USE_NORMAL_MAP - in vec3 v_tangent; - in vec3 v_bitangent; + in mediump vec4 v_tangent; uniform sampler2D normalMap; #pragma define-meta NORMAL_UV options([v_uv, v_uv1]) #endif - - #if USE_METALLIC_MAP - #pragma define-meta METALLIC_CHANNEL options([r, g, b, a]) - uniform sampler2D metallicMap; + #pragma define-meta PBR_UV options([v_uv, v_uv1]) + #if USE_PBR_MAP + uniform sampler2D pbrMap; #endif - - #if USE_ROUGHNESS_MAP - #pragma define-meta ROUGHNESS_CHANNEL options([r, g, b, a]) - uniform sampler2D roughnessMap; + #if USE_METALLIC_ROUGHNESS_MAP + uniform sampler2D metallicRoughnessMap; #endif - #if USE_OCCLUSION_MAP - #pragma define-meta OCCLUSION_CHANNEL options([r, g, b, a]) uniform sampler2D occlusionMap; #endif - - #if USE_TRANSPARENCY_MAP - uniform sampler2D transparencyMap; - #endif - - #if USE_TRANSPARENCYCOLOR_MAP - uniform sampler2D transparencyColorMap; - #endif - #if USE_EMISSIVE_MAP uniform sampler2D emissiveMap; - #endif - #if USE_EMISSIVESCALE_MAP - uniform sampler2D emissiveScaleMap; + #pragma define-meta EMISSIVE_UV options([v_uv, v_uv1]) #endif - #if USE_OPACITY_MAP - #pragma define-meta ALPHA_SOURCE_CHANNEL options([r, g, b, a]) - uniform sampler2D alphaSourceMap; - #endif + #pragma define OCCLUSION_CHANNEL r + #pragma define ROUGHNESS_CHANNEL g + #pragma define METALLIC_CHANNEL b + #pragma define SPECULAR_INTENSITY_CHANNEL a - float discolor(vec3 srcColor) { - return dot(GRAY_VECTOR, srcColor); - } + #if USE_ALPHA_TEST + #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) + #endif void surf (out StandardSurface s) { vec4 baseColor = albedo; @@ -268,114 +247,70 @@ CCProgram standard-fs %{ baseColor.rgb *= SRGBToLinear(v_color.rgb); // use linear baseColor.a *= v_color.a; #endif - #if USE_ALBEDO_MAP - vec4 texColor = texture(albedoMap, TEXTURE_UV); + vec4 texColor = texture(albedoMap, ALBEDO_UV); texColor.rgb = SRGBToLinear(texColor.rgb); - baseColor = texColor; - #endif - - #if USE_WEIGHT_MAP - vec4 weightColor = texture(baseWeightMap, TEXTURE_UV); - weightColor.rgb = SRGBToLinear(weightColor.rgb); - baseColor.rgb *= weightColor.rgb; - #else - baseColor.rgb *= albedoScale; - #endif - //////////////////////// - float metallicValue = metallic; - #if USE_METALLIC_MAP - vec4 metallicColor = texture(metallicMap, TEXTURE_UV); - metallicValue = discolor(metallicColor.rgb); - #if USE_METALLIC_CHANNEL - metallicColor.rgb = SRGBToLinear(metallicColor.rgb); - metallicValue = metallicColor.METALLIC_CHANNEL; - #endif - #endif - s.metallic = metallicValue; - - float roughnessValue = roughness; - #if USE_ROUGHNESS_MAP - vec4 roughnessColor = texture(roughnessMap, TEXTURE_UV); - roughnessValue = discolor(roughnessColor.rgb); - #if USE_ROUGHNESS_CHANNEL - roughnessColor.rgb = SRGBToLinear(roughnessColor.rgb); - roughnessValue = roughnessColor.ROUGHNESS_CHANNEL; - #endif - #endif - //fit specular ior=1.5 - s.roughness = max(0.02, roughnessValue); - - - float occlusionValue = 1.0 - occlusion; - #if USE_OCCLUSION_MAP - vec4 occlusionColor = texture(occlusionMap, TEXTURE_UV); - occlusionValue = discolor(occlusionColor.rgb); - #if USE_OCCLUSION_CHANNEL - occlusionColor.rgb = SRGBToLinear(occlusionColor.rgb); - occlusionValue = occlusionColor.OCCLUSION_CHANNEL; - #endif - #endif - s.occlusion = occlusionValue; - - #if ALPHA_SOURCE_IS_OPACITY - #if USE_OPACITY_MAP - baseColor.a = 1.0 - texture(alphaSourceMap, TEXTURE_UV).ALPHA_SOURCE_CHANNEL; - #else - baseColor.a = 1.0 - alphaSource; - #endif - #else - #if USE_OPACITY_MAP - baseColor.a = texture(alphaSourceMap, TEXTURE_UV).ALPHA_SOURCE_CHANNEL; - #else - baseColor.a = alphaSource; - #endif + baseColor *= texColor; #endif - #if USE_ALPHA_TEST - if (baseColor.a < albedoScaleAndCutoff.w) discard; - #endif - ///////////////////////////// s.albedo = baseColor; + s.albedo.rgb *= albedoScaleAndCutoff.xyz; - #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD - vec4 lightColor = texture(cc_lightingMap, v_luv.xy); - s.lightmap = lightColor.xyz * v_luv.z; - s.lightmap_test = v_luv.z; /*lum*/ + #if USE_ALPHA_TEST + if (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; #endif s.normal = v_normal; #if CC_RECEIVE_SHADOW - s.shadowBias = v_shadowBias; + s.shadowBias = v_shadowBiasAndProbeId.xy; #endif + #if CC_USE_REFLECTION_PROBE + s.reflectionProbeId = v_shadowBiasAndProbeId.z; + #endif + #if USE_NORMAL_MAP vec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5); + vec3 bitangent = cross(v_normal, v_tangent.xyz) * (v_tangent.w > 0.0 ? 1.0 : -1.0); // note the cross order s.normal = - (nmmp.x * normalStrength) * normalize(v_tangent) + - (nmmp.y * normalStrength) * normalize(v_bitangent) + + (nmmp.x * emissiveScaleParam.w) * normalize(v_tangent.xyz) + + (nmmp.y * emissiveScaleParam.w) * normalize(bitangent) + nmmp.z * normalize(s.normal); #endif + #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD + SampleAndDecodeLightMapColor(s.lightmap.rgb, s.lightmap.a, s.lightmap_test, cc_lightingMap, v_luv.xy, v_luv.z, s.normal); + #endif + HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); - s.specularIntensity = 0.5; + vec4 pbr = pbrParams; + pbr.x = 1.0; + #if USE_PBR_MAP + vec4 res = texture(pbrMap, PBR_UV); + pbr.x *= res.OCCLUSION_CHANNEL; + pbr.y *= res.ROUGHNESS_CHANNEL; + pbr.z *= res.METALLIC_CHANNEL; + pbr.w *= res.SPECULAR_INTENSITY_CHANNEL; + #endif + #if USE_METALLIC_ROUGHNESS_MAP + vec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV); + pbr.z *= metallicRoughness.METALLIC_CHANNEL; + pbr.y *= metallicRoughness.ROUGHNESS_CHANNEL; + #endif + #if USE_OCCLUSION_MAP + pbr.x = mix(1.0, texture(occlusionMap, PBR_UV).OCCLUSION_CHANNEL, pbrParams.x); + #endif + s.occlusion = pbr.x; + s.roughness = pbr.y; + s.metallic = pbr.z; + s.specularIntensity = pbr.w; - //emissive color - vec3 emissiveColor = emissive.rgb; + s.emissive = emissive.rgb; #if USE_EMISSIVE_MAP - emissiveColor.rgb = SRGBToLinear(texture(emissiveMap, TEXTURE_UV).rgb); - #endif - //emissive color scale - #if USE_EMISSIVESCALE_MAP - vec4 emissiveScaleColor = texture(emissiveScaleMap, TEXTURE_UV); - emissiveScaleColor.rgb = SRGBToLinear(emissiveScaleColor.rgb); - emissiveColor.rgb *= emissiveScaleColor.rgb; - #else - emissiveColor.rgb *= emissiveScale; + s.emissive = SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb); #endif - - s.emissive = emissiveColor.rgb; + s.emissive *= emissiveScaleParam.xyz; } CC_STANDARD_SURFACE_ENTRY() @@ -385,7 +320,6 @@ CCProgram shadow-caster-vs %{ precision highp float; #include #include - #include #include #include #include @@ -395,9 +329,10 @@ CCProgram shadow-caster-vs %{ #endif out vec2 v_uv; - out vec2 v_uv1; + #if HAS_SECOND_UV + out vec2 v_uv1; + #endif out vec4 v_worldPos; - out highp vec2 v_clip_depth; vec4 vert () { @@ -428,7 +363,9 @@ CCProgram shadow-caster-fs %{ #include in vec2 v_uv; - in vec2 v_uv1; + #if HAS_SECOND_UV + in vec2 v_uv1; + #endif in vec4 v_worldPos; in highp vec2 v_clip_depth; @@ -437,33 +374,18 @@ CCProgram shadow-caster-fs %{ #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) #endif - #pragma define-meta TEXTURE_UV options([v_uv, v_uv1]) - - #if USE_OPACITY_MAP - #pragma define-meta ALPHA_SOURCE_CHANNEL options([r, g, b, a]) - uniform sampler2D alphaSourceMap; + #if USE_ALPHA_TEST + #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) #endif vec4 frag () { + vec4 baseColor = albedo; + #if USE_ALPHA_TEST - float alpha = albedo.a; #if USE_ALBEDO_MAP - alpha = texture(albedoMap, TEXTURE_UV).a; - #endif - #if ALPHA_SOURCE_IS_OPACITY - #if USE_OPACITY_MAP - alpha = 1.0 - texture(alphaSourceMap, TEXTURE_UV).ALPHA_SOURCE_CHANNEL; - #else - alpha = 1.0 - alphaSource; - #endif - #else - #if USE_OPACITY_MAP - alpha = texture(alphaSourceMap, TEXTURE_UV).ALPHA_SOURCE_CHANNEL; - #else - alpha = alphaSource; - #endif + baseColor *= texture(albedoMap, ALBEDO_UV); #endif - if (alpha < albedoScaleAndCutoff.w) discard; + if (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; #endif highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; diff --git a/editor/assets/effects/dcc/surfaces-imported-specular-glossiness.effect.meta b/editor/assets/effects/legacy/standard.effect.meta similarity index 62% rename from editor/assets/effects/dcc/surfaces-imported-specular-glossiness.effect.meta rename to editor/assets/effects/legacy/standard.effect.meta index 7312d3f819b..ff7271daa04 100644 --- a/editor/assets/effects/dcc/surfaces-imported-specular-glossiness.effect.meta +++ b/editor/assets/effects/legacy/standard.effect.meta @@ -1,8 +1,8 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "5b7d6814-90a6-4d9f-b7fd-410dca9de957", + "uuid": "1baf0fc9-befa-459c-8bdd-af1a450a0319", "files": [ ".json" ], diff --git a/editor/assets/effects/legacy/terrain.effect b/editor/assets/effects/legacy/terrain.effect new file mode 100644 index 00000000000..957d01b6fa1 --- /dev/null +++ b/editor/assets/effects/legacy/terrain.effect @@ -0,0 +1,319 @@ +// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +CCEffect %{ + techniques: + - name: opaque + passes: + - vert: terrain-vs + frag: terrain-fs + properties: &props + UVScale: { value: [1, 1, 1, 1] } + metallic: { value: [0, 0, 0, 0] } + roughness: { value: [1, 1, 1, 1] } + weightMap: { value: black } + detailMap0: { value: grey } + detailMap1: { value: grey } + detailMap2: { value: grey } + detailMap3: { value: grey } + normalMap0: { value: normal } + normalMap1: { value: normal } + normalMap2: { value: normal } + normalMap3: { value: normal } + - vert: terrain-vs + frag: terrain-fs + phase: forward-add + propertyIndex: 0 + embeddedMacros: { CC_FORWARD_ADD: true } + depthStencilState: + depthFunc: equal + depthTest: true + depthWrite: false + blendState: + targets: + - blend: true + blendSrc: one + blendDst: one + blendSrcAlpha: zero + blendDstAlpha: one + properties: *props + - vert: shadow-caster-vs:vert + frag: shadow-caster-fs:frag + phase: shadow-add + propertyIndex: 0 + rasterizerState: + cullMode: back +}% + +CCProgram terrain-vs %{ + precision mediump float; + #include + #include + #include + #include + + in vec3 a_position; + in vec3 a_normal; + in vec2 a_texCoord; + + #if CC_RECEIVE_SHADOW + out vec2 v_shadowBias; + #endif + + out highp vec3 v_position; + out mediump vec3 v_normal; + out mediump vec2 uvw; + out mediump vec2 uv0; + out mediump vec2 uv1; + out mediump vec2 uv2; + out mediump vec2 uv3; + out mediump vec3 luv; + out mediump vec3 diffuse; + + uniform TexCoords { + vec4 UVScale; + vec4 lightMapUVParam; + }; + + void main () { + vec3 worldPos; + worldPos.x = cc_matWorld[3][0] + a_position.x; + worldPos.y = cc_matWorld[3][1] + a_position.y; + worldPos.z = cc_matWorld[3][2] + a_position.z; + + vec4 pos = vec4(worldPos, 1.0); + pos = cc_matViewProj * pos; + + uvw = a_texCoord; + uv0 = a_position.xz * UVScale.x; + uv1 = a_position.xz * UVScale.y; + uv2 = a_position.xz * UVScale.z; + uv3 = a_position.xz * UVScale.w; + #if CC_USE_LIGHTMAP + luv.xy = cc_lightingMapUVParam.xy + a_texCoord * cc_lightingMapUVParam.z; + luv.z = cc_lightingMapUVParam.w; + #endif + + v_position = worldPos; + v_normal = a_normal; + CC_TRANSFER_FOG(vec4(worldPos, 1.0)); + + #if CC_RECEIVE_SHADOW + v_shadowBias = vec2(0.0, 0.0); + #endif + + CC_TRANSFER_SHADOW(vec4(worldPos, 1.0)); + + gl_Position = pos; + } +}% + +CCProgram terrain-fs %{ + precision highp float; + #include + #include + #include + #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD + #include + #endif + #pragma define-meta LAYERS range([0, 4]) + + in highp vec3 v_position; + in mediump vec3 v_normal; + + #if CC_RECEIVE_SHADOW + in vec2 v_shadowBias; + #endif + + in mediump vec2 uvw; + in mediump vec2 uv0; + in mediump vec2 uv1; + in mediump vec2 uv2; + in mediump vec2 uv3; + in mediump vec3 diffuse; + in mediump vec3 luv; + + uniform PbrParams { + vec4 metallic; + vec4 roughness; + }; + + uniform sampler2D weightMap; + uniform sampler2D detailMap0; + uniform sampler2D detailMap1; + uniform sampler2D detailMap2; + uniform sampler2D detailMap3; + uniform sampler2D normalMap0; + uniform sampler2D normalMap1; + uniform sampler2D normalMap2; + uniform sampler2D normalMap3; + + void surf (out StandardSurface s) { + #if LAYERS > 1 + vec4 w = texture(weightMap, uvw); + #endif + + vec4 baseColor = vec4(0, 0, 0, 0); + #if LAYERS == 1 + baseColor = texture(detailMap0, uv0); + #elif LAYERS == 2 + baseColor += texture(detailMap0, uv0) * w.r; + baseColor += texture(detailMap1, uv1) * w.g; + #elif LAYERS == 3 + baseColor += texture(detailMap0, uv0) * w.r; + baseColor += texture(detailMap1, uv1) * w.g; + baseColor += texture(detailMap2, uv2) * w.b; + #elif LAYERS == 4 + baseColor += texture(detailMap0, uv0) * w.r; + baseColor += texture(detailMap1, uv1) * w.g; + baseColor += texture(detailMap2, uv2) * w.b; + baseColor += texture(detailMap3, uv3) * w.a; + #else + baseColor = texture(detailMap0, uv0); + #endif + + HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); + #if USE_NORMALMAP + vec4 baseNormal = vec4(0, 0, 0, 0); + #if LAYERS == 1 + baseNormal = texture(normalMap0, uv0); + #elif LAYERS == 2 + baseNormal += texture(normalMap0, uv0) * w.r; + baseNormal += texture(normalMap1, uv1) * w.g; + #elif LAYERS == 3 + baseNormal += texture(normalMap0, uv0) * w.r; + baseNormal += texture(normalMap1, uv1) * w.g; + baseNormal += texture(normalMap2, uv2) * w.b; + #elif LAYERS == 4 + baseNormal += texture(normalMap0, uv0) * w.r; + baseNormal += texture(normalMap1, uv1) * w.g; + baseNormal += texture(normalMap2, uv2) * w.b; + baseNormal += texture(normalMap3, uv3) * w.a; + #else + baseNormal = texture(normalMap0, uv0); + #endif + + vec3 tangent = vec3(1.0, 0.0, 0.0); + vec3 binormal = vec3(0.0, 0.0, 1.0); + + binormal = cross(tangent, v_normal); + tangent = cross(v_normal, binormal); + + vec3 nmmp = baseNormal.xyz - vec3(0.5); + s.normal = + nmmp.x * normalize(tangent) + + nmmp.y * normalize(binormal) + + nmmp.z * normalize(v_normal); + #else + s.normal = v_normal; + #endif + + #if CC_RECEIVE_SHADOW + s.shadowBias = v_shadowBias; + #endif + + s.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0); + s.occlusion = 1.0; + #if USE_PBR + s.roughness = 0.0; + #if LAYERS == 1 + s.roughness = roughness.x; + #elif LAYERS == 2 + s.roughness += roughness.x * w.r; + s.roughness += roughness.y * w.g; + #elif LAYERS == 3 + s.roughness += roughness.x * w.r; + s.roughness += roughness.y * w.g; + s.roughness += roughness.z * w.b; + #elif LAYERS == 4 + s.roughness += roughness.x * w.r; + s.roughness += roughness.y * w.g; + s.roughness += roughness.z * w.b; + s.roughness += roughness.w * w.a; + #else + s.roughness = 1.0; + #endif + + s.specularIntensity = 0.5; + + s.metallic = 0.0; + #if LAYERS == 1 + s.specularIntensity = 0.5; + s.metallic = metallic.x; + #elif LAYERS == 2 + s.metallic += metallic.x * w.r; + s.metallic += metallic.y * w.g; + #elif LAYERS == 3 + s.metallic += metallic.x * w.r; + s.metallic += metallic.y * w.g; + s.metallic += metallic.z * w.b; + #elif LAYERS == 4 + s.metallic += metallic.x * w.r; + s.metallic += metallic.y * w.g; + s.metallic += metallic.z * w.b; + s.metallic += metallic.w * w.a; + #else + s.specularIntensity = 0.5; + s.metallic = 0.0; + #endif + #else + s.roughness = 1.0; + s.specularIntensity = 0.5; + s.metallic = 0.0; + #endif + s.emissive = vec3(0.0, 0.0, 0.0); + + #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD + SampleAndDecodeLightMapColor(s.lightmap.rgb, s.lightmap.a, s.lightmap_test, cc_lightingMap, luv.xy, luv.z, s.normal); + #endif + } + + CC_STANDARD_SURFACE_ENTRY() +}% + +CCProgram shadow-caster-vs %{ + precision highp float; + #include + #include + #include + + in vec3 a_position; + in vec3 a_normal; + in vec2 a_texCoord; + + out highp vec2 v_clip_depth; + + vec4 vert () { + vec4 worldPos; + worldPos.x = cc_matWorld[3][0] + a_position.x; + worldPos.y = cc_matWorld[3][1] + a_position.y; + worldPos.z = cc_matWorld[3][2] + a_position.z; + worldPos.w = 1.0; + + vec4 clipPos = cc_matLightViewProj * worldPos; + + v_clip_depth = clipPos.zw; + + return clipPos; + } +}% + +CCProgram shadow-caster-fs %{ + precision highp float; + #include + + #pragma define SHADOWMAP_FORMAT_RGBA8 1 + #pragma define SHADOWMAP_FORMAT_FLOAT 0 + + in highp vec2 v_clip_depth; + + vec4 frag () { + highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; + + //todo: do not support linear mode spot shadow + + #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 + return packDepthToRGBA(clipDepth); + #else + return vec4(clipDepth, 1.0, 1.0, 1.0); + #endif + } +}% diff --git a/editor/assets/effects/surfaces/terrain.effect.meta b/editor/assets/effects/legacy/terrain.effect.meta similarity index 62% rename from editor/assets/effects/surfaces/terrain.effect.meta rename to editor/assets/effects/legacy/terrain.effect.meta index 8ccca297a40..495826cf692 100644 --- a/editor/assets/effects/surfaces/terrain.effect.meta +++ b/editor/assets/effects/legacy/terrain.effect.meta @@ -1,8 +1,8 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "a0fd9f76-74fe-423c-92d9-298906c189ba", + "uuid": "1d08ef62-a503-4ce2-8b9a-46c90873f7d3", "files": [ ".json" ], diff --git a/editor/assets/effects/legacy/toon.effect b/editor/assets/effects/legacy/toon.effect new file mode 100644 index 00000000000..e4b025068aa --- /dev/null +++ b/editor/assets/effects/legacy/toon.effect @@ -0,0 +1,335 @@ +// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. + +CCEffect %{ + techniques: + - passes: + - switch: USE_OUTLINE_PASS + vert: legacy/main-functions/outline-vs:vert + frag: legacy/main-functions/outline-fs:frag + rasterizerState: + cullMode: front + depthStencilState: + depthFunc: less_equal + depthTest: true + depthWrite: true + properties: + lineWidth: { value: 10, target: outlineParams.x } + depthBias: { value: 0, target: outlineParams.y } + baseColor: { editor: { type: color } } + baseColorMap: { value: grey } + - vert: toon-vs:vert + frag: toon-fs:frag + properties: &props + tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } + mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, linear: true, editor: { displayName: BaseColor, type: color } } + colorScale: { value: [1.0, 1.0, 1.0], target: colorScaleAndCutoff.xyz } + alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } + shadeColor1: { value: [0.4, 0.4, 0.4, 1.0], linear: true, editor: { type: color } } + shadeColor2: { value: [0.2, 0.2, 0.2, 1.0], linear: true, editor: { type: color } } + specular: { value: [1.0, 1.0, 1.0, 0.3], linear: true, editor: { type: color } } + baseStep: { value: 0.8, target: shadeParams.x } + baseFeather: { value: 0.001, target: shadeParams.y } + shadeStep: { value: 0.5, target: shadeParams.z } + shadeFeather: { value: 0.001, target: shadeParams.w } + shadowCover: { value: 0.5, target: miscParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } + emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleAndStrenth.xyz } + normalStrength: { value: 1.0, target: emissiveScaleAndStrenth.w, editor: { parent: USE_NORMAL_MAP }, slide: true, range: [0, 5.0], step: 0.001 } + normalMap: { value: normal } + mainTexture: { value: white, target: baseColorMap, editor: { displayName: BaseColorMap } } + shadeMap1: { value: white } + shadeMap2: { value: white } + specularMap: { value: white } + emissiveMap: { value: grey } + - vert: toon-vs:vert + frag: toon-fs:frag + phase: forward-add + propertyIndex: 1 + embeddedMacros: { CC_FORWARD_ADD: true } + depthStencilState: + depthFunc: equal + depthTest: true + depthWrite: false + blendState: + targets: + - blend: true + blendSrc: one + blendDst: one + blendSrcAlpha: zero + blendDstAlpha: one + properties: *props + - vert: shadow-caster-vs:vert + frag: shadow-caster-fs:frag + phase: shadow-caster + propertyIndex: 1 + rasterizerState: + cullMode: front + properties: + tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } + mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, editor: { displayName: BaseColor, type: color } } + colorScale: { value: [1.0, 1.0, 1.0], target: colorScaleAndCutoff.xyz } + alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } + shadeColor1: { value: [0.4, 0.4, 0.4, 1.0], editor: { type: color } } + shadeColor2: { value: [0.2, 0.2, 0.2, 1.0], editor: { type: color } } + specular: { value: [1.0, 1.0, 1.0, 0.3], editor: { type: color } } + baseStep: { value: 0.8, target: shadeParams.x } + baseFeather: { value: 0.001, target: shadeParams.y } + shadeStep: { value: 0.5, target: shadeParams.z } + shadeFeather: { value: 0.001, target: shadeParams.w } + emissive: { value: [0.0, 0.0, 0.0, 1.0], editor: { type: color } } + emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleAndStrenth.xyz } + normalStrenth: { value: 1.0, target: emissiveScaleAndStrenth.w, editor: { parent: USE_NORMAL_MAP } } + mainTexture: { value: white, target: baseColorMap, editor: { displayName: BaseColorMap } } +}% + +CCProgram shared-ubos %{ + uniform Constants { + vec4 tilingOffset; + vec4 baseColor; + vec4 colorScaleAndCutoff; + vec4 shadeColor1; + vec4 shadeColor2; + vec4 specular; // xyz: specular color, w: power + vec4 shadeParams; + vec4 miscParams; + vec4 emissive; + vec4 emissiveScaleAndStrenth; + }; +}% + +CCProgram toon-vs %{ + precision highp float; + #include + #include + #include + #include + #include + #include + + out vec3 v_position; + out vec2 v_uv; + out mediump vec3 v_normal; + + #if CC_RECEIVE_SHADOW + out mediump vec2 v_shadowBias; + #endif + + #if USE_NORMAL_MAP + out mediump vec4 v_tangent; + #endif + + vec4 vert () { + StandardVertInput In; + CCVertInput(In); + + mat4 matWorld, matWorldIT; + CCGetWorldMatrixFull(matWorld, matWorldIT); + + vec4 pos = matWorld * In.position; + v_position = pos.xyz; + v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; + + #if CC_RECEIVE_SHADOW + v_shadowBias = CCGetShadowBias(); + #endif + + v_normal = (matWorldIT * vec4(In.normal, 0.0)).xyz; + #if USE_NORMAL_MAP + v_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); + v_tangent.w = In.tangent.w; + #endif + + CC_TRANSFER_SHADOW(pos); + + return cc_matProj * (cc_matView * matWorld) * In.position; + } +}% + +CCProgram toon-fs %{ + precision highp float; + #include + #include + #include + #include + #include + + in vec3 v_position; + in vec2 v_uv; + + #if CC_RECEIVE_SHADOW + in mediump vec2 v_shadowBias; + #endif + + #if USE_BASE_COLOR_MAP + uniform sampler2D baseColorMap; + #endif + + in mediump vec3 v_normal; + #if USE_NORMAL_MAP + in mediump vec4 v_tangent; + uniform sampler2D normalMap; + #endif + + #if USE_1ST_SHADE_MAP + uniform sampler2D shadeMap1; + #endif + #if USE_2ND_SHADE_MAP + uniform sampler2D shadeMap2; + #endif + #if USE_SPECULAR_MAP + uniform sampler2D specularMap; + #endif + #if USE_EMISSIVE_MAP + uniform sampler2D emissiveMap; + #endif + + #if USE_ALPHA_TEST + #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b]) + #endif + + void surf (out ToonSurface s) { + s.shade2 = shadeColor2.rgb * colorScaleAndCutoff.rgb; + #if USE_2ND_SHADE_MAP + s.shade2 *= SRGBToLinear(texture(shadeMap2, v_uv).rgb); + #endif + s.shade1 = shadeColor1.rgb * colorScaleAndCutoff.rgb; + #if USE_1ST_SHADE_MAP + s.shade1 *= SRGBToLinear(texture(shadeMap1, v_uv).rgb); + #if SHADE_MAP_1_AS_SHADE_MAP_2 + s.shade2 *= s.shade1.rgb; + #endif + #endif + + vec4 localBaseColor = baseColor; + #if USE_BASE_COLOR_MAP + vec4 baseColorMap = texture(baseColorMap, v_uv); + baseColorMap.rgb = SRGBToLinear(baseColorMap.rgb); + localBaseColor *= baseColorMap; + #if BASE_COLOR_MAP_AS_SHADE_MAP_1 + s.shade1 *= baseColorMap.rgb; + #endif + #if BASE_COLOR_MAP_AS_SHADE_MAP_2 + s.shade2 *= baseColorMap.rgb; + #endif + #endif + s.baseColor = localBaseColor; + s.baseColor.rgb *= colorScaleAndCutoff.xyz; + + #if USE_ALPHA_TEST + if (s.baseColor.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; + #endif + + s.normal = v_normal; + + #if CC_RECEIVE_SHADOW + s.shadowBias = v_shadowBias; + #endif + + #if USE_NORMAL_MAP + vec3 nmmp = texture(normalMap, v_uv).xyz - vec3(0.5); + vec3 bitangent = cross(v_normal, v_tangent.xyz) * (v_tangent.w > 0.0 ? 1.0 : -1.0); // note the cross order + s.normal = + (nmmp.x * emissiveScaleAndStrenth.w) * normalize(v_tangent.xyz) + + (nmmp.y * emissiveScaleAndStrenth.w) * normalize(bitangent) + + nmmp.z * normalize(s.normal); + #endif + + HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); + + s.specular = specular; + #if USE_SPECULAR_MAP + s.specular.rgb *= SRGBToLinear(texture(specularMap, v_uv).rgb); + #endif + + s.emissive = emissive.rgb * emissiveScaleAndStrenth.xyz; + #if USE_EMISSIVE_MAP + s.emissive *= SRGBToLinear(texture(emissiveMap, v_uv).rgb); + #endif + + s.baseStep = shadeParams.x; + s.baseFeather = shadeParams.y; + s.shadeStep = shadeParams.z; + s.shadeFeather = shadeParams.w; + s.shadowCover = miscParams.x; + } + + vec4 frag () { + ToonSurface s; surf(s); + vec4 color = CCToonShading(s); + return CCFragOutput(color); + } +}% + +CCProgram shadow-caster-vs %{ + precision highp float; + #include + #include + #include + #include + #include + + out vec2 v_uv; + out vec4 v_worldPos; + out highp vec2 v_clip_depth; + + vec4 vert () { + StandardVertInput In; + CCVertInput(In); + + mat4 matWorld, matWorldIT; + CCGetWorldMatrixFull(matWorld, matWorldIT); + + v_worldPos = matWorld * In.position; + vec4 clipPos = cc_matLightViewProj * v_worldPos; + v_clip_depth = clipPos.zw; + + v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw; + + return clipPos; + } +}% + +CCProgram shadow-caster-fs %{ + precision highp float; + #include + #include + #include + + in vec2 v_uv; + in vec4 v_worldPos; + in highp vec2 v_clip_depth; + + #if USE_BASE_COLOR_MAP + uniform sampler2D baseColorMap; + #endif + + #if USE_ALPHA_TEST + #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b]) + #endif + + vec4 frag () { + vec4 baseColor = baseColor; + + #if USE_ALPHA_TEST + #if USE_BASE_COLOR_MAP + baseColor *= texture(baseColorMap, v_uv); + #endif + if (baseColor.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; + #endif + + highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; + // spot use linear + if(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) { + // enabled linear depth + #if CC_SHADOWMAP_USE_LINEAR_DEPTH + clipDepth = CCGetLinearDepth(v_worldPos.xyz); + #endif + } + + #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 + return packDepthToRGBA(clipDepth); + #else + return vec4(clipDepth, 1.0, 1.0, 1.0); + #endif + } +}% diff --git a/editor/assets/effects/surfaces/toon.effect.meta b/editor/assets/effects/legacy/toon.effect.meta similarity index 62% rename from editor/assets/effects/surfaces/toon.effect.meta rename to editor/assets/effects/legacy/toon.effect.meta index 17d7bf405af..350048ba08f 100644 --- a/editor/assets/effects/surfaces/toon.effect.meta +++ b/editor/assets/effects/legacy/toon.effect.meta @@ -1,8 +1,8 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, - "uuid": "9b20a514-6cc3-49de-b216-b6b863046249", + "uuid": "a7612b54-35e3-4238-a1a9-4a7b54635839", "files": [ ".json" ], diff --git a/editor/assets/effects/particles.meta b/editor/assets/effects/particles.meta new file mode 100644 index 00000000000..29c598d46a3 --- /dev/null +++ b/editor/assets/effects/particles.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "aa9d4d8a-579c-48e2-82d5-d97dddc28799", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/editor/assets/effects/builtin-billboard.effect b/editor/assets/effects/particles/builtin-billboard.effect similarity index 100% rename from editor/assets/effects/builtin-billboard.effect rename to editor/assets/effects/particles/builtin-billboard.effect diff --git a/editor/assets/effects/builtin-billboard.effect.meta b/editor/assets/effects/particles/builtin-billboard.effect.meta similarity index 90% rename from editor/assets/effects/builtin-billboard.effect.meta rename to editor/assets/effects/particles/builtin-billboard.effect.meta index e2f5bf0bdb9..304f3bd3767 100644 --- a/editor/assets/effects/builtin-billboard.effect.meta +++ b/editor/assets/effects/particles/builtin-billboard.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "711ebe11-f673-4cd9-9a83-63c60ba54c5b", diff --git a/editor/assets/effects/builtin-particle-gpu.effect b/editor/assets/effects/particles/builtin-particle-gpu.effect similarity index 100% rename from editor/assets/effects/builtin-particle-gpu.effect rename to editor/assets/effects/particles/builtin-particle-gpu.effect diff --git a/editor/assets/effects/builtin-particle-gpu.effect.meta b/editor/assets/effects/particles/builtin-particle-gpu.effect.meta similarity index 90% rename from editor/assets/effects/builtin-particle-gpu.effect.meta rename to editor/assets/effects/particles/builtin-particle-gpu.effect.meta index 879981445a9..d941b04ac81 100644 --- a/editor/assets/effects/builtin-particle-gpu.effect.meta +++ b/editor/assets/effects/particles/builtin-particle-gpu.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "971bdb23-3ff6-43eb-b422-1c30165a3663", diff --git a/editor/assets/effects/builtin-particle-trail.effect b/editor/assets/effects/particles/builtin-particle-trail.effect similarity index 100% rename from editor/assets/effects/builtin-particle-trail.effect rename to editor/assets/effects/particles/builtin-particle-trail.effect diff --git a/editor/assets/effects/builtin-particle-trail.effect.meta b/editor/assets/effects/particles/builtin-particle-trail.effect.meta similarity index 90% rename from editor/assets/effects/builtin-particle-trail.effect.meta rename to editor/assets/effects/particles/builtin-particle-trail.effect.meta index c7ed3d17a4b..203fa66b360 100644 --- a/editor/assets/effects/builtin-particle-trail.effect.meta +++ b/editor/assets/effects/particles/builtin-particle-trail.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "17debcc3-0a6b-4b8a-b00b-dc58b885581e", diff --git a/editor/assets/effects/builtin-particle-xr-trail.effect b/editor/assets/effects/particles/builtin-particle-xr-trail.effect similarity index 100% rename from editor/assets/effects/builtin-particle-xr-trail.effect rename to editor/assets/effects/particles/builtin-particle-xr-trail.effect diff --git a/editor/assets/effects/builtin-particle-xr-trail.effect.meta b/editor/assets/effects/particles/builtin-particle-xr-trail.effect.meta similarity index 90% rename from editor/assets/effects/builtin-particle-xr-trail.effect.meta rename to editor/assets/effects/particles/builtin-particle-xr-trail.effect.meta index 8d29aa52f18..3247142da8e 100644 --- a/editor/assets/effects/builtin-particle-xr-trail.effect.meta +++ b/editor/assets/effects/particles/builtin-particle-xr-trail.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "e38f81af-70ec-4f7a-b377-767b0ec76377", diff --git a/editor/assets/effects/builtin-particle.effect b/editor/assets/effects/particles/builtin-particle.effect similarity index 100% rename from editor/assets/effects/builtin-particle.effect rename to editor/assets/effects/particles/builtin-particle.effect diff --git a/editor/assets/effects/builtin-particle.effect.meta b/editor/assets/effects/particles/builtin-particle.effect.meta similarity index 90% rename from editor/assets/effects/builtin-particle.effect.meta rename to editor/assets/effects/particles/builtin-particle.effect.meta index 6e7da5c8c1c..a221b7152fa 100644 --- a/editor/assets/effects/builtin-particle.effect.meta +++ b/editor/assets/effects/particles/builtin-particle.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "d1346436-ac96-4271-b863-1f4fdead95b0", diff --git a/editor/assets/effects/pipeline/bloom.effect b/editor/assets/effects/pipeline/bloom.effect index c1593f05c7e..110f47baf2f 100644 --- a/editor/assets/effects/pipeline/bloom.effect +++ b/editor/assets/effects/pipeline/bloom.effect @@ -5,38 +5,86 @@ CCEffect %{ - passes: - vert: bloom-vs frag: prefilter-fs - phase: bloom-prefilter + pass: bloom-prefilter depthStencilState: depthTest: false depthWrite: false # Supports up to MAX_BLOOM_FILTER_PASS_NUM upsample/downsample passes - - &downsample - vert: bloom-vs - frag: downsample-fs - phase: bloom-downsample - depthStencilState: - depthTest: false - depthWrite: false - - *downsample - - *downsample - - *downsample - - *downsample - - *downsample - - &upsample - vert: bloom-vs - frag: upsample-fs - phase: bloom-upsample - depthStencilState: - depthTest: false - depthWrite: false - - *upsample - - *upsample - - *upsample - - *upsample - - *upsample + - vert: bloom-vs + frag: downsample-fs + pass: bloom-downsample0 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: downsample-fs + pass: bloom-downsample1 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: downsample-fs + pass: bloom-downsample2 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: downsample-fs + pass: bloom-downsample3 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: downsample-fs + pass: bloom-downsample4 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: downsample-fs + pass: bloom-downsample5 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: upsample-fs + pass: bloom-upsample0 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: upsample-fs + pass: bloom-upsample1 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: upsample-fs + pass: bloom-upsample2 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: upsample-fs + pass: bloom-upsample3 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: upsample-fs + pass: bloom-upsample4 + depthStencilState: + depthTest: false + depthWrite: false + - vert: bloom-vs + frag: upsample-fs + pass: bloom-upsample5 + depthStencilState: + depthTest: false + depthWrite: false - vert: bloom-vs frag: combine-fs - phase: bloom-combine + pass: bloom-combine depthStencilState: depthTest: false depthWrite: false @@ -70,6 +118,7 @@ CCProgram prefilter-fs %{ uniform BloomUBO { mediump vec4 texSize; }; + #pragma rate outputResultMap pass uniform sampler2D outputResultMap; layout(location = 0) out vec4 fragColor; @@ -98,6 +147,7 @@ CCProgram downsample-fs %{ uniform BloomUBO { mediump vec4 texSize; }; + #pragma rate bloomTexture pass uniform sampler2D bloomTexture; layout(location = 0) out vec4 fragColor; @@ -140,6 +190,7 @@ CCProgram upsample-fs %{ uniform BloomUBO { mediump vec4 texSize; }; + #pragma rate bloomTexture pass uniform sampler2D bloomTexture; layout(location = 0) out vec4 fragColor; @@ -182,7 +233,9 @@ CCProgram combine-fs %{ uniform BloomUBO { mediump vec4 texSize; }; + #pragma rate outputResultMap pass uniform sampler2D outputResultMap; + #pragma rate bloomTexture pass uniform sampler2D bloomTexture; layout(location = 0) out vec4 fragColor; diff --git a/editor/assets/effects/pipeline/bloom.effect.meta b/editor/assets/effects/pipeline/bloom.effect.meta index a486e689314..53d6a44d317 100644 --- a/editor/assets/effects/pipeline/bloom.effect.meta +++ b/editor/assets/effects/pipeline/bloom.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "28d6d6b8-3f66-4a73-9795-17a0852ba2d4", diff --git a/editor/assets/effects/pipeline/deferred-lighting.effect b/editor/assets/effects/pipeline/deferred-lighting.effect index e1f3526970e..809a967af6d 100644 --- a/editor/assets/effects/pipeline/deferred-lighting.effect +++ b/editor/assets/effects/pipeline/deferred-lighting.effect @@ -5,7 +5,7 @@ CCEffect %{ - passes: - vert: lighting-vs frag: lighting-fs - phase: deferred-lighting + pass: deferred-lighting depthStencilState: depthFunc: greater depthTest: true @@ -44,32 +44,16 @@ CCProgram lighting-fs %{ in vec2 v_uv; - #if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT - #pragma extension([GL_EXT_shader_framebuffer_fetch, __VERSION__ < 450, enable]) - #if __VERSION__ >= 450 - layout(binding = 0, input_attachment_index = 0) uniform subpassInput gbuffer_albedoMap; - layout(binding = 1, input_attachment_index = 1) uniform subpassInput gbuffer_normalMap; - layout(binding = 2, input_attachment_index = 2) uniform subpassInput gbuffer_emissiveMap; - layout(binding = 3, input_attachment_index = 3) uniform subpassInput depth_stencil; - #elif __VERSION__ >= 300 - layout(location = 0) inout vec4 gbuffer_albedoMap; - layout(location = 1) inout vec4 gbuffer_normalMap; - layout(location = 2) inout vec4 gbuffer_emissiveMap; - layout(binding = 3) uniform sampler2D depth_stencil; - #else - layout(binding = 3) uniform sampler2D depth_stencil; - #endif - #else - layout(binding = 0) uniform sampler2D gbuffer_albedoMap; - layout(binding = 1) uniform sampler2D gbuffer_normalMap; - layout(binding = 2) uniform sampler2D gbuffer_emissiveMap; - layout(binding = 3) uniform sampler2D depth_stencil; - #endif - - #if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450 - layout(location = 0) out vec4 fragColor; - #endif + #pragma rate gbuffer_albedoMap pass + layout(binding = 0) uniform sampler2D gbuffer_albedoMap; + #pragma rate gbuffer_normalMap pass + layout(binding = 1) uniform sampler2D gbuffer_normalMap; + #pragma rate gbuffer_emissiveMap pass + layout(binding = 2) uniform sampler2D gbuffer_emissiveMap; + #pragma rate depth_stencil pass + layout(binding = 3) uniform sampler2D depth_stencil; + layout(location = 0) out vec4 fragColor; vec4 screen2WS(vec3 coord) { vec3 ndc = vec3( @@ -87,29 +71,10 @@ CCProgram lighting-fs %{ void main () { StandardSurface s; - #if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT - #if __VERSION__ >= 450 - vec4 albedoMap = subpassLoad(gbuffer_albedoMap); - vec4 normalMap = subpassLoad(gbuffer_normalMap); - vec4 emissiveMap = subpassLoad(gbuffer_emissiveMap); - float depth = subpassLoad(depth_stencil).x; - #elif __VERSION__ >= 300 - vec4 albedoMap = gbuffer_albedoMap; - vec4 normalMap = gbuffer_normalMap; - vec4 emissiveMap = gbuffer_emissiveMap; - float depth = texture(depth_stencil, v_uv).x; - #else - vec4 albedoMap = gl_LastFragData[0]; - vec4 normalMap = gl_LastFragData[1]; - vec4 emissiveMap = gl_LastFragData[2]; - float depth = texture(depth_stencil, v_uv).x; - #endif - #else - vec4 albedoMap = texture(gbuffer_albedoMap,v_uv); - vec4 normalMap = texture(gbuffer_normalMap,v_uv); - vec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv); - float depth = texture(depth_stencil, v_uv).x; - #endif + vec4 albedoMap = texture(gbuffer_albedoMap,v_uv); + vec4 normalMap = texture(gbuffer_normalMap,v_uv); + vec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv); + float depth = texture(depth_stencil, v_uv).x; s.albedo = albedoMap; vec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz; @@ -136,16 +101,6 @@ CCProgram lighting-fs %{ CC_APPLY_FOG_BASE(color, fogFactor); color = CCFragOutput(color); - #if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT - #if __VERSION__ >= 450 - fragColor = color; - #elif __VERSION__ >= 300 - gbuffer_emissiveMap = color; - #else - gl_FragData[2] = color; - #endif - #else - fragColor = color; - #endif + fragColor = color; } }% diff --git a/editor/assets/effects/pipeline/deferred-lighting.effect.meta b/editor/assets/effects/pipeline/deferred-lighting.effect.meta index cf13a3ebfd3..d10da36b509 100644 --- a/editor/assets/effects/pipeline/deferred-lighting.effect.meta +++ b/editor/assets/effects/pipeline/deferred-lighting.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "5d45aa00-e064-4938-b314-4265f0c2258c", diff --git a/editor/assets/effects/pipeline/fxaa-hq.effect b/editor/assets/effects/pipeline/fxaa-hq.effect new file mode 100644 index 00000000000..e31c1b752d4 --- /dev/null +++ b/editor/assets/effects/pipeline/fxaa-hq.effect @@ -0,0 +1,67 @@ +// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +CCEffect %{ + techniques: + - name: fxaa + passes: + - vert: fxaa-vs:vert + frag: fxaa-edge-fs:frag + pass: fxaa + depthStencilState: + depthTest: false + depthWrite: false + rasterizerState: + cullMode: none +}% + +CCProgram fxaa-vs %{ + precision highp float; + #include + + in vec2 a_position; + in vec2 a_texCoord; + out vec2 v_uv; + + vec4 vert () { + vec4 pos = vec4(a_position, 0.0, 1.0); + v_uv = a_texCoord; + return pos; + } +}% + +CCProgram fxaa-edge-fs %{ + precision highp float; + #include + #include + + //#define FXAA_PRESET 5 + #include + + uniform fxaaUBO { + vec4 texSize; + }; + + in vec2 v_uv; + #pragma rate sceneColorMap pass + uniform sampler2D sceneColorMap; + + vec4 frag () { + vec3 color = FxaaPixelShader(v_uv, sceneColorMap, texSize.zw); + return vec4(color, 1.0); + } +}% + +CCProgram copy-fs %{ + precision highp float; + + uniform fxaaUBO { + vec4 texSize; + }; + + in vec2 v_uv; + #pragma rate sceneColorMap pass + uniform sampler2D sceneColorMap; + + vec4 frag () { + return texture(sceneColorMap, v_uv); + } +}% diff --git a/editor/assets/effects/pipeline/fxaa-hq.effect.meta b/editor/assets/effects/pipeline/fxaa-hq.effect.meta new file mode 100644 index 00000000000..a19e8fa829e --- /dev/null +++ b/editor/assets/effects/pipeline/fxaa-hq.effect.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.6.2", + "importer": "effect", + "imported": true, + "uuid": "2df0a40b-26c2-47ce-be0d-4d3cd4164737", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/editor/assets/effects/pipeline/planar-shadow.effect.meta b/editor/assets/effects/pipeline/planar-shadow.effect.meta index d53a4a87017..5474606442c 100644 --- a/editor/assets/effects/pipeline/planar-shadow.effect.meta +++ b/editor/assets/effects/pipeline/planar-shadow.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "9361fd90-ba52-4f84-aa93-6e878fd576ca", diff --git a/editor/assets/effects/pipeline/post-process.effect b/editor/assets/effects/pipeline/post-process.effect index 3125904c5e8..302899d1f13 100644 --- a/editor/assets/effects/pipeline/post-process.effect +++ b/editor/assets/effects/pipeline/post-process.effect @@ -5,10 +5,12 @@ CCEffect %{ - passes: - vert: post-process-vs frag: post-process-fs - phase: post-process + pass: post-process depthStencilState: depthTest: false depthWrite: false + rasterizerState: + cullMode: none blendState: targets: - blend: true @@ -20,7 +22,7 @@ CCEffect %{ CCProgram post-process-vs %{ precision highp float; - #include + #include #include #include @@ -28,7 +30,7 @@ CCProgram post-process-vs %{ void main () { StandardVertInput In; - CCVertInput(In); + CCDecode(In); CC_HANDLE_GET_CLIP_FLIP(In.position.xy); gl_Position = In.position; gl_Position.y = gl_Position.y; @@ -42,6 +44,7 @@ CCProgram post-process-fs %{ #include in vec2 v_uv; + #pragma rate outputResultMap pass layout(binding = 0) uniform sampler2D outputResultMap; layout(location = 0) out vec4 fragColor; @@ -59,17 +62,20 @@ void texcoords(vec2 fragCoord, vec2 resolution, } void main () { - mediump vec2 v_rgbNW; - mediump vec2 v_rgbNE; - mediump vec2 v_rgbSW; - mediump vec2 v_rgbSE; - mediump vec2 v_rgbM; - #if ANTIALIAS_TYPE == 1 + mediump vec2 v_rgbNW; + mediump vec2 v_rgbNE; + mediump vec2 v_rgbSW; + mediump vec2 v_rgbSE; + mediump vec2 v_rgbM; + vec2 resolution = cc_screenSize.xy; vec2 fragCoord = v_uv * resolution; texcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); fragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + #elif ANTIALIAS_TYPE == 2 + vec3 color = FxaaPixelShader(v_uv, outputResultMap, 1.0 / cc_screenSize.xy); + fragColor = vec4(color, texture(outputResultMap, v_uv).a); #else fragColor = texture(outputResultMap, v_uv); #endif diff --git a/editor/assets/effects/pipeline/post-process.effect.meta b/editor/assets/effects/pipeline/post-process.effect.meta index b51c1b10551..9db237153f3 100644 --- a/editor/assets/effects/pipeline/post-process.effect.meta +++ b/editor/assets/effects/pipeline/post-process.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "ec8106fe-05bf-4e94-943c-e0d3b7bb5e45", diff --git a/editor/assets/effects/pipeline/skybox.effect b/editor/assets/effects/pipeline/skybox.effect index 2f94ab40b11..8f6acbd3e68 100644 --- a/editor/assets/effects/pipeline/skybox.effect +++ b/editor/assets/effects/pipeline/skybox.effect @@ -68,6 +68,10 @@ CCProgram sky-fs %{ #else vec3 c = SRGBToLinear(fragTextureLod(environmentMap, rotationDir.xyz, 0.0).rgb); #endif - return CCFragOutput(vec4(c * cc_ambientSky.w, 1.0)); + vec4 color = CCFragOutput(vec4(c * cc_ambientSky.w, 1.0)); + #if CC_USE_RGBE_OUTPUT + color = packRGBE(color.rgb); + #endif + return color; } }% diff --git a/editor/assets/effects/pipeline/skybox.effect.meta b/editor/assets/effects/pipeline/skybox.effect.meta index ed157e898f5..4e941534f48 100644 --- a/editor/assets/effects/pipeline/skybox.effect.meta +++ b/editor/assets/effects/pipeline/skybox.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "511d2633-09a7-4bdd-ac42-f778032124b3", diff --git a/editor/assets/effects/pipeline/smaa.effect.meta b/editor/assets/effects/pipeline/smaa.effect.meta index 94fbbf8e61c..2c978660951 100644 --- a/editor/assets/effects/pipeline/smaa.effect.meta +++ b/editor/assets/effects/pipeline/smaa.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "6624c63c-0e3d-4d5f-bd15-a7805b71c521", diff --git a/editor/assets/effects/pipeline/tonemap.effect.meta b/editor/assets/effects/pipeline/tonemap.effect.meta index 5423bf56cb6..e2c8a3a5afa 100644 --- a/editor/assets/effects/pipeline/tonemap.effect.meta +++ b/editor/assets/effects/pipeline/tonemap.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "31b152ff-f689-4082-a292-3eb5a0b33014", diff --git a/editor/assets/effects/surfaces/standard.effect b/editor/assets/effects/surfaces/standard.effect deleted file mode 100644 index 4d8c94aac5b..00000000000 --- a/editor/assets/effects/surfaces/standard.effect +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. - -CCEffect %{ - techniques: - - name: opaque - passes: - - vert: standard-vs - frag: standard-fs - properties: &props - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: Albedo, type: color } } - albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } - alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } - occlusion: { value: 0.0, target: pbrParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - roughness: { value: 0.8, target: pbrParams.y, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - metallic: { value: 0.6, target: pbrParams.z, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - specularIntensity: { value: 0.5, target: pbrParams.w, editor: { slide: true, range: [0.0, 1.0], step: 0.001 } } - emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } - emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleParam.xyz } - normalStrength: { value: 1.0, target: emissiveScaleParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } - anisotropyIntensity: { value: 1.0, target: anisotropyParam.x, editor: { parent: IS_ANISOTROPY, slide : true, range : [0.0, 1.0] , step : 0.0001 } } - anisotropyRotation: { value: 0.0, target: anisotropyParam.y, editor: { parent: IS_ANISOTROPY, slide : true, range : [0, 1.0] , step : 0.0001 } } - anisotropyMapResolutionHeight: { value: 0.0, target: anisotropyParam.w, editor: { parent: FIX_ANISOTROPIC_ROTATION_MAP } } - mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - normalMap: { value: normal } - pbrMap: { value: grey } - occlusionMap: { value: white } - emissiveMap: { value: grey } - anisotropyMap: { value: black, editor : { parent: IS_ANISOTROPY } } - anisotropyMapNearestFilter: { value: black, editor : { parent: FIX_ANISOTROPIC_ROTATION_MAP } } - - &forward-add - vert: standard-vs - frag: standard-fs - phase: forward-add - propertyIndex: 0 - embeddedMacros: { CC_FORWARD_ADD: true } - depthStencilState: - depthFunc: equal - depthTest: true - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: one - blendDst: one - blendSrcAlpha: zero - blendDstAlpha: one - - &shadow-caster - vert: shadow-caster-vs - frag: shadow-caster-fs - phase: shadow-caster - propertyIndex: 0 - rasterizerState: - cullMode: front - properties: - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, editor: { displayName: Albedo, type: color } } - albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } - alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } - mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - - name: transparent - passes: - - vert: standard-vs - frag: standard-fs - embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: - depthTest: true - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: src_alpha - blendDst: one_minus_src_alpha - blendDstAlpha: one_minus_src_alpha - properties: *props - - *forward-add - - *shadow-caster -}% - -CCProgram shared-ubos %{ - uniform Constants { - vec4 tilingOffset; - vec4 albedo; - vec4 albedoScaleAndCutoff; - vec4 pbrParams; - vec4 emissive; - vec4 emissiveScaleParam; - vec4 anisotropyParam; - }; -}% - -CCProgram macro-remapping %{ - // ui displayed macros - #pragma define-meta HAS_SECOND_UV - #pragma define-meta USE_TWOSIDE - #pragma define-meta IS_ANISOTROPY - #pragma define-meta USE_VERTEX_COLOR - - #define CC_SURFACES_USE_SECOND_UV HAS_SECOND_UV - #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE - #define CC_SURFACES_LIGHTING_ANISOTROPIC IS_ANISOTROPY - #define CC_SURFACES_USE_VERTEX_COLOR USE_VERTEX_COLOR - - // depend on UI macros -#if IS_ANISOTROPY || USE_NORMAL_MAP - #define CC_SURFACES_USE_TANGENT_SPACE 1 -#endif - - // functionality for each effect - #define CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT 31 -}% - -CCProgram surface-vertex %{ - /*#define CC_SURFACES_VERTEX_MODIFY_WORLD_POS - vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In) - { - vec3 worldPos = In.worldPos; - worldPos.x += sin(cc_time.x * worldPos.z); - worldPos.y += cos(cc_time.x * worldPos.z); - return worldPos; - } - - #define CC_SURFACES_VERTEX_MODIFY_WORLD_NORMAL - vec3 SurfacesVertexModifyWorldNormal(in SurfacesStandardVertexIntermediate In) - { - vec3 worldNormal = In.worldNormal.xyz; - worldNormal.x += sin(cc_time.x * 3.0); - worldNormal.y += cos(cc_time.x * 3.0); - #if CC_SURFACES_USE_TWO_SIDED - worldNormal.xyz *= In.worldNormal.w; - #endif - return normalize(worldNormal); - }*/ - - #define CC_SURFACES_VERTEX_MODIFY_UV - void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) - { - In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; - #if CC_SURFACES_USE_SECOND_UV && !CC_USE_LIGHTMAP - In.texCoord1 = In.texCoord1 * tilingOffset.xy + tilingOffset.zw; - #endif - } -}% - -CCProgram surface-fragment %{ - #if USE_ALBEDO_MAP - uniform sampler2D albedoMap; - #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) - #endif - #if USE_NORMAL_MAP - uniform sampler2D normalMap; - #pragma define-meta NORMAL_UV options([v_uv, v_uv1]) - #endif - #pragma define-meta DEFAULT_UV options([v_uv, v_uv1]) - #if USE_PBR_MAP - uniform sampler2D pbrMap; - #endif - #if USE_OCCLUSION_MAP - uniform sampler2D occlusionMap; - #endif - #if USE_EMISSIVE_MAP - uniform sampler2D emissiveMap; - #pragma define-meta EMISSIVE_UV options([v_uv, v_uv1]) - #endif - #if IS_ANISOTROPY && USE_ANISOTROPY_MAP - uniform sampler2D anisotropyMap; - uniform sampler2D anisotropyMapNearestFilter; - #endif - - #pragma define OCCLUSION_CHANNEL r - #pragma define ROUGHNESS_CHANNEL g - #pragma define METALLIC_CHANNEL b - #pragma define SPECULAR_INTENSITY_CHANNEL a - - #if USE_ALPHA_TEST - #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) - #endif - - - #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TRANSPARENCY - vec4 SurfacesFragmentModifyBaseColorAndTransparency() - { - vec4 baseColor = albedo; - - #if USE_VERTEX_COLOR - baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear - baseColor.a *= FSInput_vertexColor.a; - #endif - - #if USE_ALBEDO_MAP - vec4 texColor = texture(albedoMap, ALBEDO_UV); - texColor.rgb = SRGBToLinear(texColor.rgb); - baseColor *= texColor; - #endif - - #if USE_ALPHA_TEST - if (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; - #endif - - baseColor.rgb *= albedoScaleAndCutoff.xyz; - return baseColor; - } - - #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY - void SurfacesFragmentAlphaClipOnly() - { - #if USE_ALPHA_TEST - float alpha = albedo.ALPHA_TEST_CHANNEL; - #if USE_VERTEX_COLOR - alpha *= FSInput_vertexColor.a; - #endif - #if USE_ALBEDO_MAP - alpha = texture(albedoMap, ALBEDO_UV).ALPHA_TEST_CHANNEL; - #endif - - if (alpha < albedoScaleAndCutoff.w) discard; - #endif - } - - #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL - vec3 SurfacesFragmentModifyWorldNormal() - { - vec3 normal = FSInput_worldNormal; - #if USE_NORMAL_MAP - vec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5); - normal = CalculateNormalFromTangentSpace(nmmp, emissiveScaleParam.w, normal.xyz, FSInput_worldTangent, FSInput_mirrorNormal); - #endif - - return normalize(normal); - } - - #define CC_SURFACES_FRAGMENT_MODIFY_ANISOTROPY_PARAMS - vec4 SurfacesFragmentModifyAnisotropyParams(out float isRotation) - { - float anisotropyRotation = anisotropyParam.y * PI; - float anisotropyShape = anisotropyParam.x; - #if IS_ANISOTROPY && USE_ANISOTROPY_MAP - // Rotation angle should disable trilinear filtering - vec4 tex = texture(anisotropyMap, DEFAULT_UV); - anisotropyRotation = fract(anisotropyRotation * 0.5 + tex.y) * PI2; - // less value is better for SP exported shape - anisotropyShape *= tex.x; - #endif - - // fix rotation map seam line of black and white - #if FIX_ANISOTROPIC_ROTATION_MAP - #if IS_ANISOTROPY && USE_ANISOTROPY_MAP - vec4 reference = texture(anisotropyMapNearestFilter, DEFAULT_UV); - vec2 oneTap = vec2(0.0, 1.0 / anisotropyParam.w); - float threshold = 0.2; - // scan more taps for stable result - vec4 sample1 = texture(anisotropyMapNearestFilter, DEFAULT_UV + oneTap); - vec4 sample2 = texture(anisotropyMapNearestFilter, DEFAULT_UV - oneTap); - if (abs(sample1.y - reference.y) > threshold || abs(sample2.y - reference.y) > threshold) { - tex.y = reference.y; - } - anisotropyRotation = fract(anisotropyParam.y * PI * 0.5 + tex.y) * PI2; - #endif - #endif - - isRotation = 1.0; - return vec4(anisotropyShape, anisotropyRotation, 0.0, 0.0); - } - - #define CC_SURFACES_FRAGMENT_MODIFY_EMISSIVE - vec3 SurfacesFragmentModifyEmissive() - { - vec3 emissive = emissive.rgb * emissiveScaleParam.xyz; - #if USE_EMISSIVE_MAP - emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb); - #endif - return emissive; - } - - #define CC_SURFACES_FRAGMENT_MODIFY_PBRPARAMS - vec4 SurfacesFragmentModifyPBRParams() - { - vec4 pbr = pbrParams; - pbr.x = 1.0 - pbr.x; - #if USE_PBR_MAP - vec4 res = texture(pbrMap, DEFAULT_UV); - pbr.x *= res.OCCLUSION_CHANNEL; - pbr.y *= res.ROUGHNESS_CHANNEL; - pbr.z *= res.METALLIC_CHANNEL; - pbr.w *= res.SPECULAR_INTENSITY_CHANNEL; - #endif - #if USE_OCCLUSION_MAP - pbr.x *= texture(occlusionMap, DEFAULT_UV).OCCLUSION_CHANNEL; - #endif - - return pbr; - } -}% - -CCProgram standard-vs %{ - precision highp float; - - // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros - #include - #include - - // 2. common include with corresponding shader stage, include before surface functions - #include - - // 3. user surface functions that can use user (effect) parameters (ubo Constants) - // see surfaces/default-functions/xxx.chunk - #include - #include - - // 4. surface include with corresponding shader stage and shading-model (optional) - #include - - // 5. shader entry with corresponding shader stage and technique usage/type - #include -}% - - -CCProgram shadow-caster-vs %{ - precision highp float; - #include - #include - #include - #include - #include -}% - - - -CCProgram standard-fs %{ - // shading-model : standard - // lighting-model : standard (isotropy / anisotropy pbr) - // shader stage : fs - // technique usage/type : render-to-scene - - precision highp float; - // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros - #include - #include - - // 2. common include with corresponding shader stage, include before surface functions - #include - - // 3. user surface functions that can use user (effect) parameters (ubo Constants) - // see surfaces/default-functions/xxx.chunk - #include - #include - - // 4. lighting-model (optional) - #include - - // 5. surface include with corresponding shader stage and shading-model (optional) - #include - - // 6. shader entry with corresponding shader stage and technique usage/type - #include -}% - -CCProgram shadow-caster-fs %{ - precision highp float; - #include - #include - #include - #include - #include -}% diff --git a/editor/assets/effects/surfaces/standard.effect.meta b/editor/assets/effects/surfaces/standard.effect.meta deleted file mode 100644 index 1bdb51d35b1..00000000000 --- a/editor/assets/effects/surfaces/standard.effect.meta +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ver": "1.6.0", - "importer": "effect", - "imported": true, - "uuid": "c8f66d17-351a-48da-a12c-0212d28575c4", - "files": [ - ".json" - ], - "subMetas": {}, - "userData": { - "combinations": [ - {}, - {} - ] - } -} diff --git a/editor/assets/effects/surfaces/terrain.effect b/editor/assets/effects/surfaces/terrain.effect deleted file mode 100644 index 35cc74a2abc..00000000000 --- a/editor/assets/effects/surfaces/terrain.effect +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. - -CCEffect %{ - techniques: - - name: opaque - passes: - - vert: terrain-vs - frag: terrain-fs - properties: &props - UVScale: { value: [1, 1, 1, 1] } - metallic: { value: [0, 0, 0, 0] } - roughness: { value: [1, 1, 1, 1] } - weightMap: { value: black } - detailMap0: { value: grey } - detailMap1: { value: grey } - detailMap2: { value: grey } - detailMap3: { value: grey } - normalMap0: { value: normal } - normalMap1: { value: normal } - normalMap2: { value: normal } - normalMap3: { value: normal } - - vert: terrain-vs - frag: terrain-fs - phase: forward-add - propertyIndex: 0 - embeddedMacros: { CC_FORWARD_ADD: true } - depthStencilState: - depthFunc: equal - depthTest: true - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: one - blendDst: one - blendSrcAlpha: zero - blendDstAlpha: one - properties: *props - - vert: shadow-caster-vs - frag: shadow-caster-fs - phase: shadow-add - propertyIndex: 0 - rasterizerState: - cullMode: back -}% - -CCProgram shared-ubos %{ - uniform Constants { - vec4 UVScale; - vec4 metallic; - vec4 roughness; - }; -}% - -CCProgram macro-remapping %{ - #pragma define-meta USE_NORMALMAP - #define CC_SURFACES_USE_TANGENT_SPACE USE_NORMALMAP -}% -CCProgram surface-vertex %{ - #define CC_SURFACES_VERTEX_MODIFY_WORLD_POS - vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In) - { - vec3 worldPos; - worldPos.x = cc_matWorld[3][0] + In.position.x; - worldPos.y = cc_matWorld[3][1] + In.position.y; - worldPos.z = cc_matWorld[3][2] + In.position.z; - return worldPos; - } - - #define CC_SURFACES_VERTEX_MODIFY_CLIP_POS - vec4 SurfacesVertexModifyClipPos(in SurfacesStandardVertexIntermediate In) - { - vec4 pos = vec4(In.worldPos, 1.0); - pos = cc_matViewProj * pos; - return pos; - } -}% - -CCProgram surface-fragment %{ - #pragma define-meta LAYERS range([0, 4]) - uniform sampler2D weightMap; - uniform sampler2D detailMap0; - uniform sampler2D detailMap1; - uniform sampler2D detailMap2; - uniform sampler2D detailMap3; - uniform sampler2D normalMap0; - uniform sampler2D normalMap1; - uniform sampler2D normalMap2; - uniform sampler2D normalMap3; - - #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY - void SurfacesFragmentAlphaClipOnly(){} - - #define CC_SURFACES_FRAGMENT_MODIFY_SHARED_DATA - #include - void SurfacesFragmentModifySharedData(inout SurfacesMaterialData surfaceData) - { - vec2 uvw = FSInput_texcoord; - vec2 uv0 = FSInput_localPos.xz * UVScale.x; - vec2 uv1 = FSInput_localPos.xz * UVScale.y; - vec2 uv2 = FSInput_localPos.xz * UVScale.z; - vec2 uv3 = FSInput_localPos.xz * UVScale.w; - vec4 w = vec4(0.0); - #if LAYERS > 1 - w = texture(weightMap, uvw); - #endif - vec4 baseColor = vec4(0, 0, 0, 0); - #if LAYERS == 1 - baseColor = texture(detailMap0, uv0); - #elif LAYERS == 2 - baseColor += texture(detailMap0, uv0) * w.r; - baseColor += texture(detailMap1, uv1) * w.g; - #elif LAYERS == 3 - baseColor += texture(detailMap0, uv0) * w.r; - baseColor += texture(detailMap1, uv1) * w.g; - baseColor += texture(detailMap2, uv2) * w.b; - #elif LAYERS == 4 - baseColor += texture(detailMap0, uv0) * w.r; - baseColor += texture(detailMap1, uv1) * w.g; - baseColor += texture(detailMap2, uv2) * w.b; - baseColor += texture(detailMap3, uv3) * w.a; - #else - baseColor = texture(detailMap0, uv0); - #endif - surfaceData.baseColor = vec4(SRGBToLinear(baseColor.rgb), 1.0); - - vec4 baseNormal = vec4(0, 0, 0, 0); - #if USE_NORMALMAP - #if LAYERS == 1 - baseNormal = texture(normalMap0, uv0); - #elif LAYERS == 2 - baseNormal += texture(normalMap0, uv0) * w.r; - baseNormal += texture(normalMap1, uv1) * w.g; - #elif LAYERS == 3 - baseNormal += texture(normalMap0, uv0) * w.r; - baseNormal += texture(normalMap1, uv1) * w.g; - baseNormal += texture(normalMap2, uv2) * w.b; - #elif LAYERS == 4 - baseNormal += texture(normalMap0, uv0) * w.r; - baseNormal += texture(normalMap1, uv1) * w.g; - baseNormal += texture(normalMap2, uv2) * w.b; - baseNormal += texture(normalMap3, uv3) * w.a; - #else - baseNormal = texture(normalMap0, uv0); - #endif - - vec3 tangent = vec3(1.0, 0.0, 0.0); - vec3 binormal = vec3(0.0, 0.0, 1.0); - - binormal = cross(tangent, FSInput_worldNormal); - tangent = cross(FSInput_worldNormal, binormal); - - vec3 nmmp = baseNormal.xyz - vec3(0.5); - surfaceData.worldNormal = - nmmp.x * normalize(tangent) + - nmmp.y * normalize(binormal) + - nmmp.z * normalize(FSInput_worldNormal); - #else - surfaceData.worldNormal = FSInput_worldNormal; - #endif - - float roughnessValue = 1.0; - float metallicValue = 0.0; - #if USE_PBR - #if LAYERS == 1 - roughnessValue = roughness.x; - #elif LAYERS == 2 - roughnessValue += roughness.x * w.r; - roughnessValue += roughness.y * w.g; - #elif LAYERS == 3 - roughnessValue += roughness.x * w.r; - roughnessValue += roughness.y * w.g; - roughnessValue += roughness.z * w.b; - #elif LAYERS == 4 - roughnessValue += roughness.x * w.r; - roughnessValue += roughness.y * w.g; - roughnessValue += roughness.z * w.b; - roughnessValue += roughness.w * w.a; - #endif - #if LAYERS == 1 - metallicValue = metallic.x; - #elif LAYERS == 2 - metallicValue += metallic.x * w.r; - metallicValue += metallic.y * w.g; - #elif LAYERS == 3 - metallicValue += metallic.x * w.r; - metallicValue += metallic.y * w.g; - metallicValue += metallic.z * w.b; - #elif LAYERS == 4 - metallicValue += metallic.x * w.r; - metallicValue += metallic.y * w.g; - metallicValue += metallic.z * w.b; - metallicValue += metallic.w * w.a; - #endif - #endif - - surfaceData.ao = 1.0; - surfaceData.roughness = roughnessValue; - surfaceData.metallic = metallicValue; - surfaceData.specularIntensity = 0.5; - surfaceData.emissive = vec3(0.0); - } -}% - -CCProgram terrain-vs %{ - precision highp float; - #include - #include - // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros - #include - - // 2. common include with corresponding shader stage, include before surface functions - #include - - // 3. user surface functions that can use user (effect) parameters (ubo Constants) - // see surfaces/default-functions/xxx.chunk - #include - #include - - // 4. surface include with corresponding shader stage and shading-model (optional) - #include - - // 5. shader entry with corresponding shader stage and technique usage/type - #include -}% - - -CCProgram shadow-caster-vs %{ - precision highp float; - #include - #include - #include - #include - #include - #include -}% - -CCProgram terrain-fs %{ - - precision highp float; - #include - // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros - #include - - // 2. common include with corresponding shader stage, include before surface functions - #include - - // 3. user surface functions that can use user (effect) parameters (ubo Constants) - // see surfaces/default-functions/xxx.chunk - #include - #include - - // 4. lighting-model (optional) - #include - - // 5. surface include with corresponding shader stage and shading-model (optional) - #include - - // 6. shader entry with corresponding shader stage and technique usage/type - #include -}% - -CCProgram shadow-caster-fs %{ - precision highp float; - #include - #include - #include - #include - #include -}% diff --git a/editor/assets/effects/surfaces/toon.effect b/editor/assets/effects/surfaces/toon.effect deleted file mode 100644 index d88e7e1c8e0..00000000000 --- a/editor/assets/effects/surfaces/toon.effect +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. - -CCEffect %{ - techniques: - - passes: - - switch: USE_OUTLINE_PASS - vert: silhouette-edge-vs - frag: silhouette-edge-fs - rasterizerState: - cullMode: front - depthStencilState: - depthFunc: less_equal - depthTest: true - depthWrite: true - properties: - lineWidth: { value: 10, target: outlineParams.x } - depthBias: { value: 0, target: outlineParams.y } - baseColor: { editor: { type: color } } - baseColorMap: { value: grey } - - vert: toon-vs - frag: toon-fs - properties: &props - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, linear: true, editor: { displayName: BaseColor, type: color } } - colorScale: { value: [1.0, 1.0, 1.0], target: colorScaleAndCutoff.xyz } - alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } - shadeColor1: { value: [0.4, 0.4, 0.4, 1.0], linear: true, editor: { type: color } } - shadeColor2: { value: [0.2, 0.2, 0.2, 1.0], linear: true, editor: { type: color } } - specular: { value: [1.0, 1.0, 1.0, 0.3], linear: true, editor: { type: color } } - baseStep: { value: 0.8, target: shadeParams.x } - baseFeather: { value: 0.001, target: shadeParams.y } - shadeStep: { value: 0.5, target: shadeParams.z } - shadeFeather: { value: 0.001, target: shadeParams.w } - shadowCover: { value: 0.5, target: miscParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } - emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } - emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleAndStrenth.xyz } - normalStrength: { value: 1.0, target: emissiveScaleAndStrenth.w, editor: { parent: USE_NORMAL_MAP }, slide: true, range: [0, 5.0], step: 0.001 } - normalMap: { value: normal } - mainTexture: { value: white, target: baseColorMap, editor: { displayName: BaseColorMap } } - shadeMap1: { value: white } - shadeMap2: { value: white } - specularMap: { value: white } - emissiveMap: { value: grey } - - vert: toon-vs - frag: toon-fs - phase: forward-add - propertyIndex: 1 - embeddedMacros: { CC_FORWARD_ADD: true } - depthStencilState: - depthFunc: equal - depthTest: true - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: one - blendDst: one - blendSrcAlpha: zero - blendDstAlpha: one - properties: *props - - vert: shadow-caster-vs - frag: shadow-caster-fs - phase: shadow-caster - propertyIndex: 1 - rasterizerState: - cullMode: front - properties: - tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } - mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, editor: { displayName: BaseColor, type: color } } - colorScale: { value: [1.0, 1.0, 1.0], target: colorScaleAndCutoff.xyz } - alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } - shadeColor1: { value: [0.4, 0.4, 0.4, 1.0], editor: { type: color } } - shadeColor2: { value: [0.2, 0.2, 0.2, 1.0], editor: { type: color } } - specular: { value: [1.0, 1.0, 1.0, 0.3], editor: { type: color } } - baseStep: { value: 0.8, target: shadeParams.x } - baseFeather: { value: 0.001, target: shadeParams.y } - shadeStep: { value: 0.5, target: shadeParams.z } - shadeFeather: { value: 0.001, target: shadeParams.w } - emissive: { value: [0.0, 0.0, 0.0, 1.0], editor: { type: color } } - emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleAndStrenth.xyz } - normalStrenth: { value: 1.0, target: emissiveScaleAndStrenth.w, editor: { parent: USE_NORMAL_MAP } } - mainTexture: { value: white, target: baseColorMap, editor: { displayName: BaseColorMap } } -}% - -CCProgram shared-ubos %{ - uniform Constants { - vec4 tilingOffset; - vec4 baseColor; - vec4 colorScaleAndCutoff; - vec4 shadeColor1; - vec4 shadeColor2; - vec4 specular; // xyz: specular color, w: power - vec4 shadeParams; - vec4 miscParams; - vec4 emissive; - vec4 emissiveScaleAndStrenth; - };}% - -CCProgram macro-remapping %{ - // if enabled, shadowed area is very dark - #pragma define-meta USE_COMPATIBLE_LIGHTING - #define CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING USE_COMPATIBLE_LIGHTING - - #pragma define-meta USE_NORMAL_MAP - #define CC_SURFACES_USE_TANGENT_SPACE USE_NORMAL_MAP -}% - -CCProgram surface-vertex %{ - #define CC_SURFACES_VERTEX_MODIFY_UV - void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) - { - In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; - } -}% - -CCProgram surface-fragment %{ - #if USE_BASE_COLOR_MAP - uniform sampler2D baseColorMap; - #endif - - #if USE_NORMAL_MAP - uniform sampler2D normalMap; - #endif - - #if USE_1ST_SHADE_MAP - uniform sampler2D shadeMap1; - #endif - #if USE_2ND_SHADE_MAP - uniform sampler2D shadeMap2; - #endif - #if USE_SPECULAR_MAP - uniform sampler2D specularMap; - #endif - #if USE_EMISSIVE_MAP - uniform sampler2D emissiveMap; - #endif - - #if USE_ALPHA_TEST - #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b]) - #endif - - - #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TOONSHADE - void SurfacesFragmentModifyBaseColorAndToonShade(out vec4 baseColorAndTransparency, out vec3 shade1, out vec3 shade2) - { - shade2 = shadeColor2.rgb * colorScaleAndCutoff.rgb; - #if USE_2ND_SHADE_MAP - shade2 *= SRGBToLinear(texture(shadeMap2, FSInput_texcoord).rgb); - #endif - shade1 = shadeColor1.rgb * colorScaleAndCutoff.rgb; - #if USE_1ST_SHADE_MAP - shade1 *= SRGBToLinear(texture(shadeMap1, FSInput_texcoord).rgb); - #if SHADE_MAP_1_AS_SHADE_MAP_2 - shade2 *= shade1.rgb; - #endif - #endif - - vec4 color = baseColor; - #if USE_BASE_COLOR_MAP - vec4 texColor = texture(baseColorMap, FSInput_texcoord); - texColor.rgb = SRGBToLinear(texColor.rgb); - color *= texColor; - #if BASE_COLOR_MAP_AS_SHADE_MAP_1 - shade1 *= texColor.rgb; - #endif - #if BASE_COLOR_MAP_AS_SHADE_MAP_2 - shade2 *= texColor.rgb; - #endif - #endif - baseColorAndTransparency = color; - baseColorAndTransparency.rgb *= colorScaleAndCutoff.xyz; - - #if USE_ALPHA_TEST - if (baseColorAndTransparency.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; - #endif - } - - #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY - void SurfacesFragmentAlphaClipOnly() - { - #if USE_ALPHA_TEST - float alpha = baseColor.ALPHA_TEST_CHANNEL; - #if USE_BASE_COLOR_MAP - alpha = texture(baseColorMap, FSInput_texcoord).ALPHA_TEST_CHANNEL; - #endif - - if (alpha < colorScaleAndCutoff.w) discard; - #endif - } - - #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL - vec3 SurfacesFragmentModifyWorldNormal() - { - vec3 normal = FSInput_worldNormal; - #if USE_NORMAL_MAP - vec3 nmmp = texture(normalMap, FSInput_texcoord).xyz - vec3(0.5); - normal = CalculateNormalFromTangentSpace(nmmp, emissiveScaleAndStrenth.w, normal.xyz, FSInput_worldTangent, FSInput_mirrorNormal); - #endif - - return normalize(normal); - } - - #define CC_SURFACES_FRAGMENT_MODIFY_EMISSIVE - vec3 SurfacesFragmentModifyEmissive() - { - vec3 emissive = emissive.rgb * emissiveScaleAndStrenth.xyz; - #if USE_EMISSIVE_MAP - emissive *= SRGBToLinear(texture(emissiveMap, FSInput_texcoord).rgb); - #endif - return emissive; - } - - #define CC_SURFACES_FRAGMENT_MODIFY_TOON_STEP_AND_FEATHER - vec4 SurfacesFragmentModifyToonStepAndFeather() - { - return shadeParams; - } - - #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SHADOW_COVER - float SurfacesFragmentModifyToonShadowCover() - { - return miscParams.x; - } - - #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SPECULAR - vec4 SurfacesFragmentModifyToonSpecular() - { - vec4 specularParam = specular; - #if USE_SPECULAR_MAP - specularParam.rgb *= SRGBToLinear(texture(specularMap, FSInput_texcoord).rgb); - #endif - return specularParam; - } -}% - -CCProgram toon-vs %{ - precision highp float; - - // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros - #include - #include - - // 2. common include with corresponding shader stage - #include - - // 3. user surface functions that can use user (effect) parameters (ubo Constants) - // see surfaces/default-functions/xxx.chunk - #include - #include - - // 4. surface include with corresponding shader stage and shading-model (optional) - #include - - // 5. shader entry with corresponding shader stage and technique usage/type - #include -}% - - -CCProgram shadow-caster-vs %{ - precision highp float; - #include - #include - #include - #include - #include -}% - -CCProgram toon-fs %{ - // shading-model : toon - // lighting-model : toon - // shader stage : fs - // technique usage/type : render-to-scene - - precision highp float; - // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros - #include - #include - - // 2. common include with corresponding shader stage - #include - - // 3. user surface functions that can use user (effect) parameters (ubo Constants) - // see surfaces/default-functions/xxx.chunk - #include - #include - - // 4. lighting-model (optional) - #include - - // 5. surface include with corresponding shader stage and shading-model (optional) - #include - - // 6. shader entry with corresponding shader stage and technique usage/type - #include -}% - -CCProgram shadow-caster-fs %{ - precision highp float; - #include - #include - #include - #include - #include -}% - - - - - - - - - - - - - - - -////////////////////////////////////////////////silhouette-edge sample -// how to write a simple surface material -// change technique outline-vs/fs:vert/frag to silhouette-edge-vs/fs -CCProgram surface-vertex-silhouette-edge %{ - uniform OutlineVert { - vec4 outlineParams; // x: line width, y: depth hack -}; - - #define CC_SURFACES_VERTEX_MODIFY_LOCAL_POS - vec3 SurfacesVertexModifyLocalPos(in SurfacesStandardVertexIntermediate In) - { - float width = outlineParams.x * 0.001; - vec3 localPos = In.position.xyz; - - #if USE_POSITION_SCALING - vec3 dir = normalize(localPos); - float flip = dot(dir, normalize(In.normal)) < 0.0 ? -1.0 : 1.0; - localPos += flip * dir * width * 2.0; - #else - localPos += normalize(In.normal) * width; - #endif - return localPos; - } - - #define CC_SURFACES_VERTEX_MODIFY_CLIP_POS - vec4 SurfacesVertexModifyClipPos(in SurfacesStandardVertexIntermediate In) - { - vec4 clipPos = In.clipPos; - clipPos.z -= outlineParams.y * 0.002; - return clipPos; - } -}% - -CCProgram surface-fragment-silhouette-edge %{ - uniform OutlineFrag { - vec4 baseColor; - }; - #if USE_BASE_COLOR_MAP - uniform sampler2D baseColorMap; - #endif - - // only for render-to-shadow-map or misc usage - #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TRANSPARENCY - vec4 SurfacesFragmentModifyBaseColorAndTransparency() - { - vec4 color = vec4(cc_mainLitColor.rgb, 1.0); - color.rgb = SRGBToLinear(baseColor.rgb); - #if USE_BASE_COLOR_MAP - vec4 texColor = texture(baseColorMap, FSInput_texcoord); - texColor.rgb = SRGBToLinear(texColor.rgb); - color *= texColor; - #endif - - return color; - } -}% - -CCProgram silhouette-edge-vs %{ - precision highp float; - #include - #include - #include - #include -}% - -CCProgram silhouette-edge-fs %{ - precision highp float; - #include - #include - #include - #include -}% diff --git a/editor/assets/effects/util/batched-unlit.effect.meta b/editor/assets/effects/util/batched-unlit.effect.meta index 76fdeeba7b6..98dafb057a5 100644 --- a/editor/assets/effects/util/batched-unlit.effect.meta +++ b/editor/assets/effects/util/batched-unlit.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "f1556893-88b6-4c65-8c16-a5256ef3ad25", diff --git a/editor/assets/effects/dcc.meta b/editor/assets/effects/util/dcc.meta similarity index 100% rename from editor/assets/effects/dcc.meta rename to editor/assets/effects/util/dcc.meta diff --git a/editor/assets/effects/dcc/surfaces-imported-metallic-roughness.effect b/editor/assets/effects/util/dcc/imported-metallic-roughness.effect similarity index 97% rename from editor/assets/effects/dcc/surfaces-imported-metallic-roughness.effect rename to editor/assets/effects/util/dcc/imported-metallic-roughness.effect index 1886e628d07..6e0018b9bd6 100644 --- a/editor/assets/effects/dcc/surfaces-imported-metallic-roughness.effect +++ b/editor/assets/effects/util/dcc/imported-metallic-roughness.effect @@ -18,8 +18,8 @@ CCEffect %{ metallicMap: { value: grey } occlusion: { value: 0.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } occlusionMap: { value: white } - emissiveScale: { value: 1.0, editor: { displayName: Emissive } } - emissiveScaleMap: { value: grey, editor: { displayName: EmissiveMap } } + emissiveScale: { value: 1.0 } + emissiveScaleMap: { value: grey } emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { displayName: EmissiveColor, type: color} } emissiveMap: { value: grey, editor: { displayName: EmissiveColorMap } } alphaSource: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } @@ -126,7 +126,7 @@ CCProgram surface-vertex %{ void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) { In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; - #if USE_SECOND_UV && !CC_USE_LIGHTMAP + #if CC_SURFACES_USE_SECOND_UV In.texCoord1 = In.texCoord1 * tilingOffset.xy + tilingOffset.zw; #endif } @@ -291,14 +291,15 @@ CCProgram surface-fragment %{ { vec4 pbr = vec4(1.0,1.0,1.0,1.0); //ao - float occlusionValue = 1.0 - occlusion; + float occlusionValue = 1.0; #if USE_OCCLUSION_MAP vec4 occlusionColor = texture(occlusionMap, TEXTURE_UV); - occlusionValue = discolor(occlusionColor.rgb); + float occlusionColorValue = discolor(occlusionColor.rgb); #if USE_OCCLUSION_CHANNEL occlusionColor.rgb = SRGBToLinear(occlusionColor.rgb); - occlusionValue = occlusionColor.OCCLUSION_CHANNEL; + occlusionColorValue = occlusionColor.OCCLUSION_CHANNEL; #endif + occlusionValue = mix(1.0, occlusionColorValue, occlusion); #endif pbr.x = occlusionValue; diff --git a/editor/assets/effects/dcc/imported-metallic-roughness.effect.meta b/editor/assets/effects/util/dcc/imported-metallic-roughness.effect.meta similarity index 90% rename from editor/assets/effects/dcc/imported-metallic-roughness.effect.meta rename to editor/assets/effects/util/dcc/imported-metallic-roughness.effect.meta index 7101eae823a..1967a257355 100644 --- a/editor/assets/effects/dcc/imported-metallic-roughness.effect.meta +++ b/editor/assets/effects/util/dcc/imported-metallic-roughness.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "2ec11458-f855-4978-b14d-f3ed5cf697fa", diff --git a/editor/assets/effects/dcc/surfaces-imported-specular-glossiness.effect b/editor/assets/effects/util/dcc/imported-specular-glossiness.effect similarity index 96% rename from editor/assets/effects/dcc/surfaces-imported-specular-glossiness.effect rename to editor/assets/effects/util/dcc/imported-specular-glossiness.effect index a13dc7d509f..493b70f5acd 100644 --- a/editor/assets/effects/dcc/surfaces-imported-specular-glossiness.effect +++ b/editor/assets/effects/util/dcc/imported-specular-glossiness.effect @@ -13,6 +13,8 @@ CCEffect %{ alphaThreshold: { value: 0.5, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } emissiveMap: { value: grey } + emissiveScale: { value: 1.0 } + emissiveScaleMap: { value: grey } shininessExponentMap: { value: grey, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } shininessExponent: { value: 100.0, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } specularGlossinessMap: { value: grey, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } @@ -85,6 +87,7 @@ CCProgram shared-ubos %{ vec4 diffuseColor; vec4 specularColor; vec4 emissive; + float emissiveScale; float alphaThreshold; float shininessExponent; float glossiness; @@ -128,7 +131,7 @@ CCProgram surface-vertex %{ void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) { In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; - #if USE_SECOND_UV && !CC_USE_LIGHTMAP + #if CC_SURFACES_USE_SECOND_UV In.texCoord1 = In.texCoord1 * tilingOffset.xy + tilingOffset.zw; #endif } @@ -170,6 +173,9 @@ CCProgram surface-fragment %{ #if USE_EMISSIVE_MAP uniform sampler2D emissiveMap; #endif + #if USE_EMISSIVESCALE_MAP + uniform sampler2D emissiveScaleMap; + #endif #if USE_NORMAL_MAP uniform sampler2D normalMap; @@ -268,8 +274,17 @@ CCProgram surface-fragment %{ { vec3 emissiveColor = emissive.rgb; #if USE_EMISSIVE_MAP - emissiveColor = texture(emissiveMap, TEXTURE_UV).xyz; + emissiveColor.rgb = SRGBToLinear(texture(emissiveMap, TEXTURE_UV).rgb); + #endif + //emissive color scale + #if USE_EMISSIVESCALE_MAP + vec4 emissiveScaleColor = texture(emissiveScaleMap, TEXTURE_UV); + emissiveScaleColor.rgb = SRGBToLinear(emissiveScaleColor.rgb); + emissiveColor.rgb *= emissiveScaleColor.rgb; + #else + emissiveColor.rgb *= emissiveScale; #endif + return emissiveColor; } diff --git a/editor/assets/effects/dcc/imported-specular-glossiness.effect.meta b/editor/assets/effects/util/dcc/imported-specular-glossiness.effect.meta similarity index 90% rename from editor/assets/effects/dcc/imported-specular-glossiness.effect.meta rename to editor/assets/effects/util/dcc/imported-specular-glossiness.effect.meta index ccf6219139a..cb2c6198019 100644 --- a/editor/assets/effects/dcc/imported-specular-glossiness.effect.meta +++ b/editor/assets/effects/util/dcc/imported-specular-glossiness.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "f648964e-8d32-41fc-9ac9-7a1e714dd17b", diff --git a/editor/assets/effects/util/profiler.effect b/editor/assets/effects/util/profiler.effect index 5e2ad84050a..cd3be3a9445 100644 --- a/editor/assets/effects/util/profiler.effect +++ b/editor/assets/effects/util/profiler.effect @@ -22,9 +22,9 @@ CCProgram profiler-vs %{ precision mediump float; #include - #pragma define ROWS 8 // multiple of 4 - #pragma define COLS 10 - #pragma define VECTOR_COUNT ROWS * COLS / 4 + #pragma define COLS 8 // multiple of 4 + #pragma define ROWS 11 + #pragma define VECTOR_COUNT COLS * ROWS / 4 in vec3 a_position; in vec4 a_color; diff --git a/editor/assets/effects/util/profiler.effect.meta b/editor/assets/effects/util/profiler.effect.meta index c8d6d15a876..050dcfa1df0 100644 --- a/editor/assets/effects/util/profiler.effect.meta +++ b/editor/assets/effects/util/profiler.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "871c3b6c-7379-419d-bda3-794b239ab90d", diff --git a/editor/assets/effects/util/sequence-anim.effect.meta b/editor/assets/effects/util/sequence-anim.effect.meta index ce3684f0588..22d16cbae37 100644 --- a/editor/assets/effects/util/sequence-anim.effect.meta +++ b/editor/assets/effects/util/sequence-anim.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "27cc5a0b-ec0b-4a67-98cf-b42d4fa971de", diff --git a/editor/assets/effects/util/splash-screen.effect.meta b/editor/assets/effects/util/splash-screen.effect.meta index 6ef217d3d87..09de7adaba8 100644 --- a/editor/assets/effects/util/splash-screen.effect.meta +++ b/editor/assets/effects/util/splash-screen.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.6.0", + "ver": "1.6.2", "importer": "effect", "imported": true, "uuid": "970b0598-bcb0-4714-91fb-2e81440dccd8", diff --git a/editor/assets/gizmo/light-probe.png b/editor/assets/gizmo/light-probe.png new file mode 100644 index 00000000000..bf929655098 Binary files /dev/null and b/editor/assets/gizmo/light-probe.png differ diff --git a/editor/assets/gizmo/light-probe.png.meta b/editor/assets/gizmo/light-probe.png.meta new file mode 100644 index 00000000000..08d9bd738ac --- /dev/null +++ b/editor/assets/gizmo/light-probe.png.meta @@ -0,0 +1,43 @@ +{ + "ver": "1.0.25", + "importer": "image", + "imported": true, + "uuid": "9e0cc8d3-a76b-4bee-b53e-f3abab91c4b8", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "9e0cc8d3-a76b-4bee-b53e-f3abab91c4b8@6c48a", + "displayName": "light-probe", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "9e0cc8d3-a76b-4bee-b53e-f3abab91c4b8", + "visible": true + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "texture", + "fixAlphaTransparencyArtifacts": false, + "hasAlpha": true, + "redirect": "9e0cc8d3-a76b-4bee-b53e-f3abab91c4b8@6c48a", + "flipVertical": true + } +} diff --git a/editor/assets/gizmo/reflection-probe.png b/editor/assets/gizmo/reflection-probe.png new file mode 100644 index 00000000000..ec1894a933b Binary files /dev/null and b/editor/assets/gizmo/reflection-probe.png differ diff --git a/editor/assets/gizmo/reflection-probe.png.meta b/editor/assets/gizmo/reflection-probe.png.meta new file mode 100644 index 00000000000..db53c2f5c40 --- /dev/null +++ b/editor/assets/gizmo/reflection-probe.png.meta @@ -0,0 +1,42 @@ +{ + "ver": "1.0.25", + "importer": "image", + "imported": true, + "uuid": "dee6f7cc-ba21-4091-948f-4f508495f260", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "dee6f7cc-ba21-4091-948f-4f508495f260@6c48a", + "displayName": "reflection-probe", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "repeat", + "wrapModeT": "repeat", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "nearest", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "dee6f7cc-ba21-4091-948f-4f508495f260", + "visible": true + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "texture", + "fixAlphaTransparencyArtifacts": true, + "hasAlpha": true, + "redirect": "dee6f7cc-ba21-4091-948f-4f508495f260@6c48a" + } +} diff --git a/editor/assets/gizmo/scene-gizmo.mtl.meta b/editor/assets/gizmo/scene-gizmo.mtl.meta index b6cfafcc3d5..fc18a472abd 100644 --- a/editor/assets/gizmo/scene-gizmo.mtl.meta +++ b/editor/assets/gizmo/scene-gizmo.mtl.meta @@ -1,5 +1,5 @@ { - "ver": "1.0.15", + "ver": "1.0.20", "importer": "material", "imported": true, "uuid": "6d3bfb1f-604a-4fb3-9fd8-789862cc55e7", diff --git a/editor/assets/primitives.fbx.meta b/editor/assets/primitives.fbx.meta index 28f22c74651..63b4a07312f 100644 --- a/editor/assets/primitives.fbx.meta +++ b/editor/assets/primitives.fbx.meta @@ -1,5 +1,5 @@ { - "ver": "2.3.1", + "ver": "2.3.2", "importer": "fbx", "imported": true, "uuid": "1263d74c-8167-4928-91a6-4e2672411f47", diff --git a/editor/assets/tools.meta b/editor/assets/tools.meta new file mode 100644 index 00000000000..84a595987ae --- /dev/null +++ b/editor/assets/tools.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "99317b62-549d-421a-9cd0-f575591bf3cd", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/editor/assets/tools/debug-view-runtime-control.prefab b/editor/assets/tools/debug-view-runtime-control.prefab new file mode 100644 index 00000000000..c5c7f1cdb9e --- /dev/null +++ b/editor/assets/tools/debug-view-runtime-control.prefab @@ -0,0 +1,1683 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "debug-view-runtime-control", + "_objFlags": 0, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "debug-view-runtime-control", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 26 + }, + { + "__id__": 50 + }, + { + "__id__": 54 + } + ], + "_active": true, + "_components": [ + { + "__id__": 68 + }, + { + "__id__": 70 + } + ], + "_prefab": { + "__id__": 72 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "SingleMode", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 3 + } + ], + "_active": true, + "_components": [ + { + "__id__": 23 + } + ], + "_prefab": { + "__id__": 25 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Toggle1", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 2 + }, + "_children": [ + { + "__id__": 4 + }, + { + "__id__": 10 + } + ], + "_active": true, + "_components": [ + { + "__id__": 16 + }, + { + "__id__": 18 + }, + { + "__id__": 20 + } + ], + "_prefab": { + "__id__": 22 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": -62, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Checkmark", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 3 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 5 + }, + { + "__id__": 7 + } + ], + "_prefab": { + "__id__": 9 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 4 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 32, + "height": 32 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "27HKqiuT5B4pOF1MIb61vJ" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 4 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "45828f25-b50d-4c52-a591-e19491a62b8c@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "23PLbx08lF64gH8Ui/ORRE" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "16QjTydSxOAqvHPArla6gq", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "RichText", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 3 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 11 + }, + { + "__id__": 13 + } + ], + "_prefab": { + "__id__": 15 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 20, + "y": -40, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 12 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 97.46, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a2m8iX/wZH17O0Jo37Lgoa" + }, + { + "__type__": "cc.RichText", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 14 + }, + "_lineHeight": 40, + "_string": "script11111
", + "_horizontalAlign": 0, + "_verticalAlign": 0, + "_fontSize": 20, + "_maxWidth": 0, + "_fontFamily": "Arial", + "_font": null, + "_isSystemFontUsed": true, + "_userDefinedFont": null, + "_cacheMode": 0, + "_imageAtlas": null, + "_handleTouchEvent": true, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "9a0VqDYVNI8qhA+cq51+vt" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "b4ZfJ/y25I+Z3/mKNHUFuF", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": { + "__id__": 17 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 32, + "height": 32 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1f3Rr+JCxN17x4ucB/HkCS" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "f12a23c4-b924-4322-a260-3d982428f1e8@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "4df5t3fOxBDZD2jEh3Jh8s" + }, + { + "__type__": "cc.Toggle", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": { + "__id__": 21 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 0, + "_normalColor": { + "__type__": "cc.Color", + "r": 214, + "g": 214, + "b": 214, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": { + "__uuid__": "f12a23c4-b924-4322-a260-3d982428f1e8@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": { + "__id__": 3 + }, + "checkEvents": [], + "_isChecked": true, + "_checkMark": { + "__id__": 7 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "29VhYfKnRFqp6RmJ2susGy" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "d93+Cl+1xCKrE1Mg8twr87", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.ToggleContainer", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 24 + }, + "_allowSwitchOff": false, + "checkEvents": [], + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "40XAv0zk9BMJQg7mM85F80" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "9cxP+XIN5OLIphZ7bb24Hw", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "CompositeMode", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 27 + } + ], + "_active": true, + "_components": [ + { + "__id__": 47 + } + ], + "_prefab": { + "__id__": 49 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 78.41399999999999, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Toggle", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 26 + }, + "_children": [ + { + "__id__": 28 + }, + { + "__id__": 34 + } + ], + "_active": true, + "_components": [ + { + "__id__": 40 + }, + { + "__id__": 42 + }, + { + "__id__": 44 + } + ], + "_prefab": { + "__id__": 46 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Checkmark", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 27 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 29 + }, + { + "__id__": 31 + } + ], + "_prefab": { + "__id__": 33 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 28 + }, + "_enabled": true, + "__prefab": { + "__id__": 30 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 26, + "height": 26 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ba+BNK4TNH1p7Lbf5WC49b" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 28 + }, + "_enabled": true, + "__prefab": { + "__id__": 32 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "158e7e52-3220-4cd7-9694-713e0e6e8278@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "60T5gGAZlOtL41vEBfuJpq" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "15c2ZHja1Khp1VngpvBLiB", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "RichText", + "_objFlags": 0, + "__editorExtras__": { + "editorOnly": true + }, + "_parent": { + "__id__": 27 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 35 + }, + { + "__id__": 37 + } + ], + "_prefab": { + "__id__": 39 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 20, + "y": -40, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 36 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 36.68, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d5mq0QO/NHjq5vlZqSf1ph" + }, + { + "__type__": "cc.RichText", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 38 + }, + "_lineHeight": 40, + "_string": "Test", + "_horizontalAlign": 0, + "_verticalAlign": 0, + "_fontSize": 20, + "_maxWidth": 0, + "_fontFamily": "Arial", + "_font": null, + "_isSystemFontUsed": true, + "_userDefinedFont": null, + "_cacheMode": 0, + "_imageAtlas": null, + "_handleTouchEvent": true, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "54p6VvlUZNdILjEzdiRf0W" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "eeAS4n/x1Bgbg3ZsIsQgRH", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 27 + }, + "_enabled": true, + "__prefab": { + "__id__": 41 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 28, + "height": 28 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d06/x9QxZA16XVJ2/YLDuI" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 27 + }, + "_enabled": true, + "__prefab": { + "__id__": 43 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "11bdc4b0-64a8-4eb7-a2a7-9fb9e233e977@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b469YWQjhDkq5xWkbx8Wxx" + }, + { + "__type__": "cc.Toggle", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 27 + }, + "_enabled": true, + "__prefab": { + "__id__": 45 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 0, + "_normalColor": { + "__type__": "cc.Color", + "r": 214, + "g": 214, + "b": 214, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": { + "__uuid__": "11bdc4b0-64a8-4eb7-a2a7-9fb9e233e977@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": { + "__id__": 27 + }, + "checkEvents": [], + "_isChecked": true, + "_checkMark": { + "__id__": 31 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "edendYRtdD4qoXC6Hzga2T" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "042QZey/RH5bgDNWnI5iVJ", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 26 + }, + "_enabled": true, + "__prefab": { + "__id__": 48 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "24r3io5/VNHbI+rAIVw4fM" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a2wbg53b5NMJCjbD0ld4jf", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "MiscMode", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 51 + } + ], + "_prefab": { + "__id__": 53 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 50 + }, + "_enabled": true, + "__prefab": { + "__id__": 52 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "25mqEEHJlAWpwqGC1LNTm/" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "65gtaSQcJEXpJw6NiMvTci", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "EnableAllCompositeMode", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 55 + } + ], + "_active": true, + "_components": [ + { + "__id__": 61 + }, + { + "__id__": 63 + }, + { + "__id__": 65 + } + ], + "_prefab": { + "__id__": 67 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Label", + "_objFlags": 512, + "_parent": { + "__id__": 54 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 56 + }, + { + "__id__": 58 + } + ], + "_prefab": { + "__id__": 60 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 55 + }, + "_enabled": true, + "__prefab": { + "__id__": 57 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "dexcxB9R1L2puTvBD4ErEU" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 55 + }, + "_enabled": true, + "__prefab": { + "__id__": 59 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_string": "RestoreAll", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 20, + "_fontSize": 20, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 1, + "_enableWrapText": false, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "20qbdUQG1E0aa9hTJNGeDI" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "25uCsq3pZINZr8KXqnlXsO", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 54 + }, + "_enabled": true, + "__prefab": { + "__id__": 62 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a90ruBE1hAM6DbOVsPeaOW" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 54 + }, + "_enabled": true, + "__prefab": { + "__id__": 64 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 1, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3fhv3YJoJJk4ZeDM5QBces" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 54 + }, + "_enabled": true, + "__prefab": { + "__id__": 66 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 2, + "_normalColor": { + "__type__": "cc.Color", + "r": 214, + "g": 214, + "b": 214, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": { + "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_hoverSprite": { + "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_pressedSprite": { + "__uuid__": "544e49d6-3f05-4fa8-9a9e-091f98fc2ce8@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_disabledSprite": { + "__uuid__": "951249e0-9f16-456d-8b85-a6ca954da16b@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": { + "__id__": 54 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d1I6MVupxO+74XtCg4pUBY" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "e520Fz5DBPxaDMxht6vCPC", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 69 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ec6RWYextBkI67Q9TwJtO6" + }, + { + "__type__": "b2bd1+njXxJxaFY3ymm06WU", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 71 + }, + "compositeModeToggle": { + "__id__": 27 + }, + "singleModeToggle": { + "__id__": 3 + }, + "EnableAllCompositeModeButton": { + "__id__": 54 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3405wQdHBNNL8MCuRKzDov" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a0J9bM8JxF44Zr/AjHUGPT", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/editor/assets/tools/debug-view-runtime-control.prefab.meta b/editor/assets/tools/debug-view-runtime-control.prefab.meta new file mode 100644 index 00000000000..67fc74eb901 --- /dev/null +++ b/editor/assets/tools/debug-view-runtime-control.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.43", + "importer": "prefab", + "imported": true, + "uuid": "7f4ddeab-efa9-4b76-bf6a-029520f68461", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "debug-view-runtime-control" + } +} diff --git a/editor/assets/tools/debug-view-runtime-control.ts b/editor/assets/tools/debug-view-runtime-control.ts new file mode 100644 index 00000000000..bce983913b0 --- /dev/null +++ b/editor/assets/tools/debug-view-runtime-control.ts @@ -0,0 +1,317 @@ +import { Color, Canvas, UITransform, instantiate, math, Toggle, TextureCube, _decorator, Component, Button, labelAssembler, game, director, Node, Scene, renderer, CameraComponent, Label, ForwardPipeline, RichText } from 'cc'; +const { ccclass, property } = _decorator; + +@ccclass('debugViewRuntimeControl') +export class debugViewRuntimeControl extends Component { + @property(Node) + compositeModeToggle: Node | null = null; + @property(Node) + singleModeToggle: Node | null = null; + @property(Node) + EnableAllCompositeModeButton: Node | null = null; + _single: number = 0; + + private strSingle: string[] = [ + 'No Single Debug', + 'Vertex Color', + 'Vertex Normal', + 'Vertex Tangent', + 'World Position', + 'Vertex Mirror', + 'Face Side', + 'UV0', + 'UV1', + 'UV Lightmap', + 'Project Depth', + 'Linear Depth', + + 'Fragment Normal', + 'Fragment Tangent', + 'Fragment Binormal', + 'Base Color', + 'Diffuse Color', + 'Specular Color', + 'Transparency', + 'Metallic', + 'Roughness', + 'Specular Intensity', + 'IOR', + + 'Direct Diffuse', + 'Direct Specular', + 'Direct All', + 'Env Diffuse', + 'Env Specular', + 'Env All', + 'Emissive', + 'Light Map', + 'Shadow', + 'AO', + + 'Fresnel', + 'Direct Transmit Diffuse', + 'Direct Transmit Specular', + 'Env Transmit Diffuse', + 'Env Transmit Specular', + 'Transmit All', + 'Direct TRT', + 'Env TRT', + 'TRT All', + + 'Fog', + ]; + private strComposite: string[] = [ + 'Direct Diffuse', + 'Direct Specular', + 'Env Diffuse', + 'Env Specular', + 'Emissive', + 'Light Map', + 'Shadow', + 'AO', + + 'Normal Map', + 'Fog', + + 'Tone Mapping', + 'Gamma Correction', + + 'Fresnel', + 'Transmit Diffuse', + 'Transmit Specular', + 'TRT', + ]; + private strMisc: string[] = [ + 'CSM Layer Coloration', + 'Lighting With Albedo', + ]; + + private compositeModeToggleList: Node[] = []; + private singleModeToggleList: Node[] = []; + private miscModeToggleList: Node[] = []; + private textComponentList: RichText[] = []; + private labelComponentList: Label[] = []; + private textContentList: string[] = []; + private hideButtonLabel: Label; + start() { + // get canvas resolution + const canvas = this.node.parent.getComponent(Canvas); + if (!canvas) { + console.error('debug-view-runtime-control should be child of Canvas'); + return; + } + + const uiTransform = this.node.parent.getComponent(UITransform); + const halfScreenWidth = uiTransform.width * 0.5; + const halfScreenHeight = uiTransform.height * 0.5; + + let x = -halfScreenWidth + halfScreenWidth * 0.1, y = halfScreenHeight - halfScreenHeight * 0.1; + const width = 200, height = 20; + + // new nodes + const miscNode = this.node.getChildByName('MiscMode'); + const buttonNode = instantiate(miscNode); + buttonNode.parent = this.node; + buttonNode.name = 'Buttons'; + const titleNode = instantiate(miscNode); + titleNode.parent = this.node; + titleNode.name = 'Titles'; + + // title + for (let i = 0; i < 2; i++) { + const newLabel = instantiate(this.EnableAllCompositeModeButton.getChildByName('Label')); + newLabel.setPosition(x + (i > 0 ? 50 + width * 2 : 150), y, 0.0); + newLabel.setScale(0.75, 0.75, 0.75); + newLabel.parent = titleNode; + const labelComponent = newLabel.getComponent(Label); + labelComponent.string = i ? '----------Composite Mode----------' : '----------Single Mode----------'; + labelComponent.color = Color.WHITE; + labelComponent.overflow = 0; + this.labelComponentList[this.labelComponentList.length] = labelComponent; + } + + y -= height; + // single + let currentRow = 0; + for (let i = 0; i < this.strSingle.length; i++, currentRow++) { + if (i === this.strSingle.length >> 1) { + x += width; + currentRow = 0; + } + const newNode = i ? instantiate(this.singleModeToggle) : this.singleModeToggle; + newNode.setPosition(x, y - height * currentRow, 0.0); + newNode.setScale(0.5, 0.5, 0.5); + newNode.parent = this.singleModeToggle.parent; + + const textComponent = newNode.getComponentInChildren(RichText); + textComponent.string = this.strSingle[i]; + this.textComponentList[this.textComponentList.length] = textComponent; + this.textContentList[this.textContentList.length] = textComponent.string; + + newNode.on(Toggle.EventType.TOGGLE, this.toggleSingleMode, this); + + this.singleModeToggleList[i] = newNode; + } + + x += width; + // buttons + this.EnableAllCompositeModeButton.setPosition(x + 15, y, 0.0); + this.EnableAllCompositeModeButton.setScale(0.5, 0.5, 0.5); + this.EnableAllCompositeModeButton.on(Button.EventType.CLICK, this.enableAllCompositeMode, this); + this.EnableAllCompositeModeButton.parent = buttonNode; + let labelComponent = this.EnableAllCompositeModeButton.getComponentInChildren(Label); + this.labelComponentList[this.labelComponentList.length] = labelComponent; + + const changeColorButton = instantiate(this.EnableAllCompositeModeButton); + changeColorButton.setPosition(x + 90, y, 0.0); + changeColorButton.setScale(0.5, 0.5, 0.5); + changeColorButton.on(Button.EventType.CLICK, this.changeTextColor, this); + changeColorButton.parent = buttonNode; + labelComponent = changeColorButton.getComponentInChildren(Label); + labelComponent.string = 'TextColor'; + this.labelComponentList[this.labelComponentList.length] = labelComponent; + + const HideButton = instantiate(this.EnableAllCompositeModeButton); + HideButton.setPosition(x + 200, y, 0.0); + HideButton.setScale(0.5, 0.5, 0.5); + HideButton.on(Button.EventType.CLICK, this.hideUI, this); + HideButton.parent = this.node.parent; + labelComponent = HideButton.getComponentInChildren(Label); + labelComponent.string = 'Hide UI'; + this.labelComponentList[this.labelComponentList.length] = labelComponent; + this.hideButtonLabel = labelComponent; + + // misc + y -= 40; + for (let i = 0; i < this.strMisc.length; i++) { + const newNode = instantiate(this.compositeModeToggle); + newNode.setPosition(x, y - height * i, 0.0); + newNode.setScale(0.5, 0.5, 0.5); + newNode.parent = miscNode; + + const textComponent = newNode.getComponentInChildren(RichText); + textComponent.string = this.strMisc[i]; + this.textComponentList[this.textComponentList.length] = textComponent; + this.textContentList[this.textContentList.length] = textComponent.string; + + const toggleComponent = newNode.getComponent(Toggle); + toggleComponent.isChecked = i ? true : false; + newNode.on(Toggle.EventType.TOGGLE, i ? this.toggleLightingWithAlbedo : this.toggleCSMColoration, this); + this.miscModeToggleList[i] = newNode; + } + + // composite + y -= 150; + for (let i = 0; i < this.strComposite.length; i++) { + const newNode = i ? instantiate(this.compositeModeToggle) : this.compositeModeToggle; + newNode.setPosition(x, y - height * i, 0.0); + newNode.setScale(0.5, 0.5, 0.5); + newNode.parent = this.compositeModeToggle.parent; + + const textComponent = newNode.getComponentInChildren(RichText); + textComponent.string = this.strComposite[i]; + this.textComponentList[this.textComponentList.length] = textComponent; + this.textContentList[this.textContentList.length] = textComponent.string; + + newNode.on(Toggle.EventType.TOGGLE, this.toggleCompositeMode, this); + + this.compositeModeToggleList[i] = newNode; + } + } + + isTextMatched(textUI, textDescription) : boolean { + let tempText = new String(textUI); + const findIndex = tempText.search('>'); + if (findIndex === -1) { + return textUI === textDescription; + } else { + tempText = tempText.substr(findIndex + 1); + tempText = tempText.substr(0, tempText.search('<')); + return tempText === textDescription; + } + } + toggleSingleMode(toggle: Toggle) { + const debugView = director.root!.debugView; + const textComponent = toggle.getComponentInChildren(RichText); + for (let i = 0; i < this.strSingle.length; i++) { + if (this.isTextMatched(textComponent.string, this.strSingle[i])) { + debugView.singleMode = i; + } + } + } + toggleCompositeMode(toggle: Toggle) { + const debugView = director.root!.debugView; + const textComponent = toggle.getComponentInChildren(RichText); + for (let i = 0; i < this.strComposite.length; i++) { + if (this.isTextMatched(textComponent.string, this.strComposite[i])) { + debugView.enableCompositeMode(i, toggle.isChecked); + } + } + } + toggleLightingWithAlbedo(toggle: Toggle) { + const debugView = director.root!.debugView; + debugView.lightingWithAlbedo = toggle.isChecked; + } + toggleCSMColoration(toggle: Toggle) { + const debugView = director.root!.debugView; + debugView.csmLayerColoration = toggle.isChecked; + } + enableAllCompositeMode(button: Button) { + const debugView = director.root!.debugView; + debugView.enableAllCompositeMode(true); + for (let i = 0; i < this.compositeModeToggleList.length; i++) { + const toggleComponent = this.compositeModeToggleList[i].getComponent(Toggle); + toggleComponent.isChecked = true; + } + + let toggleComponent = this.miscModeToggleList[0].getComponent(Toggle); + toggleComponent.isChecked = false; + debugView.csmLayerColoration = false; + toggleComponent = this.miscModeToggleList[1].getComponent(Toggle); + toggleComponent.isChecked = true; + debugView.lightingWithAlbedo = true; + } + hideUI(button: Button) { + const titleNode = this.node.getChildByName('Titles'); + const activeValue = !titleNode.active; + this.singleModeToggleList[0].parent.active = activeValue; + this.miscModeToggleList[0].parent.active = activeValue; + this.compositeModeToggleList[0].parent.active = activeValue; + this.EnableAllCompositeModeButton.parent.active = activeValue; + titleNode.active = activeValue; + this.hideButtonLabel.string = activeValue ? 'Hide UI' : 'Show UI'; + } + + private _currentColorIndex = 0; + private strColor: string[] = [ + '', + '', + '', + '', + '', + ]; + private color: Color[] = [ + Color.WHITE, + Color.BLACK, + Color.RED, + Color.GREEN, + Color.BLUE, + ]; + changeTextColor(button: Button) { + this._currentColorIndex++; + if (this._currentColorIndex >= this.strColor.length) { + this._currentColorIndex = 0; + } + for (let i = 0; i < this.textComponentList.length; i++) { + this.textComponentList[i].string = this.strColor[this._currentColorIndex] + this.textContentList[i] + '
'; + } + for (let i = 0; i < this.labelComponentList.length; i++) { + this.labelComponentList[i].color = this.color[this._currentColorIndex]; + } + } + + onLoad() { + } + update(deltaTime: number) { + } +} diff --git a/editor/assets/tools/debug-view-runtime-control.ts.meta b/editor/assets/tools/debug-view-runtime-control.ts.meta new file mode 100644 index 00000000000..100af74337c --- /dev/null +++ b/editor/assets/tools/debug-view-runtime-control.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "b2bd1fa7-8d7c-49c5-a158-df29a6d3a594", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/editor/engine-features/render-config.json b/editor/engine-features/render-config.json index 994a57ce0d4..9a974aa9a14 100644 --- a/editor/engine-features/render-config.json +++ b/editor/engine-features/render-config.json @@ -12,7 +12,7 @@ "label": "i18n:ENGINE.features.graphics.label", "multi": true, "description": "i18n:ENGINE.features.graphics.description", - "default": ["gfx-webgl", "gfx-webgl2", "gfx-webgpu"], + "default": ["gfx-webgl", "gfx-webgl2"], "options": { "gfx-webgl": { "required": true, @@ -53,6 +53,12 @@ "category": "2d", "wechatPlugin": true }, + "xr": { + "default": [], + "label": "i18n:ENGINE.features.xr.label", + "description": "i18n:ENGINE.features.xr.description", + "wechatPlugin": false + }, "ui": { "default": ["ui"], "label": "i18n:ENGINE.features.ui.label", @@ -209,6 +215,13 @@ "wechatPlugin": true, "category": "3d" }, + "light-probe": { + "default": ["light-probe"], + "label": "i18n:ENGINE.features.light_probe.label", + "description": "i18n:ENGINE.features.light_probe.description", + "wechatPlugin": true, + "category": "3d" + }, "tiled-map": { "default": ["tiled-map"], "label": "i18n:ENGINE.features.tiled_map.label", @@ -239,20 +252,6 @@ "wechatPlugin": false, "category": "animation" }, - "xr": { - "default": [], - "label": "i18n:ENGINE.features.base_xr.label", - "description": "i18n:ENGINE.features.base_xr.description", - "wechatPlugin": false, - "category": "xr" - }, - "ar": { - "default": [], - "label": "i18n:ENGINE.features.ar.label", - "description": "i18n:ENGINE.features.ar.description", - "wechatPlugin": false, - "category": "xr" - }, "custom-pipeline": { "default": [], "label": "i18n:ENGINE.features.custom_pipeline.label", @@ -276,10 +275,6 @@ "network": { "label": "i18n:ENGINE.features.categories.network.label", "description": "i18n:ENGINE.features.categories.network.description" - }, - "xr": { - "label": "i18n:ENGINE.features.categories.xr.label", - "description": "i18n:ENGINE.features.categories.xr.description" } } } diff --git a/editor/engine-features/schema.json b/editor/engine-features/schema.json index 26921665ec5..ecdcc5fe494 100644 --- a/editor/engine-features/schema.json +++ b/editor/engine-features/schema.json @@ -61,9 +61,6 @@ "animation": { "$ref": "#/definitions/Item" }, - "ar": { - "$ref": "#/definitions/Item" - }, "audio": { "$ref": "#/definitions/Item" }, @@ -211,9 +208,6 @@ "animation": { "$ref": "#/definitions/BaseItem" }, - "ar": { - "$ref": "#/definitions/BaseItem" - }, "audio": { "$ref": "#/definitions/BaseItem" }, diff --git a/editor/engine-features/types.ts b/editor/engine-features/types.ts index 41aa9cb9165..2ff6a5f7cd6 100644 --- a/editor/engine-features/types.ts +++ b/editor/engine-features/types.ts @@ -8,6 +8,7 @@ export type EngineFeature = | 'graphcis' | '3d' | '2d' + | 'xr' | 'ui' | 'particle' | 'physics' @@ -32,9 +33,7 @@ export type EngineFeature = | 'profiler' | 'marionette' | 'animation' - | 'skeletal-animation' - | 'xr' - | 'ar'; + | 'skeletal-animation'; export interface ModuleRenderConfig { $schema?: string; diff --git a/editor/exports/2d-misc.ts b/editor/exports/2d-misc.ts new file mode 100644 index 00000000000..cf25d1076c3 --- /dev/null +++ b/editor/exports/2d-misc.ts @@ -0,0 +1 @@ +export { earcut } from '../../cocos/2d/assembler/graphics/webgl/earcut'; \ No newline at end of file diff --git a/editor/exports/custom-pipeline.ts b/editor/exports/custom-pipeline.ts new file mode 100644 index 00000000000..85fc265b234 --- /dev/null +++ b/editor/exports/custom-pipeline.ts @@ -0,0 +1,6 @@ +export * from '../../cocos/rendering/custom/graph'; +export * from '../../cocos/rendering/custom/types'; +export * from '../../cocos/rendering/custom/layout-graph'; +export * from '../../cocos/rendering/custom/layout-graph-utils'; +export * from '../../cocos/rendering/custom/archive'; +export * from '../../cocos/rendering/custom/binary-archive'; diff --git a/editor/exports/distributed.ts b/editor/exports/distributed.ts deleted file mode 100644 index 45ff6b046c1..00000000000 --- a/editor/exports/distributed.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '../../cocos/core/distributed/utils'; diff --git a/editor/exports/exotic-animation.ts b/editor/exports/exotic-animation.ts index 6db3f30d883..c808eaabff0 100644 --- a/editor/exports/exotic-animation.ts +++ b/editor/exports/exotic-animation.ts @@ -10,3 +10,8 @@ export { export { RealArrayTrack, } from '../../cocos/animation/tracks/array-track'; + +export { + additiveSettingsTag, + AnimationClipAdditiveSettings, +} from '../../cocos/animation/animation-clip'; diff --git a/editor/exports/lod-group-utils.ts b/editor/exports/lod-group-utils.ts new file mode 100644 index 00000000000..768f4c7cc9f --- /dev/null +++ b/editor/exports/lod-group-utils.ts @@ -0,0 +1 @@ +export { LODGroupEditorUtility } from '../../cocos/rendering/lod-group-editor-utility'; diff --git a/editor/exports/material.ts b/editor/exports/material.ts new file mode 100644 index 00000000000..978bc7012ba --- /dev/null +++ b/editor/exports/material.ts @@ -0,0 +1 @@ +export * from '../../cocos/gfx/base/pipeline-state.editor'; diff --git a/editor/exports/new-gen-anim.ts b/editor/exports/new-gen-anim.ts index 260a4307293..9bb29f0814c 100644 --- a/editor/exports/new-gen-anim.ts +++ b/editor/exports/new-gen-anim.ts @@ -29,7 +29,13 @@ export type { TransitionPreviewerTimelineStats, } from '../src/marionette/preview'; +export { + cloneState, + turnMotionStateIntoSubStateMachine, +} from '../src/marionette/state-machine-operation'; + export { visitAnimationClips, visitAnimationClipsInController, + visitAnimationGraphEditorExtras, } from '../src/marionette/visit'; diff --git a/editor/exports/offline-mappings.ts b/editor/exports/offline-mappings.ts index 14e83eb82b7..7c4ac6900c1 100644 --- a/editor/exports/offline-mappings.ts +++ b/editor/exports/offline-mappings.ts @@ -3,11 +3,10 @@ import { Address, BlendFactor, BlendOp, ColorMask, ComparisonFunc, CullMode, DynamicStateFlagBit, Filter, Format, FormatInfos, FormatType, GetTypeSize, PolygonMode, PrimitiveMode, - ShadeModel, ShaderStageFlagBit, StencilOp, Type, DescriptorType, SamplerInfo, MemoryAccessBit, -} from '../../cocos/gfx/base/define'; + ShadeModel, ShaderStageFlagBit, StencilOp, Type, DescriptorType, SamplerInfo, MemoryAccessBit, Sampler, +} from '../../cocos/gfx'; import { RenderPassStage, RenderPriority, SetIndex } from '../../cocos/rendering/define'; -import { murmurhash2_32_gc } from '../../cocos/core/algorithm/murmurhash2_gc'; -import { Sampler } from '../../cocos/gfx/base/states/sampler'; +import { murmurhash2_32_gc } from '../../cocos/core'; const typeMap: Record = {}; typeMap[typeMap.bool = Type.BOOL] = 'bool'; diff --git a/editor/exports/reflection-probe.ts b/editor/exports/reflection-probe.ts new file mode 100644 index 00000000000..14721490c20 --- /dev/null +++ b/editor/exports/reflection-probe.ts @@ -0,0 +1 @@ +export { ReflectionProbeManager } from '../../cocos/rendering/reflection-probe-manager'; \ No newline at end of file diff --git a/editor/exports/serialization.ts b/editor/exports/serialization.ts index 144356819b1..cc3ac576bab 100644 --- a/editor/exports/serialization.ts +++ b/editor/exports/serialization.ts @@ -6,4 +6,4 @@ export { BufferBuilder, decodeCCONBinary, parseCCONJson, -} from '../../cocos/core/data/ccon'; +} from '../../cocos/serialization/ccon'; diff --git a/editor/i18n/en/assets.js b/editor/i18n/en/assets.js index 498e80b769e..01887bb9729 100644 --- a/editor/i18n/en/assets.js +++ b/editor/i18n/en/assets.js @@ -99,9 +99,11 @@ module.exports = { flipVertical: 'Flip Vertical', flipVerticalTip: 'Flip Vertical', fixAlphaTransparencyArtifacts: 'Fix Alpha Transparency Artifacts', - fixAlphaTransparencyArtifactsTip: 'Fill transparent pixels with color of neareast solid pixel. These filled pixels would fix the dark halos at transparent borders of textures. Please turn on this option when you use the Alpha transparency channel in textures.', + fixAlphaTransparencyArtifactsTip: + 'Fill transparent pixels with color of neareast solid pixel. These filled pixels would fix the dark halos at transparent borders of textures. Please turn on this option when you use the Alpha transparency channel in textures.', isRGBE: 'Is RGBE', isRGBETip: 'Is RGBE', + flipGreenChannel: 'Flip Green Channel', }, spriteFrame: { packable: 'Packable', @@ -329,7 +331,48 @@ module.exports = { title: 'Verbose Output', }, }, - // eslint-disable-next-line max-len + algorithm: { + name: 'Algorithm', + simplify: 'simplify', + gltfpack: 'gltfpack (deprecated)', + }, + simplify:{ + targetRatio: { + name: 'Ratio', + title: 'Target Ratio', + }, + preserveSurfaceCurvature: { + name: 'Surface Curvature', + title: 'Preserve Surface Curvature', + }, + preserveBorderEdges: { + name: 'Border Edges', + title: 'Preserve Border Edges', + }, + preserveUVSeamEdges: { + name: 'UV Seam Edges', + title: 'Preserve UV Seam Edges', + }, + preserveUVFoldoverEdges: { + name: 'UV Foldover Edges', + title: 'Preserve UV Foldover Edges', + }, + enableSmartLink: { + name: 'Smart Link', + title: 'Enable Smart Link', + }, + agressiveness: { + name: 'Agressiveness', + title: 'Agressiveness', + }, + maxIterationCount: { + name: 'Max Iteration Count', + title: 'Max Iteration Count', + }, + }, + gltfpack: { + warn: 'The current asset uses the gltfpack mesh optimization algorithm, which has been deprecated. Please use the new simplify face reduction algorithm.', + }, warn: 'Warning: After optimization, the number and names of mesh resources will change, which will cause the loss of resources referenced by the components, please update them manually in time. (In addition, for prefabs pre-generated in the model resources, the resource synchronization mechanism will update them automatically)', }, animationBakeRate: { @@ -341,9 +384,16 @@ module.exports = { name: 'Promote Single Root Node', title: 'If enabled and there is only one root node in model scene,
' + - 'the single node becomes prefab\'s root after importing.
' + + "the single node becomes prefab's root after importing.
" + "Otherwise, each root node of the scene becomes prefab's child node.", }, + generateLightmapUVNode: { + name: 'Generate Lightmap UV', + title: + 'If enabled ,create a lightmap uv in the second UV channel,
' + + 'If the second uv already exists , the set will be override .
' + + "Otherwise, use default uvs.", + }, preferLocalTimeSpan: { name: 'Prefer Local Time Span', title: @@ -387,7 +437,7 @@ module.exports = { illegalFbx: 'Import Skeleton Failed: this fbx asset has not contained sub prefab asset.', nodeEnableTip: 'Whether to enable this joint and its descendants.;
Alt + Click only toggle the state of itself.', }, - multipleWarning: 'Multi-select editing of this type of asset is not supported', + multipleWarning: 'Multi-select editing of this type of asset is not supported.', check_is_saved: { message: 'The modified data has not been saved. Do you want to save it?', assetMessage: "${assetName} is modified, it's data has not been saved. Do you want to save it?", @@ -408,7 +458,8 @@ module.exports = { reset_node: 'Reset', reset_node_position: 'Reset Position', reset_node_rotation: 'Reset Rotation', - reset_node_scale: 'Reset Scale ', + reset_node_scale: 'Reset Scale', + reset_node_mobility: 'Reset Mobility', copy_node_value: 'Copy Node Values', paste_node_value: 'Paste Node Values', diff --git a/editor/i18n/en/components.js b/editor/i18n/en/components.js index 7b68a87dfc9..4f416c12844 100644 --- a/editor/i18n/en/components.js +++ b/editor/i18n/en/components.js @@ -14,7 +14,6 @@ module.exports = { export_error: 'This resource does not support exports outside of the project.', export_tips: 'Export custom particle data to plist file.', }, - prefab_link: { brief_help: 'Since the new Prefab system is not yet complete, the prefab that has a large difference with prefab asset cannot be automatically migrated. ' + @@ -29,7 +28,18 @@ module.exports = { change_children: 'Yes, change children', change_self: 'No, this object only', }, + lightProbeGroup:{ + generateTip: 'Regenerate probes in the scene', + generateWarnTip: 'Continuing to automatically generate a new probe will overwrite the existing probe, and all the data of the existing probe on this node will be lost. Do you want to continue?', + editTip: 'Toggle the probe editing mode in the scene', + }, missScriptTip: 'Script compilation fails, please check the error message and correct it, the component will be automatically restored after correction.', + + lod: { + applyCameraSizeTip: 'Current screen ratio is less or greater than its level limit, applying current minimum or maximum instead.
Please reduce higher LOD levels\' or increase lower levels\' screen size and try again later.', + applyCameraSizeLessThanMinimum: 'Current screen ratio is less than its limit, applying current minimum instead. Please reduce lower LOD levels screen size and try again later.', + applyCameraSizeGreaterThanMaximum: 'Current screen ratio is greater than its limit, applying current maximum instead. Please Increase higher LOD levels screen size and try again later.', + }, }, }; diff --git a/editor/i18n/en/localization.js b/editor/i18n/en/localization.js index 95036c73ffa..d8dfe3d8b59 100755 --- a/editor/i18n/en/localization.js +++ b/editor/i18n/en/localization.js @@ -52,6 +52,11 @@ module.exports = { PageView: `${url}/${version}/manual/en/ui-system/components/editor/pageview.html`, UIStaticBatch: `${url}/${version}/manual/en/ui-system/components/editor/ui-static.html`, UIOpacity: `${url}/${version}/manual/en/ui-system/components/editor/ui-opacity.html`, + BoxCollider2D: `${url}/${version}/manual/en/physics-2d/physics-2d-collider.html`, + CircleCollider2D: `${url}/${version}/manual/en/physics-2d/physics-2d-collider.html`, + PolygonCollider2D: `${url}/${version}/manual/en/physics-2d/physics-2d-collider.html`, + RigidBody2D: `${url}/${version}/manual/en/physics-2d/physics-2d-rigid-body.html`, + Joint2D: `${url}/${version}/manual/en/physics-2d/physics-2d-joint.html`, BoxCollider: `${url}/${version}/manual/en/physics/physics-collider.html`, SphereCollider: `${url}/${version}/manual/en/physics/physics-component.html`, CapsuleCollider: `${url}/${version}/manual/en/physics/physics-component.html`, @@ -66,6 +71,7 @@ module.exports = { TiledMap: ``, Spine: ``, OctreeCulling: `${url}/${version}/manual/en/advanced-topics/native-scene-culling.html`, + LightProbe: ``, }, assets: { javascript: `${url}/${version}/manual/en/concepts/scene/node-component.html`, @@ -152,6 +158,7 @@ module.exports = { illuminance: 'Illuminance of the light', luminous_power: 'Luminous power of the light', luminance: 'Luminance of the light', + visibility: 'Visibility mask, declaring a set of node layers that will be visible to this valid punctual Light(Does not work with directional light)', term: 'The photometric term currently being used', size: 'Size of the light', range: 'Range of the light', @@ -167,6 +174,9 @@ module.exports = { shadowNear: 'Fix area start', shadowFar: 'Fix area end', shadowOrthoSize: 'Fix area size, the larger value, the lower precision of shadows', + shadowAdvancedOptions: 'shadow advanced options', + csmLayersTransition: 'Enable or disable CSM layers transition(Improve quality, reduce performance)', + csmTransitionRange: 'CSM layers transition range(in NDC space: value range is 0 to 1)', }, model: { shadow_receiving_model: 'Shadow receive mode', @@ -680,7 +690,8 @@ module.exports = { limitVelocityOvertimeModule: 'Particle velocity limitation module (only support on CPU)', rotationOvertimeModule: 'Particle rotation module', textureAnimationModule: 'Texture animation module', - trailModule: 'Trail module (only support on CPU)', + trailModule: 'Trail module (only supported in CPU particle system)', + noiseModule: 'Noise module (only supported in CPU particle system)', renderer: 'Particle render module', renderCulling: 'Whether to enable the particle culling feature.
If enabled, a particle emitter bounding box will be generated,
and the particle emitter will be culled if the bounding box is not in the visible range of the camera.
Please refer to the cullingMode option below for the behavior settings after particle culling.', cullingMode: 'Sets the behavior of the particle emitter after it has been culled.
The available options include Pause, Pause and Catchup, and Always Simulate.
When the Pause is selected, the particle will pause the simulation if the particle emitter bounding box is not in the camera\'s visible range.
If it resumes visibility, the particle will continue simulating at the time of last pause.
When the Pause and Catchup is selected, if the particle emitter bounding box is not in the camera\'s visible range, the particle will pause the simulation. If visible again, the particle will start simulating at the current time.
When the Always Simulate is selected, the particle will keep simulating regardless of whether the particle emitter bounding box is in the camera\'s visible range, but will not render when it is not in the camera\'s visible range.', @@ -698,8 +709,9 @@ module.exports = { 'The alpha threshold.
The content is drawn only where the stencil have pixel with alpha greater than the alphaThreshold.
(Not supported Canvas Mode)', segements: 'The segements for ellipse mask', }, - physics: { + physics2d: { rigidbody: { + group: 'group', enabledContactListener: 'Should enabled contact listener. When a collision is trigger,
the collision callback will only be called when enabled contact listener.', bullet: 'Is this a fast moving body that should be prevented from tunneling through other moving bodies?', @@ -713,9 +725,12 @@ module.exports = { linearVelocity: "The linear velocity of the body's origin in world co-ordinates", angularVelocity: 'The angular velocity of the body.', fixedRotation: 'Should this body be prevented from rotating?', - awake: 'Is this body initially awake or sleeping?', + awakeOnLoad: 'Is this body initially awake?', }, - physics_collider: { + collider: { + group: 'Group', + editing: 'Whether to edit the collider', + threshold:'Specifies the minimum distance between the vertices of the generated map outline, the larger the value, the fewer points will be generated, adjustable according to requirements', density: 'The density', sensor: 'A sensor collider collects contact information but never generates a collision response', friction: 'The friction coefficient, usually in the range [0,1].', @@ -752,6 +767,37 @@ module.exports = { tag: 'Tag. If a node has several collider components,
you can judge which type of collider is collided according to the tag.', points: 'Polygon points', }, + joint: { + anchor: 'The anchor of the rigid body.', + connectedAnchor: 'The anchor of the connected rigid body.', + connectedBody: 'The rigid body to which the other end of the joint is attached.', + collideConnected: 'Should the two rigid bodies connected with this joint collide with each other?', + distance: 'The distance separating the two ends of the joint.', + frequency: 'The spring frequency.', + dampingRatio: 'The damping ratio.', + linearOffset: 'The linear offset from connected rigid body to rigid body.', + angularOffset: 'The angular offset from connected rigid body to rigid body.', + maxForce: 'The maximum force can be applied to rigid body.', + maxTorque: 'The maximum torque can be applied to rigid body.', + correctionFactor: 'The position correction factor in the range [0,1].', + mouseRegion: "The node used to register touch event.
If this is null, it will be the joint's node.", + target: 'The target point.
The mouse joint will move chosen rigid body to target point.', + localAxisA: 'The local joint axis relative to rigid body.', + enableLimit: 'Enable joint distance limit?', + enableMotor: 'Enable joint motor?', + lowerLimit: 'The lower joint limit.', + upperLimit: 'The upper joint limit.', + maxMotorForce: 'The maximum force can be applied to rigid body to reach the target motor speed.', + motorSpeed: 'The expected motor speed.', + referenceAngle: 'The reference angle.
An angle between bodies considered to be zero for the joint angle.', + lowerAngle: 'The lower angle.', + upperAngle: 'The upper angle.', + maxMotorTorque: 'The maximum torque can be applied to rigid body to reach the target motor speed.', + maxLength: 'The max length.', + autoCalcDistance:'Whether to automatically calculate the distance between two rigid bodies connected by a joint', + autoCalcAngle:'Automatically calculates the sliding direction based on the two rigid bodies connected', + autoCalcOffset:'Automatically calculate the angularOffset and linearOffset between two rigid bodies connected by a joint', + }, }, block_input_events: { brief_help: @@ -786,10 +832,6 @@ module.exports = { label: 'Network', description: 'Network Module.', }, - xr: { - label: 'XR', - description: 'XR System.', - }, }, core: { label: "Core", @@ -879,6 +921,10 @@ module.exports = { label: "Terrain", description: "Terrain support.", }, + light_probe: { + label: "Light Probe", + description: "Light Probe support.", + }, audio: { label: "Audio", description: "Audio playing support.", @@ -935,13 +981,9 @@ module.exports = { label: "Marionette Animation System", description: "Enable the Marionette animation system", }, - base_xr: { - label: "Basic XR", - description: "Basic XR support.", - }, - ar: { - label: "AR", - description: "AR support.", + xr: { + label: "XR", + description: "Enable the XR function system", }, custom_pipeline: { label: "Custom Render Pipeline (Experimental)", @@ -1026,4 +1068,21 @@ module.exports = { maxPos: 'The maximum position of the world bounding box.', depth: 'The depth of octree.', }, + light_probe: { + giScale: 'The value of GI multiplier.', + giSamples: 'The value of GI sample counts.', + bounces: 'The value of light bounces.', + reduceRinging: 'The value to reduce ringing of light probe.', + showProbe: 'The switch of showing light probe.', + showWireframe: 'The switch of showing connection of light probe.', + showConvex: 'The switch of showing convex of light probe.', + }, + light_probe_group: { + method: 'The automatic generation algorithm of light probe.', + nProbesX: 'The number of probes generated in X axis.', + nProbesY: 'The number of probes generated in Y axis.', + nProbesZ: 'The number of probes generated in Z axis.', + minPos: 'The minimum point of the bounding box of the generated probes.', + maxPos: 'The maximum point of the bounding box of the generated probes.', + }, }; diff --git a/editor/i18n/zh/assets.js b/editor/i18n/zh/assets.js index b56569adcc4..3fb591859ad 100644 --- a/editor/i18n/zh/assets.js +++ b/editor/i18n/zh/assets.js @@ -92,16 +92,18 @@ module.exports = { frag: 'Fragment Shader', }, image: { - type: 'Type', - typeTip: 'Type', + type: '类型', + typeTip: '类型', // bakeOfflineMipmaps: 'Bake Offline Mipmaps', // bakeOfflineMipmapsTip: 'Bake Offline Mipmaps', - flipVertical: 'Flip Vertical', - flipVerticalTip: 'Flip Vertical', - fixAlphaTransparencyArtifacts: 'Fix Alpha Transparency Artifacts', - fixAlphaTransparencyArtifactsTip: '为全透明像素填充相邻像素的颜色,防止纹理过滤引起的黑边问题。当使用 Alpha 透明通道时,请启用此功能。', - isRGBE: 'Is RGBE', - isRGBETip: 'Is RGBE', + flipVertical: '垂直翻转', + flipVerticalTip: '垂直翻转', + fixAlphaTransparencyArtifacts: '消除透明伪影', + fixAlphaTransparencyArtifactsTip: + '为全透明像素填充相邻像素的颜色,防止纹理过滤引起的黑边问题。当使用 Alpha 透明通道时,请启用此功能。', + isRGBE: '作为 RGBE 格式', + isRGBETip: '作为 RGBE 格式', + flipGreenChannel: '翻转绿色通道', }, spriteFrame: { packable: 'Packable', @@ -289,7 +291,7 @@ module.exports = { '若不勾选,网格数据被提交到 GPU 后会被自动释放。
', }, meshOptimizer: { - name: 'Mesh Optimizer', + name: 'Mesh 优化', title: 'Mesh Optimizer', simplification: { name: 'Simplification', @@ -327,6 +329,48 @@ module.exports = { title: 'Verbose Output', }, }, + algorithm: { + name: '减面算法', + simplify: 'simplify', + gltfpack: 'gltfpack (已废弃)', + }, + simplify: { + targetRatio: { + name: 'LOD 压缩比例', + title: 'Target Ratio', + }, + preserveSurfaceCurvature: { + name: '保留表面曲率', + title: 'Preserve Surface Curvature', + }, + preserveBorderEdges: { + name: '保留边界边', + title: 'Preserve Border Edges', + }, + preserveUVSeamEdges: { + name: '保留 UV 缝合边', + title: 'Preserve UV Seam Edges', + }, + preserveUVFoldoverEdges: { + name: '保留 UV 折叠边', + title: 'Preserve UV Foldover Edges', + }, + enableSmartLink: { + name: '防止破面', + title: 'Smart Link', + }, + agressiveness: { + name: '误差距离', + title: 'Agressiveness', + }, + maxIterationCount: { + name: '计算迭代次数', + title: 'Max Iteration Count', + }, + }, + gltfpack: { + warn: '当前资源使用的减面算法 gltfpack 已被废弃,请选用新的 simplify 减面算法。', + }, warn: '警告:优化后,网格资源的数量和名称会发生改变,这将会造成组件引用的资源丢失,请及时手动更新;(另外,对于模型资源中预生成的预制体,资源同步机制会自动更新)', }, animationBakeRate: { @@ -338,6 +382,10 @@ module.exports = { name: '提升单一根节点', title: '若开启并且模型场景顶部仅有一个根节点,那么该节点就作为预制体的根节点。
否则,场景的所有根节点作为预制体的子节点。', }, + generateLightmapUVNode: { + name: '生成灯光贴图 UV 通道', + title: '若开启会为模型生成灯光贴图的 UV 通道, 若模型有第二套 UV , 该 UV 会被生成的 UV 覆盖。< br > 否则,使用原始 UV 信息。', + }, preferLocalTimeSpan: { name: '优先使用文件时间范围', title: '在导出 FBX 动画时,是否优先使用 FBX 文件中记录的动画时间范围。
若不使用该时间范围或此范围不可能用,则会粗略地计算动画时间范围。有些 FBX 生产工具中可能并未导出该信息。', @@ -366,7 +414,7 @@ module.exports = { }, material: { 'fail-to-load-custom-inspector': 'Material: 自定义 Effect {effect} 的 Inspector 加载失败', - 'illegal-inspector-url': "Inspector 的路径不合法", + 'illegal-inspector-url': 'Inspector 的路径不合法', }, animationGraph: { edit: '编辑', @@ -400,6 +448,7 @@ module.exports = { reset_node_position: '重置节点坐标位置', reset_node_rotation: '重置节点旋转角度', reset_node_scale: '重置节点缩放比例', + reset_node_mobility: '重置节点可移动性', copy_node_value: '复制节点的值', paste_node_value: '粘贴节点的值', diff --git a/editor/i18n/zh/components.js b/editor/i18n/zh/components.js index 85671c20986..1c4a299cfb5 100644 --- a/editor/i18n/zh/components.js +++ b/editor/i18n/zh/components.js @@ -24,7 +24,18 @@ module.exports = { change_children: '连同修改子节点', change_self: '只修改节点自身', }, + lightProbeGroup:{ + generateTip: '重新生成场景里的探针数据', + generateWarnTip: '继续自动生成新探针会覆盖已有探针,该节点的已有探针数据会全部丢失,请问是否仍要继续?', + editTip: '切换场景中的探针编辑模式', + }, missScriptTip: "脚本编译失败,请检查报错信息并进行修正,该组件将在修正后自动还原。", + + lod: { + applyCameraSizeTip: '应用当前场景中此节点的屏幕比例于此 LOD 层级,如果当前屏占比小于下一层 LOD 比例,将应用为可以应用的最小值(下一层级比例),
如果当前屏占比大于上一层 LOD 比例,将应用为可以应用的最大值(上一层级比例)', + applyCameraSizeLessThanMinimum: '当前屏占比小于目前层级能使用的最小值,无法设置,设置为目前层级能使用的最小值。请更新更低 LOD 层级的屏幕尺寸之后再次尝试。', + applyCameraSizeGreaterThanMaximum: '当前屏占比大于目前层级能使用的最大值,无法设置,设置为目前层级能使用的最大值。请更新更高 LOD 层级的屏幕尺寸之后再次尝试。', + }, }, }; diff --git a/editor/i18n/zh/localization.js b/editor/i18n/zh/localization.js index 7b285a707fe..b752e16b2f4 100755 --- a/editor/i18n/zh/localization.js +++ b/editor/i18n/zh/localization.js @@ -52,6 +52,11 @@ module.exports = { PageView: `${url}/${version}/manual/zh/ui-system/components/editor/pageview.html`, UIStaticBatch: `${url}/${version}/manual/zh/ui-system/components/editor/ui-static.html`, UIOpacity: `${url}/${version}/manual/zh/ui-system/components/editor/ui-opacity.html`, + BoxCollider2D: `${url}/${version}/manual/zh/physics-2d/physics-2d-collider.html`, + CircleCollider2D: `${url}/${version}/manual/zh/physics-2d/physics-2d-collider.html`, + PolygonCollider2D: `${url}/${version}/manual/zh/physics-2d/physics-2d-collider.html`, + RigidBody2D: `${url}/${version}/manual/zh/physics-2d/physics-2d-rigid-body.html`, + Joint2D: `${url}/${version}/manual/zh/physics-2d/physics-2d-joint.html`, BoxCollider: `${url}/${version}/manual/zh/physics/physics-collider.html`, SphereCollider: `${url}/${version}/manual/zh/physics/physics-component.html`, CapsuleCollider: `${url}/${version}/manual/zh/physics/physics-component.html`, @@ -66,6 +71,7 @@ module.exports = { TiledMap: ``, Spine: ``, OctreeCulling: `${url}/${version}/manual/zh/advanced-topics/native-scene-culling.html`, + LightProbe: ``, }, assets: { javascript: `${url}/${version}/manual/zh/concepts/scene/node-component.html`, @@ -149,6 +155,7 @@ module.exports = { illuminance: '光源强度', luminous_flux: '光通量', luminance: '光亮度', + visibility: '可见性掩码,声明在当前精确光源中可见的节点层级集合(对方向光不生效)', term: '当前使用的光度学计量单位', size: '光源大小', range: '光源范围', @@ -164,6 +171,9 @@ module.exports = { shadowNear: '固定区域开始值', shadowFar: '固定区域结束值', shadowOrthoSize: '固定区域大小,该值越大则阴影精度越低', + shadowAdvancedOptions: '阴影高级选项', + csmLayersTransition: '是否开启级联阴影层级过渡(提升质量,降低性能)', + csmTransitionRange: '级联阴影层级过渡范围(NDC空间: 取值范围为 0 ~ 1)', }, model: { shadow_receiving_model: '阴影接受方式', @@ -665,6 +675,7 @@ module.exports = { rotationOvertimeModule: '粒子旋转模块', textureAnimationModule: '贴图动画模块', trailModule: '粒子轨迹模块(只支持 CPU 粒子)', + noiseModule: '粒子噪声动画模块(只支持 CPU 粒子)', renderer: '粒子渲染模块', renderCulling: '是否开启粒子剔除功能。
开启该项将会生成一个粒子发射器包围盒,若包围盒不在摄像机的可见范围内,该粒子发射器便会被剔除。
粒子发射器被剔除后的行为请参考下面的 Culling Mode。', cullingMode: '粒子发射器被剔除之后的行为,可设置的选项包括 Pause, Pause and Catchup, Always Simulate。
选择 Pause 时,若粒子发射器包围盒不在摄像机的可见范围内,粒子暂停模拟。若恢复可见,则粒子会接着上次暂停的时间继续模拟;
选择 Pause and Catchup 时,若粒子发射器包围盒不在摄像机的可见范围内,粒子暂停模拟。若恢复可见,则粒子会以当前的时间开始模拟;
选择 Always Simulate 时,无论粒子发射器包围盒是否在摄像机的可见范围内,粒子都会一直模拟,只是不在摄像机的可见范围内时不进行渲染。', @@ -681,8 +692,9 @@ module.exports = { alphaThreshold: 'Alpha 阈值,只有当模板的像素的 Alpha 大于 Alpha Threshold 时,才会绘制内容(不支持 Canvas 模式)', segements: '椭圆遮罩的曲线细分数', }, - physics: { + physics2d: { rigidbody: { + group: '分组', enabledContactListener: '是否启用接触接听器。当 Collider 产生碰撞时,只有开启了接触接听器才会调用相应的回调函数', bullet: '这个刚体是否是一个快速移动的刚体,并且需要禁止穿过其他快速移动的刚体', type: '刚体类型:
Static(静态),
Kinematic(不受外力),
Dynamic(动态)和 Animated(通过设置线性速度和角速度驱动)', @@ -695,9 +707,12 @@ module.exports = { linearVelocity: '刚体在世界坐标下的线性速度', angularVelocity: '刚体的角速度', fixedRotation: '是否禁止此刚体进行旋转', - awake: '是否立刻唤醒此刚体', + awakeOnLoad: '是否在初始化时唤醒此刚体', }, - physics_collider: { + collider: { + group: '分组', + editing: '是否需要编辑此碰撞组件', + threshold:'指明生成贴图轮廓顶点间的最小距离,值越大则生成的点越少,可根据需求进行调节', density: '密度', sensor: '一个传感器类型的碰撞体会产生碰撞回调,但是不会发生物理碰撞效果。', friction: '摩擦系数,取值一般在 [0, 1] 之间', @@ -734,6 +749,37 @@ module.exports = { tag: '标签。当一个节点上有多个碰撞组件时,在发生碰撞后,可以使用此标签来判断是节点上的哪个碰撞组件被碰撞了。', points: '多边形顶点数组', }, + joint: { + anchor: '刚体的锚点。', + connectedAnchor: '关节另一端刚体的锚点。', + connectedBody: '关节另一端链接的刚体', + collideConnected: '链接到关节上的两个刚体是否应该相互碰撞?', + distance: '关节两端的距离', + frequency: '弹性系数。', + dampingRatio: '阻尼,表示关节变形后,恢复到初始状态受到的阻力。', + linearOffset: '关节另一端的刚体相对于起始端刚体的位置偏移量', + angularOffset: '关节另一端的刚体相对于起始端刚体的角度偏移量', + maxForce: '可以应用于刚体的最大的力值', + maxTorque: '可以应用于刚体的最大扭矩值', + correctionFactor: '位置矫正系数,范围为 [0, 1]', + mouseRegion: '用于注册触摸事件的节点。如果没有设置这个值,那么将会使用关节的节点来注册事件。', + target: '目标点,鼠标关节将会移动选中的刚体到指定的目标点', + localAxisA: '指定刚体可以移动的方向。', + enableLimit: '是否开启限制?', + enableMotor: '是否开启关节马达?', + lowerLimit: '刚体能够移动的最小值', + upperLimit: '刚体能够移动的最大值', + maxMotorForce: '可以施加到刚体的最大力。', + motorSpeed: '期望的马达速度。', + referenceAngle: '相对角度。两个物体之间角度为零时可以看作相等于关节角度', + lowerAngle: '角度的最低限制。', + upperAngle: '角度的最高限制。', + maxMotorTorque: '可以施加到刚体的最大扭矩。', + maxLength: '最大长度。', + autoCalcDistance:'是否自动计算关节连接的两个刚体间的距离', + autoCalcAngle:'根据连接的两个刚体自动计算滑动方向', + autoCalcOffset:'自动计算关节连接的两个刚体间的 angularOffset 和 linearOffset', + }, }, block_input_events: { brief_help: '该组件将拦截所有输入事件,防止输入穿透到屏幕下方的其它节点,一般用于屏幕上层 UI 的背景。', @@ -767,10 +813,6 @@ module.exports = { label: '网络', description: '网络模块。', }, - xr: { - label: 'XR', - description: 'XR系统。', - }, }, core: { label: "核心功能", @@ -860,6 +902,10 @@ module.exports = { label: "地形", description: "地形功能支持。", }, + light_probe: { + label: "光照探针", + description: "光照探针功能支持。", + }, audio: { label: "音频", description: "音频播放支持。", @@ -916,13 +962,9 @@ module.exports = { label: "Marionette 动画系统", description: "启用 Marionette 动画系统。", }, - base_xr: { - label: "基础 XR 功能", - description: "基础 XR 功能支持。", - }, - ar: { - label: "AR 功能", - description: "AR 功能支持。", + xr: { + label: "XR", + description: "启用 XR 功能系统。", }, custom_pipeline: { label: "自定义渲染管线(实验)", @@ -1007,4 +1049,21 @@ module.exports = { maxPos: '世界包围盒最大顶点的坐标', depth: '八叉树深度', }, + light_probe: { + giScale: 'GI乘数', + giSamples: 'GI采样数量', + bounces: '光照反弹次数', + reduceRinging: '减少光照探针的振铃效果', + showProbe: '是否显示光照探针', + showWireframe: '是否显示光照探针连线', + showConvex: '是否显示光照探针凸包', + }, + light_probe_group: { + method: '光照探针的自动生成算法', + nProbesX: 'X轴生成的光照探针数量', + nProbesY: 'Y轴生成的光照探针数量', + nProbesZ: 'Z轴生成的光照探针数量', + minPos: '生成光照探针的包围盒最小点', + maxPos: '生成光照探针的包围盒最大点', + }, }; diff --git a/editor/inspector/assets.js b/editor/inspector/assets.js index c44d89d8984..2cf5d09ecff 100644 --- a/editor/inspector/assets.js +++ b/editor/inspector/assets.js @@ -2,6 +2,7 @@ const { join } = require('path'); module.exports = { 'animation-graph': join(__dirname, './assets/animation-graph.js'), + 'animation-graph-variant': join(__dirname, './assets/animation-graph-variant.js'), 'animation-mask': join(__dirname, './assets/animation-mask.js'), 'audio-clip': join(__dirname, './assets/audio-clip.js'), 'auto-atlas': join(__dirname, './assets/texture/auto-atlas.js'), // reuse diff --git a/editor/inspector/assets/animation-graph-variant.js b/editor/inspector/assets/animation-graph-variant.js new file mode 100644 index 00000000000..a79f5c76352 --- /dev/null +++ b/editor/inspector/assets/animation-graph-variant.js @@ -0,0 +1,216 @@ +exports.template = ` +
+ + + + + + + + + + + + + + + +
OriginalOverride
+
+
+`; + +exports.$ = { + container: '.asset-animation-graph-variant', + graphAsset: '.graph-asset', + table: '.table', + tbody: '.tbody', +}; + +exports.style = ` +.asset-animation-graph-variant { + padding-top: 10px; +} + +.asset-animation-graph-variant .clips { + padding-top: 10px; + padding-bottom: 10px; +} + +.asset-animation-graph-variant .table { + border-collapse: collapse; + margin-left: -8px; +} + +.asset-animation-graph-variant .table td { + border: 1px solid var(--color-default-border-weaker); +} + +.asset-animation-graph-variant .thead td { + text-align: center; + width: 50%; +} + +.asset-animation-graph-variant .tbody td { + padding: 13px 5px 5px 5px; +} + +.asset-animation-graph-variant .tbody ui-asset { + width: 100%; +} +`; + +exports.methods = { + record() { + return JSON.stringify(this.animationGraphVariant); + }, + + async restore(record) { + record = JSON.parse(record); + if (!record || typeof record !== 'object') { + return false; + } + + this.animationGraphVariant = record; + await this.change(); + return true; + }, + + async query(uuid) { + return await Editor.Message.request('scene', 'query-animation-graph-variant', uuid); + }, + + async apply() { + this.reset(); + await Editor.Message.request('scene', 'apply-animation-graph-variant', this.asset.uuid, this.animationGraphVariant); + }, + + reset() { + /** + * reset 环节只需把 uuid 清空 + * 会重新进入 panel.update 周期,根据 uuid 为空的条件,把 this.dirtyData.origin 重新填充 + */ + this.dirtyData.uuid = ''; + }, + + async change() { + this.animationGraphVariant = await Editor.Message.request('scene', 'change-animation-graph-variant', this.animationGraphVariant); + + this.updateInterface(); + this.setDirtyData(); + this.dispatch('change'); + }, + + updateInterface() { + this.$.graphAsset.value = this.animationGraphVariant.graphUuid; + this.$.graphAsset.readonly = this.asset.readonly; + + const oldPropKeys = Object.keys(this.$props); + const newPropKeys = Object.keys(this.animationGraphVariant.clips); + + for (const key in this.animationGraphVariant.clips) { + // reuse + if (!this.$props[key]) { + this.$props[key] = document.createElement('tr'); + + const originTd = document.createElement('td'); + this.$props[key].$origin = document.createElement('ui-asset'); + this.$props[key].$origin.setAttribute('disabled', ''); + this.$props[key].$origin.droppable = 'cc.AnimationClip'; + originTd.appendChild(this.$props[key].$origin); + + const overrideTd = document.createElement('td'); + this.$props[key].$override = document.createElement('ui-asset'); + this.$props[key].$override.droppable = 'cc.AnimationClip'; + this.$props[key].$override.addEventListener('confirm', (event) => { + this.animationGraphVariant.clips[key] = event.target.value; + this.change(); + }); + overrideTd.appendChild(this.$props[key].$override); + + this.$props[key].appendChild(originTd); + this.$props[key].appendChild(overrideTd); + } + + this.$.tbody.appendChild(this.$props[key]); + + this.$props[key].$origin.value = key; + this.$props[key].$override.value = this.animationGraphVariant.clips[key]; + this.$props[key].$override.readonly = this.asset.readonly; + } + + for (const key of oldPropKeys) { + if (!newPropKeys.includes(key)) { + const $prop = this.$props[key]; + if ($prop && $prop.parentElement) { + $prop.parentElement.removeChild($prop); + } + } + } + }, + + /** + * Detection of data changes only determines the currently selected technique + */ + setDirtyData() { + this.dirtyData.realtime = JSON.stringify(this.animationGraphVariant); + + if (!this.dirtyData.origin) { + this.dirtyData.origin = this.dirtyData.realtime; + + this.dispatch('snapshot'); + } + }, + + isDirty() { + const isDirty = this.dirtyData.origin !== this.dirtyData.realtime; + return isDirty; + }, +}; + +exports.ready = function() { + // Used to determine whether the material has been modified in isDirty() + this.dirtyData = { + uuid: '', + origin: '', + realtime: '', + }; + + this.$props = {}; + + this.$.graphAsset.addEventListener('confirm', (event) => { + this.animationGraphVariant.graphUuid = event.target.value; + this.change(); + }); +}; + +exports.update = async function(assetList, metaList) { + this.assetList = assetList; + this.metaList = metaList; + this.asset = assetList[0]; + this.meta = metaList[0]; + + if (assetList.length !== 1) { + this.$.container.innerText = Editor.I18n.t('ENGINE.assets.multipleWarning'); + return; + } + + if (this.dirtyData.uuid !== this.asset.uuid) { + this.dirtyData.uuid = this.asset.uuid; + this.dirtyData.origin = ''; + } + + this.animationGraphVariant = await this.query(this.asset.uuid); + + this.updateInterface(); + this.setDirtyData(); +}; + +exports.close = function() { + // Used to determine whether the material has been modified in isDirty() + this.dirtyData = { + uuid: '', + origin: '', + realtime: '', + }; +}; diff --git a/editor/inspector/assets/animation-graph.js b/editor/inspector/assets/animation-graph.js index 78ddfd850b5..eddcfb04f3d 100644 --- a/editor/inspector/assets/animation-graph.js +++ b/editor/inspector/assets/animation-graph.js @@ -1,25 +1,39 @@ -exports.template = ` +'use strict'; + +const { updateElementReadonly } = require('../utils/assets'); + +exports.template = /* html */`
- +
`; -exports.style = ` +exports.style = /* css */` .asset-animation-graph { padding-top: 10px; text-align: center; } -.asset-animation-graph .tip { +.asset-animation-graph[multiple-invalid] > *:not(.multiple-warn-tip) { + display: none!important; + } + + .asset-animation-graph[multiple-invalid] > .multiple-warn-tip { + display: block; + } + +.asset-animation-graph .multiple-warn-tip { + display: none; + text-align: center; color: var(--color-focus-contrast-weakest); } `; exports.$ = { - constainer: '.asset-animation-graph', + container: '.asset-animation-graph', button: '.open', tip: '.tip', }; @@ -36,12 +50,13 @@ exports.update = function(assetList, metaList) { this.meta = this.metaList[0]; this.asset = this.assetList[0]; - if (assetList.length !== 1) { - this.$.button.disabled = true; - this.$.tip.style.display = 'block'; + if (assetList.length > 1) { + this.$.container.setAttribute('multiple-invalid', ''); + return; } else { - this.$.button.disabled = false; - this.$.tip.style.display = 'none'; + this.$.container.removeAttribute('multiple-invalid'); } + + updateElementReadonly.call(this, this.$.button); }; diff --git a/editor/inspector/assets/animation-mask.js b/editor/inspector/assets/animation-mask.js index b9169ac4385..4eba65efcae 100644 --- a/editor/inspector/assets/animation-mask.js +++ b/editor/inspector/assets/animation-mask.js @@ -1,4 +1,8 @@ -exports.template = ` +'use strict'; + +const { updateElementReadonly } = require('../utils/assets'); + +exports.template = /* html */`
@@ -13,9 +17,66 @@ exports.template = `
+
`; +exports.style = /* css */` +.asset-animation-mask { + display: flex; + height: 100%; + flex-direction: column; +} + +.asset-animation-mask[multiple-invalid] > *:not(.multiple-warn-tip) { + display: none!important; + } + + .asset-animation-mask[multiple-invalid] > .multiple-warn-tip { + display: block; + } + +.asset-animation-mask .multiple-warn-tip { + display: none; + text-align: center; + color: var(--color-focus-contrast-weakest); +} + +.asset-animation-mask > .header { + margin-top: 10px; + display: flex; +} + +.asset-animation-mask > .header ui-button { + text-align: center; +} + +.asset-animation-mask > .header .import { + flex: 1; + margin-left: 10px; +} + +.asset-animation-mask > .header .clear { + margin-left: 10px; +} + +.asset-animation-mask > .content { + flex: 1; + margin-top: 10px; +} + +.asset-animation-mask > .content .tree { + height: 100%; +} +`; + +exports.$ = { + container: '.asset-animation-mask', + import: '.import', + clear: '.clear', + tree: '.tree', +}; + exports.methods = { record() { return JSON.stringify(this.queryData); @@ -27,29 +88,60 @@ exports.methods = { return false; } - this.queryData = await Editor.Message.request('scene', 'change-animation-mask', { - method: 'change-dump', - dump: record, - }); - await this.changed({ snapshot: false }); + await this.change(record); return true; }, async query(uuid) { return await Editor.Message.request('scene', 'query-animation-mask', uuid); }, + async apply() { this.reset(); await Editor.Message.request('scene', 'apply-animation-mask', this.asset.uuid); }, + reset() { this.dirtyData.uuid = ''; }, - async changed(state) { + + async clear() { + this.queryData = await Editor.Message.request('scene', 'change-animation-mask', { + method: 'clear-nodes', + uuid: this.asset.uuid, + }); + + this.changed(); + }, + async import(info) { + this.queryData = await Editor.Message.request('scene', 'change-animation-mask', { + method: 'import-skeleton', + uuid: info.redirect.uuid, + }); + + this.changed(); + }, + + async change(dump) { + this.queryData = await Editor.Message.request('scene', 'change-animation-mask', { + method: 'change-dump', + dump, + }); + + this.changed(); + }, + + changed() { this.updateInterface(); this.setDirtyData(); - this.dispatch('change', state); + this.dispatch('change'); + + /** + * 由于编辑项中不需要区分 change 和 confirm 的情况, + * 所以可以在 change 后 snapshot + */ + this.dispatch('snapshot'); }, updateInterface() { @@ -57,30 +149,16 @@ exports.methods = { this.flatData = convertData.flatData; this.$.tree.tree = convertData.treeData; - - this.updateReadonly(this.$.import); - this.updateReadonly(this.$.clear); - this.updateReadonly(this.$.tree); + updateElementReadonly.call(this, this.$.import); + updateElementReadonly.call(this, this.$.clear); + updateElementReadonly.call(this, this.$.tree); }, - updateReadonly(element) { - if (this.asset.readonly) { - element.setAttribute('disabled', true); - } else { - element.removeAttribute('disabled'); - } - }, - - /** - * Detection of data changes only determines the currently selected technique - */ setDirtyData() { this.dirtyData.realtime = JSON.stringify(this.queryData); if (!this.dirtyData.origin) { this.dirtyData.origin = this.dirtyData.realtime; - - this.dispatch('snapshot'); } }, @@ -187,44 +265,6 @@ exports.methods = { }, }; -exports.$ = { - container: '.asset-animation-mask', - import: '.import', - clear: '.clear', - tree: '.tree', -}; - -exports.style = ` -.asset-animation-mask { - display: flex; - height: 100%; - flex-direction: column; -} - -.header { - margin-top: 10px; - display: flex; -} - -.header ui-button { - flex: 1; - text-align: center; -} - -.header .clear { - margin-left: 10px; -} - -.content { - flex: 1; - margin-top: 10px; -} - -.content .tree { - height: 100%; -} -`; - exports.ready = function() { const panel = this; @@ -245,12 +285,8 @@ exports.ready = function() { console.error(Editor.I18n.t('ENGINE.assets.animationMask.illegalFbx') + ` {asset(${uuid})}`); return; } - panel.queryData = await Editor.Message.request('scene', 'change-animation-mask', { - method: 'import-skeleton', - uuid: info.redirect.uuid, - }); - panel.changed(); + await panel.import(info); }, }, }); @@ -265,12 +301,7 @@ exports.ready = function() { }); if (result.response === 0) { - panel.queryData = await Editor.Message.request('scene', 'change-animation-mask', { - method: 'clear-nodes', - uuid: this.asset.uuid, - }); - - this.changed(); + await this.clear(); } }); @@ -289,12 +320,7 @@ exports.ready = function() { const origin = panel.flatData[key].origin; panel.jointEnableChange(key, !origin.value.enabled.value, !event.altKey); - panel.queryData = await Editor.Message.request('scene', 'change-animation-mask', { - method: 'change-dump', - dump: panel.queryData, - }); - - panel.changed(); + await panel.change(this.queryData); }); }); panel.$.tree.setRender('left', ($left) => { @@ -328,9 +354,11 @@ exports.update = async function(assetList, metaList) { this.asset = assetList[0]; this.meta = metaList[0]; - if (assetList.length !== 1) { - this.$.container.innerText = Editor.I18n.t('ENGINE.assets.multipleWarning'); + if (assetList.length > 1) { + this.$.container.setAttribute('multiple-invalid', ''); return; + } else { + this.$.container.removeAttribute('multiple-invalid'); } if (this.dirtyData.uuid !== this.asset.uuid) { diff --git a/editor/inspector/assets/audio-clip.js b/editor/inspector/assets/audio-clip.js index beca784a2f2..f61b24c12f5 100644 --- a/editor/inspector/assets/audio-clip.js +++ b/editor/inspector/assets/audio-clip.js @@ -1,8 +1,11 @@ -exports.template = ` +'use strict'; + +exports.template = /* html */`
`; -exports.style = ` + +exports.style = /* css */` .asset-audio-clip .audio { outline: none; width: 100%; @@ -10,9 +13,11 @@ exports.style = ` margin-bottom: 16px; } `; + exports.$ = { - constainer: '.asset-audio-clip', + container: '.asset-audio-clip', }; + exports.update = function(assetList, metaList) { // Support multi-select list display, limit the number of display let html = ''; @@ -30,5 +35,5 @@ exports.update = function(assetList, metaList) { html += ``; }); - this.$.constainer.innerHTML = html; + this.$.container.innerHTML = html; }; diff --git a/editor/inspector/assets/effect-header.js b/editor/inspector/assets/effect-header.js index ad9219e85d7..344fcda99c4 100644 --- a/editor/inspector/assets/effect-header.js +++ b/editor/inspector/assets/effect-header.js @@ -1,22 +1,41 @@ +'use strict'; + const { createReadStream } = require('fs'); const ReadLine = require('readline'); const MAX_LINES = 400; const MAX_LENGTH = 20000; -exports.template = ` +exports.template = /* html */`
+
`; -exports.style = ` +exports.style = /* css */` .asset-effect-header { flex: 1; display: flex; flex-direction: column; - height: 0px; // it is necessary + /* it is necessary */ + height: 0px; +} + +.asset-effect-header[multiple-invalid] > *:not(.multiple-warn-tip) { + display: none!important; + } + + .asset-effect-header[multiple-invalid] > .multiple-warn-tip { + display: block; + } + +.asset-effect-header .multiple-warn-tip { + display: none; + text-align: center; + color: var(--color-focus-contrast-weakest); } + .asset-effect-header > ui-code { flex: 1; } @@ -37,14 +56,11 @@ exports.update = function(assetList, metaList) { this.meta = metaList[0]; this.asset = assetList[0]; - let display = 'none'; - if (assetList.length === 1) { - display = 'flex'; - } - this.$.container.style.display = display; - - if (display === 'none') { + if (assetList.length > 1) { + this.$.container.setAttribute('multiple-invalid', ''); return; + } else { + this.$.container.removeAttribute('multiple-invalid'); } // Displays 400 lines or 20,000 characters diff --git a/editor/inspector/assets/effect.js b/editor/inspector/assets/effect.js index 84a9082e637..2291e9ea973 100644 --- a/editor/inspector/assets/effect.js +++ b/editor/inspector/assets/effect.js @@ -1,8 +1,9 @@ 'use strict'; const { readFileSync, existsSync } = require('fs'); +const { updateElementReadonly } = require('../utils/assets'); -exports.template = ` +exports.template = /* html */`
@@ -19,11 +20,28 @@ exports.template = `
+ +
`; -exports.style = ` +exports.style = /* css */` .asset-effect { } + + .asset-effect[multiple-invalid] > *:not(.multiple-warn-tip) { + display: none!important; + } + + .asset-effect[multiple-invalid] > .multiple-warn-tip { + display: block; + } + + .asset-effect .multiple-warn-tip { + display: none; + text-align: center; + color: var(--color-focus-contrast-weakest); + } + .asset-effect > * { margin-bottom: 8px; } @@ -98,13 +116,19 @@ const Elements = { ready() { const panel = this; + panel.shadersIndex = 0; + panel.$.shaderSelect.addEventListener('change', (event) => { - this.shadersIndex = event.target.value; + panel.shadersIndex = event.target.value; // There are other properties that are updated depending on its change Elements.combinations.update.call(panel); Elements.codes.update.call(panel); }); + + panel.$.shaderSelect.addEventListener('confirm', () => { + panel.dispatch('snapshot'); + }); }, update() { const panel = this; @@ -115,13 +139,17 @@ const Elements = { }); panel.$.shaderSelect.innerHTML = optionsHtml; + if (panel.shadersIndex > panel.shaders.length - 1) { + panel.shadersIndex = 0; + } + panel.$.shaderSelect.value = panel.shadersIndex; if (panel.shaders[panel.shadersIndex]) { panel.$.shaderSelect.setAttribute('tooltip', panel.shaders[panel.shadersIndex].name); } - panel.updateReadonly(panel.$.shaderSelect); + updateElementReadonly.call(this, panel.$.shaderSelect); }, }, combinations: { @@ -153,11 +181,9 @@ const Elements = { const name = typeof value === 'boolean' ? (value ? 'on' : 'off') : value.toString(); const button = document.createElement('ui-button'); - content.appendChild(button); - + updateElementReadonly.call(panel, button); button.setAttribute('class', 'tab'); button.setAttribute('checked', checked); - panel.updateReadonly(button); button.innerText = name; button.addEventListener('click', () => { if (!panel.combinations[panel.shadersIndex][define.name]) { @@ -175,9 +201,10 @@ const Elements = { button.setAttribute('checked', 'true'); } - panel.dataChange(); - panel.dispatch('change'); + panel.change(); }); + + content.appendChild(button); }); }); @@ -189,6 +216,18 @@ const Elements = { }, }, codes: { + ready() { + const panel = this; + + panel.glslNames = { + glsl3: 'GLSL 300 ES Output', + glsl1: 'GLSL 100 Output', + }; + panel.shaderNames = { + vert: 'Vertex Shader', + frag: 'Fragment Shader', + }; + }, update() { const panel = this; @@ -249,50 +288,17 @@ const Elements = { }, }; -/** - * A method to initialize the panel - */ -exports.ready = function() { - for (const prop in Elements) { - const element = Elements[prop]; - if (element.ready) { - element.ready.call(this); - } - } -}; - -/** - * Methods to automatically render components - * @param assetList - * @param metaList - */ -exports.update = function(assetList, metaList) { - this.assetList = assetList; - this.metaList = metaList; - this.asset = assetList[0]; - this.meta = metaList[0]; - - if (this.assetList.length !== 1) { - this.$.container.style.display = 'none'; - return; - } else { - this.$.container.style.display = 'block'; - } - - const isLegal = this.refresh(); - if (!isLegal) { - return; - } - - for (const prop in Elements) { - const element = Elements[prop]; - if (element.update) { - element.update.call(this); - } - } -}; - exports.methods = { + record() { + return JSON.stringify({ shadersIndex: this.shadersIndex }); + }, + restore(record) { + record = JSON.parse(record); + + this.$.shaderSelect.value = record.shadersIndex; + this.$.shaderSelect.dispatch('change'); + return true; + }, refresh() { const panel = this; @@ -317,16 +323,6 @@ exports.methods = { panel.shaders = dataSource.shaders; - panel.shadersIndex = 0; - panel.glslNames = { - glsl3: 'GLSL 300 ES Output', - glsl1: 'GLSL 100 Output', - }; - panel.shaderNames = { - vert: 'Vertex Shader', - frag: 'Fragment Shader', - }; - // The edited value of defines in each shader panel.combinations = []; if (Array.isArray(panel.meta.userData.combinations)) { @@ -376,17 +372,7 @@ exports.methods = { return true; }, - /** - * Update read-only status - */ - updateReadonly(element) { - if (this.asset.readonly) { - element.setAttribute('disabled', true); - } else { - element.removeAttribute('disabled'); - } - }, - dataChange() { + change() { const panel = this; // Need to exclude empty arrays, otherwise scene will report an error @@ -402,5 +388,43 @@ exports.methods = { }); panel.meta.userData.combinations = submitData; + + panel.dispatch('change'); + panel.dispatch('snapshot'); }, }; + +exports.ready = function() { + for (const prop in Elements) { + const element = Elements[prop]; + if (element.ready) { + element.ready.call(this); + } + } +}; + +exports.update = function(assetList, metaList) { + this.assetList = assetList; + this.metaList = metaList; + this.asset = assetList[0]; + this.meta = metaList[0]; + + if (assetList.length > 1) { + this.$.container.setAttribute('multiple-invalid', ''); + return; + } else { + this.$.container.removeAttribute('multiple-invalid'); + } + + const isLegal = this.refresh(); + if (!isLegal) { + return; + } + + for (const prop in Elements) { + const element = Elements[prop]; + if (element.update) { + element.update.call(this); + } + } +}; diff --git a/editor/inspector/assets/erp-texture-cube.js b/editor/inspector/assets/erp-texture-cube.js index 6ff0749a4ac..b530ea8fb69 100644 --- a/editor/inspector/assets/erp-texture-cube.js +++ b/editor/inspector/assets/erp-texture-cube.js @@ -1,3 +1,7 @@ +'use strict'; + +const { updateElementReadonly } = require('../utils/assets'); + exports.template = /* html */ `
@@ -55,7 +59,7 @@ exports.template = /* html */ `
`; -exports.style = ` +exports.style = /* css */` .asset-erp-texture-cube ui-prop{ margin-top: 4px; } @@ -84,27 +88,6 @@ exports.$ = { mipBakeMode: '#mipBakeMode', }; -exports.ready = function() { - for (const key in Elements) { - if (typeof Elements[key].ready === 'function') { - Elements[key].ready.call(this); - } - } -}; - -exports.update = function(assetList, metaList) { - this.assetList = assetList; - this.metaList = metaList; - this.asset = assetList[0]; - this.meta = metaList[0]; - - for (const key in Elements) { - if (typeof Elements[key].update === 'function') { - Elements[key].update.call(this); - } - } -}; - const ModeMap = { filter: { 'Nearest (None)': { @@ -147,27 +130,36 @@ const ModeMap = { const Elements = { anisotropy: { ready() { - this.$.anisotropy.addEventListener('change', this.dataChange.bind(this, 'anisotropy')); + this.$.anisotropy.addEventListener('change', this.change.bind(this, 'anisotropy')); + this.$.anisotropy.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { this.$.anisotropy.value = this.meta.userData.anisotropy; this.updateInvalid(this.$.anisotropy, 'anisotropy'); - this.updateReadonly(this.$.anisotropy); + updateElementReadonly.call(this, this.$.anisotropy); }, }, faceSize: { ready() { - this.$.faceSize.addEventListener('change', this.dataChange.bind(this, 'faceSize')); + this.$.faceSize.addEventListener('change', this.change.bind(this, 'faceSize')); + this.$.faceSize.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { this.$.faceSize.value = this.meta.userData.faceSize; this.updateInvalid(this.$.faceSize, 'faceSize'); - this.updateReadonly(this.$.faceSize); + updateElementReadonly.call(this, this.$.faceSize); }, }, filterMode: { ready() { - this.$.filterMode.addEventListener('change', this.dataChange.bind(this, 'filterMode')); + this.$.filterMode.addEventListener('change', this.change.bind(this, 'filterMode')); + this.$.filterMode.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -202,12 +194,15 @@ const Elements = { : (this.$.filterAdvancedSection.style.display = 'none'); this.updateInvalid(this.$.filterMode, 'filterMode'); - this.updateReadonly(this.$.filterMode); + updateElementReadonly.call(this, this.$.filterMode); }, }, minfilter: { ready() { - this.$.minfilter.addEventListener('change', this.dataChange.bind(this, 'minfilter')); + this.$.minfilter.addEventListener('change', this.change.bind(this, 'minfilter')); + this.$.minfilter.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -219,12 +214,15 @@ const Elements = { this.$.minfilter.value = this.meta.userData.minfilte || 'nearest'; this.updateInvalid(this.$.minfilter, 'minfilter'); - this.updateReadonly(this.$.minfilter); + updateElementReadonly.call(this, this.$.minfilter); }, }, magfilter: { ready() { - this.$.magfilter.addEventListener('change', this.dataChange.bind(this, 'magfilter')); + this.$.magfilter.addEventListener('change', this.change.bind(this, 'magfilter')); + this.$.magfilter.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -236,12 +234,15 @@ const Elements = { this.$.magfilter.value = this.meta.userData.magfilter || 'nearest'; this.updateInvalid(this.$.magfilter, 'magfilter'); - this.updateReadonly(this.$.magfilter); + updateElementReadonly.call(this, this.$.magfilter); }, }, generateMipmaps: { ready() { - this.$.generateMipmaps.addEventListener('change', this.dataChange.bind(this, 'generateMipmaps')); + this.$.generateMipmaps.addEventListener('change', this.change.bind(this, 'generateMipmaps')); + this.$.generateMipmaps.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { this.$.generateMipmaps.value = this.meta.userData.mipfilter ? this.meta.userData.mipfilter !== 'none' : false; @@ -252,12 +253,15 @@ const Elements = { : (this.$.generateMipmapsSection.style.display = 'none'); this.updateInvalid(this.$.generateMipmaps, 'generateMipmaps'); - this.updateReadonly(this.$.generateMipmaps); + updateElementReadonly.call(this, this.$.generateMipmaps); }, }, mipfilter: { ready() { - this.$.mipfilter.addEventListener('change', this.dataChange.bind(this, 'mipfilter')); + this.$.mipfilter.addEventListener('change', this.change.bind(this, 'mipfilter')); + this.$.mipfilter.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -269,12 +273,15 @@ const Elements = { this.$.mipfilter.value = this.meta.userData.mipfilter || 'nearest'; this.updateInvalid(this.$.mipfilter, 'mipfilter'); - this.updateReadonly(this.$.mipfilter); + updateElementReadonly.call(this, this.$.mipfilter); }, }, wrapMode: { ready() { - this.$.wrapMode.addEventListener('change', this.dataChange.bind(this, 'wrapMode')); + this.$.wrapMode.addEventListener('change', this.change.bind(this, 'wrapMode')); + this.$.wrapMode.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -309,12 +316,15 @@ const Elements = { : (this.$.wrapAdvancedSection.style.display = 'none'); this.updateInvalid(this.$.wrapMode, 'wrapMode'); - this.updateReadonly(this.$.wrapMode); + updateElementReadonly.call(this, this.$.wrapMode); }, }, wrapModeS: { ready() { - this.$.wrapModeS.addEventListener('change', this.dataChange.bind(this, 'wrapModeS')); + this.$.wrapModeS.addEventListener('change', this.change.bind(this, 'wrapModeS')); + this.$.wrapModeS.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -330,12 +340,15 @@ const Elements = { this.$.wrapModeS.value = this.meta.userData.wrapModeS || 'repeat'; this.updateInvalid(this.$.wrapModeS, 'wrapModeS'); - this.updateReadonly(this.$.wrapModeS); + updateElementReadonly.call(this, this.$.wrapModeS); }, }, wrapModeT: { ready() { - this.$.wrapModeT.addEventListener('change', this.dataChange.bind(this, 'wrapModeT')); + this.$.wrapModeT.addEventListener('change', this.change.bind(this, 'wrapModeT')); + this.$.wrapModeT.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { let optionsHtml = ''; @@ -351,17 +364,20 @@ const Elements = { this.$.wrapModeT.value = this.meta.userData.wrapModeT || 'repeat'; this.updateInvalid(this.$.wrapModeT, 'wrapModeT'); - this.updateReadonly(this.$.wrapModeT); + updateElementReadonly.call(this, this.$.wrapModeT); }, }, mipBakeMode: { ready() { - this.$.mipBakeMode.addEventListener('change', this.dataChange.bind(this, 'mipBakeMode')); + this.$.mipBakeMode.addEventListener('change', this.change.bind(this, 'mipBakeMode')); + this.$.mipBakeMode.addEventListener('confirm', () => { + this.dispatch('snapshot'); + }); }, update() { this.$.mipBakeMode.value = this.meta.userData.mipBakeMode === 2 ? true : false; this.updateInvalid(this.$.mipBakeMode, 'mipBakeMode'); - this.updateReadonly(this.$.mipBakeMode); + updateElementReadonly.call(this, this.$.mipBakeMode); }, }, }; @@ -404,14 +420,7 @@ exports.methods = { } element.invalid = invalid; }, - updateReadonly(element) { - if (this.asset.readonly) { - element.setAttribute('disabled', true); - } else { - element.removeAttribute('disabled'); - } - }, - dataChange(key, event) { + change(key, event) { let value = event.target.value; if (key === 'mipBakeMode') { value = event.target.value ? 2 : 1; @@ -460,3 +469,24 @@ exports.methods = { this.dispatch('change'); }, }; + +exports.ready = function() { + for (const key in Elements) { + if (typeof Elements[key].ready === 'function') { + Elements[key].ready.call(this); + } + } +}; + +exports.update = function(assetList, metaList) { + this.assetList = assetList; + this.metaList = metaList; + this.asset = assetList[0]; + this.meta = metaList[0]; + + for (const key in Elements) { + if (typeof Elements[key].update === 'function') { + Elements[key].update.call(this); + } + } +}; diff --git a/editor/inspector/assets/fbx/animation.js b/editor/inspector/assets/fbx/animation.js index b7493b80154..2bb70661bfc 100644 --- a/editor/inspector/assets/fbx/animation.js +++ b/editor/inspector/assets/fbx/animation.js @@ -1,4 +1,8 @@ -exports.template = ` +'use strict'; + +const { updateElementReadonly, updateElementInvalid } = require('../../utils/assets'); + +exports.template = /* html */`
@@ -67,15 +71,33 @@ exports.template = ` Speed + + Base Clip + +
+
`; -exports.style = ` +exports.style = /* css */` ui-prop, ui-section { margin: 4px 0; } +.container[multiple-invalid] > *:not(.multiple-warn-tip) { + display: none!important; + } + + .container[multiple-invalid] > .multiple-warn-tip { + display: block; + } + +.container .multiple-warn-tip { + display: none; + text-align: center; + color: var(--color-focus-contrast-weakest); +} .container > .show-type-wrap { text-align: center; } @@ -104,6 +126,7 @@ ui-section { display: flex; line-height: 1.6em; padding: 2px 5px; + cursor: pointer; } .container > .clips > .clip > .table > .line[active] { background: var(--color-focus-fill); @@ -134,6 +157,16 @@ ui-section { background: var(--color-normal-fill); } +.container > .clips > .clip > .add-clip > .button > ui-icon[disabled] { + opacity: 0.55; + pointer-events: none; +} + +.container > .editor[disabled] { + opacity: 0.55; + pointer-events: none; +} + .container > .editor > .anim-name { display: flex; justify-content: space-between; @@ -290,6 +323,7 @@ exports.$ = { clipFrames: '.clip-frames', wrapMode: '.wrap-mode', speed: '.speed', + baseClip: '.base-clip', rulerMaking: '.ruler-making', rulerGear: '.ruler-gear', controlWrap: '.control-wrap', @@ -446,6 +480,7 @@ const Elements = { const addIcon = document.createElement('ui-icon'); addIcon.setAttribute('value', 'add'); addIcon.setAttribute('tooltip', 'Duplicate Selected'); + updateElementReadonly.call(panel, addIcon); button.appendChild(addIcon); addIcon.addEventListener('click', () => { const newInfo = panel.newClipTemplate(); @@ -455,11 +490,13 @@ const Elements = { Elements.clips.update.call(panel); Elements.editor.update.call(panel); panel.dispatch('change'); + panel.dispatch('snapshot'); }); const miniIcon = document.createElement('ui-icon'); miniIcon.setAttribute('value', 'mini'); miniIcon.setAttribute('tooltip', 'Remove Selected'); + updateElementReadonly.call(panel, miniIcon); button.appendChild(miniIcon); miniIcon.addEventListener('click', () => { panel.updateCurrentClipInfo(); @@ -476,6 +513,7 @@ const Elements = { Elements.clips.update.call(panel); Elements.editor.update.call(panel); panel.dispatch('change'); + panel.dispatch('snapshot'); }); }); }, @@ -510,6 +548,9 @@ const Elements = { panel.onSpeedChangeBind = panel.onSpeedChange.bind(panel); panel.$.speed.addEventListener('confirm', panel.onSpeedChangeBind); + panel.onBaseClipChangeBind = panel.onBaseClipChange.bind(panel); + panel.$.baseClip.addEventListener('confirm', panel.onBaseClipChangeBind); + function observer() { const rect = panel.$.editor.getBoundingClientRect(); panel.gridTableWith = rect.width - 60; @@ -542,6 +583,7 @@ const Elements = { panel.$.wrapMode.removeEventListener('confirm', panel.onWrapModeChangeBind); panel.$.speed.removeEventListener('confirm', panel.onSpeedChangeBind); + panel.$.baseClip.removeEventListener('confirm', panel.onBaseClipChangeBind); }, update() { const panel = this; @@ -557,6 +599,8 @@ const Elements = { panel.$.editor.style.display = 'block'; } + updateElementReadonly.call(panel, panel.$.editor); + panel.$.clipName.value = panel.currentClipInfo.name; // ruler making @@ -617,43 +661,6 @@ const Elements = { }, }; -exports.update = function(assetList, metaList) { - this.assetList = assetList; - this.metaList = metaList; - this.asset = assetList[0]; - this.meta = metaList[0]; - - for (const prop in Elements) { - const element = Elements[prop]; - if (element.update) { - element.update.call(this); - } - } - this.initAnimationNameToUUIDMap(); - this.initAnimationInfos(); - if (this.animationInfos) { - this.onSelect(this.rawClipIndex, this.splitClipIndex); - } -}; - -exports.ready = function() { - for (const prop in Elements) { - const element = Elements[prop]; - if (element.ready) { - element.ready.call(this); - } - } -}; - -exports.close = function() { - for (const prop in Elements) { - const element = Elements[prop]; - if (element.close) { - element.close.call(this); - } - } -}; - async function callModelPreviewFunction(funcName, ...args) { return await Editor.Message.request('scene', 'call-preview-function', 'scene:model-preview', funcName, ...args); } @@ -749,6 +756,7 @@ exports.methods = { to, wrapMode: splitInfo.wrapMode, speed: splitInfo.speed || 1, + baseClip: splitInfo.additive?.baseClip || '', }; }, getRightName(name) { @@ -797,6 +805,7 @@ exports.methods = { const fps = info.fps !== undefined ? info.fps : panel.rawClipInfo.fps; const wrapMode = info.wrapMode ?? panel.rawClipInfo.wrapMode; const speed = info.speed ?? panel.rawClipInfo.speed; + const baseClip = (info.additive?.baseClip) ?? panel.rawClipInfo.baseClip; panel.currentClipInfo = { name: info.name, from: info.from * fps, @@ -817,6 +826,7 @@ exports.methods = { fps, wrapMode, speed, + baseClip, }; const maxFrames = (panel.rawClipInfo.duration * panel.currentClipInfo.fps).toFixed(0); @@ -840,6 +850,7 @@ exports.methods = { panel.$.wrapMode.value = panel.currentClipInfo.wrapMode; panel.$.speed.value = panel.currentClipInfo.speed || 1; + panel.$.baseClip.value = panel.currentClipInfo.baseClip || ''; }, updateRawClipInfo() { const panel = this; @@ -1000,6 +1011,7 @@ exports.methods = { const curClipInfo = panel.getCurClipInfo(); Editor.Message.broadcast('fbx-inspector:animation-change', curClipInfo); panel.dispatch('change'); + panel.dispatch('snapshot'); }, updateVirtualControl() { const panel = this; @@ -1038,6 +1050,7 @@ exports.methods = { panel.clipNames.add(name); panel.dispatch('change'); + panel.dispatch('snapshot'); Elements.clips.update.call(panel); }, onCutClip(event) { @@ -1050,6 +1063,7 @@ exports.methods = { Elements.editor.update.call(panel); panel.dispatch('change'); + panel.dispatch('snapshot'); }, onFpsChange(event) { const panel = this; @@ -1058,6 +1072,7 @@ exports.methods = { Elements.editor.update.call(panel); panel.dispatch('change'); + panel.dispatch('snapshot'); }, onWrapModeChange(event) { const panel = this; @@ -1072,6 +1087,7 @@ exports.methods = { ); Elements.editor.update.call(panel); panel.dispatch('change'); + panel.dispatch('snapshot'); }, onSpeedChange(event) { const panel = this; @@ -1087,5 +1103,60 @@ exports.methods = { Elements.editor.update.call(panel); panel.dispatch('change'); + panel.dispatch('snapshot'); + }, + onBaseClipChange(event) { + const panel = this; + + const baseClipUUID = String(event.target.value); + (panel.animationInfos[panel.rawClipIndex].splits[panel.splitClipIndex].additive ??= {}).baseClip = baseClipUUID; + + Elements.editor.update.call(panel); + panel.dispatch('change'); + panel.dispatch('snapshot'); }, }; + +exports.ready = function() { + for (const prop in Elements) { + const element = Elements[prop]; + if (element.ready) { + element.ready.call(this); + } + } +}; + +exports.update = function(assetList, metaList) { + this.assetList = assetList; + this.metaList = metaList; + this.asset = assetList[0]; + this.meta = metaList[0]; + + if (assetList.length > 1) { + this.$.container.setAttribute('multiple-invalid', ''); + return; + } else { + this.$.container.removeAttribute('multiple-invalid'); + } + + for (const prop in Elements) { + const element = Elements[prop]; + if (element.update) { + element.update.call(this); + } + } + this.initAnimationNameToUUIDMap(); + this.initAnimationInfos(); + if (this.animationInfos) { + this.onSelect(this.rawClipIndex, this.splitClipIndex); + } +}; + +exports.close = function() { + for (const prop in Elements) { + const element = Elements[prop]; + if (element.close) { + element.close.call(this); + } + } +}; diff --git a/editor/inspector/assets/fbx/event-editor/event-item.js b/editor/inspector/assets/fbx/event-editor/event-item.js index 74a68166dc2..e3e17db8e41 100644 --- a/editor/inspector/assets/fbx/event-editor/event-item.js +++ b/editor/inspector/assets/fbx/event-editor/event-item.js @@ -6,7 +6,7 @@ const defaultParams = { boolean: false, }; -exports.template = ` +exports.template = /* html */`
diff --git a/editor/inspector/assets/fbx/events/events.js b/editor/inspector/assets/fbx/events/events.js index 917102e60ca..47093dda60b 100644 --- a/editor/inspector/assets/fbx/events/events.js +++ b/editor/inspector/assets/fbx/events/events.js @@ -1,6 +1,6 @@ 'use strict'; -exports.template = ` +exports.template = /* html */`