diff options
292 files changed, 11543 insertions, 9202 deletions
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 71a1b580b1..e8f3d3d297 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -7,7 +7,7 @@ env: GODOT_BASE_BRANCH: master SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes --jobs=2 SCONS_CACHE_MSVC_CONFIG: true - SCONS_CACHE_LIMIT: 4096 + SCONS_CACHE_LIMIT: 3072 jobs: windows-editor: diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 7bb65dced4..03865b14ac 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -53,7 +53,7 @@ Files: ./icon.png ./logo.svg Comment: Godot Engine logo Copyright: 2017, Andrea Calabró -License: CC-BY-3.0 +License: CC-BY-4.0 Files: ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl ./platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml @@ -548,340 +548,317 @@ License: BSL-1.0 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -License: CC-BY-3.0 - Creative Commons Attribution 3.0 Unported +License: CC-BY-4.0 + Creative Commons Attribution 4.0 International Public License + . + By exercising the Licensed Rights (defined below), You accept and agree + to be bound by the terms and conditions of this Creative Commons + Attribution 4.0 International Public License ("Public + License"). To the extent this Public License may be interpreted as a + contract, You are granted the Licensed Rights in consideration of Your + acceptance of these terms and conditions, and the Licensor grants You + such rights in consideration of benefits the Licensor receives from + making the Licensed Material available under these terms and + conditions. + . + Section 1 -- Definitions. + . + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + . + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + . + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + . + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + . + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + . + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + . + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + . + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + . + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + . + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + . + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + . + Section 2 -- Scope. + . + a. License grant. + . + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + . + a. reproduce and Share the Licensed Material, in whole or + in part; and + . + b. produce, reproduce, and Share Adapted Material. + . + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + . + 3. Term. The term of this Public License is specified in Section + 6(a). + . + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + . + 5. Downstream recipients. + . + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + . + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + . + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + . + b. Other rights. + . + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + . + 2. Patent and trademark rights are not licensed under this + Public License. + . + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + . + Section 3 -- License Conditions. + . + Your exercise of the Licensed Rights is expressly made subject to the + following conditions. + . + a. Attribution. + . + 1. If You Share the Licensed Material (including in modified + form), You must: + . + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + . + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + . + ii. a copyright notice; + . + iii. a notice that refers to this Public License; + . + iv. a notice that refers to the disclaimer of + warranties; + . + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + . + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + . + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + . + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + . + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + . + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + . + Section 4 -- Sui Generis Database Rights. + . + Where the Licensed Rights include Sui Generis Database Rights that + apply to Your use of the Licensed Material: + . + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + . + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + . + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + . + For the avoidance of doubt, this Section 4 supplements and does not + replace Your obligations under this Public License where the Licensed + Rights include other Copyright and Similar Rights. + . + Section 5 -- Disclaimer of Warranties and Limitation of Liability. + . + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. . - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION - ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE - INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - ITS USE. + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. . - License + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. . - THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE - COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY - COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS - AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + Section 6 -- Term and Termination. . - BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE - TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY - BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS - CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND - CONDITIONS. + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. . - 1. Definitions + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: . - a. "Adaptation" means a work based upon the Work, or upon the Work and - other pre-existing works, such as a translation, adaptation, derivative - work, arrangement of music or other alterations of a literary or - artistic work, or phonogram or performance and includes cinematographic - adaptations or any other form in which the Work may be recast, - transformed, or adapted including in any form recognizably derived from - the original, except that a work that constitutes a Collection will not - be considered an Adaptation for the purpose of this License. For the - avoidance of doubt, where the Work is a musical work, performance or - phonogram, the synchronization of the Work in timed-relation with a - moving image ("synching") will be considered an Adaptation for the - purpose of this License. - . - b. "Collection" means a collection of literary or artistic works, such - as encyclopedias and anthologies, or performances, phonograms or - broadcasts, or other works or subject matter other than works listed in - Section 1(f) below, which, by reason of the selection and arrangement of - their contents, constitute intellectual creations, in which the Work is - included in its entirety in unmodified form along with one or more other - contributions, each constituting separate and independent works in - themselves, which together are assembled into a collective whole. A work - that constitutes a Collection will not be considered an Adaptation (as - defined above) for the purposes of this License. - . - c. "Distribute" means to make available to the public the original and - copies of the Work or Adaptation, as appropriate, through sale or other - transfer of ownership. - . - d. "Licensor" means the individual, individuals, entity or entities that - offer(s) the Work under the terms of this License. - . - e. "Original Author" means, in the case of a literary or artistic work, - the individual, individuals, entity or entities who created the Work or - if no individual or entity can be identified, the publisher; and in - addition (i) in the case of a performance the actors, singers, - musicians, dancers, and other persons who act, sing, deliver, declaim, - play in, interpret or otherwise perform literary or artistic works or - expressions of folklore; (ii) in the case of a phonogram the producer - being the person or legal entity who first fixes the sounds of a - performance or other sounds; and, (iii) in the case of broadcasts, the - organization that transmits the broadcast. - . - f. "Work" means the literary and/or artistic work offered under the - terms of this License including without limitation any production in the - literary, scientific and artistic domain, whatever may be the mode or - form of its expression including digital form, such as a book, pamphlet - and other writing; a lecture, address, sermon or other work of the same - nature; a dramatic or dramatico-musical work; a choreographic work or - entertainment in dumb show; a musical composition with or without words; - a cinematographic work to which are assimilated works expressed by a - process analogous to cinematography; a work of drawing, painting, - architecture, sculpture, engraving or lithography; a photographic work - to which are assimilated works expressed by a process analogous to - photography; a work of applied art; an illustration, map, plan, sketch - or three-dimensional work relative to geography, topography, - architecture or science; a performance; a broadcast; a phonogram; a - compilation of data to the extent it is protected as a copyrightable - work; or a work performed by a variety or circus performer to the extent - it is not otherwise considered a literary or artistic work. - . - g. "You" means an individual or entity exercising rights under this - License who has not previously violated the terms of this License with - respect to the Work, or who has received express permission from the - Licensor to exercise rights under this License despite a previous - violation. - . - h. "Publicly Perform" means to perform public recitations of the Work - and to communicate to the public those public recitations, by any means - or process, including by wire or wireless means or public digital - performances; to make available to the public Works in such a way that - members of the public may access these Works from a place and at a place - individually chosen by them; to perform the Work to the public by any - means or process and the communication to the public of the performances - of the Work, including by public digital performance; to broadcast and - rebroadcast the Work by any means including signs, sounds or images. - . - i. "Reproduce" means to make copies of the Work by any means including - without limitation by sound or visual recordings and the right of - fixation and reproducing fixations of the Work, including storage of a - protected performance or phonogram in digital form or other electronic - medium. - . - 2. Fair Dealing Rights. Nothing in this License is intended to reduce, - limit, or restrict any uses free from copyright or rights arising from - limitations or exceptions that are provided for in connection with the - copyright protection under copyright law or other applicable laws. - . - 3. License Grant. Subject to the terms and conditions of this License, - Licensor hereby grants You a worldwide, royalty-free, non-exclusive, - perpetual (for the duration of the applicable copyright) license to - exercise the rights in the Work as stated below: - . - a. to Reproduce the Work, to incorporate the Work into one or more - Collections, and to Reproduce the Work as incorporated in the - Collections; - . - b. to create and Reproduce Adaptations provided that any such - Adaptation, including any translation in any medium, takes reasonable - steps to clearly label, demarcate or otherwise identify that changes - were made to the original Work. For example, a translation could be - marked "The original work was translated from English to Spanish," or a - modification could indicate "The original work has been modified."; - . - c. to Distribute and Publicly Perform the Work including as incorporated - in Collections; and, - . - d. to Distribute and Publicly Perform Adaptations. - . - e. For the avoidance of doubt: - . - i. Non-waivable Compulsory License Schemes. In those jurisdictions in - which the right to collect royalties through any statutory or compulsory - licensing scheme cannot be waived, the Licensor reserves the exclusive - right to collect such royalties for any exercise by You of the rights - granted under this License; - . - ii. Waivable Compulsory License Schemes. In those jurisdictions in which - the right to collect royalties through any statutory or compulsory - licensing scheme can be waived, the Licensor waives the exclusive right - to collect such royalties for any exercise by You of the rights granted - under this License; and, - . - iii. Voluntary License Schemes. The Licensor waives the right to collect - royalties, whether individually or, in the event that the Licensor is a - member of a collecting society that administers voluntary licensing - schemes, via that society, from any exercise by You of the rights - granted under this License. - . - The above rights may be exercised in all media and formats whether now - known or hereafter devised. The above rights include the right to make - such modifications as are technically necessary to exercise the rights - in other media and formats. Subject to Section 8(f), all rights not - expressly granted by Licensor are hereby reserved. - . - 4. Restrictions. The license granted in Section 3 above is expressly - made subject to and limited by the following restrictions: - . - a. You may Distribute or Publicly Perform the Work only under the terms - of this License. You must include a copy of, or the Uniform Resource - Identifier (URI) for, this License with every copy of the Work You - Distribute or Publicly Perform. You may not offer or impose any terms on - the Work that restrict the terms of this License or the ability of the - recipient of the Work to exercise the rights granted to that recipient - under the terms of the License. You may not sublicense the Work. You - must keep intact all notices that refer to this License and to the - disclaimer of warranties with every copy of the Work You Distribute or - Publicly Perform. When You Distribute or Publicly Perform the Work, You - may not impose any effective technological measures on the Work that - restrict the ability of a recipient of the Work from You to exercise the - rights granted to that recipient under the terms of the License. This - Section 4(a) applies to the Work as incorporated in a Collection, but - this does not require the Collection apart from the Work itself to be - made subject to the terms of this License. If You create a Collection, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collection any credit as required by Section 4(b), as - requested. If You create an Adaptation, upon notice from any Licensor - You must, to the extent practicable, remove from the Adaptation any - credit as required by Section 4(b), as requested. - . - b. If You Distribute, or Publicly Perform the Work or any Adaptations or - Collections, You must, unless a request has been made pursuant to - Section 4(a), keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) the - name of the Original Author (or pseudonym, if applicable) if supplied, - and/or if the Original Author and/or Licensor designate another party or - parties (e.g., a sponsor institute, publishing entity, journal) for - attribution ("Attribution Parties") in Licensor's copyright notice, - terms of service or by other reasonable means, the name of such party or - parties; (ii) the title of the Work if supplied; (iii) to the extent - reasonably practicable, the URI, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and (iv) , - consistent with Section 3(b), in the case of an Adaptation, a credit - identifying the use of the Work in the Adaptation (e.g., "French - translation of the Work by Original Author," or "Screenplay based on - original Work by Original Author"). The credit required by this Section - 4 (b) may be implemented in any reasonable manner; provided, however, - that in the case of a Adaptation or Collection, at a minimum such credit - will appear, if a credit for all contributing authors of the Adaptation - or Collection appears, then as part of these credits and in a manner at - least as prominent as the credits for the other contributing authors. - For the avoidance of doubt, You may only use the credit required by this - Section for the purpose of attribution in the manner set out above and, - by exercising Your rights under this License, You may not implicitly or - explicitly assert or imply any connection with, sponsorship or - endorsement by the Original Author, Licensor and/or Attribution Parties, - as appropriate, of You or Your use of the Work, without the separate, - express prior written permission of the Original Author, Licensor and/or - Attribution Parties. - . - c. Except as otherwise agreed in writing by the Licensor or as may be - otherwise permitted by applicable law, if You Reproduce, Distribute or - Publicly Perform the Work either by itself or as part of any Adaptations - or Collections, You must not distort, mutilate, modify or take other - derogatory action in relation to the Work which would be prejudicial to - the Original Author's honor or reputation. Licensor agrees that in those - jurisdictions (e.g. Japan), in which any exercise of the right granted - in Section 3(b) of this License (the right to make Adaptations) would be - deemed to be a distortion, mutilation, modification or other derogatory - action prejudicial to the Original Author's honor and reputation, the - Licensor will waive or not assert, as appropriate, this Section, to the - fullest extent permitted by the applicable national law, to enable You - to reasonably exercise Your right under Section 3(b) of this License - (right to make Adaptations) but not otherwise. - . - 5. Representations, Warranties and Disclaimer - . - UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR - OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY - KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, - INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, - FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF - LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, - WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - . - 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE - LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR - ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES - ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS - BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - . - 7. Termination - . - a. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Adaptations or Collections - from You under this License, however, will not have their licenses - terminated provided such individuals or entities remain in full - compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will - survive any termination of this License. - . - b. Subject to the above terms and conditions, the license granted here - is perpetual (for the duration of the applicable copyright in the Work). - Notwithstanding the above, Licensor reserves the right to release the - Work under different license terms or to stop distributing the Work at - any time; provided, however that any such election will not serve to - withdraw this License (or any other license that has been, or is - required to be, granted under the terms of this License), and this - License will continue in full force and effect unless terminated as - stated above. - . - 8. Miscellaneous - . - a. Each time You Distribute or Publicly Perform the Work or a - Collection, the Licensor offers to the recipient a license to the Work - on the same terms and conditions as the license granted to You under - this License. - . - b. Each time You Distribute or Publicly Perform an Adaptation, Licensor - offers to the recipient a license to the original Work on the same terms - and conditions as the license granted to You under this License. - . - c. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of - the remainder of the terms of this License, and without further action - by the parties to this agreement, such provision shall be reformed to - the minimum extent necessary to make such provision valid and - enforceable. - . - d. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in writing - and signed by the party to be charged with such waiver or consent. This - License constitutes the entire agreement between the parties with - respect to the Work licensed here. There are no understandings, - agreements or representations with respect to the Work not specified - here. Licensor shall not be bound by any additional provisions that may - appear in any communication from You. - . - e. This License may not be modified without the mutual written agreement - of the Licensor and You. - . - f. The rights granted under, and the subject matter referenced, in this - License were drafted utilizing the terminology of the Berne Convention - for the Protection of Literary and Artistic Works (as amended on - September 28, 1979), the Rome Convention of 1961, the WIPO Copyright - Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and - the Universal Copyright Convention (as revised on July 24, 1971). These - rights and subject matter take effect in the relevant jurisdiction in - which the License terms are sought to be enforced according to the - corresponding provisions of the implementation of those treaty - provisions in the applicable national law. If the standard suite of - rights granted under applicable copyright law includes additional rights - not granted under this License, such additional rights are deemed to be - included in the License; this License is not intended to restrict the - license of any rights under applicable law. - . - Creative Commons Notice - . - Creative Commons is not a party to this License, and makes no warranty - whatsoever in connection with the Work. Creative Commons will not be - liable to You or any party on any legal theory for any damages - whatsoever, including without limitation any general, special, - incidental or consequential damages arising in connection to this - license. Notwithstanding the foregoing two (2) sentences, if Creative - Commons has expressly identified itself as the Licensor hereunder, it - shall have all rights and obligations of Licensor. - . - Except for the limited purpose of indicating to the public that the Work - is licensed under the CCPL, Creative Commons does not authorize the use - by either party of the trademark "Creative Commons" or any related - trademark or logo of Creative Commons without the prior written consent - of Creative Commons. Any permitted use will be in compliance with - Creative Commons' then-current trademark usage guidelines, as may be - published on its website or otherwise made available upon request from - time to time. For the avoidance of doubt, this trademark restriction - does not form part of this License. - . - Creative Commons may be contacted at http://creativecommons.org/. + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + . + 2. upon express reinstatement by the Licensor. + . + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + . + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + . + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + . + Section 7 -- Other Terms and Conditions. + . + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + . + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + . + Section 8 -- Interpretation. + . + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + . + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + . + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + . + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. License: Expat Permission is hereby granted, free of charge, to any person obtaining diff --git a/LOGO_LICENSE.md b/LOGO_LICENSE.md index b357c49664..52ee37fb2f 100644 --- a/LOGO_LICENSE.md +++ b/LOGO_LICENSE.md @@ -1,3 +1,5 @@ -Godot Logo (C) Andrea Calabró -Distributed under the terms of the Creative Commons Attribution License -version 3.0 (CC-BY 3.0) <https://creativecommons.org/licenses/by/3.0/legalcode>. +Godot Engine Logo +Copyright (c) 2017 Andrea Calabró + +This work is licensed under a Creative Commons Attribution 4.0 International +License (CC-BY-4.0 International) <https://creativecommons.org/licenses/by/4.0/>. diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 8b8aff3e9e..f939fca984 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -402,7 +402,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b #ifdef OSX_ENABLED if (!found) { // Attempt to load PCK from macOS .app bundle resources. - found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck")); + found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_filename + ".pck")); } #endif diff --git a/core/core_constants.cpp b/core/core_constants.cpp index db22a9ecf6..02055012ad 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -557,7 +557,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_REAL", Variant::FLOAT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT", Variant::FLOAT); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING", Variant::STRING); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2", Variant::VECTOR2); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2I", Variant::VECTOR2I); diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index d12108bca0..33ba0ba704 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -65,6 +65,22 @@ void X509Certificate::_bind_methods() { ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load); } +/// HMACContext + +void HMACContext::_bind_methods() { + ClassDB::bind_method(D_METHOD("start", "hash_type", "key"), &HMACContext::start); + ClassDB::bind_method(D_METHOD("update", "data"), &HMACContext::update); + ClassDB::bind_method(D_METHOD("finish"), &HMACContext::finish); +} + +HMACContext *(*HMACContext::_create)() = nullptr; +HMACContext *HMACContext::create() { + if (_create) { + return _create(); + } + ERR_FAIL_V_MSG(nullptr, "HMACContext is not available when the mbedtls module is disabled."); +} + /// Crypto void (*Crypto::_load_default_certificates)(String p_path) = nullptr; @@ -82,6 +98,35 @@ void Crypto::load_default_certificates(String p_path) { } } +PackedByteArray Crypto::hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg) { + Ref<HMACContext> ctx = Ref<HMACContext>(HMACContext::create()); + ERR_FAIL_COND_V_MSG(ctx.is_null(), PackedByteArray(), "HMAC is not available witout mbedtls module."); + Error err = ctx->start(p_hash_type, p_key); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + err = ctx->update(p_msg); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + return ctx->finish(); +} + +// Compares two HMACS for equality without leaking timing information in order to prevent timing attakcs. +// @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy +bool Crypto::constant_time_compare(PackedByteArray p_trusted, PackedByteArray p_received) { + const uint8_t *t = p_trusted.ptr(); + const uint8_t *r = p_received.ptr(); + int tlen = p_trusted.size(); + int rlen = p_received.size(); + // If the lengths are different then nothing else matters. + if (tlen != rlen) { + return false; + } + + uint8_t v = 0; + for (int i = 0; i < tlen; i++) { + v |= t[i] ^ r[i]; + } + return v == 0; +} + void Crypto::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes); ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa); @@ -90,6 +135,8 @@ void Crypto::_bind_methods() { ClassDB::bind_method(D_METHOD("verify", "hash_type", "hash", "signature", "key"), &Crypto::verify); ClassDB::bind_method(D_METHOD("encrypt", "key", "plaintext"), &Crypto::encrypt); ClassDB::bind_method(D_METHOD("decrypt", "key", "ciphertext"), &Crypto::decrypt); + ClassDB::bind_method(D_METHOD("hmac_digest", "hash_type", "key", "msg"), &Crypto::hmac_digest); + ClassDB::bind_method(D_METHOD("constant_time_compare", "trusted", "received"), &Crypto::constant_time_compare); } /// Resource loader/saver diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 8325f043bf..5cacddaea0 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -67,6 +67,23 @@ public: virtual Error save(String p_path) = 0; }; +class HMACContext : public Reference { + GDCLASS(HMACContext, Reference); + +protected: + static void _bind_methods(); + static HMACContext *(*_create)(); + +public: + static HMACContext *create(); + + virtual Error start(HashingContext::HashType p_hash_type, PackedByteArray p_key) = 0; + virtual Error update(PackedByteArray p_data) = 0; + virtual PackedByteArray finish() = 0; + + HMACContext() {} +}; + class Crypto : public Reference { GDCLASS(Crypto, Reference); @@ -88,6 +105,12 @@ public: virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_plaintext) = 0; virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_ciphertext) = 0; + PackedByteArray hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg); + + // Compares two PackedByteArrays for equality without leaking timing information in order to prevent timing attacks. + // @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy + bool constant_time_compare(PackedByteArray p_trusted, PackedByteArray p_received); + Crypto() {} }; diff --git a/core/doc_data.cpp b/core/doc_data.cpp new file mode 100644 index 0000000000..d84ac6d05b --- /dev/null +++ b/core/doc_data.cpp @@ -0,0 +1,126 @@ +/*************************************************************************/ +/* doc_data.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "doc_data.h" + +void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) { + if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + p_method.return_enum = p_retinfo.class_name; + if (p_method.return_enum.begins_with("_")) { //proxy class + p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length()); + } + p_method.return_type = "int"; + } else if (p_retinfo.class_name != StringName()) { + p_method.return_type = p_retinfo.class_name; + } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_method.return_type = p_retinfo.hint_string + "[]"; + } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { + p_method.return_type = p_retinfo.hint_string; + } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + p_method.return_type = "Variant"; + } else if (p_retinfo.type == Variant::NIL) { + p_method.return_type = "void"; + } else { + p_method.return_type = Variant::get_type_name(p_retinfo.type); + } +} + +void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) { + p_argument.name = p_arginfo.name; + + if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + p_argument.enumeration = p_arginfo.class_name; + if (p_argument.enumeration.begins_with("_")) { //proxy class + p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length()); + } + p_argument.type = "int"; + } else if (p_arginfo.class_name != StringName()) { + p_argument.type = p_arginfo.class_name; + } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_argument.type = p_arginfo.hint_string + "[]"; + } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { + p_argument.type = p_arginfo.hint_string; + } else if (p_arginfo.type == Variant::NIL) { + // Parameters cannot be void, so PROPERTY_USAGE_NIL_IS_VARIANT is not necessary + p_argument.type = "Variant"; + } else { + p_argument.type = Variant::get_type_name(p_arginfo.type); + } +} + +void DocData::property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo) { + p_property.name = p_memberinfo.propinfo.name; + p_property.description = p_memberinfo.doc_string; + + if (p_memberinfo.propinfo.type == Variant::OBJECT) { + p_property.type = p_memberinfo.propinfo.class_name; + } else if (p_memberinfo.propinfo.type == Variant::NIL && p_memberinfo.propinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + p_property.type = "Variant"; + } else { + p_property.type = Variant::get_type_name(p_memberinfo.propinfo.type); + } + + p_property.setter = p_memberinfo.setter; + p_property.getter = p_memberinfo.getter; + + if (p_memberinfo.has_default_value && p_memberinfo.default_value.get_type() != Variant::OBJECT) { + p_property.default_value = p_memberinfo.default_value.get_construct_string().replace("\n", ""); + } + + p_property.overridden = false; +} + +void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc) { + p_method.name = p_methodinfo.name; + p_method.description = p_desc; + + return_doc_from_retinfo(p_method, p_methodinfo.return_val); + + for (int i = 0; i < p_methodinfo.arguments.size(); i++) { + DocData::ArgumentDoc argument; + argument_doc_from_arginfo(argument, p_methodinfo.arguments[i]); + int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); + if (default_arg_index >= 0) { + Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; + argument.default_value = default_arg.get_construct_string(); + } + p_method.arguments.push_back(argument); + } +} + +void DocData::constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc) { + p_const.name = p_name; + p_const.value = p_value; + p_const.description = p_desc; +} + +void DocData::signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc) { + return method_doc_from_methodinfo(p_signal, p_methodinfo, p_desc); +} diff --git a/editor/doc_data.h b/core/doc_data.h index 2cb475d137..bf016792ea 100644 --- a/editor/doc_data.h +++ b/core/doc_data.h @@ -35,6 +35,16 @@ #include "core/templates/map.h" #include "core/variant/variant.h" +struct ScriptMemberInfo { + PropertyInfo propinfo; + String doc_string; + StringName setter; + StringName getter; + + bool has_default_value = false; + Variant default_value; +}; + class DocData { public: struct ArgumentDoc { @@ -87,6 +97,12 @@ public: } }; + struct EnumDoc { + String name = "@unnamed_enum"; + String description; + Vector<DocData::ConstantDoc> values; + }; + struct PropertyDoc { String name; String type; @@ -115,27 +131,22 @@ public: Vector<MethodDoc> methods; Vector<MethodDoc> signals; Vector<ConstantDoc> constants; + Map<String, String> enums; Vector<PropertyDoc> properties; Vector<PropertyDoc> theme_properties; + bool is_script_doc = false; + String script_path; bool operator<(const ClassDoc &p_class) const { return name < p_class.name; } }; - String version; - - Map<String, ClassDoc> class_list; - Error _load(Ref<XMLParser> parser); - -public: - void merge_from(const DocData &p_data); - void remove_from(const DocData &p_data); - void generate(bool p_basic_types = false); - Error load_classes(const String &p_dir); - static Error erase_classes(const String &p_dir); - Error save_classes(const String &p_default_path, const Map<String, String> &p_class_path); - - Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size); + static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo); + static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo); + static void property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo); + static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc); + static void constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc); + static void signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc); }; #endif // DOC_DATA_H diff --git a/core/input/input.cpp b/core/input/input.cpp index 00a7e63a73..153656e44a 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -1211,7 +1211,7 @@ void Input::parse_mapping(String p_mapping) { ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2, String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx])); - if (output == "platform") { + if (output == "platform" || output == "hint") { continue; } diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 41bc5e84b0..e04e642f6b 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -84,10 +84,6 @@ Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 return Ref<InputEvent>((InputEvent *)this); } -String InputEvent::as_text() const { - return String(); -} - bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { return false; } @@ -198,6 +194,33 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif set_metakey(event->get_metakey()); } +String InputEventWithModifiers::as_text() const { + Vector<String> mod_names; + + if (get_control()) { + mod_names.push_back(find_keycode_name(KEY_CONTROL)); + } + if (get_shift()) { + mod_names.push_back(find_keycode_name(KEY_SHIFT)); + } + if (get_alt()) { + mod_names.push_back(find_keycode_name(KEY_ALT)); + } + if (get_metakey()) { + mod_names.push_back(find_keycode_name(KEY_META)); + } + + if (!mod_names.empty()) { + return String("+").join(mod_names); + } else { + return "None"; + } +} + +String InputEventWithModifiers::to_string() { + return as_text(); +} + void InputEventWithModifiers::_bind_methods() { ClassDB::bind_method(D_METHOD("set_store_command", "enable"), &InputEventWithModifiers::set_store_command); ClassDB::bind_method(D_METHOD("is_storing_command"), &InputEventWithModifiers::is_storing_command); @@ -326,24 +349,31 @@ uint32_t InputEventKey::get_physical_keycode_with_modifiers() const { } String InputEventKey::as_text() const { - String kc = keycode_get_string(keycode); + String kc; + + if (keycode == 0) { + kc = keycode_get_string(physical_keycode) + " (" + RTR("Physical") + ")"; + } else { + kc = keycode_get_string(keycode); + } + if (kc == String()) { return kc; } - if (get_metakey()) { - kc = find_keycode_name(KEY_META) + ("+" + kc); - } - if (get_alt()) { - kc = find_keycode_name(KEY_ALT) + ("+" + kc); - } - if (get_shift()) { - kc = find_keycode_name(KEY_SHIFT) + ("+" + kc); - } - if (get_control()) { - kc = find_keycode_name(KEY_CONTROL) + ("+" + kc); + String mods_text = InputEventWithModifiers::as_text(); + return mods_text == "" ? kc : mods_text + "+" + kc; +} + +String InputEventKey::to_string() { + String p = is_pressed() ? "true" : "false"; + String e = is_echo() ? "true" : "false"; + + if (keycode == 0) { + return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", itos(physical_keycode) + " " + keycode_get_string(physical_keycode), InputEventWithModifiers::as_text(), "true", p, e); + } else { + return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", itos(keycode) + " " + keycode_get_string(keycode), InputEventWithModifiers::as_text(), "false", p, e); } - return kc; } bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { @@ -536,41 +566,74 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p return match; } +static const char *_mouse_button_descriptions[9] = { + TTRC("Left Mouse Button"), + TTRC("Right Mouse Button"), + TTRC("Middle Mouse Button"), + TTRC("Mouse Wheel Up"), + TTRC("Mouse Wheel Down"), + TTRC("Mouse Wheel Left"), + TTRC("Mouse Wheel Right"), + TTRC("Mouse Thumb Button 1"), + TTRC("Mouse Thumb Button 2") +}; + String InputEventMouseButton::as_text() const { - String button_index_string = ""; - switch (get_button_index()) { + // Modifiers + String mods_text = InputEventWithModifiers::as_text(); + String full_string = mods_text == "" ? "" : mods_text + "+"; + + // Button + int idx = get_button_index(); + switch (idx) { case BUTTON_LEFT: - button_index_string = "BUTTON_LEFT"; - break; case BUTTON_RIGHT: - button_index_string = "BUTTON_RIGHT"; - break; case BUTTON_MIDDLE: - button_index_string = "BUTTON_MIDDLE"; - break; case BUTTON_WHEEL_UP: - button_index_string = "BUTTON_WHEEL_UP"; - break; case BUTTON_WHEEL_DOWN: - button_index_string = "BUTTON_WHEEL_DOWN"; - break; case BUTTON_WHEEL_LEFT: - button_index_string = "BUTTON_WHEEL_LEFT"; - break; case BUTTON_WHEEL_RIGHT: - button_index_string = "BUTTON_WHEEL_RIGHT"; - break; case BUTTON_XBUTTON1: - button_index_string = "BUTTON_XBUTTON1"; + case BUTTON_XBUTTON2: + full_string += RTR(_mouse_button_descriptions[idx - 1]); // button index starts from 1, array index starts from 0, so subtract 1 + break; + default: + full_string += RTR("Button") + " #" + itos(idx); break; + } + + // Double Click + if (doubleclick) { + full_string += " (" + RTR("Double Click") + ")"; + } + + return full_string; +} + +String InputEventMouseButton::to_string() { + String p = is_pressed() ? "true" : "false"; + String d = doubleclick ? "true" : "false"; + + int idx = get_button_index(); + String button_string = itos(idx); + + switch (idx) { + case BUTTON_LEFT: + case BUTTON_RIGHT: + case BUTTON_MIDDLE: + case BUTTON_WHEEL_UP: + case BUTTON_WHEEL_DOWN: + case BUTTON_WHEEL_LEFT: + case BUTTON_WHEEL_RIGHT: + case BUTTON_XBUTTON1: case BUTTON_XBUTTON2: - button_index_string = "BUTTON_XBUTTON2"; + button_string += " (" + RTR(_mouse_button_descriptions[idx - 1]) + ")"; // button index starts from 1, array index starts from 0, so subtract 1 break; default: - button_index_string = itos(get_button_index()); break; } - return "InputEventMouseButton : button_index=" + button_index_string + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + "), button_mask=" + itos(get_button_mask()) + ", doubleclick=" + (doubleclick ? "true" : "false"); + + return vformat("InputEventMouseButton: button_index=%s pressed=%s position=(%s) button_mask=%s doubleclick=%s", button_index, p, String(get_position()), itos(get_button_mask()), d); } void InputEventMouseButton::_bind_methods() { @@ -653,27 +716,32 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co } String InputEventMouseMotion::as_text() const { - String button_mask_string = ""; + return vformat(RTR("Mouse motion at position (%s) with speed (%s)"), String(get_position()), String(get_speed())); +} + +String InputEventMouseMotion::to_string() { + int button_mask = get_button_mask(); + String button_mask_string = itos(button_mask); switch (get_button_mask()) { case BUTTON_MASK_LEFT: - button_mask_string = "BUTTON_MASK_LEFT"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_LEFT - 1]) + ")"; break; case BUTTON_MASK_MIDDLE: - button_mask_string = "BUTTON_MASK_MIDDLE"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_MIDDLE - 1]) + ")"; break; case BUTTON_MASK_RIGHT: - button_mask_string = "BUTTON_MASK_RIGHT"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_RIGHT - 1]) + ")"; break; case BUTTON_MASK_XBUTTON1: - button_mask_string = "BUTTON_MASK_XBUTTON1"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_XBUTTON1 - 1]) + ")"; break; case BUTTON_MASK_XBUTTON2: - button_mask_string = "BUTTON_MASK_XBUTTON2"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_XBUTTON2 - 1]) + ")"; break; default: - button_mask_string = itos(get_button_mask()); break; } + return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + ")"; } @@ -796,7 +864,26 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool * return match; } +static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = { + TTRC("Left Stick X-Axis, Joystick 0 X-Axis"), + TTRC("Left Stick Y-Axis, Joystick 0 Y-Axis"), + TTRC("Right Stick X-Axis, Joystick 1 X-Axis"), + TTRC("Right Stick Y-Axis, Joystick 1 Y-Axis"), + TTRC("Joystick 2 X-Axis, Left Trigger, Sony L2, Xbox LT"), + TTRC("Joystick 2 Y-Axis, Right Trigger, Sony R2, Xbox RT"), + TTRC("Joystick 3 X-Axis"), + TTRC("Joystick 3 Y-Axis"), + TTRC("Joystick 4 X-Axis"), + TTRC("Joystick 4 Y-Axis"), +}; + String InputEventJoypadMotion::as_text() const { + String desc = axis < JOY_AXIS_MAX ? RTR(_joy_axis_descriptions[axis]) : TTR("Unknown Joypad Axis"); + + return vformat(TTR("Joypad Motion on Axis %s (%s) with Value %s"), itos(axis), desc, String(Variant(axis_value))); +} + +String InputEventJoypadMotion::to_string() { return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value)); } @@ -869,7 +956,39 @@ bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) cons return button_index == button->button_index; } +static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = { + TTRC("Bottom Action, Sony Cross, Xbox A, Nintendo B"), + TTRC("Right Action, Sony Circle, Xbox B, Nintendo A"), + TTRC("Left Action, Sony Square, Xbox X, Nintendo Y"), + TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"), + TTRC("Back, Sony Select, Xbox Back, Nintendo -"), + TTRC("Guide, Sony PS, Xbox Home"), + TTRC("Start, Nintendo +"), + TTRC("Left Stick, Sony L3, Xbox L/LS"), + TTRC("Right Stick, Sony R3, Xbox R/RS"), + TTRC("Left Shoulder, Sony L1, Xbox LB"), + TTRC("Right Shoulder, Sony R1, Xbox RB"), + TTRC("D-pad Up"), + TTRC("D-pad Down"), + TTRC("D-pad Left"), + TTRC("D-pad Right"), +}; + String InputEventJoypadButton::as_text() const { + String text = "Joypad Button " + itos(button_index); + + if (button_index < JOY_BUTTON_SDL_MAX) { + text += vformat(" (%s)", _joy_button_descriptions[button_index]); + } + + if (pressure != 0) { + text += ", Pressure:" + String(Variant(pressure)); + } + + return text; +} + +String InputEventJoypadButton::to_string() { return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure)); } @@ -927,6 +1046,12 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co } String InputEventScreenTouch::as_text() const { + String status = pressed ? RTR("touched") : RTR("released"); + + return vformat(RTR("Screen %s at (%s) with %s touch points"), status, String(get_position()), itos(index)); +} + +String InputEventScreenTouch::to_string() { return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")"; } @@ -996,6 +1121,10 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con } String InputEventScreenDrag::as_text() const { + return vformat(RTR("Screen dragged with %s touch points at position (%s) with speed of (%s)"), itos(index), String(get_position()), String(get_speed())); +} + +String InputEventScreenDrag::to_string() { return "InputEventScreenDrag : index=" + itos(index) + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")"; } @@ -1079,6 +1208,10 @@ bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pres } String InputEventAction::as_text() const { + return vformat(RTR("Input Action %s was %s"), action, pressed ? "pressed" : "released"); +} + +String InputEventAction::to_string() { return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false"); } @@ -1142,6 +1275,10 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, } String InputEventMagnifyGesture::as_text() const { + return vformat(RTR("Magnify Gesture at (%s) with factor %s"), String(get_position()), rtos(get_factor())); +} + +String InputEventMagnifyGesture::to_string() { return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")"; } @@ -1178,6 +1315,10 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con } String InputEventPanGesture::as_text() const { + return vformat(RTR("Pan Gesture at (%s) with delta (%s)"), String(get_position()), String(get_delta())); +} + +String InputEventPanGesture::to_string() { return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")"; } @@ -1255,7 +1396,11 @@ int InputEventMIDI::get_controller_value() const { } String InputEventMIDI::as_text() const { - return "InputEventMIDI : channel=(" + itos(get_channel()) + "), message=(" + itos(get_message()) + ")"; + return vformat(RTR("MIDI Input on Channel=%s Message=%s"), itos(channel), itos(message)); +} + +String InputEventMIDI::to_string() { + return vformat("InputEvenMIDI: channel=%s message=%s pitch=%s velocity=%s pressure=%s", itos(channel), itos(message), itos(pitch), itos(velocity), itos(pressure)); } void InputEventMIDI::_bind_methods() { diff --git a/core/input/input_event.h b/core/input/input_event.h index 0eae3a2bbe..6a71a24c8b 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -132,7 +132,7 @@ public: virtual bool is_pressed() const; virtual bool is_echo() const; - virtual String as_text() const; + virtual String as_text() const = 0; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; @@ -207,6 +207,9 @@ public: void set_modifiers_from_event(const InputEventWithModifiers *event); + virtual String as_text() const override; + virtual String to_string() override; + InputEventWithModifiers() {} }; @@ -249,6 +252,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventKey() {} }; @@ -306,6 +310,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventMouseButton() {} }; @@ -336,6 +341,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; virtual bool accumulate(const Ref<InputEvent> &p_event) override; @@ -363,6 +369,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventJoypadMotion() {} }; @@ -391,6 +398,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventJoypadButton() {} }; @@ -416,6 +424,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventScreenTouch() {} }; @@ -445,6 +454,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventScreenDrag() {} }; @@ -476,6 +486,7 @@ public: virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventAction() {} }; @@ -506,6 +517,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventMagnifyGesture() {} }; @@ -523,6 +535,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventPanGesture() {} }; @@ -568,6 +581,7 @@ public: int get_controller_value() const; virtual String as_text() const override; + virtual String to_string() override; InputEventMIDI() {} }; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index d31a9a0194..30bbd43c18 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -102,6 +102,7 @@ public: virtual String get_resource_type() const = 0; virtual float get_priority() const { return 1.0; } virtual int get_import_order() const { return 0; } + virtual int get_format_version() const { return 0; } struct ImportOption { PropertyInfo option; diff --git a/core/object/object.cpp b/core/object/object.cpp index a642647853..3764316122 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1266,10 +1266,6 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons } } -Error Object::connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) { - return connect(p_signal, Callable(p_to_object, p_to_method), p_binds, p_flags); -} - Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) { ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER); @@ -1331,10 +1327,6 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, co return OK; } -bool Object::is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const { - return is_connected(p_signal, Callable(p_to_object, p_to_method)); -} - bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const { ERR_FAIL_COND_V(p_callable.is_null(), false); const SignalData *s = signal_map.getptr(p_signal); @@ -1358,10 +1350,6 @@ bool Object::is_connected(const StringName &p_signal, const Callable &p_callable //return (E!=nullptr ); } -void Object::disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) { - _disconnect(p_signal, Callable(p_to_object, p_to_method)); -} - void Object::disconnect(const StringName &p_signal, const Callable &p_callable) { _disconnect(p_signal, p_callable); } diff --git a/core/object/object.h b/core/object/object.h index 0bcfa42e3d..5bf9600c5a 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -697,10 +697,6 @@ public: int get_persistent_signal_connection_count() const; void get_signals_connected_to_this(List<Connection> *p_connections) const; - Error connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0); - void disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method); - bool is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const; - Error connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0); void disconnect(const StringName &p_signal, const Callable &p_callable); bool is_connected(const StringName &p_signal, const Callable &p_callable) const; diff --git a/core/object/script_language.h b/core/object/script_language.h index 3fd56c2f15..72586780ae 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -31,6 +31,7 @@ #ifndef SCRIPT_LANGUAGE_H #define SCRIPT_LANGUAGE_H +#include "core/doc_data.h" #include "core/io/multiplayer_api.h" #include "core/io/resource.h" #include "core/templates/map.h" @@ -145,6 +146,10 @@ public: virtual void set_source_code(const String &p_code) = 0; virtual Error reload(bool p_keep_state = false) = 0; +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const = 0; +#endif // TOOLS_ENABLED + virtual bool has_method(const StringName &p_method) const = 0; virtual MethodInfo get_method_info(const StringName &p_method) const = 0; @@ -310,6 +315,7 @@ public: virtual Script *create_script() const = 0; virtual bool has_named_classes() const = 0; virtual bool supports_builtin_mode() const = 0; + virtual bool supports_documentation() const { return false; } virtual bool can_inherit_from_file() { return false; } virtual int find_function(const String &p_function, const String &p_code) const = 0; virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const = 0; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 7e32f215e7..9883ce12a0 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -168,6 +168,7 @@ void register_core_types() { ClassDB::register_class<AESContext>(); ClassDB::register_custom_instance_class<X509Certificate>(); ClassDB::register_custom_instance_class<CryptoKey>(); + ClassDB::register_custom_instance_class<HMACContext>(); ClassDB::register_custom_instance_class<Crypto>(); ClassDB::register_custom_instance_class<StreamPeerSSL>(); diff --git a/core/templates/pass_func.h b/core/templates/pass_func.h new file mode 100644 index 0000000000..a074ad190d --- /dev/null +++ b/core/templates/pass_func.h @@ -0,0 +1,100 @@ +/*************************************************************************/ +/* pass_func.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef PASS_FUNC_H +#define PASS_FUNC_H + +#define PASS0R(m_r, m_name) \ + m_r m_name() { return PASSBASE->m_name(); } +#define PASS0RC(m_r, m_name) \ + m_r m_name() const { return PASSBASE->m_name(); } +#define PASS1R(m_r, m_name, m_type1) \ + m_r m_name(m_type1 arg1) { return PASSBASE->m_name(arg1); } +#define PASS1RC(m_r, m_name, m_type1) \ + m_r m_name(m_type1 arg1) const { return PASSBASE->m_name(arg1); } +#define PASS2R(m_r, m_name, m_type1, m_type2) \ + m_r m_name(m_type1 arg1, m_type2 arg2) { return PASSBASE->m_name(arg1, arg2); } +#define PASS2RC(m_r, m_name, m_type1, m_type2) \ + m_r m_name(m_type1 arg1, m_type2 arg2) const { return PASSBASE->m_name(arg1, arg2); } +#define PASS3R(m_r, m_name, m_type1, m_type2, m_type3) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return PASSBASE->m_name(arg1, arg2, arg3); } +#define PASS3RC(m_r, m_name, m_type1, m_type2, m_type3) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return PASSBASE->m_name(arg1, arg2, arg3); } +#define PASS4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return PASSBASE->m_name(arg1, arg2, arg3, arg4); } +#define PASS4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return PASSBASE->m_name(arg1, arg2, arg3, arg4); } +#define PASS5R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { return PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5); } +#define PASS5RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) const { return PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5); } +#define PASS6R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { return PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } +#define PASS6RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) const { return PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } + +#define PASS0(m_name) \ + void m_name() { PASSBASE->m_name(); } +#define PASS1(m_name, m_type1) \ + void m_name(m_type1 arg1) { PASSBASE->m_name(arg1); } +#define PASS1C(m_name, m_type1) \ + void m_name(m_type1 arg1) const { PASSBASE->m_name(arg1); } +#define PASS2(m_name, m_type1, m_type2) \ + void m_name(m_type1 arg1, m_type2 arg2) { PASSBASE->m_name(arg1, arg2); } +#define PASS2C(m_name, m_type1, m_type2) \ + void m_name(m_type1 arg1, m_type2 arg2) const { PASSBASE->m_name(arg1, arg2); } +#define PASS3(m_name, m_type1, m_type2, m_type3) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { PASSBASE->m_name(arg1, arg2, arg3); } +#define PASS4(m_name, m_type1, m_type2, m_type3, m_type4) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { PASSBASE->m_name(arg1, arg2, arg3, arg4); } +#define PASS5(m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5); } +#define PASS6(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } +#define PASS7(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } +#define PASS8(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } +#define PASS9(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } +#define PASS10(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } +#define PASS11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); } +#define PASS12(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); } +#define PASS13(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); } +#define PASS14(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); } +#define PASS15(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14, m_type15) \ + void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14, m_type15 arg15) { PASSBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); } + +#endif // PASS_FUNC_H diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 07b024ecb4..df29ec7b63 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -1399,6 +1399,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorSub<Quat, Quat, Quat>>(Variant::OP_SUBTRACT, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorMul<int64_t, int64_t, int64_t>>(Variant::OP_MULTIPLY, Variant::INT, Variant::INT); register_op<OperatorEvaluatorMul<double, int64_t, double>>(Variant::OP_MULTIPLY, Variant::INT, Variant::FLOAT); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 0216d2ba35..f94eb7adef 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2504,7 +2504,7 @@ <constant name="TYPE_INT" value="2" enum="Variant.Type"> Variable is of type [int]. </constant> - <constant name="TYPE_REAL" value="3" enum="Variant.Type"> + <constant name="TYPE_FLOAT" value="3" enum="Variant.Type"> Variable is of type [float] (real). </constant> <constant name="TYPE_STRING" value="4" enum="Variant.Type"> diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index dc834474ad..ef33d7ea77 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -16,8 +16,8 @@ # Initialize the ArrayMesh. var arr_mesh = ArrayMesh.new() var arrays = [] - arrays.resize(ArrayMesh.ARRAY_MAX) - arrays[ArrayMesh.ARRAY_VERTEX] = vertices + arrays.resize(Mesh.ARRAY_MAX) + arrays[Mesh.ARRAY_VERTEX] = vertices # Create the Mesh. arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) @@ -33,8 +33,8 @@ // Initialize the ArrayMesh. var arrMesh = new ArrayMesh(); var arrays = new Godot.Collections.Array(); - arrays.Resize((int)ArrayMesh.ArrayType.Max); - arrays[(int)ArrayMesh.ArrayType.Vertex] = vertices; + arrays.Resize((int)Mesh.ArrayType.Max); + arrays[(int)Mesh.ArrayType.Vertex] = vertices; // Create the Mesh. arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); @@ -71,12 +71,12 @@ <argument index="3" name="lods" type="Dictionary" default="{ }"> </argument> - <argument index="4" name="compress_flags" type="int" default="31744"> + <argument index="4" name="compress_flags" type="int" default="0"> </argument> <description> Creates a new surface. Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface. - The [code]arrays[/code] argument is an array of arrays. See [enum ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant ARRAY_INDEX] if it is used. + The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data, and the index array defines the order of the vertices. </description> </method> @@ -209,77 +209,19 @@ </method> </methods> <members> - <member name="blend_shape_mode" type="int" setter="set_blend_shape_mode" getter="get_blend_shape_mode" enum="Mesh.BlendShapeMode" default="1"> - Sets the blend shape mode to one of [enum Mesh.BlendShapeMode]. + <member name="blend_shape_mode" type="int" setter="set_blend_shape_mode" getter="get_blend_shape_mode" enum="ArrayMesh.BlendShapeMode" default="1"> + Sets the blend shape mode to one of [enum ArrayMesh.BlendShapeMode]. </member> <member name="custom_aabb" type="AABB" setter="set_custom_aabb" getter="get_custom_aabb" default="AABB( 0, 0, 0, 0, 0, 0 )"> Overrides the [AABB] with one defined by user for use with frustum culling. Especially useful to avoid unexpected culling when using a shader to offset vertices. </member> </members> <constants> - <constant name="NO_INDEX_ARRAY" value="-1"> - Default value used for index_array_len when no indices are present. + <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode"> + Blend shapes are normalized. </constant> - <constant name="ARRAY_WEIGHTS_SIZE" value="4"> - Amount of weights/bone indices per vertex (always 4). - </constant> - <constant name="ARRAY_VERTEX" value="0" enum="ArrayType"> - [PackedVector3Array], [PackedVector2Array], or [Array] of vertex positions. - </constant> - <constant name="ARRAY_NORMAL" value="1" enum="ArrayType"> - [PackedVector3Array] of vertex normals. - </constant> - <constant name="ARRAY_TANGENT" value="2" enum="ArrayType"> - [PackedFloat32Array] of vertex tangents. Each element in groups of 4 floats, first 3 floats determine the tangent, and the last the binormal direction as -1 or 1. - </constant> - <constant name="ARRAY_COLOR" value="3" enum="ArrayType"> - [PackedColorArray] of vertex colors. - </constant> - <constant name="ARRAY_TEX_UV" value="4" enum="ArrayType"> - [PackedVector2Array] for UV coordinates. - </constant> - <constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType"> - [PackedVector2Array] for second UV coordinates. - </constant> - <constant name="ARRAY_BONES" value="6" enum="ArrayType"> - [PackedFloat32Array] or [PackedInt32Array] of bone indices. Each element in groups of 4 floats. - </constant> - <constant name="ARRAY_WEIGHTS" value="7" enum="ArrayType"> - [PackedFloat32Array] of bone weights. Each element in groups of 4 floats. - </constant> - <constant name="ARRAY_INDEX" value="8" enum="ArrayType"> - [PackedInt32Array] of integers used as indices referencing vertices, colors, normals, tangents, and textures. All of those arrays must have the same number of elements as the vertex array. No index can be beyond the vertex array size. When this index array is present, it puts the function into "index mode," where the index selects the *i*'th vertex, normal, tangent, color, UV, etc. This means if you want to have different normals or colors along an edge, you have to duplicate the vertices. - For triangles, the index array is interpreted as triples, referring to the vertices of each triangle. For lines, the index array is in pairs indicating the start and end of each line. - </constant> - <constant name="ARRAY_MAX" value="9" enum="ArrayType"> - Represents the size of the [enum ArrayType] enum. - </constant> - <constant name="ARRAY_FORMAT_VERTEX" value="1" enum="ArrayFormat"> - Array format will include vertices (mandatory). - </constant> - <constant name="ARRAY_FORMAT_NORMAL" value="2" enum="ArrayFormat"> - Array format will include normals. - </constant> - <constant name="ARRAY_FORMAT_TANGENT" value="4" enum="ArrayFormat"> - Array format will include tangents. - </constant> - <constant name="ARRAY_FORMAT_COLOR" value="8" enum="ArrayFormat"> - Array format will include a color array. - </constant> - <constant name="ARRAY_FORMAT_TEX_UV" value="16" enum="ArrayFormat"> - Array format will include UVs. - </constant> - <constant name="ARRAY_FORMAT_TEX_UV2" value="32" enum="ArrayFormat"> - Array format will include another set of UVs. - </constant> - <constant name="ARRAY_FORMAT_BONES" value="64" enum="ArrayFormat"> - Array format will include bone indices. - </constant> - <constant name="ARRAY_FORMAT_WEIGHTS" value="128" enum="ArrayFormat"> - Array format will include bone weights. - </constant> - <constant name="ARRAY_FORMAT_INDEX" value="256" enum="ArrayFormat"> - Index array will be used. + <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode"> + Blend shapes are relative to base weight. </constant> </constants> </class> diff --git a/doc/classes/CubeMesh.xml b/doc/classes/BoxMesh.xml index 1f64b4a21f..88d22ac899 100644 --- a/doc/classes/CubeMesh.xml +++ b/doc/classes/BoxMesh.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CubeMesh" inherits="PrimitiveMesh" version="4.0"> +<class name="BoxMesh" inherits="PrimitiveMesh" version="4.0"> <brief_description> - Generate an axis-aligned cuboid [PrimitiveMesh]. + Generate an axis-aligned box [PrimitiveMesh]. </brief_description> <description> - Generate an axis-aligned cuboid [PrimitiveMesh]. - The cube's UV layout is arranged in a 3×2 layout that allows texturing each face individually. To apply the same texture on all faces, change the material's UV property to [code]Vector3(3, 2, 1)[/code]. + Generate an axis-aligned box [PrimitiveMesh]. + The box's UV layout is arranged in a 3×2 layout that allows texturing each face individually. To apply the same texture on all faces, change the material's UV property to [code]Vector3(3, 2, 1)[/code]. </description> <tutorials> </tutorials> @@ -13,7 +13,7 @@ </methods> <members> <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3( 2, 2, 2 )"> - Size of the cuboid mesh. + Size of the box mesh. </member> <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" default="0"> Number of extra edge loops inserted along the Z axis. diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index fcf2feb3b9..aa9f99a31e 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -50,10 +50,10 @@ <method name="get_particle_flag" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="flag" type="int" enum="CPUParticles2D.Flags"> + <argument index="0" name="particle_flag" type="int" enum="CPUParticles2D.ParticleFlags"> </argument> <description> - Returns the enabled state of the given flag (see [enum Flags] for options). + Returns the enabled state of the given flag (see [enum ParticleFlags] for options). </description> </method> <method name="restart"> @@ -99,12 +99,12 @@ <method name="set_particle_flag"> <return type="void"> </return> - <argument index="0" name="flag" type="int" enum="CPUParticles2D.Flags"> + <argument index="0" name="particle_flag" type="int" enum="CPUParticles2D.ParticleFlags"> </argument> <argument index="1" name="enable" type="bool"> </argument> <description> - Enables or disables the given flag (see [enum Flags] for options). + Enables or disables the given flag (see [enum ParticleFlags] for options). </description> </method> </methods> @@ -196,9 +196,6 @@ <member name="fixed_fps" type="int" setter="set_fixed_fps" getter="get_fixed_fps" default="0"> The particle system's frame rate is fixed to a value. For instance, changing the value to 2 will make the particles render at 2 frames per second. Note this does not slow down the simulation of the particle system itself. </member> - <member name="flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> - Align Y axis of particle with the direction of its velocity. - </member> <member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" default="true"> If [code]true[/code], results in fractional delta calculation which has a smoother particles display effect. </member> @@ -250,6 +247,9 @@ <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Orbital velocity randomness ratio. </member> + <member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + Align Y axis of particle with the direction of its velocity. + </member> <member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" default="0.0"> Particle system starts as if it had already run for this many seconds. </member> @@ -339,17 +339,17 @@ <constant name="PARAM_MAX" value="12" enum="Parameter"> Represents the size of the [enum Parameter] enum. </constant> - <constant name="FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="Flags"> - Use with [method set_particle_flag] to set [member flag_align_y]. + <constant name="PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_align_y]. </constant> - <constant name="FLAG_ROTATE_Y" value="1" enum="Flags"> + <constant name="PARTICLE_FLAG_ROTATE_Y" value="1" enum="ParticleFlags"> Present for consistency with 3D particle nodes, not used in 2D. </constant> - <constant name="FLAG_DISABLE_Z" value="2" enum="Flags"> + <constant name="PARTICLE_FLAG_DISABLE_Z" value="2" enum="ParticleFlags"> Present for consistency with 3D particle nodes, not used in 2D. </constant> - <constant name="FLAG_MAX" value="3" enum="Flags"> - Represents the size of the [enum Flags] enum. + <constant name="PARTICLE_FLAG_MAX" value="3" enum="ParticleFlags"> + Represents the size of the [enum ParticleFlags] enum. </constant> <constant name="EMISSION_SHAPE_POINT" value="0" enum="EmissionShape"> All particles will be emitted from a single point. diff --git a/doc/classes/CPUParticles3D.xml b/doc/classes/CPUParticles3D.xml index 07da066bd9..0512efa8c2 100644 --- a/doc/classes/CPUParticles3D.xml +++ b/doc/classes/CPUParticles3D.xml @@ -49,10 +49,10 @@ <method name="get_particle_flag" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="flag" type="int" enum="CPUParticles3D.Flags"> + <argument index="0" name="particle_flag" type="int" enum="CPUParticles3D.ParticleFlags"> </argument> <description> - Returns the enabled state of the given flag (see [enum Flags] for options). + Returns the enabled state of the given particle flag (see [enum ParticleFlags] for options). </description> </method> <method name="restart"> @@ -98,12 +98,12 @@ <method name="set_particle_flag"> <return type="void"> </return> - <argument index="0" name="flag" type="int" enum="CPUParticles3D.Flags"> + <argument index="0" name="particle_flag" type="int" enum="CPUParticles3D.ParticleFlags"> </argument> <argument index="1" name="enable" type="bool"> </argument> <description> - Enables or disables the given flag (see [enum Flags] for options). + Enables or disables the given particle flag (see [enum ParticleFlags] for options). </description> </method> </methods> @@ -195,15 +195,6 @@ <member name="fixed_fps" type="int" setter="set_fixed_fps" getter="get_fixed_fps" default="0"> The particle system's frame rate is fixed to a value. For instance, changing the value to 2 will make the particles render at 2 frames per second. Note this does not slow down the particle system itself. </member> - <member name="flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> - Align Y axis of particle with the direction of its velocity. - </member> - <member name="flag_disable_z" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> - If [code]true[/code], particles will not move on the z axis. - </member> - <member name="flag_rotate_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> - If [code]true[/code], particles rotate around Y axis by [member angle]. - </member> <member name="flatness" type="float" setter="set_flatness" getter="get_flatness" default="0.0"> Amount of [member spread] in Y/Z plane. A value of [code]1[/code] restricts particles to X/Z plane. </member> @@ -254,7 +245,7 @@ </member> <member name="orbit_velocity" type="float" setter="set_param" getter="get_param"> Orbital velocity applied to each particle. Makes the particles circle around origin in the local XY plane. Specified in number of full rotations around origin per second. - This property is only available when [member flag_disable_z] is [code]true[/code]. + This property is only available when [member particle_flag_disable_z] is [code]true[/code]. </member> <member name="orbit_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's orbital velocity will vary along this [Curve]. @@ -262,6 +253,15 @@ <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness"> Orbital velocity randomness ratio. </member> + <member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + Align Y axis of particle with the direction of its velocity. + </member> + <member name="particle_flag_disable_z" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + If [code]true[/code], particles will not move on the Z axis. + </member> + <member name="particle_flag_rotate_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + If [code]true[/code], particles rotate around Y axis by [member angle]. + </member> <member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" default="0.0"> Particle system starts as if it had already run for this many seconds. </member> @@ -351,17 +351,17 @@ <constant name="PARAM_MAX" value="12" enum="Parameter"> Represents the size of the [enum Parameter] enum. </constant> - <constant name="FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="Flags"> - Use with [method set_particle_flag] to set [member flag_align_y]. + <constant name="PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_align_y]. </constant> - <constant name="FLAG_ROTATE_Y" value="1" enum="Flags"> - Use with [method set_particle_flag] to set [member flag_rotate_y]. + <constant name="PARTICLE_FLAG_ROTATE_Y" value="1" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_rotate_y]. </constant> - <constant name="FLAG_DISABLE_Z" value="2" enum="Flags"> - Use with [method set_particle_flag] to set [member flag_disable_z]. + <constant name="PARTICLE_FLAG_DISABLE_Z" value="2" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_disable_z]. </constant> - <constant name="FLAG_MAX" value="3" enum="Flags"> - Represents the size of the [enum Flags] enum. + <constant name="PARTICLE_FLAG_MAX" value="3" enum="ParticleFlags"> + Represents the size of the [enum ParticleFlags] enum. </constant> <constant name="EMISSION_SHAPE_POINT" value="0" enum="EmissionShape"> All particles will be emitted from a single point. diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 9705a196ed..89c5e355ec 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -255,6 +255,14 @@ <description> </description> </method> + <method name="operator -" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> <method name="operator /" qualifiers="operator"> <return type="Color"> </return> diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml index b3bbbae94f..1f6cb40cde 100644 --- a/doc/classes/Crypto.xml +++ b/doc/classes/Crypto.xml @@ -73,6 +73,18 @@ <tutorials> </tutorials> <methods> + <method name="constant_time_compare"> + <return type="bool"> + </return> + <argument index="0" name="trusted" type="PackedByteArray"> + </argument> + <argument index="1" name="received" type="PackedByteArray"> + </argument> + <description> + Compares two [PackedByteArray]s for equality without leaking timing information in order to prevent timing attacks. + See [url=https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy]this blog post[/url] for more information. + </description> + </method> <method name="decrypt"> <return type="PackedByteArray"> </return> @@ -147,6 +159,20 @@ [/codeblocks] </description> </method> + <method name="hmac_digest"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="hash_type" type="int" enum="HashingContext.HashType"> + </argument> + <argument index="1" name="key" type="PackedByteArray"> + </argument> + <argument index="2" name="msg" type="PackedByteArray"> + </argument> + <description> + Generates an [url=https://en.wikipedia.org/wiki/HMAC]HMAC[/url] digest of [code]msg[/code] using [code]key[/code]. The [code]hash_type[/code] parameter is the hashing algorithm that is used for the inner and outer hashes. + Currently, only [constant HashingContext.HASH_SHA256] and [constant HashingContext.HASH_SHA1] are supported. + </description> + </method> <method name="sign"> <return type="PackedByteArray"> </return> diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml index a6a0e0c33d..bda04f010b 100644 --- a/doc/classes/Curve3D.xml +++ b/doc/classes/Curve3D.xml @@ -145,7 +145,7 @@ <argument index="1" name="cubic" type="bool" default="false"> </argument> <description> - Returns a point within the curve at position [code]offset[/code], where [code]offset[/code] is measured as a pixel distance along the curve. + Returns a point within the curve at position [code]offset[/code], where [code]offset[/code] is measured as a distance in 3D units along the curve. To do that, it finds the two cached points where the [code]offset[/code] lies between, then interpolates the values. This interpolation is cubic if [code]cubic[/code] is set to [code]true[/code], or linear if set to [code]false[/code]. Cubic interpolation tends to follow the curves better, but linear is faster (and often, precise enough). </description> diff --git a/doc/classes/HMACContext.xml b/doc/classes/HMACContext.xml new file mode 100644 index 0000000000..00d528ef8f --- /dev/null +++ b/doc/classes/HMACContext.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="HMACContext" inherits="Reference" version="4.0"> + <brief_description> + Used to create an HMAC for a message using a key. + </brief_description> + <description> + The HMACContext class is useful for advanced HMAC use cases, such as streaming the message as it supports creating the message over time rather than providing it all at once. + [codeblocks] + [gdscript] + extends Node + var ctx = HMACContext.new() + + func _ready(): + var key = "supersecret".to_utf8() + var err = ctx.start(HashingContext.HASH_SHA256, key) + assert(err == OK) + var msg1 = "this is ".to_utf8() + var msg2 = "vewy vewy secret".to_utf8() + err = ctx.update(msg1) + assert(err == OK) + err = ctx.update(msg2) + assert(err == OK) + var hmac = ctx.finish() + print(hmac.hex_encode()) + + [/gdscript] + [csharp] + using Godot; + using System; + using System.Diagnostics; + + public class CryptoNode : Node + { + private HMACContext ctx = new HMACContext(); + public override void _Ready() + { + PackedByteArray key = String("supersecret").to_utf8(); + Error err = ctx.Start(HashingContext.HASH_SHA256, key); + GD.Assert(err == OK); + PackedByteArray msg1 = String("this is ").to_utf8(); + PackedByteArray msg2 = String("vewy vew secret").to_utf8(); + err = ctx.Update(msg1); + GD.Assert(err == OK); + err = ctx.Update(msg2); + GD.Assert(err == OK); + PackedByteArray hmac = ctx.Finish(); + GD.Print(hmac.HexEncode()); + } + } + + [/csharp] + [/codeblocks] + [b]Note:[/b] Not available in HTML5 exports. + </description> + <tutorials> + </tutorials> + <methods> + <method name="finish"> + <return type="PackedByteArray"> + </return> + <description> + Returns the resulting HMAC. If the HMAC failed, an empty [PackedByteArray] is returned. + </description> + </method> + <method name="start"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="hash_type" type="int" enum="HashingContext.HashType"> + </argument> + <argument index="1" name="key" type="PackedByteArray"> + </argument> + <description> + Initializes the HMACContext. This method cannot be called again on the same HMACContext until [method finish] has been called. + </description> + </method> + <method name="update"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="data" type="PackedByteArray"> + </argument> + <description> + Updates the message to be HMACed. This can be called multiple times before [method finish] is called to append [code]data[/code] to the message, but cannot be called until [method start] has been called. + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/LightOccluder2D.xml b/doc/classes/LightOccluder2D.xml index 9f128e5942..550daf9225 100644 --- a/doc/classes/LightOccluder2D.xml +++ b/doc/classes/LightOccluder2D.xml @@ -12,12 +12,14 @@ <methods> </methods> <members> - <member name="light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" default="1"> - The LightOccluder2D's light mask. The LightOccluder2D will cast shadows only from Light2D(s) that have the same light mask(s). - </member> <member name="occluder" type="OccluderPolygon2D" setter="set_occluder_polygon" getter="get_occluder_polygon"> The [OccluderPolygon2D] used to compute the shadow. </member> + <member name="occluder_light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" default="1"> + The LightOccluder2D's occluder light mask. The LightOccluder2D will cast shadows only from Light2D(s) that have the same light mask(s). + </member> + <member name="sdf_collision" type="bool" setter="set_as_sdf_collision" getter="is_set_as_sdf_collision" default="true"> + </member> </members> <constants> </constants> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index 4b8ab3a6cf..93384843de 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -39,6 +39,7 @@ </method> </methods> <members> + <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" /> <member name="language" type="String" setter="set_language" getter="get_language" default=""""> Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. </member> diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index ac371d1e7b..a002ce636b 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -31,6 +31,7 @@ <members> <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" override="true" enum="BaseButton.ActionMode" default="0" /> <member name="flat" type="bool" setter="set_flat" getter="is_flat" override="true" default="true" /> + <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" /> <member name="switch_on_hover" type="bool" setter="set_switch_on_hover" getter="is_switch_on_hover" default="false"> If [code]true[/code], when the cursor hovers above another [MenuButton] within the same parent which also has [code]switch_on_hover[/code] enabled, it will close the current [MenuButton] and open the other one. </member> diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index 78db09feee..dff4b4f7ab 100644 --- a/doc/classes/Mesh.xml +++ b/doc/classes/Mesh.xml @@ -126,11 +126,63 @@ <constant name="PRIMITIVE_TRIANGLE_STRIP" value="4" enum="PrimitiveType"> Render array as triangle strips. </constant> - <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode"> - Blend shapes are normalized. + <constant name="ARRAY_VERTEX" value="0" enum="ArrayType"> + [PackedVector3Array], [PackedVector2Array], or [Array] of vertex positions. + </constant> + <constant name="ARRAY_NORMAL" value="1" enum="ArrayType"> + [PackedVector3Array] of vertex normals. + </constant> + <constant name="ARRAY_TANGENT" value="2" enum="ArrayType"> + [PackedFloat32Array] of vertex tangents. Each element in groups of 4 floats, first 3 floats determine the tangent, and the last the binormal direction as -1 or 1. + </constant> + <constant name="ARRAY_COLOR" value="3" enum="ArrayType"> + [PackedColorArray] of vertex colors. + </constant> + <constant name="ARRAY_TEX_UV" value="4" enum="ArrayType"> + [PackedVector2Array] for UV coordinates. + </constant> + <constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType"> + [PackedVector2Array] for second UV coordinates. + </constant> + <constant name="ARRAY_CUSTOM0" value="6" enum="ArrayType"> + </constant> + <constant name="ARRAY_CUSTOM1" value="7" enum="ArrayType"> + </constant> + <constant name="ARRAY_CUSTOM2" value="8" enum="ArrayType"> + </constant> + <constant name="ARRAY_CUSTOM3" value="9" enum="ArrayType"> + </constant> + <constant name="ARRAY_BONES" value="10" enum="ArrayType"> + [PackedFloat32Array] or [PackedInt32Array] of bone indices. Each element is a group of 4 numbers. + </constant> + <constant name="ARRAY_WEIGHTS" value="11" enum="ArrayType"> + [PackedFloat32Array] of bone weights. Each element in groups of 4 floats. + </constant> + <constant name="ARRAY_INDEX" value="12" enum="ArrayType"> + [PackedInt32Array] of integers used as indices referencing vertices, colors, normals, tangents, and textures. All of those arrays must have the same number of elements as the vertex array. No index can be beyond the vertex array size. When this index array is present, it puts the function into "index mode," where the index selects the *i*'th vertex, normal, tangent, color, UV, etc. This means if you want to have different normals or colors along an edge, you have to duplicate the vertices. + For triangles, the index array is interpreted as triples, referring to the vertices of each triangle. For lines, the index array is in pairs indicating the start and end of each line. + </constant> + <constant name="ARRAY_MAX" value="13" enum="ArrayType"> + Represents the size of the [enum ArrayType] enum. + </constant> + <constant name="ARRAY_CUSTOM_RGBA8_UNORM" value="0" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_RGBA8_SNORM" value="1" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_RG_HALF" value="2" enum="ArrayCustomFormat"> </constant> - <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode"> - Blend shapes are relative to base weight. + <constant name="ARRAY_CUSTOM_RGBA_HALF" value="3" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_R_FLOAT" value="4" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_RG_FLOAT" value="5" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_RGB_FLOAT" value="6" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_RGBA_FLOAT" value="7" enum="ArrayCustomFormat"> + </constant> + <constant name="ARRAY_CUSTOM_MAX" value="8" enum="ArrayCustomFormat"> + Represents the size of the [enum ArrayCustomFormat] enum. </constant> <constant name="ARRAY_FORMAT_VERTEX" value="1" enum="ArrayFormat"> Mesh array contains vertices. All meshes require a vertex array so this should always be present. @@ -150,68 +202,45 @@ <constant name="ARRAY_FORMAT_TEX_UV2" value="32" enum="ArrayFormat"> Mesh array contains second UV. </constant> - <constant name="ARRAY_FORMAT_BONES" value="64" enum="ArrayFormat"> - Mesh array contains bones. - </constant> - <constant name="ARRAY_FORMAT_WEIGHTS" value="128" enum="ArrayFormat"> - Mesh array contains bone weights. - </constant> - <constant name="ARRAY_FORMAT_INDEX" value="256" enum="ArrayFormat"> - Mesh array uses indices. - </constant> - <constant name="ARRAY_COMPRESS_NORMAL" value="1024" enum="ArrayFormat"> - Flag used to mark a compressed (half float) normal array. + <constant name="ARRAY_FORMAT_CUSTOM0" value="64" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_TANGENT" value="2048" enum="ArrayFormat"> - Flag used to mark a compressed (half float) tangent array. + <constant name="ARRAY_FORMAT_CUSTOM1" value="128" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_COLOR" value="4096" enum="ArrayFormat"> - Flag used to mark a compressed (half float) color array. + <constant name="ARRAY_FORMAT_CUSTOM2" value="256" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_TEX_UV" value="8192" enum="ArrayFormat"> - Flag used to mark a compressed (half float) UV coordinates array. + <constant name="ARRAY_FORMAT_CUSTOM3" value="512" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_TEX_UV2" value="16384" enum="ArrayFormat"> - Flag used to mark a compressed (half float) UV coordinates array for the second UV coordinates. + <constant name="ARRAY_FORMAT_BONES" value="1024" enum="ArrayFormat"> + Mesh array contains bones. </constant> - <constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat"> - Flag used to mark a compressed index array. + <constant name="ARRAY_FORMAT_WEIGHTS" value="2048" enum="ArrayFormat"> + Mesh array contains bone weights. </constant> - <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat"> - Flag used to mark that the array contains 2D vertices. + <constant name="ARRAY_FORMAT_INDEX" value="4096" enum="ArrayFormat"> + Mesh array uses indices. </constant> - <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat"> - Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly. + <constant name="ARRAY_FORMAT_BLEND_SHAPE_MASK" value="2147475463" enum="ArrayFormat"> </constant> - <constant name="ARRAY_VERTEX" value="0" enum="ArrayType"> - Array of vertices. + <constant name="ARRAY_FORMAT_CUSTOM_BASE" value="13" enum="ArrayFormat"> </constant> - <constant name="ARRAY_NORMAL" value="1" enum="ArrayType"> - Array of normals. + <constant name="ARRAY_FORMAT_CUSTOM0_SHIFT" value="13" enum="ArrayFormat"> </constant> - <constant name="ARRAY_TANGENT" value="2" enum="ArrayType"> - Array of tangents as an array of floats, 4 floats per tangent. + <constant name="ARRAY_FORMAT_CUSTOM1_SHIFT" value="16" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COLOR" value="3" enum="ArrayType"> - Array of colors. + <constant name="ARRAY_FORMAT_CUSTOM2_SHIFT" value="19" enum="ArrayFormat"> </constant> - <constant name="ARRAY_TEX_UV" value="4" enum="ArrayType"> - Array of UV coordinates. + <constant name="ARRAY_FORMAT_CUSTOM3_SHIFT" value="22" enum="ArrayFormat"> </constant> - <constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType"> - Array of second set of UV coordinates. + <constant name="ARRAY_FORMAT_CUSTOM_MASK" value="7" enum="ArrayFormat"> </constant> - <constant name="ARRAY_BONES" value="6" enum="ArrayType"> - Array of bone data. + <constant name="ARRAY_COMPRESS_FLAGS_BASE" value="25" enum="ArrayFormat"> </constant> - <constant name="ARRAY_WEIGHTS" value="7" enum="ArrayType"> - Array of weights. + <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="33554432" enum="ArrayFormat"> + Flag used to mark that the array contains 2D vertices. </constant> - <constant name="ARRAY_INDEX" value="8" enum="ArrayType"> - Array of indices. + <constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="67108864" enum="ArrayFormat"> </constant> - <constant name="ARRAY_MAX" value="9" enum="ArrayType"> - Represents the size of the [enum ArrayType] enum. + <constant name="ARRAY_FLAG_USE_8_BONE_WEIGHTS" value="134217728" enum="ArrayFormat"> </constant> </constants> </class> diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml index e107b1a108..db7a3187f0 100644 --- a/doc/classes/MeshDataTool.xml +++ b/doc/classes/MeshDataTool.xml @@ -10,7 +10,7 @@ [codeblocks] [gdscript] var mesh = ArrayMesh.new() - mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, CubeMesh.new().get_mesh_arrays()) + mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, BoxMesh.new().get_mesh_arrays()) var mdt = MeshDataTool.new() mdt.create_from_surface(mesh, 0) for i in range(mdt.get_vertex_count()): @@ -27,7 +27,7 @@ [/gdscript] [csharp] var mesh = new ArrayMesh(); - mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, new CubeMesh().GetMeshArrays()); + mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, new BoxMesh().GetMeshArrays()); var mdt = new MeshDataTool(); mdt.CreateFromSurface(mesh, 0); for (var i = 0; i < mdt.GetVertexCount(); i++) @@ -169,8 +169,8 @@ <return type="int"> </return> <description> - Returns the [Mesh]'s format. Format is an integer made up of [Mesh] format flags combined together. For example, a mesh containing both vertices and normals would return a format of [code]3[/code] because [constant ArrayMesh.ARRAY_FORMAT_VERTEX] is [code]1[/code] and [constant ArrayMesh.ARRAY_FORMAT_NORMAL] is [code]2[/code]. - See [enum ArrayMesh.ArrayFormat] for a list of format flags. + Returns the [Mesh]'s format. Format is an integer made up of [Mesh] format flags combined together. For example, a mesh containing both vertices and normals would return a format of [code]3[/code] because [constant Mesh.ARRAY_FORMAT_VERTEX] is [code]1[/code] and [constant Mesh.ARRAY_FORMAT_NORMAL] is [code]2[/code]. + See [enum Mesh.ArrayFormat] for a list of format flags. </description> </method> <method name="get_material" qualifiers="const"> diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml index 77df6245e9..85058cb9d4 100644 --- a/doc/classes/ParticlesMaterial.xml +++ b/doc/classes/ParticlesMaterial.xml @@ -11,15 +11,6 @@ <tutorials> </tutorials> <methods> - <method name="get_flag" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="flag" type="int" enum="ParticlesMaterial.Flags"> - </argument> - <description> - Returns [code]true[/code] if the specified flag is enabled. - </description> - </method> <method name="get_param" qualifiers="const"> <return type="float"> </return> @@ -47,15 +38,13 @@ Returns the [Texture2D] used by the specified parameter. </description> </method> - <method name="set_flag"> - <return type="void"> + <method name="get_particle_flag" qualifiers="const"> + <return type="bool"> </return> - <argument index="0" name="flag" type="int" enum="ParticlesMaterial.Flags"> - </argument> - <argument index="1" name="enable" type="bool"> + <argument index="0" name="particle_flag" type="int" enum="ParticlesMaterial.ParticleFlags"> </argument> <description> - If [code]true[/code], enables the specified flag. See [enum Flags] for options. + Returns [code]true[/code] if the specified particle flag is enabled. See [enum ParticleFlags] for options. </description> </method> <method name="set_param"> @@ -91,11 +80,22 @@ Sets the [Texture2D] for the specified [enum Parameter]. </description> </method> + <method name="set_particle_flag"> + <return type="void"> + </return> + <argument index="0" name="particle_flag" type="int" enum="ParticlesMaterial.ParticleFlags"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + If [code]true[/code], enables the specified particle flag. See [enum ParticleFlags] for options. + </description> + </method> </methods> <members> <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0"> Initial rotation applied to each particle, in degrees. - Only applied when [member flag_disable_z] or [member flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES]. + Only applied when [member particle_flag_disable_z] or [member particle_flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES]. </member> <member name="angle_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture"> Each particle's rotation will be animated along this [CurveTexture]. @@ -105,7 +105,7 @@ </member> <member name="angular_velocity" type="float" setter="set_param" getter="get_param" default="0.0"> Initial angular velocity applied to each particle. Sets the speed of rotation of the particle. - Only applied when [member flag_disable_z] or [member flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES]. + Only applied when [member particle_flag_disable_z] or [member particle_flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES]. </member> <member name="angular_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture"> Each particle's angular velocity will vary along this [CurveTexture]. @@ -180,15 +180,6 @@ <member name="emission_sphere_radius" type="float" setter="set_emission_sphere_radius" getter="get_emission_sphere_radius"> The sphere's radius if [code]emission_shape[/code] is set to [constant EMISSION_SHAPE_SPHERE]. </member> - <member name="flag_align_y" type="bool" setter="set_flag" getter="get_flag" default="false"> - Align Y axis of particle with the direction of its velocity. - </member> - <member name="flag_disable_z" type="bool" setter="set_flag" getter="get_flag" default="false"> - If [code]true[/code], particles will not move on the z axis. - </member> - <member name="flag_rotate_y" type="bool" setter="set_flag" getter="get_flag" default="false"> - If [code]true[/code], particles rotate around Y axis by [member angle]. - </member> <member name="flatness" type="float" setter="set_flatness" getter="get_flatness" default="0.0"> Amount of [member spread] in Y/Z plane. A value of [code]1[/code] restricts particles to X/Z plane. </member> @@ -224,7 +215,7 @@ </member> <member name="orbit_velocity" type="float" setter="set_param" getter="get_param"> Orbital velocity applied to each particle. Makes the particles circle around origin. Specified in number of full rotations around origin per second. - Only available when [member flag_disable_z] is [code]true[/code]. + Only available when [member particle_flag_disable_z] is [code]true[/code]. </member> <member name="orbit_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture"> Each particle's orbital velocity will vary along this [CurveTexture]. @@ -232,6 +223,15 @@ <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness"> Orbital velocity randomness ratio. </member> + <member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + Align Y axis of particle with the direction of its velocity. + </member> + <member name="particle_flag_disable_z" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + If [code]true[/code], particles will not move on the z axis. + </member> + <member name="particle_flag_rotate_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false"> + If [code]true[/code], particles rotate around Y axis by [member angle]. + </member> <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Radial acceleration applied to each particle. Makes particle accelerate away from origin. </member> @@ -311,17 +311,17 @@ <constant name="PARAM_MAX" value="12" enum="Parameter"> Represents the size of the [enum Parameter] enum. </constant> - <constant name="FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="Flags"> - Use with [method set_flag] to set [member flag_align_y]. + <constant name="PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_align_y]. </constant> - <constant name="FLAG_ROTATE_Y" value="1" enum="Flags"> - Use with [method set_flag] to set [member flag_rotate_y]. + <constant name="PARTICLE_FLAG_ROTATE_Y" value="1" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_rotate_y]. </constant> - <constant name="FLAG_DISABLE_Z" value="2" enum="Flags"> - Use with [method set_flag] to set [member flag_disable_z]. + <constant name="PARTICLE_FLAG_DISABLE_Z" value="2" enum="ParticleFlags"> + Use with [method set_particle_flag] to set [member particle_flag_disable_z]. </constant> - <constant name="FLAG_MAX" value="3" enum="Flags"> - Represents the size of the [enum Flags] enum. + <constant name="PARTICLE_FLAG_MAX" value="3" enum="ParticleFlags"> + Represents the size of the [enum ParticleFlags] enum. </constant> <constant name="EMISSION_SHAPE_POINT" value="0" enum="EmissionShape"> All particles will be emitted from a single point. diff --git a/doc/classes/PathFollow2D.xml b/doc/classes/PathFollow2D.xml index bbaeca12da..4b55e7b781 100644 --- a/doc/classes/PathFollow2D.xml +++ b/doc/classes/PathFollow2D.xml @@ -29,8 +29,8 @@ <member name="offset" type="float" setter="set_offset" getter="get_offset" default="0.0"> The distance along the path in pixels. </member> - <member name="rotate" type="bool" setter="set_rotate" getter="is_rotating" default="true"> - If [code]true[/code], this node rotates to follow the path, making its descendants rotate. + <member name="rotates" type="bool" setter="set_rotates" getter="is_rotating" default="true"> + If [code]true[/code], this node rotates to follow the path, with the +X direction facing forward on the path. </member> <member name="unit_offset" type="float" setter="set_unit_offset" getter="get_unit_offset" default="0.0"> The distance along the path as a number in the range 0.0 (for the first vertex) to 1.0 (for the last). This is just another way of expressing the offset within the path, as the offset supplied is multiplied internally by the path's length. diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index 0808e4a724..dcf24c1d32 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -117,9 +117,6 @@ <member name="mass" type="float" setter="set_mass" getter="get_mass" default="1.0"> The body's mass. </member> - <member name="weight" type="float" setter="set_weight" getter="get_weight" default="9.8"> - The body's weight based on its mass and the global 3D gravity. Global values are set in [b]Project > Project Settings > Physics > 3d[/b]. - </member> </members> <constants> <constant name="JOINT_TYPE_NONE" value="0" enum="JointType"> diff --git a/doc/classes/PrimitiveMesh.xml b/doc/classes/PrimitiveMesh.xml index 7e9bccc1d7..25943f6d47 100644 --- a/doc/classes/PrimitiveMesh.xml +++ b/doc/classes/PrimitiveMesh.xml @@ -4,7 +4,7 @@ Base class for all primitive meshes. Handles applying a [Material] to a primitive mesh. </brief_description> <description> - Base class for all primitive meshes. Handles applying a [Material] to a primitive mesh. Examples include [CapsuleMesh], [CubeMesh], [CylinderMesh], [PlaneMesh], [PrismMesh], [QuadMesh], and [SphereMesh]. + Base class for all primitive meshes. Handles applying a [Material] to a primitive mesh. Examples include [BoxMesh], [CapsuleMesh], [CylinderMesh], [PlaneMesh], [PrismMesh], [QuadMesh], and [SphereMesh]. </description> <tutorials> </tutorials> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index fa4ce9bc6d..eab06f633c 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1084,6 +1084,10 @@ </member> <member name="rendering/quality/2d/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false"> </member> + <member name="rendering/quality/2d_sdf/oversize" type="int" setter="" getter="" default="1"> + </member> + <member name="rendering/quality/2d_sdf/scale" type="int" setter="" getter="" default="1"> + </member> <member name="rendering/quality/2d_shadow_atlas/size" type="int" setter="" getter="" default="2048"> </member> <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml index 5932a624f2..00ad4ee934 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quat.xml @@ -218,6 +218,14 @@ <description> </description> </method> + <method name="operator -" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> <method name="operator /" qualifiers="operator"> <return type="Quat"> </return> diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml index 664d4cadff..e41ddff368 100644 --- a/doc/classes/RDTextureFormat.xml +++ b/doc/classes/RDTextureFormat.xml @@ -37,7 +37,7 @@ </member> <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0"> </member> - <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.TextureType" default="1"> + <member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="RenderingDevice.TextureType" default="1"> </member> <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" default="0"> </member> diff --git a/doc/classes/RDUniform.xml b/doc/classes/RDUniform.xml index e5bace32af..bc8a21e985 100644 --- a/doc/classes/RDUniform.xml +++ b/doc/classes/RDUniform.xml @@ -31,7 +31,7 @@ <members> <member name="binding" type="int" setter="set_binding" getter="get_binding" default="0"> </member> - <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.UniformType" default="3"> + <member name="uniform_type" type="int" setter="set_uniform_type" getter="get_uniform_type" enum="RenderingDevice.UniformType" default="3"> </member> </members> <constants> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 77a80cb8b6..74eb6a17e5 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -537,17 +537,6 @@ Sets the shape of the occluder polygon. </description> </method> - <method name="canvas_occluder_polygon_set_shape_as_lines"> - <return type="void"> - </return> - <argument index="0" name="occluder_polygon" type="RID"> - </argument> - <argument index="1" name="shape" type="PackedVector2Array"> - </argument> - <description> - Sets the shape of the occluder polygon as lines. - </description> - </method> <method name="canvas_set_item_mirroring"> <return type="void"> </return> @@ -1625,25 +1614,6 @@ Sets a shader material's shader. </description> </method> - <method name="mesh_add_surface_from_arrays"> - <return type="void"> - </return> - <argument index="0" name="mesh" type="RID"> - </argument> - <argument index="1" name="primitive" type="int" enum="RenderingServer.PrimitiveType"> - </argument> - <argument index="2" name="arrays" type="Array"> - </argument> - <argument index="3" name="blend_shapes" type="Array" default="[ ]"> - </argument> - <argument index="4" name="lods" type="Dictionary" default="{ -}"> - </argument> - <argument index="5" name="compress_format" type="int" default="31744"> - </argument> - <description> - </description> - </method> <method name="mesh_clear"> <return type="void"> </return> @@ -1742,32 +1712,46 @@ Returns a mesh's surface's arrays for blend shapes. </description> </method> - <method name="mesh_surface_get_format_offset" qualifiers="const"> + <method name="mesh_surface_get_format_attribute_stride" qualifiers="const"> <return type="int"> </return> <argument index="0" name="format" type="int"> </argument> - <argument index="1" name="vertex_len" type="int"> + <argument index="1" name="vertex_count" type="int"> + </argument> + <description> + </description> + </method> + <method name="mesh_surface_get_format_offset" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="format" type="int"> </argument> - <argument index="2" name="index_len" type="int"> + <argument index="1" name="vertex_count" type="int"> </argument> - <argument index="3" name="array_index" type="int"> + <argument index="2" name="array_index" type="int"> </argument> <description> - Function is unused in Godot 3.x. </description> </method> - <method name="mesh_surface_get_format_stride" qualifiers="const"> + <method name="mesh_surface_get_format_skin_stride" qualifiers="const"> <return type="int"> </return> <argument index="0" name="format" type="int"> </argument> - <argument index="1" name="vertex_len" type="int"> + <argument index="1" name="vertex_count" type="int"> + </argument> + <description> + </description> + </method> + <method name="mesh_surface_get_format_vertex_stride" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="format" type="int"> </argument> - <argument index="2" name="index_len" type="int"> + <argument index="1" name="vertex_count" type="int"> </argument> <description> - Function is unused in Godot 3.x. </description> </method> <method name="mesh_surface_get_material" qualifiers="const"> @@ -3084,16 +3068,24 @@ <constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType"> Array is an UV coordinates array for the second UV coordinates. </constant> - <constant name="ARRAY_BONES" value="6" enum="ArrayType"> + <constant name="ARRAY_CUSTOM0" value="6" enum="ArrayType"> + </constant> + <constant name="ARRAY_CUSTOM1" value="7" enum="ArrayType"> + </constant> + <constant name="ARRAY_CUSTOM2" value="8" enum="ArrayType"> + </constant> + <constant name="ARRAY_CUSTOM3" value="9" enum="ArrayType"> + </constant> + <constant name="ARRAY_BONES" value="10" enum="ArrayType"> Array contains bone information. </constant> - <constant name="ARRAY_WEIGHTS" value="7" enum="ArrayType"> + <constant name="ARRAY_WEIGHTS" value="11" enum="ArrayType"> Array is weight information. </constant> - <constant name="ARRAY_INDEX" value="8" enum="ArrayType"> + <constant name="ARRAY_INDEX" value="12" enum="ArrayType"> Array is index array. </constant> - <constant name="ARRAY_MAX" value="9" enum="ArrayType"> + <constant name="ARRAY_MAX" value="13" enum="ArrayType"> Represents the size of the [enum ArrayType] enum. </constant> <constant name="ARRAY_FORMAT_VERTEX" value="1" enum="ArrayFormat"> @@ -3114,40 +3106,45 @@ <constant name="ARRAY_FORMAT_TEX_UV2" value="32" enum="ArrayFormat"> Flag used to mark an UV coordinates array for the second UV coordinates. </constant> - <constant name="ARRAY_FORMAT_BONES" value="64" enum="ArrayFormat"> + <constant name="ARRAY_FORMAT_CUSTOM0" value="64" enum="ArrayFormat"> + </constant> + <constant name="ARRAY_FORMAT_CUSTOM1" value="128" enum="ArrayFormat"> + </constant> + <constant name="ARRAY_FORMAT_CUSTOM2" value="256" enum="ArrayFormat"> + </constant> + <constant name="ARRAY_FORMAT_CUSTOM3" value="512" enum="ArrayFormat"> + </constant> + <constant name="ARRAY_FORMAT_BONES" value="1024" enum="ArrayFormat"> Flag used to mark a bone information array. </constant> - <constant name="ARRAY_FORMAT_WEIGHTS" value="128" enum="ArrayFormat"> + <constant name="ARRAY_FORMAT_WEIGHTS" value="2048" enum="ArrayFormat"> Flag used to mark a weights array. </constant> - <constant name="ARRAY_FORMAT_INDEX" value="256" enum="ArrayFormat"> + <constant name="ARRAY_FORMAT_INDEX" value="4096" enum="ArrayFormat"> Flag used to mark an index array. </constant> - <constant name="ARRAY_COMPRESS_NORMAL" value="1024" enum="ArrayFormat"> - Flag used to mark a compressed (half float) normal array. + <constant name="ARRAY_FORMAT_BLEND_SHAPE_MASK" value="2147475463" enum="ArrayFormat"> + </constant> + <constant name="ARRAY_FORMAT_CUSTOM_BASE" value="13" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_TANGENT" value="2048" enum="ArrayFormat"> - Flag used to mark a compressed (half float) tangent array. + <constant name="ARRAY_FORMAT_CUSTOM0_SHIFT" value="13" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_COLOR" value="4096" enum="ArrayFormat"> - Flag used to mark a compressed (half float) color array. + <constant name="ARRAY_FORMAT_CUSTOM1_SHIFT" value="16" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_TEX_UV" value="8192" enum="ArrayFormat"> - Flag used to mark a compressed (half float) UV coordinates array. + <constant name="ARRAY_FORMAT_CUSTOM2_SHIFT" value="19" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_TEX_UV2" value="16384" enum="ArrayFormat"> - Flag used to mark a compressed (half float) UV coordinates array for the second UV coordinates. + <constant name="ARRAY_FORMAT_CUSTOM3_SHIFT" value="22" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat"> - Flag used to mark a compressed index array. + <constant name="ARRAY_FORMAT_CUSTOM_MASK" value="7" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat"> - Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly. + <constant name="ARRAY_COMPRESS_FLAGS_BASE" value="25" enum="ArrayFormat"> </constant> - <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat"> + <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="33554432" enum="ArrayFormat"> Flag used to mark that the array contains 2D vertices. </constant> - <constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="1048576" enum="ArrayFormat"> + <constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="67108864" enum="ArrayFormat"> + </constant> + <constant name="ARRAY_FLAG_USE_8_BONE_WEIGHTS" value="134217728" enum="ArrayFormat"> </constant> <constant name="PRIMITIVE_POINTS" value="0" enum="PrimitiveType"> Primitive to draw consists of points. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 4faff95fd3..faf0d97766 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -329,9 +329,6 @@ The raw text of the label. When set, clears the tag stack and adds a raw text tag to the top of it. Does not parse BBCodes. Does not modify [member bbcode_text]. </member> - <member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0"> - Base text writing direction. - </member> <member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1"> The restricted number of characters to display in the label. If [code]-1[/code], all characters will be displayed. </member> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index 4f02cd00dd..82ffe86251 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -8,11 +8,11 @@ [codeblock] var st = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) - st.add_color(Color(1, 0, 0)) - st.add_uv(Vector2(0, 0)) - st.add_vertex(Vector3(0, 0, 0)) + st.set_color(Color(1, 0, 0)) + st.set_uv(Vector2(0, 0)) + st.set_vertex(Vector3(0, 0, 0)) [/codeblock] - The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method add_uv] or [method add_color], then the last values would be used. + The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method set_uv] or [method set_color], then the last values would be used. Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh. Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices. See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for procedural geometry generation. @@ -22,25 +22,6 @@ <link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link> </tutorials> <methods> - <method name="add_bones"> - <return type="void"> - </return> - <argument index="0" name="bones" type="PackedInt32Array"> - </argument> - <description> - Adds an array of bones for the next vertex to use. [code]bones[/code] must contain 4 integers. - </description> - </method> - <method name="add_color"> - <return type="void"> - </return> - <argument index="0" name="color" type="Color"> - </argument> - <description> - Specifies a [Color] for the next vertex to use. - [b]Note:[/b] The material must have [member BaseMaterial3D.vertex_color_use_as_albedo] enabled for the vertex color to be visible. - </description> - </method> <method name="add_index"> <return type="void"> </return> @@ -50,15 +31,6 @@ Adds an index to index array if you are using indexed vertices. Does not need to be called before adding vertices. </description> </method> - <method name="add_normal"> - <return type="void"> - </return> - <argument index="0" name="normal" type="Vector3"> - </argument> - <description> - Specifies a normal for the next vertex to use. - </description> - </method> <method name="add_smooth_group"> <return type="void"> </return> @@ -68,15 +40,6 @@ Specifies whether the current vertex (if using only vertex arrays) or current index (if also using index arrays) should use smooth normals for normal calculation. </description> </method> - <method name="add_tangent"> - <return type="void"> - </return> - <argument index="0" name="tangent" type="Plane"> - </argument> - <description> - Specifies a tangent for the next vertex to use. - </description> - </method> <method name="add_triangle_fan"> <return type="void"> </return> @@ -97,24 +60,6 @@ Requires the primitive type be set to [constant Mesh.PRIMITIVE_TRIANGLES]. </description> </method> - <method name="add_uv"> - <return type="void"> - </return> - <argument index="0" name="uv" type="Vector2"> - </argument> - <description> - Specifies a set of UV coordinates to use for the next vertex. - </description> - </method> - <method name="add_uv2"> - <return type="void"> - </return> - <argument index="0" name="uv2" type="Vector2"> - </argument> - <description> - Specifies an optional second set of UV coordinates to use for the next vertex. - </description> - </method> <method name="add_vertex"> <return type="void"> </return> @@ -124,15 +69,6 @@ Specifies the position of current vertex. Should be called after specifying other vertex properties (e.g. Color, UV). </description> </method> - <method name="add_weights"> - <return type="void"> - </return> - <argument index="0" name="weights" type="PackedFloat32Array"> - </argument> - <description> - Specifies weight values for next vertex to use. [code]weights[/code] must contain 4 values. - </description> - </method> <method name="append_from"> <return type="void"> </return> @@ -167,11 +103,11 @@ </return> <argument index="0" name="existing" type="ArrayMesh" default="null"> </argument> - <argument index="1" name="flags" type="int" default="31744"> + <argument index="1" name="flags" type="int" default="0"> </argument> <description> Returns a constructed [ArrayMesh] from current information passed in. If an existing [ArrayMesh] is passed in as an argument, will add an extra surface to the existing [ArrayMesh]. - Default flag is [constant Mesh.ARRAY_COMPRESS_DEFAULT]. See [code]ARRAY_COMPRESS_*[/code] constants in [enum Mesh.ArrayFormat] for other flags. + [b]FIXME:[/b] Document possible values for [code]flags[/code], it changed in 4.0. Likely some combinations of [enum Mesh.ArrayFormat]. </description> </method> <method name="commit_to_arrays"> @@ -229,6 +165,20 @@ Generates a tangent vector for each vertex. Requires that each vertex have UVs and normals set already. </description> </method> + <method name="get_custom_format" qualifiers="const"> + <return type="int" enum="SurfaceTool.CustomFormat"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_skin_weight_count" qualifiers="const"> + <return type="int" enum="SurfaceTool.SkinWeightCount"> + </return> + <description> + </description> + </method> <method name="index"> <return type="void"> </return> @@ -236,6 +186,45 @@ Shrinks the vertex array by creating an index array (avoids reusing vertices). </description> </method> + <method name="set_bones"> + <return type="void"> + </return> + <argument index="0" name="bones" type="PackedInt32Array"> + </argument> + <description> + Specifies an array of bones for the next vertex to use. [code]bones[/code] must contain 4 integers. + </description> + </method> + <method name="set_color"> + <return type="void"> + </return> + <argument index="0" name="color" type="Color"> + </argument> + <description> + Specifies a [Color] for the next vertex to use. + [b]Note:[/b] The material must have [member BaseMaterial3D.vertex_color_use_as_albedo] enabled for the vertex color to be visible. + </description> + </method> + <method name="set_custom"> + <return type="void"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <argument index="1" name="custom" type="Color"> + </argument> + <description> + </description> + </method> + <method name="set_custom_format"> + <return type="void"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <argument index="1" name="format" type="int" enum="SurfaceTool.CustomFormat"> + </argument> + <description> + </description> + </method> <method name="set_material"> <return type="void"> </return> @@ -245,7 +234,82 @@ Sets [Material] to be used by the [Mesh] you are constructing. </description> </method> + <method name="set_normal"> + <return type="void"> + </return> + <argument index="0" name="normal" type="Vector3"> + </argument> + <description> + Specifies a normal for the next vertex to use. + </description> + </method> + <method name="set_skin_weight_count"> + <return type="void"> + </return> + <argument index="0" name="count" type="int" enum="SurfaceTool.SkinWeightCount"> + </argument> + <description> + </description> + </method> + <method name="set_tangent"> + <return type="void"> + </return> + <argument index="0" name="tangent" type="Plane"> + </argument> + <description> + Specifies a tangent for the next vertex to use. + </description> + </method> + <method name="set_uv"> + <return type="void"> + </return> + <argument index="0" name="uv" type="Vector2"> + </argument> + <description> + Specifies a set of UV coordinates to use for the next vertex. + </description> + </method> + <method name="set_uv2"> + <return type="void"> + </return> + <argument index="0" name="uv2" type="Vector2"> + </argument> + <description> + Specifies an optional second set of UV coordinates to use for the next vertex. + </description> + </method> + <method name="set_weights"> + <return type="void"> + </return> + <argument index="0" name="weights" type="PackedFloat32Array"> + </argument> + <description> + Specifies weight values for next vertex to use. [code]weights[/code] must contain 4 values. + </description> + </method> </methods> <constants> + <constant name="CUSTOM_RGBA8_UNORM" value="0" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_RGBA8_SNORM" value="1" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_RG_HALF" value="2" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_RGBA_HALF" value="3" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_R_FLOAT" value="4" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_RG_FLOAT" value="5" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_RGB_FLOAT" value="6" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_RGBA_FLOAT" value="7" enum="CustomFormat"> + </constant> + <constant name="CUSTOM_MAX" value="8" enum="CustomFormat"> + </constant> + <constant name="SKIN_4_WEIGHTS" value="0" enum="SkinWeightCount"> + </constant> + <constant name="SKIN_8_WEIGHTS" value="1" enum="SkinWeightCount"> + </constant> </constants> </class> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 43388bb7f1..9c34c63e2f 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -1160,7 +1160,7 @@ <constant name="FEATURE_FONT_SYSTEM" value="32" enum="Feature"> TextServer supports loading system fonts. </constant> - <constant name="FEATURE_USE_SUPPORT_DATA" value="128" enum="Feature"> + <constant name="FEATURE_USE_SUPPORT_DATA" value="64" enum="Feature"> TextServer require external data file for some features. </constant> </constants> diff --git a/doc/classes/VehicleBody3D.xml b/doc/classes/VehicleBody3D.xml index 1125a1da94..90d0591949 100644 --- a/doc/classes/VehicleBody3D.xml +++ b/doc/classes/VehicleBody3D.xml @@ -26,7 +26,6 @@ <member name="steering" type="float" setter="set_steering" getter="get_steering" default="0.0"> The steering angle for the vehicle. Setting this to a non-zero value will result in the vehicle turning when it's moving. Wheels that have [member VehicleWheel3D.use_as_steering] set to [code]true[/code] will automatically be rotated. </member> - <member name="weight" type="float" setter="set_weight" getter="get_weight" override="true" default="392.0" /> </members> <constants> </constants> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 85dc5e8fd8..e2cf848f45 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -234,6 +234,10 @@ <member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0"> Sets the screen-space antialiasing method used. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. </member> + <member name="sdf_oversize" type="int" setter="set_sdf_oversize" getter="get_sdf_oversize" enum="Viewport.SDFOversize" default="1"> + </member> + <member name="sdf_scale" type="int" setter="set_sdf_scale" getter="get_sdf_scale" enum="Viewport.SDFScale" default="1"> + </member> <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2"> The subdivision amount of the first quadrant on the shadow atlas. </member> @@ -428,5 +432,23 @@ <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="3" enum="DefaultCanvasItemTextureRepeat"> Max value for [enum DefaultCanvasItemTextureRepeat] enum. </constant> + <constant name="SDF_OVERSIZE_100_PERCENT" value="0" enum="SDFOversize"> + </constant> + <constant name="SDF_OVERSIZE_120_PERCENT" value="1" enum="SDFOversize"> + </constant> + <constant name="SDF_OVERSIZE_150_PERCENT" value="2" enum="SDFOversize"> + </constant> + <constant name="SDF_OVERSIZE_200_PERCENT" value="3" enum="SDFOversize"> + </constant> + <constant name="SDF_OVERSIZE_MAX" value="4" enum="SDFOversize"> + </constant> + <constant name="SDF_SCALE_100_PERCENT" value="0" enum="SDFScale"> + </constant> + <constant name="SDF_SCALE_50_PERCENT" value="1" enum="SDFScale"> + </constant> + <constant name="SDF_SCALE_25_PERCENT" value="2" enum="SDFScale"> + </constant> + <constant name="SDF_SCALE_MAX" value="3" enum="SDFScale"> + </constant> </constants> </class> diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml index 0b57c9478f..5ed7a26b19 100644 --- a/doc/classes/XRPositionalTracker.xml +++ b/doc/classes/XRPositionalTracker.xml @@ -33,13 +33,6 @@ Returns the mesh related to a controller or anchor point if one is available. </description> </method> - <method name="get_name" qualifiers="const"> - <return type="StringName"> - </return> - <description> - Returns the controller or anchor point's name if available. - </description> - </method> <method name="get_orientation" qualifiers="const"> <return type="Basis"> </return> @@ -61,6 +54,20 @@ Returns the internal tracker ID. This uniquely identifies the tracker per tracker type and matches the ID you need to specify for nodes such as the [XRController3D] and [XRAnchor3D] nodes. </description> </method> + <method name="get_tracker_name" qualifiers="const"> + <return type="StringName"> + </return> + <description> + Returns the controller or anchor point's name, if applicable. + </description> + </method> + <method name="get_tracker_type" qualifiers="const"> + <return type="int" enum="XRServer.TrackerType"> + </return> + <description> + Returns the tracker's type, which will be one of the values from the [enum XRServer.TrackerType] enum. + </description> + </method> <method name="get_tracks_orientation" qualifiers="const"> <return type="bool"> </return> @@ -84,13 +91,6 @@ Returns the transform combining this device's orientation and position. </description> </method> - <method name="get_type" qualifiers="const"> - <return type="int" enum="XRServer.TrackerType"> - </return> - <description> - Returns the tracker's type. - </description> - </method> </methods> <members> <member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0"> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index b0d0a4bd7b..a63c509937 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -70,7 +70,7 @@ <argument index="0" name="from" type="float"> </argument> <description> - Cast a float value to an integer value, this method simply removes the number fractions, so for example [code]int(2.7)[/code] will be equals to 2, [code]int(.1)[/code] will be equals to 0 and [code]int(-2.7)[/code] will be equals to -2. + Cast a float value to an integer value, this method simply removes the number fractions (i.e. rounds [code]from[/code] towards zero), so for example [code]int(2.7)[/code] will be equals to 2, [code]int(0.1)[/code] will be equals to 0 and [code]int(-2.7)[/code] will be equals to -2. This operation is also called truncation. </description> </method> <method name="operator !=" qualifiers="operator"> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 473535ebf5..39525cecc8 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -35,10 +35,10 @@ #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" #include "scene/resources/mesh.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" -class RasterizerSceneDummy : public RasterizerScene { +class RasterizerSceneDummy : public RendererSceneRender { public: /* SHADOW ATLAS API */ @@ -179,7 +179,7 @@ public: ~RasterizerSceneDummy() {} }; -class RasterizerStorageDummy : public RasterizerStorage { +class RasterizerStorageDummy : public RendererStorage { public: /* TEXTURE API */ struct DummyTexture { @@ -383,7 +383,7 @@ public: bool material_is_animated(RID p_material) override { return false; } bool material_casts_shadows(RID p_material) override { return false; } void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {} - void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) override {} + void material_update_dependency(RID p_material, RendererSceneRender::InstanceBase *p_instance) override {} /* MESH API */ @@ -642,8 +642,8 @@ public: float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; } bool reflection_probe_renders_shadows(RID p_probe) const override { return false; } - void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) override {} - void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) override {} + void base_update_dependency(RID p_base, RendererSceneRender::InstanceBase *p_instance) override {} + void skeleton_update_dependency(RID p_base, RendererSceneRender::InstanceBase *p_instance) override {} /* DECAL API */ @@ -710,10 +710,10 @@ public: /* LIGHTMAP CAPTURE */ #if 0 struct Instantiable { - SelfList<RasterizerScene::InstanceBase>::List instance_list; + SelfList<RendererSceneRender::InstanceBase>::List instance_list; _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) override { - SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); + SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first(); while (instances) override { //instances->self()->base_changed(p_aabb, p_materials); instances = instances->next(); @@ -721,9 +721,9 @@ public: } _FORCE_INLINE_ void instance_remove_deps() override { - SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); + SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first(); while (instances) override { - SelfList<RasterizerScene::InstanceBase> *next = instances->next(); + SelfList<RendererSceneRender::InstanceBase> *next = instances->next(); //instances->self()->base_removed(); instances = next; } @@ -826,8 +826,8 @@ public: int particles_get_draw_passes(RID p_particles) const override { return 0; } RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override { return RID(); } - void particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) override {} - void particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) override {} + void particles_add_collision(RID p_particles, RendererSceneRender::InstanceBase *p_instance) override {} + void particles_remove_collision(RID p_particles, RendererSceneRender::InstanceBase *p_instance) override {} void update_particles() override {} @@ -927,7 +927,7 @@ public: String get_video_adapter_name() const override { return String(); } String get_video_adapter_vendor() const override { return String(); } - static RasterizerStorage *base_singleton; + static RendererStorage *base_singleton; void capture_timestamps_begin() override {} void capture_timestamp(const String &p_name) override {} @@ -941,7 +941,7 @@ public: ~RasterizerStorageDummy() {} }; -class RasterizerCanvasDummy : public RasterizerCanvas { +class RasterizerCanvasDummy : public RendererCanvasRender { public: PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override { return 0; } void free_polygon(PolygonID p_polygon) override {} @@ -970,7 +970,7 @@ public: ~RasterizerCanvasDummy() {} }; -class RasterizerDummy : public Rasterizer { +class RasterizerDummy : public RendererCompositor { private: uint64_t frame = 1; float delta = 0; @@ -981,9 +981,9 @@ protected: RasterizerSceneDummy scene; public: - RasterizerStorage *get_storage() override { return &storage; } - RasterizerCanvas *get_canvas() override { return &canvas; } - RasterizerScene *get_scene() override { return &scene; } + RendererStorage *get_storage() override { return &storage; } + RendererCanvasRender *get_canvas() override { return &canvas; } + RendererSceneRender *get_scene() override { return &scene; } void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override {} @@ -1004,7 +1004,7 @@ public: void finalize() override {} - static Rasterizer *_create_current() { + static RendererCompositor *_create_current() { return memnew(RasterizerDummy); } diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 23e6b3bfb6..f857315e90 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -615,6 +615,7 @@ int RenderingDeviceVulkan::get_format_vertex_size(DataFormat p_format) { case DATA_FORMAT_B8G8R8A8_SNORM: case DATA_FORMAT_B8G8R8A8_UINT: case DATA_FORMAT_B8G8R8A8_SINT: + case DATA_FORMAT_A2B10G10R10_UNORM_PACK32: return 4; case DATA_FORMAT_R16_UNORM: case DATA_FORMAT_R16_SNORM: @@ -1691,16 +1692,16 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T #endif } - if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) { + if (p_format.texture_type == TEXTURE_TYPE_CUBE || p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY) { image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; } /*if (p_format.type == TEXTURE_TYPE_2D || p_format.type == TEXTURE_TYPE_2D_ARRAY) { image_create_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; }*/ - ERR_FAIL_INDEX_V(p_format.type, TEXTURE_TYPE_MAX, RID()); + ERR_FAIL_INDEX_V(p_format.texture_type, TEXTURE_TYPE_MAX, RID()); - image_create_info.imageType = vulkan_image_type[p_format.type]; + image_create_info.imageType = vulkan_image_type[p_format.texture_type]; ERR_FAIL_COND_V_MSG(p_format.width < 1, RID(), "Width must be equal or greater than 1 for all textures"); @@ -1725,10 +1726,10 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T image_create_info.mipLevels = p_format.mipmaps; - if (p_format.type == TEXTURE_TYPE_1D_ARRAY || p_format.type == TEXTURE_TYPE_2D_ARRAY || p_format.type == TEXTURE_TYPE_CUBE_ARRAY || p_format.type == TEXTURE_TYPE_CUBE) { + if (p_format.texture_type == TEXTURE_TYPE_1D_ARRAY || p_format.texture_type == TEXTURE_TYPE_2D_ARRAY || p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY || p_format.texture_type == TEXTURE_TYPE_CUBE) { ERR_FAIL_COND_V_MSG(p_format.array_layers < 1, RID(), "Amount of layers must be equal or greater than 1 for arrays and cubemaps."); - ERR_FAIL_COND_V_MSG((p_format.type == TEXTURE_TYPE_CUBE_ARRAY || p_format.type == TEXTURE_TYPE_CUBE) && (p_format.array_layers % 6) != 0, RID(), + ERR_FAIL_COND_V_MSG((p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY || p_format.texture_type == TEXTURE_TYPE_CUBE) && (p_format.array_layers % 6) != 0, RID(), "Cubemap and cubemap array textures must provide a layer number that is multiple of 6"); image_create_info.arrayLayers = p_format.array_layers; } else { @@ -1858,7 +1859,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T VkResult err = vmaCreateImage(allocator, &image_create_info, &allocInfo, &texture.image, &texture.allocation, &texture.allocation_info); ERR_FAIL_COND_V_MSG(err, RID(), "vmaCreateImage failed with error " + itos(err) + "."); - texture.type = p_format.type; + texture.type = p_format.texture_type; texture.format = p_format.format; texture.width = image_create_info.extent.width; texture.height = image_create_info.extent.height; @@ -1926,7 +1927,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, }; - image_view_create_info.viewType = view_types[p_format.type]; + image_view_create_info.viewType = view_types[p_format.texture_type]; if (p_view.format_override == DATA_FORMAT_MAX) { image_view_create_info.format = image_create_info.format; } else { @@ -3528,7 +3529,7 @@ RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(cons ERR_FAIL_COND_V(used_locations.has(p_vertex_formats[i].location), INVALID_ID); ERR_FAIL_COND_V_MSG(get_format_vertex_size(p_vertex_formats[i].format) == 0, INVALID_ID, - "Data format for attachment (" + itos(i) + ") is not valid for a vertex array."); + "Data format for attachment (" + itos(i) + "), '" + named_formats[p_vertex_formats[i].format] + "', is not valid for a vertex array."); vdcache.bindings[i].binding = i; vdcache.bindings[i].stride = p_vertex_formats[i].stride; @@ -4611,8 +4612,8 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, const Uniform &uniform = uniforms[uniform_idx]; - ERR_FAIL_COND_V_MSG(uniform.type != set_uniform.type, RID(), - "Mismatch uniform type for binding (" + itos(set_uniform.binding) + "), set (" + itos(p_shader_set) + "). Expected '" + shader_uniform_names[set_uniform.type] + "', supplied: '" + shader_uniform_names[uniform.type] + "'."); + ERR_FAIL_COND_V_MSG(uniform.uniform_type != set_uniform.type, RID(), + "Mismatch uniform type for binding (" + itos(set_uniform.binding) + "), set (" + itos(p_shader_set) + "). Expected '" + shader_uniform_names[set_uniform.type] + "', supplied: '" + shader_uniform_names[uniform.uniform_type] + "'."); VkWriteDescriptorSet write; //common header write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -4627,7 +4628,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, write.pTexelBufferView = nullptr; uint32_t type_size = 1; - switch (uniform.type) { + switch (uniform.uniform_type) { case UNIFORM_TYPE_SAMPLER: { if (uniform.ids.size() != set_uniform.length) { if (set_uniform.length > 1) { diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 22adf4f267..25ff7f884a 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -507,14 +507,14 @@ Ref<Animation> AnimationBezierTrackEdit::get_animation() const { void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track) { animation = p_animation; track = p_track; - if (is_connected_compat("select_key", editor, "_key_selected")) { - disconnect_compat("select_key", editor, "_key_selected"); + if (is_connected("select_key", Callable(editor, "_key_selected"))) { + disconnect("select_key", Callable(editor, "_key_selected")); } - if (is_connected_compat("deselect_key", editor, "_key_deselected")) { - disconnect_compat("deselect_key", editor, "_key_deselected"); + if (is_connected("deselect_key", Callable(editor, "_key_deselected"))) { + disconnect("deselect_key", Callable(editor, "_key_deselected")); } - connect_compat("select_key", editor, "_key_selected", varray(p_track), CONNECT_DEFERRED); - connect_compat("deselect_key", editor, "_key_deselected", varray(p_track), CONNECT_DEFERRED); + connect("select_key", Callable(editor, "_key_selected"), varray(p_track), CONNECT_DEFERRED); + connect("deselect_key", Callable(editor, "_key_deselected"), varray(p_track), CONNECT_DEFERRED); update(); } @@ -533,7 +533,7 @@ void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) { editor = p_editor; - connect_compat("clear_selection", editor, "_clear_selection", varray(false)); + connect("clear_selection", Callable(editor, "_clear_selection"), varray(false)); } void AnimationBezierTrackEdit::_play_position_draw() { diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 823fd7e852..556b5717b3 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -873,7 +873,7 @@ Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptCodeCompletionOp tex = get_theme_icon("MemberMethod", "EditorIcons"); break; case ScriptCodeCompletionOption::KIND_PLAIN_TEXT: - tex = get_theme_icon("CubeMesh", "EditorIcons"); + tex = get_theme_icon("BoxMesh", "EditorIcons"); break; default: tex = get_theme_icon("String", "EditorIcons"); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index a04065a463..2630589912 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -31,6 +31,7 @@ #include "connections_dialog.h" #include "core/string/print_string.h" +#include "editor/doc_tools.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" @@ -998,7 +999,7 @@ void ConnectionsDock::update_tree() { } if (!found) { - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(base); while (F && descr == String()) { for (int i = 0; i < F->get().signals.size(); i++) { diff --git a/editor/doc_data.cpp b/editor/doc_tools.cpp index 165a5c8546..5ee9abb183 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_tools.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* doc_data.cpp */ +/* doc_tools.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "doc_data.h" +#include "doc_tools.h" #include "core/config/engine.h" #include "core/config/project_settings.h" @@ -43,22 +43,22 @@ // Used for a hack preserving Mono properties on non-Mono builds. #include "modules/modules_enabled.gen.h" -void DocData::merge_from(const DocData &p_data) { - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - ClassDoc &c = E->get(); +void DocTools::merge_from(const DocTools &p_data) { + for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { + DocData::ClassDoc &c = E->get(); if (!p_data.class_list.has(c.name)) { continue; } - const ClassDoc &cf = p_data.class_list[c.name]; + const DocData::ClassDoc &cf = p_data.class_list[c.name]; c.description = cf.description; c.brief_description = cf.brief_description; c.tutorials = cf.tutorials; for (int i = 0; i < c.methods.size(); i++) { - MethodDoc &m = c.methods.write[i]; + DocData::MethodDoc &m = c.methods.write[i]; for (int j = 0; j < cf.methods.size(); j++) { if (cf.methods[j].name != m.name) { @@ -95,7 +95,7 @@ void DocData::merge_from(const DocData &p_data) { continue; } - const MethodDoc &mf = cf.methods[j]; + const DocData::MethodDoc &mf = cf.methods[j]; m.description = mf.description; break; @@ -103,13 +103,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.signals.size(); i++) { - MethodDoc &m = c.signals.write[i]; + DocData::MethodDoc &m = c.signals.write[i]; for (int j = 0; j < cf.signals.size(); j++) { if (cf.signals[j].name != m.name) { continue; } - const MethodDoc &mf = cf.signals[j]; + const DocData::MethodDoc &mf = cf.signals[j]; m.description = mf.description; break; @@ -117,13 +117,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.constants.size(); i++) { - ConstantDoc &m = c.constants.write[i]; + DocData::ConstantDoc &m = c.constants.write[i]; for (int j = 0; j < cf.constants.size(); j++) { if (cf.constants[j].name != m.name) { continue; } - const ConstantDoc &mf = cf.constants[j]; + const DocData::ConstantDoc &mf = cf.constants[j]; m.description = mf.description; break; @@ -131,13 +131,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.properties.size(); i++) { - PropertyDoc &p = c.properties.write[i]; + DocData::PropertyDoc &p = c.properties.write[i]; for (int j = 0; j < cf.properties.size(); j++) { if (cf.properties[j].name != p.name) { continue; } - const PropertyDoc &pf = cf.properties[j]; + const DocData::PropertyDoc &pf = cf.properties[j]; p.description = pf.description; break; @@ -145,13 +145,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.theme_properties.size(); i++) { - PropertyDoc &p = c.theme_properties.write[i]; + DocData::PropertyDoc &p = c.theme_properties.write[i]; for (int j = 0; j < cf.theme_properties.size(); j++) { if (cf.theme_properties[j].name != p.name) { continue; } - const PropertyDoc &pf = cf.theme_properties[j]; + const DocData::PropertyDoc &pf = cf.theme_properties[j]; p.description = pf.description; break; @@ -177,57 +177,29 @@ void DocData::merge_from(const DocData &p_data) { } } -void DocData::remove_from(const DocData &p_data) { - for (Map<String, ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { +void DocTools::remove_from(const DocTools &p_data) { + for (Map<String, DocData::ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { if (class_list.has(E->key())) { class_list.erase(E->key()); } } } -static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) { - if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { - p_method.return_enum = p_retinfo.class_name; - if (p_method.return_enum.begins_with("_")) { //proxy class - p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length()); - } - p_method.return_type = "int"; - } else if (p_retinfo.class_name != StringName()) { - p_method.return_type = p_retinfo.class_name; - } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { - p_method.return_type = p_retinfo.hint_string + "[]"; - } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - p_method.return_type = p_retinfo.hint_string; - } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { - p_method.return_type = "Variant"; - } else if (p_retinfo.type == Variant::NIL) { - p_method.return_type = "void"; - } else { - p_method.return_type = Variant::get_type_name(p_retinfo.type); - } +void DocTools::add_doc(const DocData::ClassDoc &p_class_doc) { + ERR_FAIL_COND(p_class_doc.name == ""); + class_list[p_class_doc.name] = p_class_doc; } -static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) { - p_argument.name = p_arginfo.name; +void DocTools::remove_doc(const String &p_class_name) { + ERR_FAIL_COND(p_class_name == "" || !class_list.has(p_class_name)); + class_list.erase(p_class_name); +} - if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { - p_argument.enumeration = p_arginfo.class_name; - if (p_argument.enumeration.begins_with("_")) { //proxy class - p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length()); - } - p_argument.type = "int"; - } else if (p_arginfo.class_name != StringName()) { - p_argument.type = p_arginfo.class_name; - } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { - p_argument.type = p_arginfo.hint_string + "[]"; - } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - p_argument.type = p_arginfo.hint_string; - } else if (p_arginfo.type == Variant::NIL) { - // Parameters cannot be void, so PROPERTY_USAGE_NIL_IS_VARIANT is not necessary - p_argument.type = "Variant"; - } else { - p_argument.type = Variant::get_type_name(p_arginfo.type); +bool DocTools::has_doc(const String &p_class_name) { + if (p_class_name == "") { + return false; } + return class_list.has(p_class_name); } static Variant get_documentation_default_value(const StringName &p_class_name, const StringName &p_property_name, bool &r_default_value_valid) { @@ -253,7 +225,7 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c return default_value; } -void DocData::generate(bool p_basic_types) { +void DocTools::generate(bool p_basic_types) { List<StringName> classes; ClassDB::get_class_list(&classes); classes.sort_custom<StringName::AlphCompare>(); @@ -277,8 +249,8 @@ void DocData::generate(bool p_basic_types) { cname = cname.substr(1, name.length()); } - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; c.inherits = ClassDB::get_parent_class(name); @@ -305,7 +277,7 @@ void DocData::generate(bool p_basic_types) { continue; } - PropertyDoc prop; + DocData::PropertyDoc prop; prop.name = E->get().name; @@ -409,7 +381,7 @@ void DocData::generate(bool p_basic_types) { } } - MethodDoc method; + DocData::MethodDoc method; method.name = E->get().name; @@ -432,12 +404,12 @@ void DocData::generate(bool p_basic_types) { for (int i = -1; i < E->get().arguments.size(); i++) { if (i == -1) { #ifdef DEBUG_METHODS_ENABLED - return_doc_from_retinfo(method, E->get().return_val); + DocData::return_doc_from_retinfo(method, E->get().return_val); #endif } else { const PropertyInfo &arginfo = E->get().arguments[i]; - ArgumentDoc argument; - argument_doc_from_arginfo(argument, arginfo); + DocData::ArgumentDoc argument; + DocData::argument_doc_from_arginfo(argument, arginfo); int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size()); if (darg_idx >= 0) { @@ -457,12 +429,12 @@ void DocData::generate(bool p_basic_types) { if (signal_list.size()) { for (List<MethodInfo>::Element *EV = signal_list.front(); EV; EV = EV->next()) { - MethodDoc signal; + DocData::MethodDoc signal; signal.name = EV->get().name; for (int i = 0; i < EV->get().arguments.size(); i++) { const PropertyInfo &arginfo = EV->get().arguments[i]; - ArgumentDoc argument; - argument_doc_from_arginfo(argument, arginfo); + DocData::ArgumentDoc argument; + DocData::argument_doc_from_arginfo(argument, arginfo); signal.arguments.push_back(argument); } @@ -475,7 +447,7 @@ void DocData::generate(bool p_basic_types) { ClassDB::get_integer_constant_list(name, &constant_list, true); for (List<String>::Element *E = constant_list.front(); E; E = E->next()) { - ConstantDoc constant; + DocData::ConstantDoc constant; constant.name = E->get(); constant.value = itos(ClassDB::get_integer_constant(name, E->get())); constant.is_value_valid = true; @@ -489,7 +461,7 @@ void DocData::generate(bool p_basic_types) { List<StringName> l; Theme::get_default()->get_constant_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "int"; pd.default_value = itos(Theme::get_default()->get_constant(E->get(), cname)); @@ -499,7 +471,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_color_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Color"; pd.default_value = Variant(Theme::get_default()->get_color(E->get(), cname)).get_construct_string(); @@ -509,7 +481,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_icon_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Texture2D"; c.theme_properties.push_back(pd); @@ -517,7 +489,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_font_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Font"; c.theme_properties.push_back(pd); @@ -525,7 +497,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_font_size_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "int"; c.theme_properties.push_back(pd); @@ -533,7 +505,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_stylebox_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "StyleBox"; c.theme_properties.push_back(pd); @@ -545,7 +517,7 @@ void DocData::generate(bool p_basic_types) { { // So we can document the concept of Variant even if it's not a usable class per se. - class_list["Variant"] = ClassDoc(); + class_list["Variant"] = DocData::ClassDoc(); class_list["Variant"].name = "Variant"; } @@ -564,8 +536,8 @@ void DocData::generate(bool p_basic_types) { String cname = Variant::get_type_name(Variant::Type(i)); - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; Callable::CallError cerror; @@ -642,7 +614,7 @@ void DocData::generate(bool p_basic_types) { for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { MethodInfo &mi = E->get(); - MethodDoc method; + DocData::MethodDoc method; method.name = mi.name; if (method.name == cname) { @@ -653,8 +625,8 @@ void DocData::generate(bool p_basic_types) { for (int j = 0; j < mi.arguments.size(); j++) { PropertyInfo arginfo = mi.arguments[j]; - ArgumentDoc ad; - argument_doc_from_arginfo(ad, mi.arguments[j]); + DocData::ArgumentDoc ad; + DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); ad.name = arginfo.name; int darg_idx = mi.default_arguments.size() - mi.arguments.size() + j; @@ -666,7 +638,7 @@ void DocData::generate(bool p_basic_types) { method.arguments.push_back(ad); } - return_doc_from_retinfo(method, mi.return_val); + DocData::return_doc_from_retinfo(method, mi.return_val); if (mi.flags & METHOD_FLAG_VARARG) { if (method.qualifiers != "") { @@ -682,7 +654,7 @@ void DocData::generate(bool p_basic_types) { v.get_property_list(&properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { PropertyInfo pi = E->get(); - PropertyDoc property; + DocData::PropertyDoc property; property.name = pi.name; property.type = Variant::get_type_name(pi.type); property.default_value = v.get(pi.name).get_construct_string(); @@ -694,7 +666,7 @@ void DocData::generate(bool p_basic_types) { Variant::get_constants_for_type(Variant::Type(i), &constants); for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { - ConstantDoc constant; + DocData::ConstantDoc constant; constant.name = E->get(); Variant value = Variant::get_constant_value(Variant::Type(i), E->get()); constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string(); @@ -707,12 +679,12 @@ void DocData::generate(bool p_basic_types) { { String cname = "@GlobalScope"; - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { - ConstantDoc cd; + DocData::ConstantDoc cd; cd.name = CoreConstants::get_global_constant_name(i); if (!CoreConstants::get_ignore_value_in_docs(i)) { cd.value = itos(CoreConstants::get_global_constant_value(i)); @@ -729,7 +701,7 @@ void DocData::generate(bool p_basic_types) { //servers (this is kind of hackish) for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; Engine::Singleton &s = E->get(); if (!s.ptr) { continue; @@ -749,7 +721,7 @@ void DocData::generate(bool p_basic_types) { Variant::get_utility_function_list(&utility_functions); utility_functions.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { - MethodDoc md; + DocData::MethodDoc md; md.name = E->get(); //return if (Variant::has_utility_function_return_value(E->get())) { @@ -759,7 +731,7 @@ void DocData::generate(bool p_basic_types) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } DocData::ArgumentDoc ad; - argument_doc_from_arginfo(ad, pi); + DocData::argument_doc_from_arginfo(ad, pi); md.return_type = ad.type; } @@ -774,7 +746,7 @@ void DocData::generate(bool p_basic_types) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } DocData::ArgumentDoc ad; - argument_doc_from_arginfo(ad, pi); + DocData::argument_doc_from_arginfo(ad, pi); md.arguments.push_back(ad); } } @@ -791,7 +763,7 @@ void DocData::generate(bool p_basic_types) { for (int i = 0; i < ScriptServer::get_language_count(); i++) { ScriptLanguage *lang = ScriptServer::get_language(i); String cname = "@" + lang->get_name(); - ClassDoc c; + DocData::ClassDoc c; c.name = cname; // Get functions. @@ -800,7 +772,7 @@ void DocData::generate(bool p_basic_types) { for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) { MethodInfo &mi = E->get(); - MethodDoc md; + DocData::MethodDoc md; md.name = mi.name; if (mi.flags & METHOD_FLAG_VARARG) { @@ -810,11 +782,11 @@ void DocData::generate(bool p_basic_types) { md.qualifiers += "vararg"; } - return_doc_from_retinfo(md, mi.return_val); + DocData::return_doc_from_retinfo(md, mi.return_val); for (int j = 0; j < mi.arguments.size(); j++) { - ArgumentDoc ad; - argument_doc_from_arginfo(ad, mi.arguments[j]); + DocData::ArgumentDoc ad; + DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); int darg_idx = j - (mi.arguments.size() - mi.default_arguments.size()); if (darg_idx >= 0) { @@ -833,7 +805,7 @@ void DocData::generate(bool p_basic_types) { lang->get_public_constants(&cinfo); for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) { - ConstantDoc cd; + DocData::ConstantDoc cd; cd.name = E->get().first; cd.value = E->get().second; cd.is_value_valid = true; @@ -911,7 +883,7 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & return OK; } -Error DocData::load_classes(const String &p_dir) { +Error DocTools::load_classes(const String &p_dir) { Error err; DirAccessRef da = DirAccess::open(p_dir, &err); if (!da) { @@ -939,7 +911,7 @@ Error DocData::load_classes(const String &p_dir) { return OK; } -Error DocData::erase_classes(const String &p_dir) { +Error DocTools::erase_classes(const String &p_dir) { Error err; DirAccessRef da = DirAccess::open(p_dir, &err); if (!da) { @@ -967,7 +939,7 @@ Error DocData::erase_classes(const String &p_dir) { return OK; } -Error DocData::_load(Ref<XMLParser> parser) { +Error DocTools::_load(Ref<XMLParser> parser) { Error err = OK; while ((err = parser->read()) == OK) { @@ -983,8 +955,8 @@ Error DocData::_load(Ref<XMLParser> parser) { ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); String name = parser->get_attribute_value("name"); - class_list[name] = ClassDoc(); - ClassDoc &c = class_list[name]; + class_list[name] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[name]; c.name = name; if (parser->has_attribute("inherits")) { @@ -1012,7 +984,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "link") { - TutorialDoc tutorial; + DocData::TutorialDoc tutorial; if (parser->has_attribute("title")) { tutorial.title = parser->get_attribute_value("title"); } @@ -1041,7 +1013,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "member") { - PropertyDoc prop2; + DocData::PropertyDoc prop2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); prop2.name = parser->get_attribute_value("name"); @@ -1078,7 +1050,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "theme_item") { - PropertyDoc prop2; + DocData::PropertyDoc prop2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); prop2.name = parser->get_attribute_value("name"); @@ -1106,7 +1078,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "constant") { - ConstantDoc constant2; + DocData::ConstantDoc constant2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); constant2.name = parser->get_attribute_value("name"); ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT); @@ -1155,9 +1127,9 @@ static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) f->store_string(tab + p_string + "\n"); } -Error DocData::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - ClassDoc &c = E->get(); +Error DocTools::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { + for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { + DocData::ClassDoc &c = E->get(); String save_path; if (p_class_path.has(c.name)) { @@ -1192,7 +1164,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<tutorials>"); for (int i = 0; i < c.tutorials.size(); i++) { - TutorialDoc tutorial = c.tutorials.get(i); + DocData::TutorialDoc tutorial = c.tutorials.get(i); String title_attribute = (!tutorial.title.empty()) ? " title=\"" + tutorial.title.xml_escape() + "\"" : ""; _write_string(f, 2, "<link" + title_attribute + ">" + tutorial.link.xml_escape() + "</link>"); } @@ -1203,7 +1175,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri c.methods.sort(); for (int i = 0; i < c.methods.size(); i++) { - const MethodDoc &m = c.methods[i]; + const DocData::MethodDoc &m = c.methods[i]; String qualifiers; if (m.qualifiers != "") { @@ -1222,7 +1194,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri } for (int j = 0; j < m.arguments.size(); j++) { - const ArgumentDoc &a = m.arguments[j]; + const DocData::ArgumentDoc &a = m.arguments[j]; String enum_text; if (a.enumeration != String()) { @@ -1261,7 +1233,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\""; } - const PropertyDoc &p = c.properties[i]; + const DocData::PropertyDoc &p = c.properties[i]; if (c.properties[i].overridden) { _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" override=\"true\"" + additional_attributes + " />"); @@ -1279,10 +1251,10 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<signals>"); for (int i = 0; i < c.signals.size(); i++) { - const MethodDoc &m = c.signals[i]; + const DocData::MethodDoc &m = c.signals[i]; _write_string(f, 2, "<signal name=\"" + m.name + "\">"); for (int j = 0; j < m.arguments.size(); j++) { - const ArgumentDoc &a = m.arguments[j]; + const DocData::ArgumentDoc &a = m.arguments[j]; _write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">"); _write_string(f, 3, "</argument>"); } @@ -1300,7 +1272,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<constants>"); for (int i = 0; i < c.constants.size(); i++) { - const ConstantDoc &k = c.constants[i]; + const DocData::ConstantDoc &k = c.constants[i]; if (k.is_value_valid) { if (k.enumeration != String()) { _write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">"); @@ -1325,7 +1297,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<theme_items>"); for (int i = 0; i < c.theme_properties.size(); i++) { - const PropertyDoc &p = c.theme_properties[i]; + const DocData::PropertyDoc &p = c.theme_properties[i]; if (p.default_value != "") { _write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\" default=\"" + p.default_value.xml_escape(true) + "\">"); @@ -1346,7 +1318,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri return OK; } -Error DocData::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { +Error DocTools::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { Vector<uint8_t> data; data.resize(p_uncompressed_size); Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE); diff --git a/editor/doc_tools.h b/editor/doc_tools.h new file mode 100644 index 0000000000..db27e38c8b --- /dev/null +++ b/editor/doc_tools.h @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* doc_tools.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef DOC_TOOLS_H +#define DOC_TOOLS_H + +#include "core/doc_data.h" + +class DocTools { +public: + String version; + Map<String, DocData::ClassDoc> class_list; + + static Error erase_classes(const String &p_dir); + + void merge_from(const DocTools &p_data); + void remove_from(const DocTools &p_data); + void add_doc(const DocData::ClassDoc &p_class_doc); + void remove_doc(const String &p_class_name); + bool has_doc(const String &p_class_name); + void generate(bool p_basic_types = false); + Error load_classes(const String &p_dir); + Error save_classes(const String &p_default_path, const Map<String, String> &p_class_path); + + Error _load(Ref<XMLParser> parser); + Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size); +}; + +#endif // DOC_DATA_H diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index c66bc9b3fa..738b88a86b 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -357,10 +357,12 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo List<String> to_check; + String importer_name; String source_file = ""; String source_md5 = ""; Vector<String> dest_files; String dest_md5 = ""; + int version = 0; while (true) { assign = Variant(); @@ -384,6 +386,10 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo for (int i = 0; i < fa.size(); i++) { to_check.push_back(fa[i]); } + } else if (assign == "importer_version") { + version = value; + } else if (assign == "importer") { + importer_name = value; } else if (!p_only_imported_files) { if (assign == "source_file") { source_file = value; @@ -399,6 +405,12 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo memdelete(f); + Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name); + + if (importer->get_format_version() > version) { + return true; // version changed, reimport + } + // Read the md5's from a separate file (so the import parameters aren't dependent on the file version String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_path); FileAccess *md5s = FileAccess::open(base_path + ".md5", FileAccess::READ, &err); @@ -799,6 +811,20 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } } + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptLanguage *lang = ScriptServer::get_language(i); + if (lang->supports_documentation() && fi->type == lang->get_type()) { + Ref<Script> script = ResourceLoader::load(path); + if (script == nullptr) { + continue; + } + const Vector<DocData::ClassDoc> &docs = script->get_documentation(); + for (int j = 0; j < docs.size(); j++) { + EditorHelp::get_doc_data()->add_doc(docs[j]); + } + } + } + p_dir->files.push_back(fi); p_progress.update(idx, total); } @@ -1562,6 +1588,10 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector f->store_line("[remap]"); f->store_line(""); f->store_line("importer=\"" + importer->get_importer_name() + "\""); + int version = importer->get_format_version(); + if (version > 0) { + f->store_line("importer_version=" + itos(importer->get_format_version())); + } if (importer->get_resource_type() != "") { f->store_line("type=\"" + importer->get_resource_type() + "\""); } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 2c49782fd2..4c553950a7 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -40,7 +40,7 @@ #define CONTRIBUTE_URL "https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html" -DocData *EditorHelp::doc = nullptr; +DocTools *EditorHelp::doc = nullptr; void EditorHelp::_init_colors() { title_color = get_theme_color("accent_color", "Editor"); @@ -388,7 +388,7 @@ void EditorHelp::_update_doc() { } // Descendents - if (ClassDB::class_exists(cd.name)) { + if (cd.is_script_doc || ClassDB::class_exists(cd.name)) { bool found = false; bool prev = false; @@ -494,7 +494,19 @@ void EditorHelp::_update_doc() { Set<String> skip_methods; bool property_descr = false; - if (cd.properties.size()) { + bool has_properties = cd.properties.size() != 0; + if (cd.is_script_doc) { + has_properties = false; + for (int i = 0; i < cd.properties.size(); i++) { + if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.empty()) { + continue; + } + has_properties = true; + break; + } + } + + if (has_properties) { section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); @@ -509,6 +521,10 @@ void EditorHelp::_update_doc() { class_desc->set_table_column_expand(1, true); for (int i = 0; i < cd.properties.size(); i++) { + // Ignore undocumented private. + if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.empty()) { + continue; + } property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description class_desc->push_cell(); @@ -565,6 +581,32 @@ void EditorHelp::_update_doc() { class_desc->pop(); } + if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) { + class_desc->push_color(symbol_color); + class_desc->add_text(" [" + TTR("property:") + " "); + class_desc->pop(); // color + + if (cd.properties[i].setter != "") { + class_desc->push_color(value_color); + class_desc->add_text("setter"); + class_desc->pop(); // color + } + if (cd.properties[i].getter != "") { + if (cd.properties[i].setter != "") { + class_desc->push_color(symbol_color); + class_desc->add_text(", "); + class_desc->pop(); // color + } + class_desc->push_color(value_color); + class_desc->add_text("getter"); + class_desc->pop(); // color + } + + class_desc->push_color(symbol_color); + class_desc->add_text("]"); + class_desc->pop(); // color + } + class_desc->pop(); class_desc->pop(); @@ -590,6 +632,10 @@ void EditorHelp::_update_doc() { continue; } } + // Ignore undocumented private. + if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.empty()) { + continue; + } methods.push_back(cd.methods[i]); } @@ -802,13 +848,17 @@ void EditorHelp::_update_doc() { Vector<DocData::ConstantDoc> constants; for (int i = 0; i < cd.constants.size(); i++) { - if (cd.constants[i].enumeration != String()) { + if (!cd.constants[i].enumeration.empty()) { if (!enums.has(cd.constants[i].enumeration)) { enums[cd.constants[i].enumeration] = Vector<DocData::ConstantDoc>(); } enums[cd.constants[i].enumeration].push_back(cd.constants[i]); } else { + // Ignore undocumented private. + if (cd.constants[i].name.begins_with("_") && cd.constants[i].description.empty()) { + continue; + } constants.push_back(cd.constants[i]); } } @@ -848,6 +898,19 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); class_desc->add_newline(); + // Enum description. + if (e != "@unnamed_enums" && cd.enums.has(e)) { + class_desc->push_color(text_color); + class_desc->push_font(doc_font); + class_desc->push_indent(1); + _add_text(cd.enums[e]); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + } + class_desc->push_indent(1); Vector<DocData::ConstantDoc> enum_list = E->get(); @@ -1018,60 +1081,89 @@ void EditorHelp::_update_doc() { class_desc->pop(); // color } + if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) { + class_desc->push_color(symbol_color); + class_desc->add_text(" [" + TTR("property:") + " "); + class_desc->pop(); // color + + if (cd.properties[i].setter != "") { + class_desc->push_color(value_color); + class_desc->add_text("setter"); + class_desc->pop(); // color + } + if (cd.properties[i].getter != "") { + if (cd.properties[i].setter != "") { + class_desc->push_color(symbol_color); + class_desc->add_text(", "); + class_desc->pop(); // color + } + class_desc->push_color(value_color); + class_desc->add_text("getter"); + class_desc->pop(); // color + } + + class_desc->push_color(symbol_color); + class_desc->add_text("]"); + class_desc->pop(); // color + } + class_desc->pop(); // font class_desc->pop(); // cell - Map<String, DocData::MethodDoc> method_map; - for (int j = 0; j < methods.size(); j++) { - method_map[methods[j].name] = methods[j]; - } + // Script doc doesn't have setter, getter. + if (!cd.is_script_doc) { + Map<String, DocData::MethodDoc> method_map; + for (int j = 0; j < methods.size(); j++) { + method_map[methods[j].name] = methods[j]; + } - if (cd.properties[i].setter != "") { - class_desc->push_cell(); - class_desc->pop(); // cell + if (cd.properties[i].setter != "") { + class_desc->push_cell(); + class_desc->pop(); // cell - class_desc->push_cell(); - class_desc->push_font(doc_code_font); - class_desc->push_color(text_color); - if (method_map[cd.properties[i].setter].arguments.size() > 1) { - // Setters with additional arguments are exposed in the method list, so we link them here for quick access. - class_desc->push_meta("@method " + cd.properties[i].setter); - class_desc->add_text(cd.properties[i].setter + TTR("(value)")); - class_desc->pop(); - } else { - class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + class_desc->push_color(text_color); + if (method_map[cd.properties[i].setter].arguments.size() > 1) { + // Setters with additional arguments are exposed in the method list, so we link them here for quick access. + class_desc->push_meta("@method " + cd.properties[i].setter); + class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + class_desc->pop(); + } else { + class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + } + class_desc->pop(); // color + class_desc->push_color(comment_color); + class_desc->add_text(" setter"); + class_desc->pop(); // color + class_desc->pop(); // font + class_desc->pop(); // cell + method_line[cd.properties[i].setter] = property_line[cd.properties[i].name]; } - class_desc->pop(); // color - class_desc->push_color(comment_color); - class_desc->add_text(" setter"); - class_desc->pop(); // color - class_desc->pop(); // font - class_desc->pop(); // cell - method_line[cd.properties[i].setter] = property_line[cd.properties[i].name]; - } - if (cd.properties[i].getter != "") { - class_desc->push_cell(); - class_desc->pop(); // cell + if (cd.properties[i].getter != "") { + class_desc->push_cell(); + class_desc->pop(); // cell - class_desc->push_cell(); - class_desc->push_font(doc_code_font); - class_desc->push_color(text_color); - if (method_map[cd.properties[i].getter].arguments.size() > 0) { - // Getters with additional arguments are exposed in the method list, so we link them here for quick access. - class_desc->push_meta("@method " + cd.properties[i].getter); - class_desc->add_text(cd.properties[i].getter + "()"); - class_desc->pop(); - } else { - class_desc->add_text(cd.properties[i].getter + "()"); + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + class_desc->push_color(text_color); + if (method_map[cd.properties[i].getter].arguments.size() > 0) { + // Getters with additional arguments are exposed in the method list, so we link them here for quick access. + class_desc->push_meta("@method " + cd.properties[i].getter); + class_desc->add_text(cd.properties[i].getter + "()"); + class_desc->pop(); + } else { + class_desc->add_text(cd.properties[i].getter + "()"); + } + class_desc->pop(); //color + class_desc->push_color(comment_color); + class_desc->add_text(" getter"); + class_desc->pop(); //color + class_desc->pop(); //font + class_desc->pop(); //cell + method_line[cd.properties[i].getter] = property_line[cd.properties[i].name]; } - class_desc->pop(); //color - class_desc->push_color(comment_color); - class_desc->add_text(" getter"); - class_desc->pop(); //color - class_desc->pop(); //font - class_desc->pop(); //cell - method_line[cd.properties[i].getter] = property_line[cd.properties[i].name]; } class_desc->pop(); // table @@ -1082,13 +1174,17 @@ void EditorHelp::_update_doc() { class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); - if (cd.properties[i].description.strip_edges() != String()) { + if (!cd.properties[i].description.strip_edges().empty()) { _add_text(DTR(cd.properties[i].description)); } else { class_desc->add_image(get_theme_icon("Error", "EditorIcons")); class_desc->add_text(" "); class_desc->push_color(comment_color); - class_desc->append_bbcode(TTR("There is currently no description for this property. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + if (cd.is_script_doc) { + class_desc->append_bbcode(TTR("There is currently no description for this property.")); + } else { + class_desc->append_bbcode(TTR("There is currently no description for this property. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + } class_desc->pop(); } class_desc->pop(); @@ -1133,13 +1229,17 @@ void EditorHelp::_update_doc() { class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); - if (methods_filtered[i].description.strip_edges() != String()) { + if (!methods_filtered[i].description.strip_edges().empty()) { _add_text(DTR(methods_filtered[i].description)); } else { class_desc->add_image(get_theme_icon("Error", "EditorIcons")); class_desc->add_text(" "); class_desc->push_color(comment_color); - class_desc->append_bbcode(TTR("There is currently no description for this method. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + if (cd.is_script_doc) { + class_desc->append_bbcode(TTR("There is currently no description for this method.")); + } else { + class_desc->append_bbcode(TTR("There is currently no description for this method. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + } class_desc->pop(); } @@ -1223,7 +1323,7 @@ void EditorHelp::_help_callback(const String &p_topic) { } static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); String base_path; Ref<Font> doc_font = p_rt->get_theme_font("doc", "EditorFonts"); @@ -1518,9 +1618,9 @@ void EditorHelp::_add_text(const String &p_bbcode) { } void EditorHelp::generate_doc() { - doc = memnew(DocData); + doc = memnew(DocTools); doc->generate(true); - DocData compdoc; + DocTools compdoc; compdoc.load_compressed(_doc_data_compressed, _doc_data_compressed_size, _doc_data_uncompressed_size); doc->merge_from(compdoc); //ensure all is up to date } @@ -1549,6 +1649,12 @@ void EditorHelp::go_to_class(const String &p_class, int p_scroll) { _goto_desc(p_class, p_scroll); } +void EditorHelp::update_doc() { + ERR_FAIL_COND(!doc->class_list.has(edited_class)); + ERR_FAIL_COND(!doc->class_list[edited_class].is_script_doc); + _update_doc(); +} + Vector<Pair<String, int>> EditorHelp::get_sections() { Vector<Pair<String, int>> sections; diff --git a/editor/editor_help.h b/editor/editor_help.h index cdb674cffd..737f841d30 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -32,7 +32,7 @@ #define EDITOR_HELP_H #include "editor/code_editor.h" -#include "editor/doc_data.h" +#include "editor/doc_tools.h" #include "editor/editor_plugin.h" #include "scene/gui/margin_container.h" #include "scene/gui/menu_button.h" @@ -118,7 +118,7 @@ class EditorHelp : public VBoxContainer { RichTextLabel *class_desc; HSplitContainer *h_split; - static DocData *doc; + static DocTools *doc; ConfirmationDialog *search_dialog; LineEdit *search; @@ -166,10 +166,11 @@ protected: public: static void generate_doc(); - static DocData *get_doc_data() { return doc; } + static DocTools *get_doc_data() { return doc; } void go_to_help(const String &p_help); void go_to_class(const String &p_class, int p_scroll = 0); + void update_doc(); Vector<Pair<String, int>> get_sections(); void scroll_to_section(int p_section_index); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 0c419168c0..d88a0e3ff8 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -32,6 +32,7 @@ #include "array_property_edit.h" #include "dictionary_property_edit.h" +#include "editor/doc_tools.h" #include "editor_feature_profile.h" #include "editor_node.h" #include "editor_scale.h" @@ -1708,7 +1709,7 @@ void EditorInspector::update_tree() { StringName type2 = p.name; if (!class_descr_cache.has(type2)) { String descr; - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type2); if (E) { descr = DTR(E->get().brief_description); @@ -1878,7 +1879,7 @@ void EditorInspector::update_tree() { } if (!found) { - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(classname); while (F && descr == String()) { for (int i = 0; i < F->get().properties.size(); i++) { diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index f984f48c1c..1fdba10a74 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -42,7 +42,7 @@ void EditorPluginSettings::_notification(int p_what) { if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) { update_plugins(); } else if (p_what == Node::NOTIFICATION_READY) { - plugin_config_dialog->connect_compat("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready"); + plugin_config_dialog->connect("plugin_ready", Callable(EditorNode::get_singleton(), "_on_plugin_ready")); plugin_list->connect("button_pressed", callable_mp(this, &EditorPluginSettings::_cell_button_pressed)); } } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index c65c796e5e..aa19bdf342 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2368,16 +2368,16 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str } if (p_paths.size() == 1) { - p_popup->add_icon_item(get_theme_icon("ActionCopy", "EditorIcons"), TTR("Copy Path"), FILE_COPY_PATH); + p_popup->add_icon_shortcut(get_theme_icon("ActionCopy", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/copy_path"), FILE_COPY_PATH); if (p_paths[0] != "res://") { - p_popup->add_icon_item(get_theme_icon("Rename", "EditorIcons"), TTR("Rename..."), FILE_RENAME); - p_popup->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Duplicate..."), FILE_DUPLICATE); + p_popup->add_icon_shortcut(get_theme_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/rename"), FILE_RENAME); + p_popup->add_icon_shortcut(get_theme_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/duplicate"), FILE_DUPLICATE); } } if (p_paths.size() > 1 || p_paths[0] != "res://") { p_popup->add_icon_item(get_theme_icon("MoveUp", "EditorIcons"), TTR("Move To..."), FILE_MOVE); - p_popup->add_icon_item(get_theme_icon("Remove", "EditorIcons"), TTR("Move to Trash"), FILE_REMOVE); + p_popup->add_icon_shortcut(get_theme_icon("Remove", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/delete"), FILE_REMOVE); } if (p_paths.size() == 1) { @@ -2511,7 +2511,11 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { _tree_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { _tree_rmb_option(FILE_RENAME); + } else { + return; } + + accept_event(); } } @@ -2526,7 +2530,11 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { _file_list_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { _file_list_rmb_option(FILE_RENAME); + } else { + return; } + + accept_event(); } } @@ -2682,8 +2690,8 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { // `KEY_MASK_CMD | KEY_C` conflicts with other editor shortcuts. ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_C); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KEY_MASK_CMD | KEY_D); - ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), KEY_DELETE); - ED_SHORTCUT("filesystem_dock/rename", TTR("Rename")); + ED_SHORTCUT("filesystem_dock/delete", TTR("Move to Trash"), KEY_DELETE); + ED_SHORTCUT("filesystem_dock/rename", TTR("Rename..."), KEY_F2); VBoxContainer *top_vbc = memnew(VBoxContainer); add_child(top_vbc); diff --git a/editor/icons/CubeMesh.svg b/editor/icons/BoxMesh.svg index d540858248..d540858248 100644 --- a/editor/icons/CubeMesh.svg +++ b/editor/icons/BoxMesh.svg diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 12cbaaa885..b14dff711f 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -470,9 +470,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me p_mesh->add_blend_shape(name); } if (p_morph_data->mode == "RELATIVE") { - p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_RELATIVE); + p_mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_RELATIVE); } else if (p_morph_data->mode == "NORMALIZED") { - p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); + p_mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED); } } @@ -844,19 +844,19 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me for (int k = 0; k < vertex_array.size(); k++) { if (normal_src) { - surftool->add_normal(vertex_array[k].normal); + surftool->set_normal(vertex_array[k].normal); if (binormal_src && tangent_src) { - surftool->add_tangent(vertex_array[k].tangent); + surftool->set_tangent(vertex_array[k].tangent); } } if (uv_src) { - surftool->add_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y)); + surftool->set_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y)); } if (uv2_src) { - surftool->add_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y)); + surftool->set_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y)); } if (color_src) { - surftool->add_color(vertex_array[k].color); + surftool->set_color(vertex_array[k].color); } if (has_weights) { @@ -876,8 +876,8 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me } } - surftool->add_bones(bones); - surftool->add_weights(weights); + surftool->set_bones(bones); + surftool->set_weights(weights); } surftool->add_vertex(vertex_array[k].vertex); @@ -923,7 +923,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me mr.push_back(a); } - p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), p_use_compression ? Mesh::ARRAY_COMPRESS_DEFAULT : 0); + p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), 0); if (material.is_valid()) { if (p_use_mesh_material) { diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 0c860a8965..ac76f67ef9 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -970,8 +970,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { return OK; } - bool compress_vert_data = state.import_flags & IMPORT_USE_COMPRESSION; - uint32_t mesh_flags = compress_vert_data ? Mesh::ARRAY_COMPRESS_DEFAULT : 0; + uint32_t mesh_flags = 0; Array meshes = state.json["meshes"]; for (GLTFMeshIndex i = 0; i < meshes.size(); i++) { @@ -1113,7 +1112,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { //ideally BLEND_SHAPE_MODE_RELATIVE since gltf2 stores in displacement //but it could require a larger refactor? - mesh.mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); + mesh.mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED); if (j == 0) { const Array &target_names = extras.has("targetNames") ? (Array)extras["targetNames"] : Array(); diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 49b47bf4be..d4560a2984 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -210,7 +210,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ bool generate_tangents = p_generate_tangents; Vector3 scale_mesh = p_scale_mesh; Vector3 offset_mesh = p_offset_mesh; - int mesh_flags = p_optimize ? Mesh::ARRAY_COMPRESS_DEFAULT : 0; + int mesh_flags = 0; Vector<Vector3> vertices; Vector<Vector3> normals; @@ -294,7 +294,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ norm += normals.size() + 1; } ERR_FAIL_INDEX_V(norm, normals.size(), ERR_FILE_CORRUPT); - surf_tool->add_normal(normals[norm]); + surf_tool->set_normal(normals[norm]); } if (face[idx].size() >= 2 && face[idx][1] != String()) { @@ -303,7 +303,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ uv += uvs.size() + 1; } ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_FILE_CORRUPT); - surf_tool->add_uv(uvs[uv]); + surf_tool->set_uv(uvs[uv]); } int vtx = face[idx][0].to_int() - 1; @@ -473,6 +473,10 @@ String ResourceImporterOBJ::get_resource_type() const { return "Mesh"; } +int ResourceImporterOBJ::get_format_version() const { + return 1; +} + int ResourceImporterOBJ::get_preset_count() const { return 0; } diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index 4083bc7403..97f747b33c 100644 --- a/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h @@ -54,6 +54,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const override; virtual String get_save_extension() const override; virtual String get_resource_type() const override; + virtual int get_format_version() const override; virtual int get_preset_count() const override; virtual String get_preset_name(int p_idx) const override; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 5dcdf6bec4..fc4f673ec4 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -172,6 +172,10 @@ String ResourceImporterScene::get_resource_type() const { return "PackedScene"; } +int ResourceImporterScene::get_format_version() const { + return 1; +} + bool ResourceImporterScene::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { if (p_option.begins_with("animation/")) { if (p_option != "animation/import" && !bool(p_options["animation/import"])) { diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 465d11116b..cd61ec01f2 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -133,6 +133,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const override; virtual String get_save_extension() const override; virtual String get_resource_type() const override; + virtual int get_format_version() const override; virtual int get_preset_count() const override; virtual String get_preset_name(int p_idx) const override; diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp index 5b6d850096..686fd4c08b 100644 --- a/editor/input_map_editor.cpp +++ b/editor/input_map_editor.cpp @@ -35,47 +35,6 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" -static const char *_button_descriptions[JOY_BUTTON_SDL_MAX] = { - TTRC("Bottom Action, Sony Cross, Xbox A, Nintendo B"), - TTRC("Right Action, Sony Circle, Xbox B, Nintendo A"), - TTRC("Left Action, Sony Square, Xbox X, Nintendo Y"), - TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"), - TTRC("Back, Sony Select, Xbox Back, Nintendo -"), - TTRC("Guide, Sony PS, Xbox Home"), - TTRC("Start, Nintendo +"), - TTRC("Left Stick, Sony L3, Xbox L/LS"), - TTRC("Right Stick, Sony R3, Xbox R/RS"), - TTRC("Left Shoulder, Sony L1, Xbox LB"), - TTRC("Right Shoulder, Sony R1, Xbox RB"), - TTRC("D-pad Up"), - TTRC("D-pad Down"), - TTRC("D-pad Left"), - TTRC("D-pad Right"), -}; - -static const char *_axis_descriptions[JOY_AXIS_MAX * 2] = { - TTRC("Left Stick Left, Joystick 0 Left"), - TTRC("Left Stick Right, Joystick 0 Right"), - TTRC("Left Stick Up, Joystick 0 Up"), - TTRC("Left Stick Down, Joystick 0 Down"), - TTRC("Right Stick Left, Joystick 1 Left"), - TTRC("Right Stick Right, Joystick 1 Right"), - TTRC("Right Stick Up, Joystick 1 Up"), - TTRC("Right Stick Down, Joystick 1 Down"), - TTRC("Joystick 2 Left"), - TTRC("Left Trigger, L2, LT, Joystick 2 Right"), - TTRC("Joystick 2 Up"), - TTRC("Right Trigger, R2, RT, Joystick 2 Down"), - TTRC("Joystick 3 Left"), - TTRC("Joystick 3 Right"), - TTRC("Joystick 3 Up"), - TTRC("Joystick 3 Down"), - TTRC("Joystick 4 Left"), - TTRC("Joystick 4 Right"), - TTRC("Joystick 4 Up"), - TTRC("Joystick 4 Down"), -}; - void InputMapEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -395,6 +354,42 @@ void InputMapEditor::_show_last_added(const Ref<InputEvent> &p_event, const Stri } } +// Maps to 2*axis if value is neg, or + 1 if value is pos. +static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = { + TTRC("Left Stick Left, Joystick 0 Left"), + TTRC("Left Stick Right, Joystick 0 Right"), + TTRC("Left Stick Up, Joystick 0 Up"), + TTRC("Left Stick Down, Joystick 0 Down"), + TTRC("Right Stick Left, Joystick 1 Left"), + TTRC("Right Stick Right, Joystick 1 Right"), + TTRC("Right Stick Up, Joystick 1 Up"), + TTRC("Right Stick Down, Joystick 1 Down"), + TTRC("Joystick 2 Left"), + TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"), + TTRC("Joystick 2 Up"), + TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"), + TTRC("Joystick 3 Left"), + TTRC("Joystick 3 Right"), + TTRC("Joystick 3 Up"), + TTRC("Joystick 3 Down"), + TTRC("Joystick 4 Left"), + TTRC("Joystick 4 Right"), + TTRC("Joystick 4 Up"), + TTRC("Joystick 4 Down"), +}; + +// Separate from `InputEvent::as_text()` since the descriptions need to be different for the input map editor. See #43660. +String InputMapEditor::_get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event) { + ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEventJoypadMotion"); + + String desc = TTR("Unknown Joypad Axis"); + if (p_event->get_axis() < JOY_AXIS_MAX) { + desc = RTR(_joy_axis_descriptions[2 * p_event->get_axis() + (p_event->get_axis_value() < 0 ? 0 : 1)]); + } + + return vformat("Joypad Axis %s %s (%s)", itos(p_event->get_axis()), p_event->get_axis_value() < 0 ? "-" : "+", desc); +} + void InputMapEditor::_wait_for_key(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; @@ -481,9 +476,11 @@ void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) { device_index_label->set_text(TTR("Joypad Axis Index:")); device_index->clear(); for (int i = 0; i < JOY_AXIS_MAX * 2; i++) { - String desc = TTR("Axis") + " " + itos(i / 2) + " " + ((i & 1) ? "+" : "-") + - " (" + TTR(_axis_descriptions[i]) + ")"; - device_index->add_item(desc); + Ref<InputEventJoypadMotion> jm; + jm.instance(); + jm->set_axis(i / 2); + jm->set_axis_value((i & 1) ? 1 : -1); + device_index->add_item(_get_joypad_motion_event_text(jm)); } device_input->popup_centered(Size2(350, 95) * EDSCALE); @@ -502,11 +499,10 @@ void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) { device_index_label->set_text(TTR("Joypad Button Index:")); device_index->clear(); for (int i = 0; i < JOY_BUTTON_MAX; i++) { - String desc = TTR("Button") + " " + itos(i); - if (i < JOY_BUTTON_SDL_MAX) { - desc += " (" + TTR(_button_descriptions[i]) + ")"; - } - device_index->add_item(desc); + Ref<InputEventJoypadButton> jb; + jb.instance(); + jb->set_button_index(i); + device_index->add_item(jb->as_text()); } device_input->popup_centered(Size2(350, 95) * EDSCALE); @@ -714,14 +710,7 @@ void InputMapEditor::_update_actions() { Ref<InputEventJoypadButton> jb = event; if (jb.is_valid()) { - const int idx = jb->get_button_index(); - String str = _get_device_string(jb->get_device()) + ", " + - TTR("Button") + " " + itos(idx); - if (idx >= 0 && idx < JOY_BUTTON_SDL_MAX) { - str += String() + " (" + TTR(_button_descriptions[jb->get_button_index()]) + ")"; - } - - action2->set_text(0, str); + action2->set_text(0, jb->as_text()); action2->set_icon(0, input_editor->get_theme_icon("JoyButton", "EditorIcons")); } @@ -754,12 +743,8 @@ void InputMapEditor::_update_actions() { Ref<InputEventJoypadMotion> jm = event; if (jm.is_valid()) { - int ax = jm->get_axis(); - int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1); - String str = _get_device_string(jm->get_device()) + ", " + - TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + - " (" + _axis_descriptions[n] + ")"; - action2->set_text(0, str); + device_index->add_item(_get_joypad_motion_event_text(jm)); + action2->set_text(0, jm->as_text()); action2->set_icon(0, input_editor->get_theme_icon("JoyAxis", "EditorIcons")); } action2->set_metadata(0, i); diff --git a/editor/input_map_editor.h b/editor/input_map_editor.h index b9a3ce19d4..b59eb97e1d 100644 --- a/editor/input_map_editor.h +++ b/editor/input_map_editor.h @@ -88,6 +88,8 @@ class InputMapEditor : public Control { void _press_a_key_confirm(); void _show_last_added(const Ref<InputEvent> &p_event, const String &p_name); + String _get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event); + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index b7f7d637d2..1f6c32ed70 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -398,10 +398,10 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position) { ERR_FAIL_COND(!spatial_node); - CubeMesh cubem; - cubem.set_size(p_size); + BoxMesh box_mesh; + box_mesh.set_size(p_size); - Array arrays = cubem.surface_get_arrays(0); + Array arrays = box_mesh.surface_get_arrays(0); PackedVector3Array vertex = arrays[RS::ARRAY_VERTEX]; Vector3 *w = vertex.ptrw(); @@ -412,7 +412,7 @@ void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size, arrays[RS::ARRAY_VERTEX] = vertex; Ref<ArrayMesh> m = memnew(ArrayMesh); - m->add_surface_from_arrays(cubem.surface_get_primitive_type(0), arrays); + m->add_surface_from_arrays(box_mesh.surface_get_primitive_type(0), arrays); m->surface_set_material(0, p_material); add_mesh(m); } @@ -792,7 +792,7 @@ bool Light3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Light3D>(p_spatial) != nullptr; } -String Light3DGizmoPlugin::get_name() const { +String Light3DGizmoPlugin::get_gizmo_name() const { return "Light3D"; } @@ -1061,7 +1061,7 @@ bool AudioStreamPlayer3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<AudioStreamPlayer3D>(p_spatial) != nullptr; } -String AudioStreamPlayer3DGizmoPlugin::get_name() const { +String AudioStreamPlayer3DGizmoPlugin::get_gizmo_name() const { return "AudioStreamPlayer3D"; } @@ -1195,7 +1195,7 @@ bool Camera3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Camera3D>(p_spatial) != nullptr; } -String Camera3DGizmoPlugin::get_name() const { +String Camera3DGizmoPlugin::get_gizmo_name() const { return "Camera3D"; } @@ -1432,7 +1432,7 @@ bool MeshInstance3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<MeshInstance3D>(p_spatial) != nullptr && Object::cast_to<SoftBody3D>(p_spatial) == nullptr; } -String MeshInstance3DGizmoPlugin::get_name() const { +String MeshInstance3DGizmoPlugin::get_gizmo_name() const { return "MeshInstance3D"; } @@ -1469,7 +1469,7 @@ bool Sprite3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Sprite3D>(p_spatial) != nullptr; } -String Sprite3DGizmoPlugin::get_name() const { +String Sprite3DGizmoPlugin::get_gizmo_name() const { return "Sprite3D"; } @@ -1531,7 +1531,7 @@ bool Position3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Position3D>(p_spatial) != nullptr; } -String Position3DGizmoPlugin::get_name() const { +String Position3DGizmoPlugin::get_gizmo_name() const { return "Position3D"; } @@ -1556,7 +1556,7 @@ bool Skeleton3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Skeleton3D>(p_spatial) != nullptr; } -String Skeleton3DGizmoPlugin::get_name() const { +String Skeleton3DGizmoPlugin::get_gizmo_name() const { return "Skeleton3D"; } @@ -1625,13 +1625,13 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { int pointidx = 0; for (int j = 0; j < 3; j++) { bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(rootcolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(rootcolor); surface_tool->add_vertex(v0 - grests[parent].basis[j].normalized() * dist * 0.05); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(rootcolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(rootcolor); surface_tool->add_vertex(v0 + grests[parent].basis[j].normalized() * dist * 0.05); if (j == closest) { @@ -1654,24 +1654,24 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { point += axis * dist * 0.1; bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(v0); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(point); bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(point); bones.write[0] = i; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(v1); points[pointidx++] = point; } @@ -1680,13 +1680,13 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { SWAP(points[1], points[2]); for (int j = 0; j < 4; j++) { bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(points[j]); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(points[(j + 1) % 4]); } @@ -1758,7 +1758,7 @@ bool PhysicalBone3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<PhysicalBone3D>(p_spatial) != nullptr; } -String PhysicalBone3DGizmoPlugin::get_name() const { +String PhysicalBone3DGizmoPlugin::get_gizmo_name() const { return "PhysicalBone3D"; } @@ -1895,7 +1895,7 @@ bool RayCast3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<RayCast3D>(p_spatial) != nullptr; } -String RayCast3DGizmoPlugin::get_name() const { +String RayCast3DGizmoPlugin::get_gizmo_name() const { return "RayCast3D"; } @@ -1947,7 +1947,7 @@ bool SpringArm3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<SpringArm3D>(p_spatial) != nullptr; } -String SpringArm3DGizmoPlugin::get_name() const { +String SpringArm3DGizmoPlugin::get_gizmo_name() const { return "SpringArm3D"; } @@ -1966,7 +1966,7 @@ bool VehicleWheel3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<VehicleWheel3D>(p_spatial) != nullptr; } -String VehicleWheel3DGizmoPlugin::get_name() const { +String VehicleWheel3DGizmoPlugin::get_gizmo_name() const { return "VehicleWheel3D"; } @@ -2038,7 +2038,7 @@ bool SoftBody3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<SoftBody3D>(p_spatial) != nullptr; } -String SoftBody3DGizmoPlugin::get_name() const { +String SoftBody3DGizmoPlugin::get_gizmo_name() const { return "SoftBody3D"; } @@ -2114,7 +2114,7 @@ bool VisibilityNotifier3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<VisibilityNotifier3D>(p_spatial) != nullptr; } -String VisibilityNotifier3DGizmoPlugin::get_name() const { +String VisibilityNotifier3DGizmoPlugin::get_gizmo_name() const { return "VisibilityNotifier3D"; } @@ -2270,7 +2270,7 @@ bool CPUParticles3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<CPUParticles3D>(p_spatial) != nullptr; } -String CPUParticles3DGizmoPlugin::get_name() const { +String CPUParticles3DGizmoPlugin::get_gizmo_name() const { return "CPUParticles3D"; } @@ -2302,7 +2302,7 @@ bool GPUParticles3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<GPUParticles3D>(p_spatial) != nullptr; } -String GPUParticles3DGizmoPlugin::get_name() const { +String GPUParticles3DGizmoPlugin::get_gizmo_name() const { return "GPUParticles3D"; } @@ -2469,7 +2469,7 @@ bool GPUParticlesCollision3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return (Object::cast_to<GPUParticlesCollision3D>(p_spatial) != nullptr) || (Object::cast_to<GPUParticlesAttractor3D>(p_spatial) != nullptr); } -String GPUParticlesCollision3DGizmoPlugin::get_name() const { +String GPUParticlesCollision3DGizmoPlugin::get_gizmo_name() const { return "GPUParticlesCollision3D"; } @@ -2733,7 +2733,7 @@ bool ReflectionProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<ReflectionProbe>(p_spatial) != nullptr; } -String ReflectionProbeGizmoPlugin::get_name() const { +String ReflectionProbeGizmoPlugin::get_gizmo_name() const { return "ReflectionProbe"; } @@ -2918,7 +2918,7 @@ bool DecalGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Decal>(p_spatial) != nullptr; } -String DecalGizmoPlugin::get_name() const { +String DecalGizmoPlugin::get_gizmo_name() const { return "Decal"; } @@ -3059,7 +3059,7 @@ bool GIProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<GIProbe>(p_spatial) != nullptr; } -String GIProbeGizmoPlugin::get_name() const { +String GIProbeGizmoPlugin::get_gizmo_name() const { return "GIProbe"; } @@ -3254,7 +3254,7 @@ bool BakedLightmapGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<BakedLightmap>(p_spatial) != nullptr; } -String BakedLightmapGizmoPlugin::get_name() const { +String BakedLightmapGizmoPlugin::get_gizmo_name() const { return "BakedLightmap"; } @@ -3436,7 +3436,7 @@ bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<LightmapProbe>(p_spatial) != nullptr; } -String LightmapProbeGizmoPlugin::get_name() const { +String LightmapProbeGizmoPlugin::get_gizmo_name() const { return "LightmapProbe"; } @@ -3520,7 +3520,7 @@ bool CollisionShape3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<CollisionShape3D>(p_spatial) != nullptr; } -String CollisionShape3DGizmoPlugin::get_name() const { +String CollisionShape3DGizmoPlugin::get_gizmo_name() const { return "CollisionShape3D"; } @@ -4120,7 +4120,7 @@ bool CollisionPolygon3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<CollisionPolygon3D>(p_spatial) != nullptr; } -String CollisionPolygon3DGizmoPlugin::get_name() const { +String CollisionPolygon3DGizmoPlugin::get_gizmo_name() const { return "CollisionPolygon3D"; } @@ -4167,7 +4167,7 @@ bool NavigationRegion3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<NavigationRegion3D>(p_spatial) != nullptr; } -String NavigationRegion3DGizmoPlugin::get_name() const { +String NavigationRegion3DGizmoPlugin::get_gizmo_name() const { return "NavigationRegion3D"; } @@ -4532,7 +4532,7 @@ bool Joint3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<Joint3D>(p_spatial) != nullptr; } -String Joint3DGizmoPlugin::get_name() const { +String Joint3DGizmoPlugin::get_gizmo_name() const { return "Joint3D"; } diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h index 4826054643..e418456d60 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/node_3d_editor_gizmos.h @@ -41,7 +41,7 @@ class Light3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; @@ -58,7 +58,7 @@ class AudioStreamPlayer3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; @@ -75,7 +75,7 @@ class Camera3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; @@ -92,7 +92,7 @@ class MeshInstance3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; bool can_be_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -105,7 +105,7 @@ class Sprite3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; bool can_be_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -121,7 +121,7 @@ class Position3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -133,7 +133,7 @@ class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -145,7 +145,7 @@ class PhysicalBone3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -157,7 +157,7 @@ class RayCast3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -169,7 +169,7 @@ class SpringArm3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -181,7 +181,7 @@ class VehicleWheel3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -193,7 +193,7 @@ class SoftBody3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -211,7 +211,7 @@ class VisibilityNotifier3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -228,7 +228,7 @@ class CPUParticles3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -240,7 +240,7 @@ class GPUParticles3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -258,7 +258,7 @@ class GPUParticlesCollision3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -275,7 +275,7 @@ class ReflectionProbeGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -292,7 +292,7 @@ class DecalGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -309,7 +309,7 @@ class GIProbeGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -326,7 +326,7 @@ class BakedLightmapGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -343,7 +343,7 @@ class LightmapProbeGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -360,7 +360,7 @@ class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -377,7 +377,7 @@ class CollisionPolygon3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; CollisionPolygon3DGizmoPlugin(); @@ -395,7 +395,7 @@ class NavigationRegion3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; @@ -427,7 +427,7 @@ class Joint3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index a6df790620..570ba9ae03 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -55,7 +55,7 @@ class MaterialEditor : public Control { Camera3D *camera; Ref<SphereMesh> sphere_mesh; - Ref<CubeMesh> box_mesh; + Ref<BoxMesh> box_mesh; TextureButton *sphere_switch; TextureButton *box_switch; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index ccf868b3d5..804a72bd1d 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -63,12 +63,15 @@ #define GIZMO_SCALE_OFFSET (GIZMO_CIRCLE_SIZE + 0.3) #define GIZMO_ARROW_OFFSET (GIZMO_CIRCLE_SIZE + 0.3) -#define ZOOM_MIN_DISTANCE 0.001 -#define ZOOM_MULTIPLIER 1.08 -#define ZOOM_INDICATOR_DELAY_S 1.5 - -#define FREELOOK_MIN_SPEED 0.01 -#define FREELOOK_SPEED_MULTIPLIER 1.08 +#define ZOOM_FREELOOK_MIN 0.01 +#define ZOOM_FREELOOK_MULTIPLIER 1.08 +#define ZOOM_FREELOOK_INDICATOR_DELAY_S 1.5 + +#ifdef REAL_T_IS_DOUBLE +#define ZOOM_FREELOOK_MAX 1'000'000'000'000 +#else +#define ZOOM_FREELOOK_MAX 10'000 +#endif #define MIN_Z 0.01 #define MAX_Z 1000000.0 @@ -1117,7 +1120,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (b.is_valid()) { emit_signal("clicked", this); - float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor(); + float zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor(); switch (b->get_button_index()) { case BUTTON_WHEEL_UP: { if (is_freelook_active()) { @@ -2207,34 +2210,28 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) { } void Node3DEditorViewport::scale_cursor_distance(real_t scale) { - // Prevents zero distance which would short-circuit any scaling - if (cursor.distance < ZOOM_MIN_DISTANCE) { - cursor.distance = ZOOM_MIN_DISTANCE; - } - - cursor.distance *= scale; - - if (cursor.distance < ZOOM_MIN_DISTANCE) { - cursor.distance = ZOOM_MIN_DISTANCE; + real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + if (unlikely(min_distance > max_distance)) { + cursor.distance = (min_distance + max_distance) / 2; + } else { + cursor.distance = CLAMP(cursor.distance * scale, min_distance, max_distance); } - zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S; + zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S; surface->update(); } void Node3DEditorViewport::scale_freelook_speed(real_t scale) { - // Prevents zero distance which would short-circuit any scaling - if (freelook_speed < FREELOOK_MIN_SPEED) { - freelook_speed = FREELOOK_MIN_SPEED; - } - - freelook_speed *= scale; - - if (freelook_speed < FREELOOK_MIN_SPEED) { - freelook_speed = FREELOOK_MIN_SPEED; + real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + if (unlikely(min_speed > max_speed)) { + freelook_speed = (min_speed + max_speed) / 2; + } else { + freelook_speed = CLAMP(freelook_speed * scale, min_speed, max_speed); } - zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S; + zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S; surface->update(); } @@ -2698,19 +2695,13 @@ void Node3DEditorViewport::_draw() { if (is_freelook_active()) { // Show speed - real_t min_speed = FREELOOK_MIN_SPEED; - real_t max_speed = camera->get_zfar(); + real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); real_t scale_length = (max_speed - min_speed); if (!Math::is_zero_approx(scale_length)) { real_t logscale_t = 1.0 - Math::log(1 + freelook_speed - min_speed) / Math::log(1 + scale_length); - // There is no real maximum speed so that factor can become negative, - // Let's make it look asymptotic instead (will decrease slower and slower). - if (logscale_t < 0.25) { - logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); - } - // Display the freelook speed to help the user get a better sense of scale. const int precision = freelook_speed < 1.0 ? 2 : 1; draw_indicator_bar( @@ -2725,19 +2716,13 @@ void Node3DEditorViewport::_draw() { } else { // Show zoom - real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom? - real_t max_distance = camera->get_zfar(); + real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); real_t scale_length = (max_distance - min_distance); if (!Math::is_zero_approx(scale_length)) { real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length); - // There is no real maximum distance so that factor can become negative, - // Let's make it look asymptotic instead (will decrease slower and slower). - if (logscale_t < 0.25) { - logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); - } - // Display the zoom center distance to help the user get a better sense of scale. const int precision = cursor.distance < 1.0 ? 2 : 1; draw_indicator_bar( @@ -2970,11 +2955,11 @@ void Node3DEditorViewport::_menu_option(int p_option) { int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); bool current = view_menu->get_popup()->is_item_checked(idx); current = !current; + uint32_t layers = ((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_GRID_LAYER) | (1 << MISC_TOOL_LAYER); if (current) { - camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER)); - } else { - camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_GRID_LAYER)); + layers |= (1 << GIZMO_EDIT_LAYER); } + camera->set_cull_mask(layers); view_menu->get_popup()->set_item_checked(idx, current); } break; @@ -3895,7 +3880,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito surface->set_clip_contents(true); camera = memnew(Camera3D); camera->set_disable_gizmo(true); - camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + p_index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER)); + camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + p_index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER) | (1 << MISC_TOOL_LAYER)); viewport->add_child(camera); camera->make_current(); surface->set_focus_mode(FOCUS_ALL); @@ -4514,12 +4499,14 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) { RS::get_singleton()->instance_geometry_set_cast_shadows_setting( si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_set_layer_mask(si->sbox_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); si->sbox_instance_xray = RenderingServer::get_singleton()->instance_create2( selection_box_xray->get_rid(), sp->get_world_3d()->get_scenario()); RS::get_singleton()->instance_geometry_set_cast_shadows_setting( si->sbox_instance_xray, RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_xray, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); return si; } @@ -5360,7 +5347,7 @@ void Node3DEditor::_init_indicators() { Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m)); Vector3 normal = ivec * ofs.x + ivec2 * ofs.y; - surftool->add_normal(basis.xform(normal)); + surftool->set_normal(basis.xform(normal)); surftool->add_vertex(vertex); } } @@ -6680,7 +6667,7 @@ Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) { editor->get_viewport()->add_child(spatial_editor); spatial_editor->hide(); - spatial_editor->connect_compat("transform_key_request", editor->get_inspector_dock(), "_transform_keyed"); + spatial_editor->connect("transform_key_request", Callable(editor->get_inspector_dock(), "_transform_keyed")); } Node3DEditorPlugin::~Node3DEditorPlugin() { @@ -6815,9 +6802,9 @@ Ref<StandardMaterial3D> EditorNode3DGizmoPlugin::get_material(const String &p_na return mat; } -String EditorNode3DGizmoPlugin::get_name() const { - if (get_script_instance() && get_script_instance()->has_method("get_name")) { - return get_script_instance()->call("get_name"); +String EditorNode3DGizmoPlugin::get_gizmo_name() const { + if (get_script_instance() && get_script_instance()->has_method("get_gizmo_name")) { + return get_script_instance()->call("get_gizmo_name"); } return TTR("Nameless gizmo"); } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 2e98fcad4c..f46f40d646 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -229,6 +229,7 @@ public: GIZMO_BASE_LAYER = 27, GIZMO_EDIT_LAYER = 26, GIZMO_GRID_LAYER = 25, + MISC_TOOL_LAYER = 24, FRAME_TIME_HISTORY = 20, }; @@ -867,7 +868,7 @@ public: Ref<StandardMaterial3D> get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo = Ref<EditorNode3DGizmo>()); - virtual String get_name() const; + virtual String get_gizmo_name() const; virtual int get_priority() const; virtual bool can_be_hidden() const; virtual bool is_selectable_when_hidden() const; diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 280f6fafd8..febe2693c7 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -630,7 +630,7 @@ Ref<EditorNode3DGizmo> Path3DGizmoPlugin::create_gizmo(Node3D *p_spatial) { return ref; } -String Path3DGizmoPlugin::get_name() const { +String Path3DGizmoPlugin::get_gizmo_name() const { return "Path3D"; } diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index be275944a6..3b92a59143 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -59,7 +59,7 @@ protected: Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial) override; public: - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; Path3DGizmoPlugin(); }; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 6ee8193291..12790a6746 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1249,13 +1249,35 @@ void ScriptEditor::_menu_option(int p_option) { RES resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; + Ref<Script> script = resource; + if (text_file != nullptr) { current->apply_code(); _save_text_file(text_file, text_file->get_path()); break; } + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->save_resource(resource); + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } + } break; case FILE_SAVE_AS: { if (trim_trailing_whitespace_on_save) { @@ -1274,6 +1296,8 @@ void ScriptEditor::_menu_option(int p_option) { RES resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; + Ref<Script> script = resource; + if (text_file != nullptr) { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); @@ -1289,9 +1313,27 @@ void ScriptEditor::_menu_option(int p_option) { break; } + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->push_item(resource.ptr()); editor->save_resource_as(resource); + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } } break; case FILE_TOOL_RELOAD: @@ -2318,11 +2360,33 @@ void ScriptEditor::save_all_scripts() { if (edited_res->get_path() != "" && edited_res->get_path().find("local://") == -1 && edited_res->get_path().find("::") == -1) { Ref<TextFile> text_file = edited_res; + Ref<Script> script = edited_res; + if (text_file != nullptr) { _save_text_file(text_file, text_file->get_path()); continue; } + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->save_resource(edited_res); //external script, save it + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } } } @@ -2900,6 +2964,18 @@ void ScriptEditor::_help_class_goto(const String &p_desc) { _save_layout(); } +void ScriptEditor::update_doc(const String &p_name) { + ERR_FAIL_COND(!EditorHelp::get_doc_data()->has_doc(p_name)); + + for (int i = 0; i < tab_container->get_child_count(); i++) { + EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i)); + if (eh && eh->get_class() == p_name) { + eh->update_doc(); + return; + } + } +} + void ScriptEditor::_update_selected_editor_menu() { for (int i = 0; i < tab_container->get_child_count(); i++) { bool current = tab_container->get_current_tab() == i; diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index f1453c3d20..cc02a1ccbe 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -482,6 +482,7 @@ public: void close_builtin_scripts_from_scene(const String &p_scene); void goto_help(const String &p_desc) { _help_class_goto(p_desc); } + void update_doc(const String &p_name); bool can_take_away_focus() const; diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 6d2fd65dd6..900a2c75a0 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -2359,8 +2359,8 @@ void TileSetEditor::_set_edited_collision_shape(const Ref<Shape2D> &p_shape) { } void TileSetEditor::_set_snap_step(Vector2 p_val) { - snap_step.x = CLAMP(p_val.x, 0, 256); - snap_step.y = CLAMP(p_val.y, 0, 256); + snap_step.x = CLAMP(p_val.x, 1, 256); + snap_step.y = CLAMP(p_val.y, 1, 256); workspace->update(); } @@ -3620,11 +3620,11 @@ void TileSetEditorPlugin::make_visible(bool p_visible) { if (p_visible) { tileset_editor_button->show(); editor->make_bottom_panel_item_visible(tileset_editor); - get_tree()->connect_compat("idle_frame", tileset_editor, "_on_workspace_process"); + get_tree()->connect("idle_frame", Callable(tileset_editor, "_on_workspace_process")); } else { editor->hide_bottom_panel(); tileset_editor_button->hide(); - get_tree()->disconnect_compat("idle_frame", tileset_editor, "_on_workspace_process"); + get_tree()->disconnect("idle_frame", Callable(tileset_editor, "_on_workspace_process")); } } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index b075eb83e4..6112e69299 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -120,9 +120,11 @@ void VisualShaderGraphPlugin::set_connections(List<VisualShader::Connection> &p_ } void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id) { - if (visual_shader->get_shader_type() == p_type && links.has(p_node_id)) { + if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].output_ports.has(p_port_id)) { for (Map<int, Port>::Element *E = links[p_node_id].output_ports.front(); E; E = E->next()) { - E->value().preview_button->set_pressed(false); + if (E->value().preview_button != nullptr) { + E->value().preview_button->set_pressed(false); + } } if (links[p_node_id].preview_visible && !is_dirty() && links[p_node_id].preview_box != nullptr) { @@ -132,7 +134,7 @@ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p links[p_node_id].preview_visible = false; } - if (p_port_id != -1) { + if (p_port_id != -1 && links[p_node_id].output_ports[p_port_id].preview_button != nullptr) { if (is_dirty()) { links[p_node_id].preview_pos = links[p_node_id].graph_node->get_child_count(); } @@ -497,16 +499,32 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (group_node->is_editable()) { HBoxContainer *hb2 = memnew(HBoxContainer); + String input_port_name = "input" + itos(group_node->get_free_input_port_id()); + String output_port_name = "output" + itos(group_node->get_free_output_port_id()); + + for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { + if (i < vsnode->get_input_port_count()) { + if (input_port_name == vsnode->get_input_port_name(i)) { + input_port_name = "_" + input_port_name; + } + } + if (i < vsnode->get_output_port_count()) { + if (output_port_name == vsnode->get_output_port_name(i)) { + output_port_name = "_" + output_port_name; + } + } + } + Button *add_input_btn = memnew(Button); add_input_btn->set_text(TTR("Add Input")); - add_input_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED); + add_input_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, input_port_name), CONNECT_DEFERRED); hb2->add_child(add_input_btn); hb2->add_spacer(); Button *add_output_btn = memnew(Button); add_output_btn->set_text(TTR("Add Output")); - add_output_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED); + add_output_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, output_port_name), CONNECT_DEFERRED); hb2->add_child(add_output_btn); node->add_child(hb2); @@ -583,8 +601,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0)); name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); name_box->set_text(name_left); - name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i)); - name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false)); + name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED); + name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false), CONNECT_DEFERRED); Button *remove_btn = memnew(Button); remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons")); @@ -624,8 +642,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0)); name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); name_box->set_text(name_right); - name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i)); - name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true)); + name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED); + name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true), CONNECT_DEFERRED); OptionButton *type_box = memnew(OptionButton); hb->add_child(type_box); @@ -1335,29 +1353,57 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_ undo_redo->commit_action(); } -void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) { +void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *p_line_edit, int p_node_id, int p_port_id) { VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); + String prev_name = node->get_input_port_name(p_port_id); + if (prev_name == p_text) { + return; + } + + LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit); + ERR_FAIL_COND(!line_edit); + + String validated_name = visual_shader->validate_port_name(p_text, node.ptr(), p_port_id, false); + if (validated_name == String() || prev_name == validated_name) { + line_edit->set_text(node->get_input_port_name(p_port_id)); + return; + } + undo_redo->create_action(TTR("Change Input Port Name")); - undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, p_text); + undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, validated_name); undo_redo->add_undo_method(node.ptr(), "set_input_port_name", p_port_id, node->get_input_port_name(p_port_id)); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->commit_action(); } -void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) { +void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *p_line_edit, int p_node_id, int p_port_id) { VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); + String prev_name = node->get_output_port_name(p_port_id); + if (prev_name == p_text) { + return; + } + + LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit); + ERR_FAIL_COND(!line_edit); + + String validated_name = visual_shader->validate_port_name(p_text, node.ptr(), p_port_id, true); + if (validated_name == String() || prev_name == validated_name) { + line_edit->set_text(node->get_output_port_name(p_port_id)); + return; + } + undo_redo->create_action(TTR("Change Output Port Name")); - undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, p_text); - undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, node->get_output_port_name(p_port_id)); + undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, validated_name); + undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, prev_name); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->commit_action(); @@ -1452,6 +1498,17 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { } } + int preview_port = node->get_output_port_for_preview(); + if (preview_port != -1) { + if (preview_port == p_port) { + undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", -1); + undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", preview_port); + } else if (preview_port > p_port) { + undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", preview_port - 1); + undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", preview_port); + } + } + undo_redo->add_do_method(node.ptr(), "remove_output_port", p_port); undo_redo->add_undo_method(node.ptr(), "add_output_port", p_port, (int)node->get_output_port_type(p_port), node->get_output_port_name(p_port)); @@ -1596,53 +1653,10 @@ void VisualShaderEditor::_uniform_line_edit_focus_out(Object *line_edit, int p_n } void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output) { - VisualShader::Type type = get_current_shader_type(); - - Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); - ERR_FAIL_COND(!node.is_valid()); - - String text = Object::cast_to<LineEdit>(line_edit)->get_text(); - - if (!p_output) { - if (node->get_input_port_name(p_port_id) == text) { - return; - } - } else { - if (node->get_output_port_name(p_port_id) == text) { - return; - } - } - - List<String> input_names; - List<String> output_names; - - for (int i = 0; i < node->get_input_port_count(); i++) { - if (!p_output && i == p_port_id) { - continue; - } - input_names.push_back(node->get_input_port_name(i)); - } - for (int i = 0; i < node->get_output_port_count(); i++) { - if (p_output && i == p_port_id) { - continue; - } - output_names.push_back(node->get_output_port_name(i)); - } - - String validated_name = visual_shader->validate_port_name(text, input_names, output_names); - if (validated_name == "") { - if (!p_output) { - Object::cast_to<LineEdit>(line_edit)->set_text(node->get_input_port_name(p_port_id)); - } else { - Object::cast_to<LineEdit>(line_edit)->set_text(node->get_output_port_name(p_port_id)); - } - return; - } - if (!p_output) { - _change_input_port_name(validated_name, line_edit, p_node_id, p_port_id); + _change_input_port_name(Object::cast_to<LineEdit>(line_edit)->get_text(), line_edit, p_node_id, p_port_id); } else { - _change_output_port_name(validated_name, line_edit, p_node_id, p_port_id); + _change_output_port_name(Object::cast_to<LineEdit>(line_edit)->get_text(), line_edit, p_node_id, p_port_id); } } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 73bebcd192..2e7e9a8898 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -354,12 +354,12 @@ class VisualShaderEditor : public VBoxContainer { void _add_input_port(int p_node, int p_port, int p_port_type, const String &p_name); void _remove_input_port(int p_node, int p_port); void _change_input_port_type(int p_type, int p_node, int p_port); - void _change_input_port_name(const String &p_text, Object *line_edit, int p_node, int p_port); + void _change_input_port_name(const String &p_text, Object *p_line_edit, int p_node, int p_port); void _add_output_port(int p_node, int p_port, int p_port_type, const String &p_name); void _remove_output_port(int p_node, int p_port); void _change_output_port_type(int p_type, int p_node, int p_port); - void _change_output_port_name(const String &p_text, Object *line_edit, int p_node, int p_port); + void _change_output_port_name(const String &p_text, Object *p_line_edit, int p_node, int p_port); void _expression_focus_out(Object *code_edit, int p_node); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 75509c7544..8435dccf4a 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -865,10 +865,10 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) { if (invalid_path) { export_project->get_ok()->set_disabled(true); - export_project->get_line_edit()->disconnect_compat("text_entered", export_project, "_file_entered"); + export_project->get_line_edit()->disconnect("text_entered", Callable(export_project, "_file_entered")); } else { export_project->get_ok()->set_disabled(false); - export_project->get_line_edit()->connect_compat("text_entered", export_project, "_file_entered"); + export_project->get_line_edit()->connect("text_entered", Callable(export_project, "_file_entered")); } } @@ -900,9 +900,9 @@ void ProjectExportDialog::_export_project() { // with _validate_export_path. // FIXME: This is a hack, we should instead change EditorFileDialog to allow // disabling validation by the "text_entered" signal. - if (!export_project->get_line_edit()->is_connected_compat("text_entered", export_project, "_file_entered")) { + if (!export_project->get_line_edit()->is_connected("text_entered", Callable(export_project, "_file_entered"))) { export_project->get_ok()->set_disabled(false); - export_project->get_line_edit()->connect_compat("text_entered", export_project, "_file_entered"); + export_project->get_line_edit()->connect("text_entered", Callable(export_project, "_file_entered")); } export_project->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 75420a1ef4..1ff73f25c5 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -31,6 +31,7 @@ #include "property_selector.h" #include "core/os/keyboard.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor_scale.h" @@ -349,7 +350,7 @@ void PropertySelector::_item_selected() { class_type = base_type; } - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); String text; if (properties) { diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index fafb90e864..9c37ae584a 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1073,14 +1073,14 @@ void SceneTreeDock::_notification(int p_what) { CanvasItemEditorPlugin *canvas_item_plugin = Object::cast_to<CanvasItemEditorPlugin>(editor_data->get_editor("2D")); if (canvas_item_plugin) { - canvas_item_plugin->get_canvas_item_editor()->connect_compat("item_lock_status_changed", scene_tree, "_update_tree"); - canvas_item_plugin->get_canvas_item_editor()->connect_compat("item_group_status_changed", scene_tree, "_update_tree"); + canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree")); + canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree")); scene_tree->connect("node_changed", callable_mp((CanvasItem *)canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), &CanvasItem::update)); } Node3DEditorPlugin *spatial_editor_plugin = Object::cast_to<Node3DEditorPlugin>(editor_data->get_editor("3D")); - spatial_editor_plugin->get_spatial_editor()->connect_compat("item_lock_status_changed", scene_tree, "_update_tree"); - spatial_editor_plugin->get_spatial_editor()->connect_compat("item_group_status_changed", scene_tree, "_update_tree"); + spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree")); + spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree")); button_add->set_icon(get_theme_icon("Add", "EditorIcons")); button_instance->set_icon(get_theme_icon("Instance", "EditorIcons")); diff --git a/glsl_builders.py b/glsl_builders.py index 29971fd4e7..57aaed5f9f 100644 --- a/glsl_builders.py +++ b/glsl_builders.py @@ -107,7 +107,7 @@ def build_rd_header(filename): out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD" fd.write("\n") - fd.write('#include "servers/rendering/rasterizer_rd/shader_rd.h"\n\n') + fd.write('#include "servers/rendering/renderer_rd/shader_rd.h"\n\n') fd.write("class " + out_file_class + " : public ShaderRD {\n\n") fd.write("public:\n\n") diff --git a/main/main.cpp b/main/main.cpp index 3bef04b15d..a824b53e5a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -70,7 +70,7 @@ #include "servers/physics_server_2d.h" #include "servers/physics_server_3d.h" #include "servers/register_server_types.h" -#include "servers/rendering/rendering_server_raster.h" +#include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_wrap_mt.h" #include "servers/text_server.h" #include "servers/xr_server.h" @@ -81,8 +81,8 @@ #ifdef TOOLS_ENABLED -#include "editor/doc_data.h" #include "editor/doc_data_class_path.gen.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/progress_dialog.h" @@ -1563,7 +1563,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { /* Initialize Visual Server */ - rendering_server = memnew(RenderingServerRaster); + rendering_server = memnew(RenderingServerDefault); if (OS::get_singleton()->get_render_thread_mode() != OS::RENDER_THREAD_UNSAFE) { rendering_server = memnew(RenderingServerWrapMT(rendering_server, OS::get_singleton()->get_render_thread_mode() == @@ -1914,10 +1914,10 @@ bool Main::start() { GLOBAL_DEF("mono/project/auto_update_project", true); #endif - DocData doc; + DocTools doc; doc.generate(doc_base); - DocData docsrc; + DocTools docsrc; Map<String, String> doc_data_classes; Set<String> checked_paths; print_line("Loading docs..."); @@ -1957,7 +1957,7 @@ bool Main::start() { doc.merge_from(docsrc); for (Set<String>::Element *E = checked_paths.front(); E; E = E->next()) { print_line("Erasing old docs at: " + E->get()); - DocData::erase_classes(E->get()); + DocTools::erase_classes(E->get()); } print_line("Generating new docs..."); diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm index e8fa023ac7..6d69f4a2f4 100644 --- a/modules/arkit/arkit_interface.mm +++ b/modules/arkit/arkit_interface.mm @@ -712,8 +712,8 @@ void ARKitInterface::_add_or_update_anchor(GodotARAnchor *p_anchor) { int16_t index = planeAnchor.geometry.triangleIndices[j]; simd_float3 vrtx = planeAnchor.geometry.vertices[index]; simd_float2 textcoord = planeAnchor.geometry.textureCoordinates[index]; - surftool->add_uv(Vector2(textcoord[0], textcoord[1])); - surftool->add_color(Color(0.8, 0.8, 0.8)); + surftool->set_uv(Vector2(textcoord[0], textcoord[1])); + surftool->set_color(Color(0.8, 0.8, 0.8)); surftool->add_vertex(Vector3(vrtx[0], vrtx[1], vrtx[2])); } diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp index e5becfd559..796ee27a7d 100644 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ b/modules/assimp/editor_scene_importer_assimp.cpp @@ -827,8 +827,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat Ref<ArrayMesh> mesh; mesh.instance(); bool has_uvs = false; - bool compress_vert_data = state.import_flags & IMPORT_USE_COMPRESSION; - uint32_t mesh_flags = compress_vert_data ? Mesh::ARRAY_COMPRESS_DEFAULT : 0; + uint32_t mesh_flags = 0; Map<String, uint32_t> morph_mesh_string_lookup; @@ -839,7 +838,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName); if (!morph_mesh_string_lookup.has(ai_anim_mesh_name)) { morph_mesh_string_lookup.insert(ai_anim_mesh_name, j); - mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); + mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED); if (ai_anim_mesh_name.empty()) { ai_anim_mesh_name = String("morph_") + itos(j); } @@ -904,33 +903,33 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Get the texture coordinates if they exist if (ai_mesh->HasTextureCoords(0)) { has_uvs = true; - st->add_uv(Vector2(ai_mesh->mTextureCoords[0][j].x, 1.0f - ai_mesh->mTextureCoords[0][j].y)); + st->set_uv(Vector2(ai_mesh->mTextureCoords[0][j].x, 1.0f - ai_mesh->mTextureCoords[0][j].y)); } if (ai_mesh->HasTextureCoords(1)) { has_uvs = true; - st->add_uv2(Vector2(ai_mesh->mTextureCoords[1][j].x, 1.0f - ai_mesh->mTextureCoords[1][j].y)); + st->set_uv2(Vector2(ai_mesh->mTextureCoords[1][j].x, 1.0f - ai_mesh->mTextureCoords[1][j].y)); } // Assign vertex colors if (ai_mesh->HasVertexColors(0)) { Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b, ai_mesh->mColors[0]->a); - st->add_color(color); + st->set_color(color); } // Work out normal calculations? - this needs work it doesn't work properly on huestos if (ai_mesh->mNormals != nullptr) { const aiVector3D normals = ai_mesh->mNormals[j]; const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z); - st->add_normal(godot_normal); + st->set_normal(godot_normal); if (ai_mesh->HasTangentsAndBitangents()) { const aiVector3D tangents = ai_mesh->mTangents[j]; const Vector3 godot_tangent = Vector3(tangents.x, tangents.y, tangents.z); const aiVector3D bitangent = ai_mesh->mBitangents[j]; const Vector3 godot_bitangent = Vector3(bitangent.x, bitangent.y, bitangent.z); float d = godot_normal.cross(godot_tangent).dot(godot_bitangent) > 0.0f ? 1.0f : -1.0f; - st->add_tangent(Plane(tangents.x, tangents.y, tangents.z, d)); + st->set_tangent(Plane(tangents.x, tangents.y, tangents.z, d)); } } @@ -948,8 +947,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat weights.write[k] = bone_info[k].weight; } - st->add_bones(bones); - st->add_weights(weights); + st->set_bones(bones); + st->set_weights(weights); } // Assign vertex diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index eb599df74c..0c64c3640f 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -744,7 +744,7 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { } btBody->setCcdSweptSphereRadius(radius * 0.2); } else { - btBody->setCcdMotionThreshold(10000.0); + btBody->setCcdMotionThreshold(0.); btBody->setCcdSweptSphereRadius(0.); } } @@ -824,7 +824,7 @@ void RigidBodyBullet::reload_shapes() { btBody->updateInertiaTensor(); reload_kinematic_shapes(); - set_continuous_collision_detection(btBody->getCcdMotionThreshold() < 9998.0); + set_continuous_collision_detection(is_continuous_collision_detection_enabled()); reload_body(); } diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index cce72770f5..f8c05761bb 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -319,7 +319,7 @@ bool CSGShape3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<CSGSphere3D>(p_spatial) || Object::cast_to<CSGBox3D>(p_spatial) || Object::cast_to<CSGCylinder3D>(p_spatial) || Object::cast_to<CSGTorus3D>(p_spatial) || Object::cast_to<CSGMesh3D>(p_spatial) || Object::cast_to<CSGPolygon3D>(p_spatial); } -String CSGShape3DGizmoPlugin::get_name() const { +String CSGShape3DGizmoPlugin::get_gizmo_name() const { return "CSGShape3D"; } diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h index 83ee847caf..cf44f76f37 100644 --- a/modules/csg/csg_gizmos.h +++ b/modules/csg/csg_gizmos.h @@ -40,7 +40,7 @@ class CSGShape3DGizmoPlugin : public EditorNode3DGizmoPlugin { public: bool has_gizmo(Node3D *p_spatial) override; - String get_name() const override; + String get_gizmo_name() const override; int get_priority() const override; bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index 0a611b76e9..2e803d602b 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -52,7 +52,7 @@ typedef enum godot_variant_type { // atomic types GODOT_VARIANT_TYPE_BOOL, GODOT_VARIANT_TYPE_INT, - GODOT_VARIANT_TYPE_REAL, + GODOT_VARIANT_TYPE_FLOAT, GODOT_VARIANT_TYPE_STRING, // math types diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 2aaa4be325..e91d9b7bfb 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -31,6 +31,7 @@ #ifndef NATIVE_SCRIPT_H #define NATIVE_SCRIPT_H +#include "core/doc_data.h" #include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -152,6 +153,13 @@ public: virtual void set_source_code(const String &p_code) override; virtual Error reload(bool p_keep_state = false) override; +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const override { + static Vector<DocData::ClassDoc> docs; + return docs; + } +#endif // TOOLS_ENABLED + virtual bool has_method(const StringName &p_method) const override; virtual MethodInfo get_method_info(const StringName &p_method) const override; diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 150de05e74..dc1ed6d576 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -32,6 +32,8 @@ #define PLUGINSCRIPT_SCRIPT_H // Godot imports + +#include "core/doc_data.h" #include "core/object/script_language.h" // PluginScript imports #include "pluginscript_language.h" @@ -97,6 +99,13 @@ public: // TODO: load_source_code only allow utf-8 file, should handle bytecode as well ? virtual Error load_source_code(const String &p_path); +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const override { + static Vector<DocData::ClassDoc> docs; + return docs; + } +#endif // TOOLS_ENABLED + virtual bool has_method(const StringName &p_method) const override; virtual MethodInfo get_method_info(const StringName &p_method) const override; diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp index 5329600e39..3310123ca9 100644 --- a/modules/gdnavigation/navigation_mesh_generator.cpp +++ b/modules/gdnavigation/navigation_mesh_generator.cpp @@ -176,10 +176,10 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, BoxShape3D *box = Object::cast_to<BoxShape3D>(*s); if (box) { - Ref<CubeMesh> cube_mesh; - cube_mesh.instance(); - cube_mesh->set_size(box->get_extents() * 2.0); - mesh = cube_mesh; + Ref<BoxMesh> box_mesh; + box_mesh.instance(); + box_mesh->set_size(box->get_extents() * 2.0); + mesh = box_mesh; } CapsuleShape3D *capsule = Object::cast_to<CapsuleShape3D>(*s); diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index d90b3e52d0..eeb66ebfc0 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -55,8 +55,7 @@ <description> Returns the absolute value of parameter [code]s[/code] (i.e. positive value). [codeblock] - # a is 1 - a = abs(-1) + a = abs(-1) # a is 1 [/codeblock] </description> </method> @@ -166,10 +165,10 @@ <description> Rounds [code]s[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]s[/code]. [codeblock] - i = ceil(1.45) # i is 2 - i = ceil(1.001) # i is 2 + a = ceil(1.45) # a is 2.0 + a = ceil(1.001) # a is 2.0 [/codeblock] - See also [method floor], [method round], and [method stepify]. + See also [method floor], [method round], [method stepify], and [int]. </description> </method> <method name="char"> @@ -199,13 +198,9 @@ <description> Clamps [code]value[/code] and returns a value not less than [code]min[/code] and not more than [code]max[/code]. [codeblock] - speed = 1000 - # a is 20 - a = clamp(speed, 1, 20) - - speed = -10 - # a is 1 - a = clamp(speed, 1, 20) + a = clamp(1000, 1, 20) # a is 20 + a = clamp(-10, 1, 20) # a is 1 + a = clamp(15, 1, 20) # a is 15 [/codeblock] </description> </method> @@ -236,9 +231,8 @@ <description> Returns the cosine of angle [code]s[/code] in radians. [codeblock] - # Prints 1 then -1 - print(cos(PI * 2)) - print(cos(PI)) + a = cos(TAU) # a is 1.0 + a = cos(PI) # a is -1.0 [/codeblock] </description> </method> @@ -250,8 +244,7 @@ <description> Returns the hyperbolic cosine of [code]s[/code] in radians. [codeblock] - # Prints 1.543081 - print(cosh(1)) + print(cosh(1)) # Prints 1.543081 [/codeblock] </description> </method> @@ -276,8 +269,7 @@ <description> Returns the result of [code]value[/code] decreased by [code]step[/code] * [code]amount[/code]. [codeblock] - # a = 59 - a = dectime(60, 10, 0.1)) + a = dectime(60, 10, 0.1)) # a is 59.0 [/codeblock] </description> </method> @@ -289,8 +281,7 @@ <description> Converts an angle expressed in degrees to radians. [codeblock] - # r is 3.141593 - r = deg2rad(180) + r = deg2rad(180) # r is 3.141593 [/codeblock] </description> </method> @@ -300,7 +291,7 @@ <argument index="0" name="dict" type="Dictionary"> </argument> <description> - Converts a previously converted instance to a dictionary, back into an instance. Useful for deserializing. + Converts a dictionary (previously created with [method inst2dict]) back to an instance. Useful for deserializing. </description> </method> <method name="ease"> @@ -336,13 +327,12 @@ <description> Rounds [code]s[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]s[/code]. [codeblock] - # a is 2.0 - a = floor(2.99) - # a is -3.0 - a = floor(-2.99) + a = floor(2.45) # a is 2.0 + a = floor(2.99) # a is 2.0 + a = floor(-2.99) # a is -3.0 [/codeblock] - See also [method ceil], [method round], and [method stepify]. - [b]Note:[/b] This method returns a float. If you need an integer, you can use [code]int(s)[/code] directly. + See also [method ceil], [method round], [method stepify], and [int]. + [b]Note:[/b] This method returns a float. If you need an integer and [code]s[/code] is a non-negative number, you can use [code]int(s)[/code] directly. </description> </method> <method name="fmod"> @@ -355,8 +345,7 @@ <description> Returns the floating-point remainder of [code]a/b[/code], keeping the sign of [code]a[/code]. [codeblock] - # Remainder is 1.5 - var remainder = fmod(7, 5.5) + r = fmod(7, 5.5) # r is 1.5 [/codeblock] For the integer remainder operation, use the % operator. </description> @@ -776,7 +765,7 @@ <description> Returns the result of [code]x[/code] raised to the power of [code]y[/code]. [codeblock] - pow(2, 5) # Returns 32 + pow(2, 5) # Returns 32.0 [/codeblock] </description> </method> @@ -801,7 +790,7 @@ Converts one or more arguments to strings in the best way possible and prints them to the console. [codeblock] a = [1, 2, 3] - print("a", "b", a) # Prints ab[1, 2, 3] + print("a", "=", a) # Prints a=[1, 2, 3] [/codeblock] [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. </description> @@ -900,7 +889,7 @@ <description> Converts an angle expressed in radians to degrees. [codeblock] - rad2deg(0.523599) # Returns 30 + rad2deg(0.523599) # Returns 30.0 [/codeblock] </description> </method> @@ -1022,9 +1011,11 @@ <description> Rounds [code]s[/code] to the nearest whole number, with halfway cases rounded away from zero. [codeblock] - round(2.6) # Returns 3 + a = round(2.49) # a is 2.0 + a = round(2.5) # a is 3.0 + a = round(2.51) # a is 3.0 [/codeblock] - See also [method floor], [method ceil], and [method stepify]. + See also [method floor], [method ceil], [method stepify], and [int]. </description> </method> <method name="seed"> @@ -1094,9 +1085,9 @@ This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code]. [codeblock] smoothstep(0, 2, -5.0) # Returns 0.0 - smoothstep(0, 2, 0.5) # Returns 0.15625 - smoothstep(0, 2, 1.0) # Returns 0.5 - smoothstep(0, 2, 2.0) # Returns 1.0 + smoothstep(0, 2, 0.5) # Returns 0.15625 + smoothstep(0, 2, 1.0) # Returns 0.5 + smoothstep(0, 2, 2.0) # Returns 1.0 [/codeblock] </description> </method> @@ -1121,12 +1112,9 @@ <description> Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation. [codeblock] - # n is 0 - n = step_decimals(5) - # n is 4 - n = step_decimals(1.0005) - # n is 9 - n = step_decimals(0.000000005) + n = step_decimals(5) # n is 0 + n = step_decimals(1.0005) # n is 4 + n = step_decimals(0.000000005) # n is 9 [/codeblock] </description> </method> @@ -1140,10 +1128,10 @@ <description> Snaps float value [code]s[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals. [codeblock] - stepify(100, 32) # Returns 96 + stepify(100, 32) # Returns 96.0 stepify(3.14159, 0.01) # Returns 3.14 [/codeblock] - See also [method ceil], [method floor], and [method round]. + See also [method ceil], [method floor], [method round], and [int]. </description> </method> <method name="str" qualifiers="vararg"> @@ -1193,8 +1181,8 @@ <description> Returns the hyperbolic tangent of [code]s[/code]. [codeblock] - a = log(2.0) # Returns 0.693147 - tanh(a) # Returns 0.6 + a = log(2.0) # a is 0.693147 + b = tanh(a) # b is 0.6 [/codeblock] </description> </method> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 6b74abf15d..4425b59d62 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -231,7 +231,7 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { } #endif -void GDScript::get_script_method_list(List<MethodInfo> *p_list) const { +void GDScript::_get_script_method_list(List<MethodInfo> *r_list, bool p_include_base) const { const GDScript *current = this; while (current) { for (const Map<StringName, GDScriptFunction *>::Element *E = current->member_functions.front(); E; E = E->next()) { @@ -239,18 +239,29 @@ void GDScript::get_script_method_list(List<MethodInfo> *p_list) const { MethodInfo mi; mi.name = E->key(); for (int i = 0; i < func->get_argument_count(); i++) { - mi.arguments.push_back(func->get_argument_type(i)); + PropertyInfo arginfo = func->get_argument_type(i); +#ifdef TOOLS_ENABLED + arginfo.name = func->get_argument_name(i); +#endif + mi.arguments.push_back(arginfo); } mi.return_val = func->get_return_type(); - p_list->push_back(mi); + r_list->push_back(mi); + } + if (!p_include_base) { + return; } current = current->_base; } } -void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const { +void GDScript::get_script_method_list(List<MethodInfo> *r_list) const { + _get_script_method_list(r_list, true); +} + +void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_include_base) const { const GDScript *sptr = this; List<PropertyInfo> props; @@ -269,15 +280,22 @@ void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < msort.size(); i++) { props.push_front(sptr->member_info[msort[i].name]); } + if (!p_include_base) { + break; + } sptr = sptr->_base; } for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - p_list->push_back(E->get()); + r_list->push_back(E->get()); } } +void GDScript::get_script_property_list(List<PropertyInfo> *r_list) const { + _get_script_property_list(r_list, true); +} + bool GDScript::has_method(const StringName &p_method) const { return member_functions.has(p_method); } @@ -383,6 +401,183 @@ void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<Pro propnames.push_back(E->get()); } } + +void GDScript::_add_doc(const DocData::ClassDoc &p_inner_class) { + if (_owner) { + _owner->_add_doc(p_inner_class); + } else { + for (int i = 0; i < docs.size(); i++) { + if (docs[i].name == p_inner_class.name) { + docs.remove(i); + break; + } + } + docs.append(p_inner_class); + } +} + +void GDScript::_clear_doc() { + docs.clear(); + doc = DocData::ClassDoc(); +} + +void GDScript::_update_doc() { + _clear_doc(); + + doc.script_path = "\"" + get_path().get_slice("://", 1) + "\""; + if (!name.empty()) { + doc.name = name; + } else { + doc.name = doc.script_path; + } + + if (_owner) { + doc.name = _owner->doc.name + "." + doc.name; + doc.script_path = doc.script_path + "." + doc.name; + } + + doc.is_script_doc = true; + + if (base.is_valid() && base->is_valid()) { + if (base->doc.name != String()) { + doc.inherits = base->doc.name; + } else { + doc.inherits = base->get_instance_base_type(); + } + } else if (native.is_valid()) { + doc.inherits = native->get_name(); + } + + doc.brief_description = doc_brief_description; + doc.description = doc_description; + doc.tutorials = doc_tutorials; + + for (Map<String, DocData::EnumDoc>::Element *E = doc_enums.front(); E; E = E->next()) { + if (E->value().description != "") { + doc.enums[E->key()] = E->value().description; + } + } + + List<MethodInfo> methods; + _get_script_method_list(&methods, false); + for (int i = 0; i < methods.size(); i++) { + // Ignore internal methods. + if (methods[i].name[0] == '@') { + continue; + } + + DocData::MethodDoc method_doc; + const String &class_name = methods[i].name; + if (member_functions.has(class_name)) { + GDScriptFunction *fn = member_functions[class_name]; + + // Change class name if return type is script reference. + GDScriptDataType return_type = fn->get_return_type(); + if (return_type.kind == GDScriptDataType::GDSCRIPT) { + methods[i].return_val.class_name = _get_gdscript_reference_class_name(Object::cast_to<GDScript>(return_type.script_type)); + } + + // Change class name if argumetn is script reference. + for (int j = 0; j < fn->get_argument_count(); j++) { + GDScriptDataType arg_type = fn->get_argument_type(j); + if (arg_type.kind == GDScriptDataType::GDSCRIPT) { + methods[i].arguments[j].class_name = _get_gdscript_reference_class_name(Object::cast_to<GDScript>(arg_type.script_type)); + } + } + } + if (doc_functions.has(methods[i].name)) { + DocData::method_doc_from_methodinfo(method_doc, methods[i], doc_functions[methods[i].name]); + } else { + DocData::method_doc_from_methodinfo(method_doc, methods[i], String()); + } + doc.methods.push_back(method_doc); + } + + List<PropertyInfo> props; + _get_script_property_list(&props, false); + for (int i = 0; i < props.size(); i++) { + ScriptMemberInfo scr_member_info; + scr_member_info.propinfo = props[i]; + scr_member_info.propinfo.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + if (member_indices.has(props[i].name)) { + const MemberInfo &mi = member_indices[props[i].name]; + scr_member_info.setter = mi.setter; + scr_member_info.getter = mi.getter; + if (mi.data_type.kind == GDScriptDataType::GDSCRIPT) { + scr_member_info.propinfo.class_name = _get_gdscript_reference_class_name( + Object::cast_to<GDScript>(mi.data_type.script_type)); + } + } + if (member_default_values.has(props[i].name)) { + scr_member_info.has_default_value = true; + scr_member_info.default_value = member_default_values[props[i].name]; + } + if (doc_variables.has(props[i].name)) { + scr_member_info.doc_string = doc_variables[props[i].name]; + } + + DocData::PropertyDoc prop_doc; + DocData::property_doc_from_scriptmemberinfo(prop_doc, scr_member_info); + doc.properties.push_back(prop_doc); + } + + List<MethodInfo> signals; + _get_script_signal_list(&signals, false); + for (int i = 0; i < signals.size(); i++) { + DocData::MethodDoc signal_doc; + if (doc_signals.has(signals[i].name)) { + DocData::signal_doc_from_methodinfo(signal_doc, signals[i], signals[i].name); + } else { + DocData::signal_doc_from_methodinfo(signal_doc, signals[i], String()); + } + doc.signals.push_back(signal_doc); + } + + for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { + if (subclasses.has(E->key())) { + continue; + } + + // Enums. + bool is_enum = false; + if (E->value().get_type() == Variant::DICTIONARY) { + if (doc_enums.has(E->key())) { + is_enum = true; + for (int i = 0; i < doc_enums[E->key()].values.size(); i++) { + doc_enums[E->key()].values.write[i].enumeration = E->key(); + doc.constants.push_back(doc_enums[E->key()].values[i]); + } + } + } + if (!is_enum && doc_enums.has("@unnamed_enums")) { + for (int i = 0; i < doc_enums["@unnamed_enums"].values.size(); i++) { + if (E->key() == doc_enums["@unnamed_enums"].values[i].name) { + is_enum = true; + DocData::ConstantDoc constant_doc; + constant_doc.enumeration = "@unnamed_enums"; + DocData::constant_doc_from_variant(constant_doc, E->key(), E->value(), doc_enums["@unnamed_enums"].values[i].description); + doc.constants.push_back(constant_doc); + break; + } + } + } + if (!is_enum) { + DocData::ConstantDoc constant_doc; + String doc_description; + if (doc_constants.has(E->key())) { + doc_description = doc_constants[E->key()]; + } + DocData::constant_doc_from_variant(constant_doc, E->key(), E->value(), doc_description); + doc.constants.push_back(constant_doc); + } + } + + for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { + E->get()->_update_doc(); + } + + _add_doc(doc); +} #endif bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { @@ -642,6 +837,10 @@ Error GDScript::reload(bool p_keep_state) { GDScriptCompiler compiler; err = compiler.compile(&parser, this, p_keep_state); +#ifdef TOOLS_ENABLED + _update_doc(); +#endif + if (err) { if (can_run) { if (EngineDebugger::is_active()) { @@ -915,7 +1114,7 @@ bool GDScript::has_script_signal(const StringName &p_signal) const { return false; } -void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { +void GDScript::_get_script_signal_list(List<MethodInfo> *r_list, bool p_include_base) const { for (const Map<StringName, Vector<StringName>>::Element *E = _signals.front(); E; E = E->next()) { MethodInfo mi; mi.name = E->key(); @@ -924,20 +1123,43 @@ void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { arg.name = E->get()[i]; mi.arguments.push_back(arg); } - r_signals->push_back(mi); + r_list->push_back(mi); + } + + if (!p_include_base) { + return; } if (base.is_valid()) { - base->get_script_signal_list(r_signals); + base->get_script_signal_list(r_list); } #ifdef TOOLS_ENABLED else if (base_cache.is_valid()) { - base_cache->get_script_signal_list(r_signals); + base_cache->get_script_signal_list(r_list); } #endif } +void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { + _get_script_signal_list(r_signals, true); +} + +String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript) { + ERR_FAIL_NULL_V(p_gdscript, String()); + + String class_name; + while (p_gdscript) { + if (class_name == "") { + class_name = p_gdscript->get_script_class_name(); + } else { + class_name = p_gdscript->get_script_class_name() + "." + class_name; + } + p_gdscript = p_gdscript->_owner; + } + return class_name; +} + GDScript::GDScript() : script_list(this) { valid = false; @@ -1065,6 +1287,13 @@ GDScript::~GDScript() { _save_orphaned_subclasses(); +#ifdef TOOLS_ENABLED + // Clearing inner class doc, script doc only cleared when the script source deleted. + if (_owner) { + _clear_doc(); + } +#endif + #ifdef DEBUG_ENABLED { MutexLock lock(GDScriptLanguage::get_singleton()->lock); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index b69a6e39c0..3eb260f95f 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -33,6 +33,7 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/doc_data.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/object/script_language.h" @@ -91,9 +92,7 @@ class GDScript : public Script { #ifdef TOOLS_ENABLED Map<StringName, int> member_lines; - Map<StringName, Variant> member_default_values; - List<PropertyInfo> members_cache; Map<StringName, Variant> member_default_values_cache; Ref<GDScript> base_cache; @@ -102,6 +101,20 @@ class GDScript : public Script { bool placeholder_fallback_enabled; void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); + DocData::ClassDoc doc; + Vector<DocData::ClassDoc> docs; + String doc_brief_description; + String doc_description; + Vector<DocData::TutorialDoc> doc_tutorials; + Map<String, String> doc_functions; + Map<String, String> doc_variables; + Map<String, String> doc_constants; + Map<String, String> doc_signals; + Map<String, DocData::EnumDoc> doc_enums; + void _clear_doc(); + void _update_doc(); + void _add_doc(const DocData::ClassDoc &p_inner_class); + #endif Map<StringName, PropertyInfo> member_info; @@ -141,6 +154,13 @@ class GDScript : public Script { void _save_orphaned_subclasses(); void _init_rpc_methods_properties(); + void _get_script_property_list(List<PropertyInfo> *r_list, bool p_include_base) const; + void _get_script_method_list(List<MethodInfo> *r_list, bool p_include_base) const; + void _get_script_signal_list(List<MethodInfo> *r_list, bool p_include_base) const; + + // This method will map the class name from "Reference" to "MyClass.InnerClass". + static String _get_gdscript_reference_class_name(const GDScript *p_gdscript); + protected: bool _get(const StringName &p_name, Variant &r_ret) const; bool _set(const StringName &p_name, const Variant &p_value); @@ -191,6 +211,12 @@ public: virtual void set_source_code(const String &p_code) override; virtual void update_exports() override; +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const override { + return docs; + } +#endif // TOOLS_ENABLED + virtual Error reload(bool p_keep_state = false) override; void set_script_path(const String &p_path) { path = p_path; } //because subclasses need a path too... @@ -444,6 +470,7 @@ public: virtual Script *create_script() const; virtual bool has_named_classes() const; virtual bool supports_builtin_mode() const; + virtual bool supports_documentation() const; virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index aa2fa67ef2..1b76c7f967 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -860,7 +860,12 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode * parser->push_warning(p_function->parameters[i]->identifier, GDScriptWarning::UNUSED_PARAMETER, p_function->identifier->name, p_function->parameters[i]->identifier->name); } is_shadowing(p_function->parameters[i]->identifier, "function parameter"); -#endif +#endif // DEBUG_ENABLED +#ifdef TOOLS_ENABLED + if (p_function->parameters[i]->default_value && p_function->parameters[i]->default_value->is_constant) { + p_function->default_arg_values.push_back(p_function->parameters[i]->default_value->reduced_value); + } +#endif // TOOLS_ENABLED } if (p_function->identifier->name == "_init") { @@ -1611,7 +1616,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o if (p_binary_op->reduced_value.get_type() == Variant::STRING) { push_error(vformat(R"(%s in operator %s.)", p_binary_op->reduced_value, Variant::get_operator_name(p_binary_op->variant_op)), p_binary_op); } else { - push_error(vformat(R"(Invalid operands to operator %s, %s and %s.".)", + push_error(vformat(R"(Invalid operands to operator %s, %s and %s.)", Variant::get_operator_name(p_binary_op->variant_op), Variant::get_type_name(p_binary_op->left_operand->reduced_value.get_type()), Variant::get_type_name(p_binary_op->right_operand->reduced_value.get_type())), diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 7c20cda39c..d89b89c8b9 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -40,10 +40,6 @@ uint32_t GDScriptByteCodeGenerator::add_parameter(const StringName &p_name, bool function->_argument_count++; function->argument_types.push_back(p_type); if (p_is_optional) { - if (function->_default_arg_count == 0) { - append(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT); - } - function->default_arguments.push_back(opcodes.size()); function->_default_arg_count++; } @@ -96,7 +92,12 @@ void GDScriptByteCodeGenerator::pop_temporary() { current_temporaries--; } -void GDScriptByteCodeGenerator::start_parameters() {} +void GDScriptByteCodeGenerator::start_parameters() { + if (function->_default_arg_count > 0) { + append(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT); + function->default_arguments.push_back(opcodes.size()); + } +} void GDScriptByteCodeGenerator::end_parameters() { function->default_arguments.invert(); @@ -167,7 +168,7 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { } if (function->default_arguments.size()) { - function->_default_arg_count = function->default_arguments.size(); + function->_default_arg_count = function->default_arguments.size() - 1; function->_default_arg_ptr = &function->default_arguments[0]; } else { function->_default_arg_count = 0; @@ -633,6 +634,11 @@ void GDScriptByteCodeGenerator::write_assign_false(const Address &p_target) { append(p_target); } +void GDScriptByteCodeGenerator::write_assign_default_parameter(const Address &p_dst, const Address &p_src) { + write_assign(p_dst, p_src); + function->default_arguments.push_back(opcodes.size()); +} + void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) { int index = 0; diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index 34d2bb6098..5cbd12a0ba 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -401,6 +401,7 @@ public: virtual void write_assign(const Address &p_target, const Address &p_source) override; virtual void write_assign_true(const Address &p_target) override; virtual void write_assign_false(const Address &p_target) override; + virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override; virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) override; virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override; virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index 35e326c61f..559f9b8406 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -122,6 +122,7 @@ public: virtual void write_assign(const Address &p_target, const Address &p_source) = 0; virtual void write_assign_true(const Address &p_target) = 0; virtual void write_assign_false(const Address &p_target) = 0; + virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0; virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) = 0; virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0; virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index b41dc15324..f2d3b1fb18 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1838,7 +1838,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser return error; } GDScriptCodeGenerator::Address dst_addr = codegen.parameters[parameter->identifier->name]; - codegen.generator->write_assign(dst_addr, src_addr); + codegen.generator->write_assign_default_parameter(dst_addr, src_addr); if (src_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) { codegen.generator->pop_temporary(); } @@ -1883,6 +1883,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser codegen.generator->set_initial_line(p_func->start_line); #ifdef TOOLS_ENABLED p_script->member_lines[func_name] = p_func->start_line; + p_script->doc_functions[func_name] = p_func->doc_description; #endif } else { codegen.generator->set_initial_line(0); @@ -1896,6 +1897,21 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser p_script->implicit_initializer = gd_function; } + if (p_func) { + // if no return statement -> return type is void not unresolved Variant + if (p_func->body->has_return) { + gd_function->return_type = _gdtype_from_datatype(p_func->get_datatype()); + } else { + gd_function->return_type = GDScriptDataType(); + gd_function->return_type.has_type = true; + gd_function->return_type.kind = GDScriptDataType::BUILTIN; + gd_function->return_type.builtin_type = Variant::NIL; + } +#ifdef TOOLS_ENABLED + gd_function->default_arg_values = p_func->default_arg_values; +#endif + } + p_script->member_functions[func_name] = gd_function; memdelete(codegen.generator); @@ -1993,6 +2009,24 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } } +#ifdef TOOLS_ENABLED + p_script->doc_functions.clear(); + p_script->doc_variables.clear(); + p_script->doc_constants.clear(); + p_script->doc_enums.clear(); + p_script->doc_signals.clear(); + p_script->doc_tutorials.clear(); + + p_script->doc_brief_description = p_class->doc_brief_description; + p_script->doc_description = p_class->doc_description; + for (int i = 0; i < p_class->doc_tutorials.size(); i++) { + DocData::TutorialDoc td; + td.title = p_class->doc_tutorials[i].first; + td.link = p_class->doc_tutorials[i].second; + p_script->doc_tutorials.append(td); + } +#endif + p_script->native = Ref<GDScriptNativeClass>(); p_script->base = Ref<GDScript>(); p_script->_base = nullptr; @@ -2105,20 +2139,23 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar prop_info.hint = export_info.hint; prop_info.hint_string = export_info.hint_string; prop_info.usage = export_info.usage; -#ifdef TOOLS_ENABLED - if (variable->initializer != nullptr && variable->initializer->type == GDScriptParser::Node::LITERAL) { - p_script->member_default_values[name] = static_cast<const GDScriptParser::LiteralNode *>(variable->initializer)->value; - } -#endif } else { prop_info.usage = PROPERTY_USAGE_SCRIPT_VARIABLE; } +#ifdef TOOLS_ENABLED + p_script->doc_variables[name] = variable->doc_description; +#endif p_script->member_info[name] = prop_info; p_script->member_indices[name] = minfo; p_script->members.insert(name); #ifdef TOOLS_ENABLED + if (variable->initializer != nullptr && variable->initializer->is_constant) { + p_script->member_default_values[name] = variable->initializer->reduced_value; + } else { + p_script->member_default_values.erase(name); + } p_script->member_lines[name] = variable->start_line; #endif } break; @@ -2129,8 +2166,10 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(name, constant->initializer->reduced_value); #ifdef TOOLS_ENABLED - p_script->member_lines[name] = constant->start_line; + if (constant->doc_description != String()) { + p_script->doc_constants[name] = constant->doc_description; + } #endif } break; @@ -2141,6 +2180,15 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(name, enum_value.value); #ifdef TOOLS_ENABLED p_script->member_lines[name] = enum_value.identifier->start_line; + if (!p_script->doc_enums.has("@unnamed_enums")) { + p_script->doc_enums["@unnamed_enums"] = DocData::EnumDoc(); + p_script->doc_enums["@unnamed_enums"].name = "@unnamed_enums"; + } + DocData::ConstantDoc const_doc; + const_doc.name = enum_value.identifier->name; + const_doc.value = Variant(enum_value.value).operator String(); // TODO-DOC: enum value currently is int. + const_doc.description = enum_value.doc_description; + p_script->doc_enums["@unnamed_enums"].values.push_back(const_doc); #endif } break; @@ -2176,6 +2224,11 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar parameters_names.write[j] = signal->parameters[j]->identifier->name; } p_script->_signals[name] = parameters_names; +#ifdef TOOLS_ENABLED + if (!signal->doc_description.empty()) { + p_script->doc_signals[name] = signal->doc_description; + } +#endif } break; case GDScriptParser::ClassNode::Member::ENUM: { @@ -2192,6 +2245,16 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(enum_n->identifier->name, new_enum); #ifdef TOOLS_ENABLED p_script->member_lines[enum_n->identifier->name] = enum_n->start_line; + p_script->doc_enums[enum_n->identifier->name] = DocData::EnumDoc(); + p_script->doc_enums[enum_n->identifier->name].name = enum_n->identifier->name; + p_script->doc_enums[enum_n->identifier->name].description = enum_n->doc_description; + for (int j = 0; j < enum_n->values.size(); j++) { + DocData::ConstantDoc const_doc; + const_doc.name = enum_n->values[j].identifier->name; + const_doc.value = Variant(enum_n->values[j].value).operator String(); + const_doc.description = enum_n->values[j].doc_description; + p_script->doc_enums[enum_n->identifier->name].values.push_back(const_doc); + } #endif } break; default: diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index a426046797..af9673a9b8 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -193,6 +193,10 @@ bool GDScriptLanguage::supports_builtin_mode() const { return true; } +bool GDScriptLanguage::supports_documentation() const { + return true; +} + int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const { GDScriptTokenizer tokenizer; tokenizer.set_source_code(p_code); @@ -1054,10 +1058,8 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool } static const char *_keywords[] = { - "and", "in", "not", "or", "false", "PI", "TAU", "INF", "NAN", "self", "true", "as", "assert", - "breakpoint", "class", "extends", "is", "func", "preload", "signal", "tool", "await", - "const", "enum", "static", "super", "var", "break", "continue", "if", "elif", - "else", "for", "pass", "return", "match", "while", + "false", "PI", "TAU", "INF", "NAN", "self", "true", "breakpoint", "tool", "super", + "break", "continue", "pass", "return", 0 }; @@ -1068,6 +1070,33 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool kw++; } + static const char *_keywords_with_space[] = { + "and", "in", "not", "or", "as", "class", "extends", "is", "func", "signal", "await", + "const", "enum", "static", "var", "if", "elif", "else", "for", "match", "while", + 0 + }; + + const char **kws = _keywords_with_space; + while (*kws) { + ScriptCodeCompletionOption option(*kws, ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + option.insert_text += " "; + r_result.insert(option.display, option); + kws++; + } + + static const char *_keywords_with_args[] = { + "assert", "preload", + 0 + }; + + const char **kwa = _keywords_with_args; + while (*kwa) { + ScriptCodeCompletionOption option(*kwa, ScriptCodeCompletionOption::KIND_FUNCTION); + option.insert_text += "("; + r_result.insert(option.display, option); + kwa++; + } + Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (const Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E != nullptr; E = E->next()) { if (!E->value().is_singleton) { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index bb5cc1284d..7bc20672d5 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -379,6 +379,7 @@ private: #ifdef TOOLS_ENABLED Vector<StringName> arg_names; + Vector<Variant> default_arg_values; #endif List<StackDebug> stack_debug; @@ -458,6 +459,11 @@ public: ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), Variant()); return default_arguments[p_idx]; } +#ifdef TOOLS_ENABLED + const Vector<Variant> &get_default_arg_values() const { + return default_arg_values; + } +#endif // TOOLS_ENABLED Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state = nullptr); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 372af204f5..48fca16ab1 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -558,6 +558,17 @@ void GDScriptParser::parse_program() { parse_class_body(); +#ifdef TOOLS_ENABLED + for (Map<int, GDScriptTokenizer::CommentData>::Element *E = tokenizer.get_comments().front(); E; E = E->next()) { + if (E->get().new_line && E->get().comment.begins_with("##")) { + class_doc_line = MIN(class_doc_line, E->key()); + } + } + if (has_comment(class_doc_line)) { + get_class_doc_comment(class_doc_line, head->doc_brief_description, head->doc_description, head->doc_tutorials, false); + } +#endif // TOOLS_ENABLED + if (!check(GDScriptTokenizer::Token::TK_EOF)) { push_error("Expected end of file."); } @@ -668,6 +679,10 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() if (member == nullptr) { return; } +#ifdef TOOLS_ENABLED + int doc_comment_line = member->start_line - 1; +#endif // TOOLS_ENABLED + // Consume annotations. while (!annotation_stack.empty()) { AnnotationNode *last_annotation = annotation_stack.back()->get(); @@ -680,7 +695,25 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() clear_unused_annotations(); return; } +#ifdef TOOLS_ENABLED + if (last_annotation->start_line == doc_comment_line) { + doc_comment_line--; + } +#endif // TOOLS_ENABLED + } + +#ifdef TOOLS_ENABLED + // Consume doc comments. + class_doc_line = MIN(class_doc_line, doc_comment_line - 1); + if (has_comment(doc_comment_line)) { + if constexpr (std::is_same_v<T, ClassNode>) { + get_class_doc_comment(doc_comment_line, member->doc_brief_description, member->doc_description, member->doc_tutorials, true); + } else { + member->doc_description = get_doc_comment(doc_comment_line); + } } +#endif // TOOLS_ENABLED + if (member->identifier != nullptr) { // Enums may be unnamed. // TODO: Consider names in outer scope too, for constants and classes (and static functions?) @@ -1050,6 +1083,7 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() { item.parent_enum = enum_node; item.line = previous.start_line; item.leftmost_column = previous.leftmost_column; + item.rightmost_column = previous.rightmost_column; if (elements.has(item.identifier->name)) { push_error(vformat(R"(Name "%s" was already in this enum (at line %d).)", item.identifier->name, elements[item.identifier->name]), item.identifier); @@ -1088,6 +1122,31 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() { pop_multiline(); consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected closing "}" for enum.)"); +#ifdef TOOLS_ENABLED + // Enum values documentaion. + for (int i = 0; i < enum_node->values.size(); i++) { + if (i == enum_node->values.size() - 1) { + // If close bracket is same line as last value. + if (enum_node->values[i].line != previous.start_line && has_comment(enum_node->values[i].line)) { + if (named) { + enum_node->values.write[i].doc_description = get_doc_comment(enum_node->values[i].line, true); + } else { + current_class->set_enum_value_doc(enum_node->values[i].identifier->name, get_doc_comment(enum_node->values[i].line, true)); + } + } + } else { + // If two values are same line. + if (enum_node->values[i].line != enum_node->values[i + 1].line && has_comment(enum_node->values[i].line)) { + if (named) { + enum_node->values.write[i].doc_description = get_doc_comment(enum_node->values[i].line, true); + } else { + current_class->set_enum_value_doc(enum_node->values[i].identifier->name, get_doc_comment(enum_node->values[i].line, true)); + } + } + } + } +#endif // TOOLS_ENABLED + end_statement("enum"); return enum_node; @@ -2624,6 +2683,218 @@ GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) { return type; } +#ifdef TOOLS_ENABLED +static bool _in_codeblock(String p_line, bool p_already_in, int *r_block_begins = nullptr) { + int start_block = p_line.rfind("[codeblock]"); + int end_block = p_line.rfind("[/codeblock]"); + + if (start_block != -1 && r_block_begins) { + *r_block_begins = start_block; + } + + if (p_already_in) { + if (end_block == -1) { + return true; + } else if (start_block == -1) { + return false; + } else { + return start_block > end_block; + } + } else { + if (start_block == -1) { + return false; + } else if (end_block == -1) { + return true; + } else { + return start_block > end_block; + } + } +} + +bool GDScriptParser::has_comment(int p_line) { + return tokenizer.get_comments().has(p_line); +} + +String GDScriptParser::get_doc_comment(int p_line, bool p_single_line) { + const Map<int, GDScriptTokenizer::CommentData> &comments = tokenizer.get_comments(); + ERR_FAIL_COND_V(!comments.has(p_line), String()); + + if (p_single_line) { + if (comments[p_line].comment.begins_with("##")) { + return comments[p_line].comment.trim_prefix("##").strip_edges(); + } + return ""; + } + + String doc; + + int line = p_line; + bool in_codeblock = false; + + while (comments.has(line - 1)) { + if (!comments[line - 1].new_line || !comments[line - 1].comment.begins_with("##")) { + break; + } + line--; + } + + int codeblock_begins = 0; + while (comments.has(line)) { + if (!comments[line].new_line || !comments[line].comment.begins_with("##")) { + break; + } + String doc_line = comments[line].comment.trim_prefix("##"); + + in_codeblock = _in_codeblock(doc_line, in_codeblock, &codeblock_begins); + + if (in_codeblock) { + int i = 0; + for (; i < codeblock_begins; i++) { + if (doc_line[i] != ' ') { + break; + } + } + doc_line = doc_line.substr(i); + } else { + doc_line = doc_line.strip_edges(); + } + String line_join = (in_codeblock) ? "\n" : " "; + + doc = (doc.empty()) ? doc_line : doc + line_join + doc_line; + line++; + } + + return doc; +} + +void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &p_desc, Vector<Pair<String, String>> &p_tutorials, bool p_inner_class) { + const Map<int, GDScriptTokenizer::CommentData> &comments = tokenizer.get_comments(); + if (!comments.has(p_line)) { + return; + } + ERR_FAIL_COND(p_brief != "" || p_desc != "" || p_tutorials.size() != 0); + + int line = p_line; + bool in_codeblock = false; + enum Mode { + BRIEF, + DESC, + TUTORIALS, + DONE, + }; + Mode mode = BRIEF; + + if (p_inner_class) { + while (comments.has(line - 1)) { + if (!comments[line - 1].new_line || !comments[line - 1].comment.begins_with("##")) { + break; + } + line--; + } + } + + int codeblock_begins = 0; + while (comments.has(line)) { + if (!comments[line].new_line || !comments[line].comment.begins_with("##")) { + break; + } + + String title, link; // For tutorials. + String doc_line = comments[line++].comment.trim_prefix("##"); + String striped_line = doc_line.strip_edges(); + + // Set the read mode. + if (striped_line.begins_with("@desc:") && p_desc == "") { + mode = DESC; + striped_line = striped_line.trim_prefix("@desc:"); + in_codeblock = _in_codeblock(doc_line, in_codeblock); + + } else if (striped_line.begins_with("@tutorial")) { + int begin_scan = String("@tutorial").length(); + if (begin_scan >= striped_line.length()) { + continue; // invalid syntax. + } + + if (striped_line[begin_scan] == ':') { // No title. + // Syntax: ## @tutorial: https://godotengine.org/ // The title argument is optional. + title = ""; + link = striped_line.trim_prefix("@tutorial:").strip_edges(); + + } else { + /* Syntax: + @tutorial ( The Title Here ) : http://the.url/ + ^ open ^ close ^ colon ^ url + */ + int open_bracket_pos = begin_scan, close_bracket_pos = 0; + while (open_bracket_pos < striped_line.length() && (striped_line[open_bracket_pos] == ' ' || striped_line[open_bracket_pos] == '\t')) { + open_bracket_pos++; + } + if (open_bracket_pos == striped_line.length() || striped_line[open_bracket_pos++] != '(') { + continue; // invalid syntax. + } + close_bracket_pos = open_bracket_pos; + while (close_bracket_pos < striped_line.length() && striped_line[close_bracket_pos] != ')') { + close_bracket_pos++; + } + if (close_bracket_pos == striped_line.length()) { + continue; // invalid syntax. + } + + int colon_pos = close_bracket_pos + 1; + while (colon_pos < striped_line.length() && (striped_line[colon_pos] == ' ' || striped_line[colon_pos] == '\t')) { + colon_pos++; + } + if (colon_pos == striped_line.length() || striped_line[colon_pos++] != ':') { + continue; // invalid syntax. + } + + title = striped_line.substr(open_bracket_pos, close_bracket_pos - open_bracket_pos).strip_edges(); + link = striped_line.substr(colon_pos).strip_edges(); + } + + mode = TUTORIALS; + in_codeblock = false; + } else if (striped_line.empty()) { + continue; + } else { + // Tutorial docs are single line, we need a @tag after it. + if (mode == TUTORIALS) { + mode = DONE; + } + + in_codeblock = _in_codeblock(doc_line, in_codeblock, &codeblock_begins); + } + + if (in_codeblock) { + int i = 0; + for (; i < codeblock_begins; i++) { + if (doc_line[i] != ' ') { + break; + } + } + doc_line = doc_line.substr(i); + } else { + doc_line = striped_line; + } + String line_join = (in_codeblock) ? "\n" : " "; + + switch (mode) { + case BRIEF: + p_brief = (p_brief.length() == 0) ? doc_line : p_brief + line_join + doc_line; + break; + case DESC: + p_desc = (p_desc.length() == 0) ? doc_line : p_desc + line_join + doc_line; + break; + case TUTORIALS: + p_tutorials.append(Pair<String, String>(title, link)); + break; + case DONE: + return; + } + } +} +#endif // TOOLS_ENABLED + GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Type p_token_type) { // Function table for expression parsing. // clang-format destroys the alignment here, so turn off for the table. diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index b24acc4778..44605bc20f 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -413,9 +413,16 @@ public: int line = 0; int leftmost_column = 0; int rightmost_column = 0; +#ifdef TOOLS_ENABLED + String doc_description; +#endif // TOOLS_ENABLED }; + IdentifierNode *identifier = nullptr; Vector<Value> values; +#ifdef TOOLS_ENABLED + String doc_description; +#endif // TOOLS_ENABLED EnumNode() { type = ENUM; @@ -568,6 +575,17 @@ public: Vector<StringName> extends; // List for indexing: extends A.B.C DataType base_type; String fqcn; // Fully-qualified class name. Identifies uniquely any class in the project. +#ifdef TOOLS_ENABLED + String doc_description; + String doc_brief_description; + Vector<Pair<String, String>> doc_tutorials; + + // EnumValue docs are parsed after itself, so we need a method to add/modify the doc property later. + void set_enum_value_doc(const StringName &p_name, const String &p_doc_description) { + ERR_FAIL_INDEX(members_indices[p_name], members.size()); + members.write[members_indices[p_name]].enum_value.doc_description = p_doc_description; + } +#endif // TOOLS_ENABLED bool resolved_interface = false; bool resolved_body = false; @@ -602,6 +620,9 @@ public: TypeNode *datatype_specifier = nullptr; bool infer_datatype = false; int usages = 0; +#ifdef TOOLS_ENABLED + String doc_description; +#endif // TOOLS_ENABLED ConstantNode() { type = CONSTANT; @@ -653,6 +674,10 @@ public: bool is_coroutine = false; MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; MethodInfo info; +#ifdef TOOLS_ENABLED + Vector<Variant> default_arg_values; + String doc_description; +#endif // TOOLS_ENABLED bool resolved_signature = false; bool resolved_body = false; @@ -820,6 +845,9 @@ public: IdentifierNode *identifier = nullptr; Vector<ParameterNode *> parameters; HashMap<StringName, int> parameters_indices; +#ifdef TOOLS_ENABLED + String doc_description; +#endif // TOOLS_ENABLED SignalNode() { type = SIGNAL; @@ -1012,6 +1040,9 @@ public: MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; int assignments = 0; int usages = 0; +#ifdef TOOLS_ENABLED + String doc_description; +#endif // TOOLS_ENABLED VariableNode() { type = VARIABLE; @@ -1270,6 +1301,13 @@ private: ExpressionNode *parse_subscript(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_invalid_token(ExpressionNode *p_previous_operand, bool p_can_assign); TypeNode *parse_type(bool p_allow_void = false); +#ifdef TOOLS_ENABLED + // Doc comments. + int class_doc_line = 0x7FFFFFFF; + bool has_comment(int p_line); + String get_doc_comment(int p_line, bool p_single_line = false); + void get_class_doc_comment(int p_line, String &p_brief, String &p_desc, Vector<Pair<String, String>> &p_tutorials, bool p_inner_class); +#endif // TOOLS_ENABLED public: Error parse(const String &p_source_code, const String &p_script_path, bool p_for_completion); diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index b91777ede1..ac43105254 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -1014,9 +1014,17 @@ void GDScriptTokenizer::check_indent() { } if (_peek() == '#') { // Comment. Advance to the next line. +#ifdef TOOLS_ENABLED + String comment; + while (_peek() != '\n' && !_is_at_end()) { + comment += _advance(); + } + comments[line] = CommentData(comment, true); +#else while (_peek() != '\n' && !_is_at_end()) { _advance(); } +#endif // TOOLS_ENABLED if (_is_at_end()) { // Reached the end with an empty line, so just dedent as much as needed. pending_indents -= indent_level(); @@ -1125,18 +1133,26 @@ void GDScriptTokenizer::_skip_whitespace() { newline(!is_bol); // Don't create new line token if line is empty. check_indent(); break; - case '#': + case '#': { // Comment. +#ifdef TOOLS_ENABLED + String comment; + while (_peek() != '\n' && !_is_at_end()) { + comment += _advance(); + } + comments[line] = CommentData(comment, is_bol); +#else while (_peek() != '\n' && !_is_at_end()) { _advance(); } +#endif // TOOLS_ENABLED if (_is_at_end()) { return; } _advance(); // Consume '\n' newline(!is_bol); check_indent(); - break; + } break; default: return; } diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index d51f1f250f..f236c86f9f 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -32,6 +32,7 @@ #define GDSCRIPT_TOKENIZER_H #include "core/templates/list.h" +#include "core/templates/map.h" #include "core/templates/set.h" #include "core/templates/vector.h" #include "core/variant/variant.h" @@ -181,6 +182,21 @@ public: } }; +#ifdef TOOLS_ENABLED + struct CommentData { + String comment; + bool new_line = false; + CommentData() {} + CommentData(const String &p_comment, bool p_new_line) { + comment = p_comment; + new_line = p_new_line; + } + }; + const Map<int, CommentData> &get_comments() const { + return comments; + } +#endif // TOOLS_ENABLED + private: String source; const char32_t *_source = nullptr; @@ -207,6 +223,10 @@ private: int position = 0; int length = 0; +#ifdef TOOLS_ENABLED + Map<int, CommentData> comments; +#endif // TOOLS_ENABLED + _FORCE_INLINE_ bool _is_at_end() { return position >= length; } _FORCE_INLINE_ char32_t _peek(int p_offset = 0) { return position + p_offset >= 0 && position + p_offset < length ? _current[p_offset] : '\0'; } int indent_level() const { return indent_stack.size(); } diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 6ddb0d149e..729be237ec 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/io/json.h" #include "core/os/copymem.h" +#include "editor/doc_tools.h" #include "editor/editor_log.h" #include "editor/editor_node.h" @@ -212,7 +213,7 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { void GDScriptLanguageProtocol::initialized(const Variant &p_params) { lsp::GodotCapabilities capabilities; - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { lsp::GodotNativeClassInfo gdclass; gdclass.name = E->get().name; diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index f6643d07f9..60668e7b31 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -34,6 +34,7 @@ #include "../gdscript_parser.h" #include "core/config/project_settings.h" #include "core/object/script_language.h" +#include "editor/doc_tools.h" #include "editor/editor_file_system.h" #include "editor/editor_help.h" #include "editor/editor_node.h" @@ -189,7 +190,7 @@ Error GDScriptWorkspace::initialize() { return OK; } - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { const DocData::ClassDoc &class_data = E->value(); lsp::DocumentSymbol class_symbol; diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 288fd41c87..1029c53bbf 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -31,9 +31,9 @@ #ifndef GODOT_LSP_H #define GODOT_LSP_H +#include "core/doc_data.h" #include "core/object/class_db.h" #include "core/templates/list.h" -#include "editor/doc_data.h" namespace lsp { diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 0e6ec7f520..cda217acf0 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1030,11 +1030,15 @@ void GridMapEditor::_notification(int p_what) { for (int i = 0; i < 3; i++) { grid[i] = RS::get_singleton()->mesh_create(); grid_instance[i] = RS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); selection_level_instance[i] = RenderingServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(selection_level_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); } selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(selection_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(paste_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); _update_selection_transform(); _update_paste_indicator(); diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 1ef991841b..49ae6e28b2 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -543,7 +543,7 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i tf.width = grid_size; tf.height = grid_size; tf.depth = grid_size; - tf.type = RD::TEXTURE_TYPE_3D; + tf.texture_type = RD::TEXTURE_TYPE_3D; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; Vector<Vector<uint8_t>> texdata; @@ -695,7 +695,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d tf.width = atlas_size.width; tf.height = atlas_size.height; tf.array_layers = atlas_slices; - tf.type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; @@ -826,84 +826,84 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(vertex_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; u.ids.push_back(triangle_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; u.ids.push_back(box_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; u.ids.push_back(triangle_cell_indices_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 5; u.ids.push_back(lights_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; u.ids.push_back(seams_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 7; u.ids.push_back(probe_positions_buffer); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 8; u.ids.push_back(grid_texture); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; u.ids.push_back(grid_texture_sdf); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 10; u.ids.push_back(albedo_array_tex); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 11; u.ids.push_back(emission_array_tex); base_uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 12; u.ids.push_back(sampler); base_uniforms.push_back(u); @@ -917,7 +917,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d tf.width = atlas_size.width; tf.height = atlas_size.height; tf.depth = 1; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; tf.format = RD::DATA_FORMAT_D32_SFLOAT; @@ -1049,14 +1049,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(position_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(unocclude_tex); //will be unused uniforms.push_back(u); @@ -1089,42 +1089,42 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(light_source_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; u.ids.push_back(light_dest_tex); //will be unused uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; u.ids.push_back(position_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; u.ids.push_back(normal_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; u.ids.push_back(light_accum_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; u.ids.push_back(light_primary_dynamic_tex); uniforms.push_back(u); @@ -1169,49 +1169,49 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(light_dest_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; u.ids.push_back(light_source_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; u.ids.push_back(position_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; u.ids.push_back(normal_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; u.ids.push_back(light_accum_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; u.ids.push_back(unocclude_tex); //reuse unocclude tex uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 6; u.ids.push_back(light_environment_tex); //reuse unocclude tex uniforms.push_back(u); @@ -1317,28 +1317,28 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(light_probe_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; u.ids.push_back(light_dest_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; u.ids.push_back(light_primary_dynamic_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; u.ids.push_back(light_environment_tex); uniforms.push_back(u); @@ -1463,14 +1463,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(light_accum_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; u.ids.push_back(light_accum_tex2); uniforms.push_back(u); @@ -1554,7 +1554,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; u.ids.push_back(light_accum_tex2); uniforms.push_back(u); diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 5f5d25a3ee..3b1739c6ee 100755 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -100,3 +100,7 @@ if env["builtin_mbedtls"]: # Module sources env_mbed_tls.add_source_files(env.modules_sources, "*.cpp") + +if env["tests"]: + env_mbed_tls.Append(CPPDEFINES=["TESTS_ENABLED"]) + env_mbed_tls.add_source_files(env.modules_sources, "./tests/*.cpp") diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index bec792450a..4ea38ebd60 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -44,6 +44,7 @@ #define PEM_END_CRT "-----END CERTIFICATE-----\n" #include <mbedtls/debug.h> +#include <mbedtls/md.h> #include <mbedtls/pem.h> CryptoKey *CryptoKeyMbedTLS::create() { @@ -186,6 +187,68 @@ Error X509CertificateMbedTLS::save(String p_path) { return OK; } +bool HMACContextMbedTLS::is_md_type_allowed(mbedtls_md_type_t p_md_type) { + switch (p_md_type) { + case MBEDTLS_MD_SHA1: + case MBEDTLS_MD_SHA256: + return true; + default: + return false; + } +} + +HMACContext *HMACContextMbedTLS::create() { + return memnew(HMACContextMbedTLS); +} + +Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, PackedByteArray p_key) { + ERR_FAIL_COND_V_MSG(ctx != nullptr, ERR_FILE_ALREADY_IN_USE, "HMACContext already started."); + + // HMAC keys can be any size. + ERR_FAIL_COND_V_MSG(p_key.empty(), ERR_INVALID_PARAMETER, "Key must not be empty."); + + hash_type = p_hash_type; + mbedtls_md_type_t ht = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, hash_len); + + bool allowed = HMACContextMbedTLS::is_md_type_allowed(ht); + ERR_FAIL_COND_V_MSG(!allowed, ERR_INVALID_PARAMETER, "Unsupported hash type."); + + ctx = memalloc(sizeof(mbedtls_md_context_t)); + mbedtls_md_init((mbedtls_md_context_t *)ctx); + + mbedtls_md_setup((mbedtls_md_context_t *)ctx, mbedtls_md_info_from_type((mbedtls_md_type_t)ht), 1); + int ret = mbedtls_md_hmac_starts((mbedtls_md_context_t *)ctx, (const uint8_t *)p_key.ptr(), (size_t)p_key.size()); + return ret ? FAILED : OK; +} + +Error HMACContextMbedTLS::update(PackedByteArray p_data) { + ERR_FAIL_COND_V_MSG(ctx == nullptr, ERR_INVALID_DATA, "Start must be called before update."); + + ERR_FAIL_COND_V_MSG(p_data.empty(), ERR_INVALID_PARAMETER, "Src must not be empty."); + + int ret = mbedtls_md_hmac_update((mbedtls_md_context_t *)ctx, (const uint8_t *)p_data.ptr(), (size_t)p_data.size()); + return ret ? FAILED : OK; +} + +PackedByteArray HMACContextMbedTLS::finish() { + ERR_FAIL_COND_V_MSG(ctx == nullptr, PackedByteArray(), "Start must be called before finish."); + ERR_FAIL_COND_V_MSG(hash_len == 0, PackedByteArray(), "Unsupported hash type."); + + PackedByteArray out; + out.resize(hash_len); + + unsigned char *out_ptr = (unsigned char *)out.ptrw(); + int ret = mbedtls_md_hmac_finish((mbedtls_md_context_t *)ctx, out_ptr); + + mbedtls_md_free((mbedtls_md_context_t *)ctx); + memfree((mbedtls_md_context_t *)ctx); + ctx = nullptr; + hash_len = 0; + + ERR_FAIL_COND_V_MSG(ret, PackedByteArray(), "Error received while finishing HMAC"); + return out; +} + Crypto *CryptoMbedTLS::create() { return memnew(CryptoMbedTLS); } @@ -199,6 +262,7 @@ void CryptoMbedTLS::initialize_crypto() { Crypto::_load_default_certificates = load_default_certificates; X509CertificateMbedTLS::make_default(); CryptoKeyMbedTLS::make_default(); + HMACContextMbedTLS::make_default(); } void CryptoMbedTLS::finalize_crypto() { @@ -210,6 +274,7 @@ void CryptoMbedTLS::finalize_crypto() { } X509CertificateMbedTLS::finalize(); CryptoKeyMbedTLS::finalize(); + HMACContextMbedTLS::finalize(); } CryptoMbedTLS::CryptoMbedTLS() { @@ -313,7 +378,7 @@ PackedByteArray CryptoMbedTLS::generate_random_bytes(int p_bytes) { return out; } -mbedtls_md_type_t CryptoMbedTLS::_md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size) { +mbedtls_md_type_t CryptoMbedTLS::md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size) { switch (p_hash_type) { case HashingContext::HASH_MD5: r_size = 16; @@ -332,7 +397,7 @@ mbedtls_md_type_t CryptoMbedTLS::_md_type_from_hashtype(HashingContext::HashType Vector<uint8_t> CryptoMbedTLS::sign(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Ref<CryptoKey> p_key) { int size; - mbedtls_md_type_t type = _md_type_from_hashtype(p_hash_type, size); + mbedtls_md_type_t type = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, size); ERR_FAIL_COND_V_MSG(type == MBEDTLS_MD_NONE, Vector<uint8_t>(), "Invalid hash type."); ERR_FAIL_COND_V_MSG(p_hash.size() != size, Vector<uint8_t>(), "Invalid hash provided. Size must be " + itos(size)); Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS>>(p_key); @@ -350,7 +415,7 @@ Vector<uint8_t> CryptoMbedTLS::sign(HashingContext::HashType p_hash_type, Vector bool CryptoMbedTLS::verify(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Vector<uint8_t> p_signature, Ref<CryptoKey> p_key) { int size; - mbedtls_md_type_t type = _md_type_from_hashtype(p_hash_type, size); + mbedtls_md_type_t type = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, size); ERR_FAIL_COND_V_MSG(type == MBEDTLS_MD_NONE, false, "Invalid hash type."); ERR_FAIL_COND_V_MSG(p_hash.size() != size, false, "Invalid hash provided. Size must be " + itos(size)); Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS>>(p_key); diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h index e40ca08643..990f8ae578 100644 --- a/modules/mbedtls/crypto_mbedtls.h +++ b/modules/mbedtls/crypto_mbedtls.h @@ -101,12 +101,31 @@ public: friend class SSLContextMbedTLS; }; +class HMACContextMbedTLS : public HMACContext { +private: + HashingContext::HashType hash_type; + int hash_len = 0; + void *ctx = nullptr; + +public: + static HMACContext *create(); + static void make_default() { HMACContext::_create = create; } + static void finalize() { HMACContext::_create = nullptr; } + + static bool is_md_type_allowed(mbedtls_md_type_t p_md_type); + + virtual Error start(HashingContext::HashType p_hash_type, PackedByteArray p_key); + virtual Error update(PackedByteArray p_data); + virtual PackedByteArray finish(); + + HMACContextMbedTLS() {} +}; + class CryptoMbedTLS : public Crypto { private: mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; static X509CertificateMbedTLS *default_certs; - mbedtls_md_type_t _md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size); public: static Crypto *create(); @@ -114,6 +133,7 @@ public: static void finalize_crypto(); static X509CertificateMbedTLS *get_default_certificates(); static void load_default_certificates(String p_path); + static mbedtls_md_type_t md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size); virtual PackedByteArray generate_random_bytes(int p_bytes); virtual Ref<CryptoKey> generate_rsa(int p_bytes); diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp index 84a27c29bd..59abbac8ec 100644 --- a/modules/mbedtls/register_types.cpp +++ b/modules/mbedtls/register_types.cpp @@ -35,6 +35,10 @@ #include "packet_peer_mbed_dtls.h" #include "stream_peer_mbedtls.h" +#ifdef TESTS_ENABLED +#include "tests/test_crypto_mbedtls.h" +#endif + void register_mbedtls_types() { CryptoMbedTLS::initialize_crypto(); StreamPeerMbedTLS::initialize_ssl(); diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.cpp b/modules/mbedtls/tests/test_crypto_mbedtls.cpp new file mode 100644 index 0000000000..c5a27aa794 --- /dev/null +++ b/modules/mbedtls/tests/test_crypto_mbedtls.cpp @@ -0,0 +1,62 @@ +/*************************************************************************/ +/* test_crypto_mbedtls.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "modules/mbedtls/tests/test_crypto_mbedtls.h" + +#include "modules/mbedtls/crypto_mbedtls.h" +#include "tests/test_macros.h" + +namespace TestCryptoMbedTLS { + +void hmac_digest_test(HashingContext::HashType ht, String expected_hex) { + CryptoMbedTLS crypto; + PackedByteArray key = String("supersecretkey").to_utf8_buffer(); + PackedByteArray msg = String("Return of the MAC!").to_utf8_buffer(); + PackedByteArray digest = crypto.hmac_digest(ht, key, msg); + String hex = String::hex_encode_buffer(digest.ptr(), digest.size()); + CHECK(hex == expected_hex); +} + +void hmac_context_digest_test(HashingContext::HashType ht, String expected_hex) { + HMACContextMbedTLS ctx; + PackedByteArray key = String("supersecretkey").to_utf8_buffer(); + PackedByteArray msg1 = String("Return of ").to_utf8_buffer(); + PackedByteArray msg2 = String("the MAC!").to_utf8_buffer(); + Error err = ctx.start(ht, key); + CHECK(err == OK); + err = ctx.update(msg1); + CHECK(err == OK); + err = ctx.update(msg2); + CHECK(err == OK); + PackedByteArray digest = ctx.finish(); + String hex = String::hex_encode_buffer(digest.ptr(), digest.size()); + CHECK(hex == expected_hex); +} +} // namespace TestCryptoMbedTLS diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.h b/modules/mbedtls/tests/test_crypto_mbedtls.h new file mode 100644 index 0000000000..7b1e062239 --- /dev/null +++ b/modules/mbedtls/tests/test_crypto_mbedtls.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/* test_crypto_mbedtls.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef TEST_CRYPTO_MBEDTLS_H +#define TEST_CRYPTO_MBEDTLS_H + +#include "core/crypto/hashing_context.h" + +#include "tests/test_macros.h" + +namespace TestCryptoMbedTLS { + +void hmac_digest_test(HashingContext::HashType ht, String expected_hex); + +TEST_CASE("[CryptoMbedTLS] HMAC digest") { + // SHA-256 + hmac_digest_test(HashingContext::HashType::HASH_SHA256, "fe442023f8a7d36a810e1e7cd8a8e2816457f350a008fbf638296afa12085e59"); + + // SHA-1 + hmac_digest_test(HashingContext::HashType::HASH_SHA1, "a0ac4cd68a2f4812c355983d94e8d025afe7dddf"); +} + +void hmac_context_digest_test(HashingContext::HashType ht, String expected_hex); + +TEST_CASE("[HMACContext] HMAC digest") { + // SHA-256 + hmac_context_digest_test(HashingContext::HashType::HASH_SHA256, "fe442023f8a7d36a810e1e7cd8a8e2816457f350a008fbf638296afa12085e59"); + + // SHA-1 + hmac_context_digest_test(HashingContext::HashType::HASH_SHA1, "a0ac4cd68a2f4812c355983d94e8d025afe7dddf"); +} +} // namespace TestCryptoMbedTLS + +#endif // TEST_CRYPTO_MBEDTLS_H diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py index 04f8c80243..28494bff6e 100644 --- a/modules/mono/build_scripts/make_android_mono_config.py +++ b/modules/mono/build_scripts/make_android_mono_config.py @@ -38,10 +38,10 @@ String get_godot_android_mono_config() { Vector<uint8_t> data; data.resize(config_uncompressed_size); uint8_t* w = data.ptrw(); - Compression::decompress(w.ptr(), config_uncompressed_size, config_compressed_data, + Compression::decompress(w, config_uncompressed_size, config_compressed_data, config_compressed_size, Compression::MODE_DEFLATE); String s; - if (s.parse_utf8((const char *)w.ptr(), data.size())) { + if (s.parse_utf8((const char *)w, data.size())) { ERR_FAIL_V(String()); } return s; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b4537f531d..63ac0956f4 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2984,7 +2984,7 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { p_script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); } -#if TOOLS_ENABLED +#ifdef TOOLS_ENABLED if (!p_script->tool) { p_script->tool = p_script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 3e4e6c3f86..f482cc21f0 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -31,6 +31,7 @@ #ifndef CSHARP_SCRIPT_H #define CSHARP_SCRIPT_H +#include "core/doc_data.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/object/script_language.h" @@ -189,6 +190,14 @@ public: String get_source_code() const override; void set_source_code(const String &p_code) override; +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const override { + // TODO + static Vector<DocData::ClassDoc> docs; + return docs; + } +#endif // TOOLS_ENABLED + Error reload(bool p_keep_state = false) override; bool has_script_signal(const StringName &p_signal) const override; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index 9514cc9622..1a1639aac7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -2,6 +2,7 @@ using Godot; using System; using Godot.Collections; using GodotTools.Internals; +using JetBrains.Annotations; using File = GodotTools.Utils.File; using Path = System.IO.Path; @@ -26,6 +27,9 @@ namespace GodotTools.Build private TextEdit buildLog; private PopupMenu issuesListContextMenu; + private readonly object pendingBuildLogTextLock = new object(); + [NotNull] private string pendingBuildLogText = string.Empty; + [Signal] public event Action BuildStateChanged; public bool HasBuildExited { get; private set; } = false; @@ -240,16 +244,34 @@ namespace GodotTools.Build EmitSignal(nameof(BuildStateChanged)); } + private void UpdateBuildLogText() + { + lock (pendingBuildLogTextLock) + { + buildLog.Text += pendingBuildLogText; + pendingBuildLogText = string.Empty; + ScrollToLastNonEmptyLogLine(); + } + } + private void StdOutputReceived(string text) { - buildLog.Text += text + "\n"; - ScrollToLastNonEmptyLogLine(); + lock (pendingBuildLogTextLock) + { + if (pendingBuildLogText.Length == 0) + CallDeferred(nameof(UpdateBuildLogText)); + pendingBuildLogText += text + "\n"; + } } private void StdErrorReceived(string text) { - buildLog.Text += text + "\n"; - ScrollToLastNonEmptyLogLine(); + lock (pendingBuildLogTextLock) + { + if (pendingBuildLogText.Length == 0) + CallDeferred(nameof(UpdateBuildLogText)); + pendingBuildLogText += text + "\n"; + } } private void ScrollToLastNonEmptyLogLine() @@ -377,12 +399,14 @@ namespace GodotTools.Build BuildManager.BuildStarted += BuildStarted; BuildManager.BuildFinished += BuildFinished; // StdOutput/Error can be received from different threads, so we need to use CallDeferred - BuildManager.StdOutputReceived += line => CallDeferred(nameof(StdOutputReceived), line); - BuildManager.StdErrorReceived += line => CallDeferred(nameof(StdErrorReceived), line); + BuildManager.StdOutputReceived += StdOutputReceived; + BuildManager.StdErrorReceived += StdErrorReceived; } public void OnBeforeSerialize() { + // In case it didn't update yet. We don't want to have to serialize any pending output. + UpdateBuildLogText(); } public void OnAfterDeserialize() diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index ff3122a77f..968f9f29c7 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -185,7 +185,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf return String(); } - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); String bbcode = p_bbcode; diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index eeab518954..6fefcd48a4 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -31,9 +31,10 @@ #ifndef BINDINGS_GENERATOR_H #define BINDINGS_GENERATOR_H +#include "core/doc_data.h" #include "core/object/class_db.h" #include "core/string/string_builder.h" -#include "editor/doc_data.h" +#include "editor/doc_tools.h" #include "editor/editor_help.h" #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 350eafb4fd..05fd57255c 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -480,6 +480,7 @@ void set_pending_exception(MonoException *p_exc) { #else if (get_runtime_invoke_count() == 0) { debug_unhandled_exception(p_exc); + return; } if (!mono_runtime_set_pending_exception(p_exc, false)) { diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index 5f9bc38205..f220abfb4c 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -48,18 +48,10 @@ Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signa } bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { + // Only called if both instances are of type SignalAwaiterCallable. Static cast is safe. const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a); const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b); - - if (a->target_id != b->target_id) { - return false; - } - - if (a->signal != b->signal) { - return false; - } - - return true; + return a->awaiter_handle.handle == b->awaiter_handle.handle; } bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { diff --git a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml index d89828037f..9fe4c9c249 100644 --- a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml +++ b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml @@ -24,7 +24,7 @@ <tutorials> </tutorials> <methods> - <method name="get_image"> + <method name="get_image" qualifiers="const"> <return type="Image"> </return> <argument index="0" name="width" type="int"> @@ -35,7 +35,7 @@ Generate a noise image with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. </description> </method> - <method name="get_noise_1d"> + <method name="get_noise_1d" qualifiers="const"> <return type="float"> </return> <argument index="0" name="x" type="float"> @@ -45,7 +45,7 @@ [b]Note:[/b] This method actually returns the 2D noise value [code][-1,1][/code] with fixed y-coordinate value 0.0. </description> </method> - <method name="get_noise_2d"> + <method name="get_noise_2d" qualifiers="const"> <return type="float"> </return> <argument index="0" name="x" type="float"> @@ -56,7 +56,7 @@ Returns the 2D noise value [code][-1,1][/code] at the given position. </description> </method> - <method name="get_noise_2dv"> + <method name="get_noise_2dv" qualifiers="const"> <return type="float"> </return> <argument index="0" name="pos" type="Vector2"> @@ -65,7 +65,7 @@ Returns the 2D noise value [code][-1,1][/code] at the given position. </description> </method> - <method name="get_noise_3d"> + <method name="get_noise_3d" qualifiers="const"> <return type="float"> </return> <argument index="0" name="x" type="float"> @@ -78,7 +78,7 @@ Returns the 3D noise value [code][-1,1][/code] at the given position. </description> </method> - <method name="get_noise_3dv"> + <method name="get_noise_3dv" qualifiers="const"> <return type="float"> </return> <argument index="0" name="pos" type="Vector3"> @@ -87,7 +87,7 @@ Returns the 3D noise value [code][-1,1][/code] at the given position. </description> </method> - <method name="get_noise_4d"> + <method name="get_noise_4d" qualifiers="const"> <return type="float"> </return> <argument index="0" name="x" type="float"> @@ -102,7 +102,7 @@ Returns the 4D noise value [code][-1,1][/code] at the given position. </description> </method> - <method name="get_seamless_image"> + <method name="get_seamless_image" qualifiers="const"> <return type="Image"> </return> <argument index="0" name="size" type="int"> diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp index b08219d258..aded4d2a07 100644 --- a/modules/opensimplex/open_simplex_noise.cpp +++ b/modules/opensimplex/open_simplex_noise.cpp @@ -63,7 +63,7 @@ void OpenSimplexNoise::set_seed(int p_seed) { emit_changed(); } -int OpenSimplexNoise::get_seed() { +int OpenSimplexNoise::get_seed() const { return seed; } @@ -102,7 +102,7 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) { emit_changed(); } -Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) { +Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const { Vector<uint8_t> data; data.resize(p_width * p_height * 4); @@ -124,7 +124,7 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) { return image; } -Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) { +Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const { Vector<uint8_t> data; data.resize(p_size * p_size * 4); @@ -193,11 +193,11 @@ void OpenSimplexNoise::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity"); } -float OpenSimplexNoise::get_noise_1d(float x) { +float OpenSimplexNoise::get_noise_1d(float x) const { return get_noise_2d(x, 1.0); } -float OpenSimplexNoise::get_noise_2d(float x, float y) { +float OpenSimplexNoise::get_noise_2d(float x, float y) const { x /= period; y /= period; @@ -217,7 +217,7 @@ float OpenSimplexNoise::get_noise_2d(float x, float y) { return sum / max; } -float OpenSimplexNoise::get_noise_3d(float x, float y, float z) { +float OpenSimplexNoise::get_noise_3d(float x, float y, float z) const { x /= period; y /= period; z /= period; @@ -239,7 +239,7 @@ float OpenSimplexNoise::get_noise_3d(float x, float y, float z) { return sum / max; } -float OpenSimplexNoise::get_noise_4d(float x, float y, float z, float w) { +float OpenSimplexNoise::get_noise_4d(float x, float y, float z, float w) const { x /= period; y /= period; z /= period; diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h index 835f8ed35e..d9bf05115d 100644 --- a/modules/opensimplex/open_simplex_noise.h +++ b/modules/opensimplex/open_simplex_noise.h @@ -61,7 +61,7 @@ public: void _init_seeds(); void set_seed(int seed); - int get_seed(); + int get_seed() const; void set_octaves(int p_octaves); int get_octaves() const { return octaves; } @@ -75,22 +75,22 @@ public: void set_lacunarity(float p_lacunarity); float get_lacunarity() const { return lacunarity; } - Ref<Image> get_image(int p_width, int p_height); - Ref<Image> get_seamless_image(int p_size); + Ref<Image> get_image(int p_width, int p_height) const; + Ref<Image> get_seamless_image(int p_size) const; - float get_noise_1d(float x); - float get_noise_2d(float x, float y); - float get_noise_3d(float x, float y, float z); - float get_noise_4d(float x, float y, float z, float w); + float get_noise_1d(float x) const; + float get_noise_2d(float x, float y) const; + float get_noise_3d(float x, float y, float z) const; + float get_noise_4d(float x, float y, float z, float w) const; - _FORCE_INLINE_ float _get_octave_noise_2d(int octave, float x, float y) { return open_simplex_noise2(&(contexts[octave]), x, y); } - _FORCE_INLINE_ float _get_octave_noise_3d(int octave, float x, float y, float z) { return open_simplex_noise3(&(contexts[octave]), x, y, z); } - _FORCE_INLINE_ float _get_octave_noise_4d(int octave, float x, float y, float z, float w) { return open_simplex_noise4(&(contexts[octave]), x, y, z, w); } + _FORCE_INLINE_ float _get_octave_noise_2d(int octave, float x, float y) const { return open_simplex_noise2(&(contexts[octave]), x, y); } + _FORCE_INLINE_ float _get_octave_noise_3d(int octave, float x, float y, float z) const { return open_simplex_noise3(&(contexts[octave]), x, y, z); } + _FORCE_INLINE_ float _get_octave_noise_4d(int octave, float x, float y, float z, float w) const { return open_simplex_noise4(&(contexts[octave]), x, y, z, w); } // Convenience - _FORCE_INLINE_ float get_noise_2dv(Vector2 v) { return get_noise_2d(v.x, v.y); } - _FORCE_INLINE_ float get_noise_3dv(Vector3 v) { return get_noise_3d(v.x, v.y, v.z); } + _FORCE_INLINE_ float get_noise_2dv(const Vector2 &v) const { return get_noise_2d(v.x, v.y); } + _FORCE_INLINE_ float get_noise_3dv(const Vector3 &v) const { return get_noise_3d(v.x, v.y, v.z); } protected: static void _bind_methods(); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index b10d4523f2..f9ef184579 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -2367,7 +2367,7 @@ void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p binds.push_back(p_binds[i]); } binds.push_back(Ref<VisualScriptFunctionState>(this)); //add myself on the back to avoid dying from unreferencing - p_obj->connect_compat(p_signal, this, "_signal_callback", binds, CONNECT_ONESHOT); + p_obj->connect(p_signal, Callable(this, "_signal_callback"), binds, CONNECT_ONESHOT); } bool VisualScriptFunctionState::is_valid() const { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 85dab4e6cf..59bdfb2fc3 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -33,6 +33,7 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/doc_data.h" #include "core/object/script_language.h" #include "core/os/thread.h" @@ -342,6 +343,13 @@ public: virtual void set_source_code(const String &p_code) override; virtual Error reload(bool p_keep_state = false) override; +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const override { + static Vector<DocData::ClassDoc> docs; + return docs; + } +#endif // TOOLS_ENABLED + virtual bool is_tool() const override; virtual bool is_valid() const override; diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 875270e74f..54d86d5a9c 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -31,6 +31,7 @@ #include "visual_script_property_selector.h" #include "core/os/keyboard.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "modules/visual_script/visual_script.h" @@ -437,7 +438,7 @@ void VisualScriptPropertySelector::_item_selected() { class_type = base_type; } - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); String text; String at_class = class_type; diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 65350518c3..224038d604 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -141,11 +141,11 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver xatlas::Atlas *atlas = xatlas::Create(); printf("Adding mesh..\n"); - xatlas::AddMeshError::Enum err = xatlas::AddMesh(atlas, input_mesh, 1); - ERR_FAIL_COND_V_MSG(err != xatlas::AddMeshError::Enum::Success, false, xatlas::StringForEnum(err)); + xatlas::AddMeshError err = xatlas::AddMesh(atlas, input_mesh, 1); + ERR_FAIL_COND_V_MSG(err != xatlas::AddMeshError::Success, false, xatlas::StringForEnum(err)); printf("Generate..\n"); - xatlas::Generate(atlas, chart_options, xatlas::ParameterizeOptions(), pack_options); + xatlas::Generate(atlas, chart_options, pack_options); *r_size_hint_x = atlas->width; *r_size_hint_y = atlas->height; diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index aab5da4fde..c8ed44d699 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -41,7 +41,7 @@ #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/android/vulkan/vulkan_context_android.h" -#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif DisplayServerAndroid *DisplayServerAndroid::get_singleton() { @@ -447,7 +447,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis rendering_device_vulkan = memnew(RenderingDeviceVulkan); rendering_device_vulkan->initialize(context_vulkan); - RasterizerRD::make_current(); + RendererCompositorRD::make_current(); } #endif diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index f3e985f944..6d5be312f1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -181,6 +181,7 @@ public class GodotInputHandler implements InputDeviceListener { arr[i * 3 + 2] = event.getY(i); } final int action = event.getActionMasked(); + final int pointer_idx = event.getPointerId(event.getActionIndex()); mRenderView.queueOnRenderThread(new Runnable() { @Override @@ -189,12 +190,9 @@ public class GodotInputHandler implements InputDeviceListener { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_MOVE: { - GodotLib.touch(event.getSource(), action, 0, evcount, arr); - } break; + case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_DOWN: { - int pointer_idx = event.getPointerId(event.getActionIndex()); GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); } break; } diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h index 229b1e80db..2d77e9adff 100644 --- a/platform/iphone/display_server_iphone.h +++ b/platform/iphone/display_server_iphone.h @@ -36,7 +36,7 @@ #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" -#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "vulkan_context_iphone.h" diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm index d47d131719..e8abf1e3fa 100644 --- a/platform/iphone/display_server_iphone.mm +++ b/platform/iphone/display_server_iphone.mm @@ -73,7 +73,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ // return ERR_UNAVAILABLE; } - // rendering_server = memnew(RenderingServerRaster); + // rendering_server = memnew(RenderingServerDefault); // // FIXME: Reimplement threaded rendering // if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { // rendering_server = memnew(RenderingServerWrapMT(rendering_server, @@ -118,7 +118,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ rendering_device_vulkan = memnew(RenderingDeviceVulkan); rendering_device_vulkan->initialize(context_vulkan); - RasterizerRD::make_current(); + RendererCompositorRD::make_current(); } #endif diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 04a0a478d5..e98f870ba9 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -38,7 +38,7 @@ #include "ios.h" #include "joypad_iphone.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index b87e6f37a0..dac61f2d9d 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -47,7 +47,7 @@ #import <dlfcn.h> #if defined(VULKAN_ENABLED) -#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #import <QuartzCore/CAMetalLayer.h> #include <vulkan/vulkan_metal.h> #endif diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 356668a375..136bee68e3 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -40,9 +40,10 @@ #include "scene/resources/texture.h" #if defined(VULKAN_ENABLED) -#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -4087,12 +4088,12 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode rendering_device_vulkan = memnew(RenderingDeviceVulkan); rendering_device_vulkan->initialize(context_vulkan); - RasterizerRD::make_current(); + RendererCompositorRD::make_current(); } #endif /* - rendering_server = memnew(RenderingServerRaster); + rendering_server = memnew(RenderingServerDefault); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { rendering_server = memnew(RenderingServerWrapMT(rendering_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 61fb04cbf3..3c6f462e92 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -43,7 +43,7 @@ #include "drivers/unix/os_unix.h" #include "joypad_linux.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" #if defined(OPENGL_ENABLED) diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index cd4fbd9db5..6e93bf6ef2 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -39,7 +39,7 @@ #include "drivers/unix/os_unix.h" #include "joypad_linux.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" class OS_LinuxBSD : public OS_Unix { diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 3025210195..c4c2426f1f 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -52,7 +52,7 @@ #endif #if defined(VULKAN_ENABLED) -#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include <QuartzCore/CAMetalLayer.h> #endif @@ -3870,7 +3870,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode rendering_device_vulkan = memnew(RenderingDeviceVulkan); rendering_device_vulkan->initialize(context_vulkan); - RasterizerRD::make_current(); + RendererCompositorRD::make_current(); } #endif diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index e988e51e72..f5aad91946 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -42,7 +42,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "platform/osx/logo.gen.h" -#include "string.h" + #include <sys/stat.h> class EditorExportPlatformOSX : public EditorExportPlatform { @@ -572,36 +572,36 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p pkg_name = "Unnamed"; } - String pkg_name_safe = OS::get_singleton()->get_safe_dir_name(pkg_name); - - Error err = OK; - String tmp_app_path_name = ""; + pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); - DirAccess *tmp_app_path = nullptr; String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip"; // Create our application bundle. - tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app"); + String tmp_app_dir_name = pkg_name + ".app"; + String tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(tmp_app_dir_name); print_line("Exporting to " + tmp_app_path_name); - tmp_app_path = DirAccess::create_for_path(tmp_app_path_name); - if (!tmp_app_path) { + + Error err = OK; + + DirAccessRef tmp_app_dir = DirAccess::create_for_path(tmp_app_path_name); + if (!tmp_app_dir) { err = ERR_CANT_CREATE; } // Create our folder structure. if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/MacOS"); - err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS"); + err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS"); } if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks"); - err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks"); + err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks"); } if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Resources"); - err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); + err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); } // Now process our template. @@ -678,14 +678,14 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name_safe + "/"); + file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name + "/"); } if (file.find("/data.mono.osx.64.release/") != -1) { if (p_debug) { ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name_safe + "/"); + file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name + "/"); } print_line("ADDING: " + file + " size: " + itos(data.size())); @@ -694,7 +694,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p // Write it into our application bundle. file = tmp_app_path_name.plus_file(file); if (err == OK) { - err = tmp_app_path->make_dir_recursive(file.get_base_dir()); + err = tmp_app_dir->make_dir_recursive(file.get_base_dir()); } if (err == OK) { FileAccess *f = FileAccess::open(file, FileAccess::WRITE); @@ -797,7 +797,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } // Clean up temporary .app dir. - OS::get_singleton()->move_to_trash(tmp_app_path_name); + tmp_app_dir->change_dir(tmp_app_path_name); + tmp_app_dir->erase_contents_recursive(); + tmp_app_dir->change_dir(".."); + tmp_app_dir->remove(tmp_app_dir_name); } return err; diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index 9937ae5b62..22af8ba985 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -33,7 +33,7 @@ #include "core/string/print_string.h" #include "drivers/dummy/rasterizer_dummy.h" #include "drivers/dummy/texture_loader_dummy.h" -#include "servers/rendering/rendering_server_raster.h" +#include "servers/rendering/rendering_server_default.h" #include "main/main.h" @@ -76,7 +76,7 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int video_driver_index = p_video_driver; // unused in server platform, but should still be initialized - rendering_server = memnew(RenderingServerRaster); + rendering_server = memnew(RenderingServerDefault); rendering_server->init(); AudioDriverManager::initialize(p_audio_driver); diff --git a/platform/server/os_server.h b/platform/server/os_server.h index 06ea483fd4..a4ae6a0bf6 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -41,7 +41,7 @@ #include "platform/x11/crash_handler_linuxbsd.h" #endif #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" #undef CursorShape diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 79508055e5..780eba8407 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -44,7 +44,7 @@ #include "main/main.h" #include "platform/windows/windows_terminal_logger.h" #include "servers/audio_server.h" -#include "servers/rendering/rendering_server_raster.h" +#include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_wrap_mt.h" #include "thread_uwp.h" @@ -240,7 +240,7 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a set_video_mode(vm); - rendering_server = memnew(RenderingServerRaster); + rendering_server = memnew(RenderingServerDefault); // FIXME: Reimplement threaded rendering if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { rendering_server = memnew(RenderingServerWrapMT(rendering_server, false)); diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 88961bf143..c2d1acf8a0 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -39,7 +39,7 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #include "joypad_uwp.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" #include <fcntl.h> diff --git a/platform/windows/detect.py b/platform/windows/detect.py index e0b2a52014..ee13e3c774 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -71,6 +71,7 @@ def get_opts(): BoolVariable("use_mingw", "Use the Mingw compiler, even if MSVC is installed. Only used on Windows.", False), BoolVariable("use_llvm", "Use the LLVM compiler", False), BoolVariable("use_thinlto", "Use ThinLTO", False), + BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True), ] @@ -221,7 +222,11 @@ def configure_msvc(env, manual_msvc_config): ## Compile/link flags - env.AppendUnique(CCFLAGS=["/MT", "/Gd", "/GR", "/nologo"]) + if env["use_static_cpp"]: + env.AppendUnique(CCFLAGS=["/MT"]) + else: + env.AppendUnique(CCFLAGS=["/MD"]) + env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"]) # Force to use Unicode encoding env.AppendUnique(CCFLAGS=["/utf-8"]) env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++ @@ -373,12 +378,14 @@ def configure_mingw(env): mingw_prefix = "" if env["bits"] == "32": - env.Append(LINKFLAGS=["-static"]) - env.Append(LINKFLAGS=["-static-libgcc"]) - env.Append(LINKFLAGS=["-static-libstdc++"]) + if env["use_static_cpp"]: + env.Append(LINKFLAGS=["-static"]) + env.Append(LINKFLAGS=["-static-libgcc"]) + env.Append(LINKFLAGS=["-static-libstdc++"]) mingw_prefix = env["mingw_prefix_32"] else: - env.Append(LINKFLAGS=["-static"]) + if env["use_static_cpp"]: + env.Append(LINKFLAGS=["-static"]) mingw_prefix = env["mingw_prefix_64"] if env["use_llvm"]: diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 2581cc3af6..62fcd20f61 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3205,7 +3205,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win rendering_device_vulkan = memnew(RenderingDeviceVulkan); rendering_device_vulkan->initialize(context_vulkan); - RasterizerRD::make_current(); + RendererCompositorRD::make_current(); } #endif diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index c64a1b3b09..684746919a 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -43,8 +43,8 @@ #include "joypad_windows.h" #include "key_mapping_windows.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" -#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering_server.h" #ifdef XAUDIO2_ENABLED diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 2a5c8a7763..ae5e846dac 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -151,7 +151,7 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) { const DWORD devtype = (instance->dwDevType & 0xFF); - if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) { + if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON) && (devtype != DI8DEVTYPE_DRIVING)) { return false; } diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 646bc3aa4c..ae6b54513d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -46,7 +46,7 @@ #include "main/main.h" #include "platform/windows/display_server_windows.h" #include "servers/audio_server.h" -#include "servers/rendering/rendering_server_raster.h" +#include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_wrap_mt.h" #include "windows_terminal_logger.h" diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index a3dbb23182..5451e15d36 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -40,7 +40,7 @@ #include "drivers/winmidi/midi_driver_winmidi.h" #include "key_mapping_windows.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" #ifdef XAUDIO2_ENABLED #include "drivers/xaudio2/audio_driver_xaudio2.h" diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index ef2a9a4911..3649746c40 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -397,14 +397,14 @@ Ref<Gradient> CPUParticles2D::get_color_ramp() const { return color_ramp; } -void CPUParticles2D::set_particle_flag(Flags p_flag, bool p_enable) { - ERR_FAIL_INDEX(p_flag, FLAG_MAX); - flags[p_flag] = p_enable; +void CPUParticles2D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { + ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); + particle_flags[p_particle_flag] = p_enable; } -bool CPUParticles2D::get_particle_flag(Flags p_flag) const { - ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); - return flags[p_flag]; +bool CPUParticles2D::get_particle_flag(ParticleFlags p_particle_flag) const { + ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false); + return particle_flags[p_particle_flag]; } void CPUParticles2D::set_emission_shape(EmissionShape p_shape) { @@ -905,7 +905,7 @@ void CPUParticles2D::_particles_process(float p_delta) { p.color *= p.base_color; - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { p.transform.elements[1] = p.velocity.normalized(); p.transform.elements[0] = p.transform.elements[1].tangent(); @@ -1130,7 +1130,7 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_color_ramp(gt->get_gradient()); } - set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY)); + set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); set_emission_shape(EmissionShape(material->get_emission_shape())); set_emission_sphere_radius(material->get_emission_sphere_radius()); @@ -1246,8 +1246,8 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles2D::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles2D::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_particle_flag", "flag", "enable"), &CPUParticles2D::set_particle_flag); - ClassDB::bind_method(D_METHOD("get_particle_flag", "flag"), &CPUParticles2D::get_particle_flag); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles2D::set_particle_flag); + ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles2D::get_particle_flag); ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &CPUParticles2D::set_emission_shape); ClassDB::bind_method(D_METHOD("get_emission_shape"), &CPUParticles2D::get_emission_shape); @@ -1279,8 +1279,8 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); - ADD_GROUP("Flags", "flag_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); + ADD_GROUP("Particle Flags", "particle_flag_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); @@ -1351,10 +1351,10 @@ void CPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_MAX); - BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY); - BIND_ENUM_CONSTANT(FLAG_ROTATE_Y); // Unused, but exposed for consistency with 3D. - BIND_ENUM_CONSTANT(FLAG_DISABLE_Z); // Unused, but exposed for consistency with 3D. - BIND_ENUM_CONSTANT(FLAG_MAX); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ROTATE_Y); // Unused, but exposed for consistency with 3D. + BIND_ENUM_CONSTANT(PARTICLE_FLAG_DISABLE_Z); // Unused, but exposed for consistency with 3D. + BIND_ENUM_CONSTANT(PARTICLE_FLAG_MAX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); @@ -1415,8 +1415,8 @@ CPUParticles2D::CPUParticles2D() { set_param_randomness(Parameter(i), 0); } - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + particle_flags[i] = false; } set_color(Color(1, 1, 1, 1)); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 0f2a3e4920..857f19b20f 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -61,11 +61,11 @@ public: PARAM_MAX }; - enum Flags { - FLAG_ALIGN_Y_TO_VELOCITY, - FLAG_ROTATE_Y, // Unused, but exposed for consistency with 3D. - FLAG_DISABLE_Z, // Unused, but exposed for consistency with 3D. - FLAG_MAX + enum ParticleFlags { + PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, + PARTICLE_FLAG_ROTATE_Y, // Unused, but exposed for consistency with 3D. + PARTICLE_FLAG_DISABLE_Z, // Unused, but exposed for consistency with 3D. + PARTICLE_FLAG_MAX }; enum EmissionShape { @@ -159,7 +159,7 @@ private: Color color; Ref<Gradient> color_ramp; - bool flags[FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX]; EmissionShape emission_shape; float emission_sphere_radius; @@ -253,8 +253,8 @@ public: void set_color_ramp(const Ref<Gradient> &p_ramp); Ref<Gradient> get_color_ramp() const; - void set_particle_flag(Flags p_flag, bool p_enable); - bool get_particle_flag(Flags p_flag) const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); + bool get_particle_flag(ParticleFlags p_particle_flag) const; void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); @@ -287,7 +287,7 @@ public: VARIANT_ENUM_CAST(CPUParticles2D::DrawOrder) VARIANT_ENUM_CAST(CPUParticles2D::Parameter) -VARIANT_ENUM_CAST(CPUParticles2D::Flags) +VARIANT_ENUM_CAST(CPUParticles2D::ParticleFlags) VARIANT_ENUM_CAST(CPUParticles2D::EmissionShape) #endif // CPU_PARTICLES_2D_H diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index a4a930455b..46096d7460 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -127,9 +127,9 @@ void GPUParticles2D::_update_particle_emission_transform() { void GPUParticles2D::set_process_material(const Ref<Material> &p_material) { process_material = p_material; Ref<ParticlesMaterial> pm = p_material; - if (pm.is_valid() && !pm->get_flag(ParticlesMaterial::FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) { + if (pm.is_valid() && !pm->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) { // Likely a new (3D) material, modify it to match 2D space - pm->set_flag(ParticlesMaterial::FLAG_DISABLE_Z, true); + pm->set_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z, true); pm->set_gravity(Vector3(0, 98, 0)); } RID material_rid; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 6908fbeada..b5b39ccc8f 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -238,7 +238,7 @@ Ref<OccluderPolygon2D> LightOccluder2D::get_occluder_polygon() const { void LightOccluder2D::set_occluder_light_mask(int p_mask) { mask = p_mask; - RS::get_singleton()->canvas_light_occluder_set_light_mask(occluder, mask); + RS::get_singleton()->canvas_light_occluder_set_light_mask(occluder, p_mask); } int LightOccluder2D::get_occluder_light_mask() const { @@ -285,7 +285,7 @@ void LightOccluder2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"), "set_occluder_polygon", "get_occluder_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdf_collision"), "set_as_sdf_collision", "is_set_as_sdf_collision"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); } LightOccluder2D::LightOccluder2D() { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index d305f2805e..f40a993423 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -170,7 +170,7 @@ void PathFollow2D::_update_transform() { } Vector2 pos = c->interpolate_baked(offset, cubic); - if (rotate) { + if (rotates) { float ahead = offset + lookahead; if (loop && ahead >= path_length) { @@ -279,7 +279,7 @@ void PathFollow2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_unit_offset", "unit_offset"), &PathFollow2D::set_unit_offset); ClassDB::bind_method(D_METHOD("get_unit_offset"), &PathFollow2D::get_unit_offset); - ClassDB::bind_method(D_METHOD("set_rotate", "enable"), &PathFollow2D::set_rotate); + ClassDB::bind_method(D_METHOD("set_rotates", "enable"), &PathFollow2D::set_rotates); ClassDB::bind_method(D_METHOD("is_rotating"), &PathFollow2D::is_rotating); ClassDB::bind_method(D_METHOD("set_cubic_interpolation", "enable"), &PathFollow2D::set_cubic_interpolation); @@ -295,7 +295,7 @@ void PathFollow2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotate"), "set_rotate", "is_rotating"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotates"), "set_rotates", "is_rotating"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead"); @@ -371,13 +371,13 @@ float PathFollow2D::get_lookahead() const { return lookahead; } -void PathFollow2D::set_rotate(bool p_rotate) { - rotate = p_rotate; +void PathFollow2D::set_rotates(bool p_rotates) { + rotates = p_rotates; _update_transform(); } bool PathFollow2D::is_rotating() const { - return rotate; + return rotates; } void PathFollow2D::set_loop(bool p_loop) { @@ -393,7 +393,7 @@ PathFollow2D::PathFollow2D() { h_offset = 0; v_offset = 0; path = nullptr; - rotate = true; + rotates = true; cubic = true; loop = true; lookahead = 4; diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 7fea75cd7c..fcb8b40125 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -70,7 +70,7 @@ private: real_t lookahead; bool cubic; bool loop; - bool rotate; + bool rotates; void _update_transform(); @@ -99,7 +99,7 @@ public: void set_loop(bool p_loop); bool has_loop() const; - void set_rotate(bool p_rotate); + void set_rotates(bool p_rotates); bool is_rotating() const; void set_cubic_interpolation(bool p_enable); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index c977e0d4aa..215d9e062c 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -39,7 +39,7 @@ AABB CPUParticles3D::get_aabb() const { return AABB(); } -Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_particle_flags) const { return Vector<Face3>(); } @@ -368,17 +368,17 @@ Ref<Gradient> CPUParticles3D::get_color_ramp() const { return color_ramp; } -void CPUParticles3D::set_particle_flag(Flags p_flag, bool p_enable) { - ERR_FAIL_INDEX(p_flag, FLAG_MAX); - flags[p_flag] = p_enable; - if (p_flag == FLAG_DISABLE_Z) { +void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { + ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); + particle_flags[p_particle_flag] = p_enable; + if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { _change_notify(); } } -bool CPUParticles3D::get_particle_flag(Flags p_flag) const { - ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); - return flags[p_flag]; +bool CPUParticles3D::get_particle_flag(ParticleFlags p_particle_flag) const { + ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false); + return particle_flags[p_particle_flag]; } void CPUParticles3D::set_emission_shape(EmissionShape p_shape) { @@ -459,7 +459,7 @@ void CPUParticles3D::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { + if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { property.usage = 0; } } @@ -675,7 +675,7 @@ void CPUParticles3D::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); @@ -725,7 +725,7 @@ void CPUParticles3D::_particles_process(float p_delta) { p.transform.origin = emission_points.get(random_idx); if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS && emission_normals.size() == pc) { - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { Vector3 normal = emission_normals.get(random_idx); Vector2 normal_2d(normal.x, normal.y); Transform2D m2; @@ -762,7 +762,7 @@ void CPUParticles3D::_particles_process(float p_delta) { p.transform = emission_xform * p.transform; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { p.velocity.z = 0.0; p.transform.origin.z = 0.0; } @@ -783,7 +783,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } float tex_orbit_velocity = 0.0; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]); } @@ -830,7 +830,7 @@ void CPUParticles3D::_particles_process(float p_delta) { Vector3 force = gravity; Vector3 position = p.transform.origin; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { position.z = 0.0; } //apply linear acceleration @@ -840,7 +840,7 @@ void CPUParticles3D::_particles_process(float p_delta) { Vector3 diff = position - org; force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3(); //apply tangential acceleration; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { Vector2 yx = Vector2(diff.y, diff.x); Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized(); force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3(); @@ -852,7 +852,7 @@ void CPUParticles3D::_particles_process(float p_delta) { //apply attractor forces p.velocity += force * local_delta; //orbit velocity - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); if (orbit_amount != 0.0) { float ang = orbit_amount * local_delta * Math_PI * 2.0; @@ -923,8 +923,8 @@ void CPUParticles3D::_particles_process(float p_delta) { p.color *= p.base_color; - if (flags[FLAG_DISABLE_Z]) { - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { p.transform.basis.set_axis(1, p.velocity.normalized()); } else { @@ -941,7 +941,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } else { //orient particle Y towards velocity - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { p.transform.basis.set_axis(1, p.velocity.normalized()); } else { @@ -959,7 +959,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } //turn particle by rotation in Y - if (flags[FLAG_ROTATE_Y]) { + if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) { Basis rot_y(Vector3(0, 1, 0), p.custom[0]); p.transform.basis = p.transform.basis * rot_y; } @@ -973,7 +973,7 @@ void CPUParticles3D::_particles_process(float p_delta) { p.transform.basis.scale(Vector3(1, 1, 1) * base_scale); - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { p.velocity.z = 0.0; p.transform.origin.z = 0.0; } @@ -1199,9 +1199,9 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_color_ramp(gt->get_gradient()); } - set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY)); - set_particle_flag(FLAG_ROTATE_Y, material->get_flag(ParticlesMaterial::FLAG_ROTATE_Y)); - set_particle_flag(FLAG_DISABLE_Z, material->get_flag(ParticlesMaterial::FLAG_DISABLE_Z)); + set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); + set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ROTATE_Y)); + set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z)); set_emission_shape(EmissionShape(material->get_emission_shape())); set_emission_sphere_radius(material->get_emission_sphere_radius()); @@ -1318,8 +1318,8 @@ void CPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles3D::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles3D::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_particle_flag", "flag", "enable"), &CPUParticles3D::set_particle_flag); - ClassDB::bind_method(D_METHOD("get_particle_flag", "flag"), &CPUParticles3D::get_particle_flag); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles3D::set_particle_flag); + ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles3D::get_particle_flag); ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &CPUParticles3D::set_emission_shape); ClassDB::bind_method(D_METHOD("get_emission_shape"), &CPUParticles3D::get_emission_shape); @@ -1351,10 +1351,10 @@ void CPUParticles3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); - ADD_GROUP("Flags", "flag_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_particle_flag", "get_particle_flag", FLAG_ROTATE_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_particle_flag", "get_particle_flag", FLAG_DISABLE_Z); + ADD_GROUP("Particle Flags", "particle_flag_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); @@ -1426,10 +1426,10 @@ void CPUParticles3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_MAX); - BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY); - BIND_ENUM_CONSTANT(FLAG_ROTATE_Y); - BIND_ENUM_CONSTANT(FLAG_DISABLE_Z); - BIND_ENUM_CONSTANT(FLAG_MAX); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ROTATE_Y); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_DISABLE_Z); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_MAX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); @@ -1493,8 +1493,8 @@ CPUParticles3D::CPUParticles3D() { set_param_randomness(Parameter(i), 0); } - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + particle_flags[i] = false; } can_update = false; diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index da4811b60e..8c1b8a684c 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -61,11 +61,11 @@ public: PARAM_MAX }; - enum Flags { - FLAG_ALIGN_Y_TO_VELOCITY, - FLAG_ROTATE_Y, - FLAG_DISABLE_Z, - FLAG_MAX + enum ParticleFlags { + PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, + PARTICLE_FLAG_ROTATE_Y, + PARTICLE_FLAG_DISABLE_Z, + PARTICLE_FLAG_MAX }; enum EmissionShape { @@ -160,7 +160,7 @@ private: Color color; Ref<Gradient> color_ramp; - bool flags[FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX]; EmissionShape emission_shape; float emission_sphere_radius; @@ -256,8 +256,8 @@ public: void set_color_ramp(const Ref<Gradient> &p_ramp); Ref<Gradient> get_color_ramp() const; - void set_particle_flag(Flags p_flag, bool p_enable); - bool get_particle_flag(Flags p_flag) const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); + bool get_particle_flag(ParticleFlags p_particle_flag) const; void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); @@ -290,7 +290,7 @@ public: VARIANT_ENUM_CAST(CPUParticles3D::DrawOrder) VARIANT_ENUM_CAST(CPUParticles3D::Parameter) -VARIANT_ENUM_CAST(CPUParticles3D::Flags) +VARIANT_ENUM_CAST(CPUParticles3D::ParticleFlags) VARIANT_ENUM_CAST(CPUParticles3D::EmissionShape) #endif // CPU_PARTICLES_H diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 3d3467583d..2ae01c7ab8 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -182,6 +182,7 @@ void NavigationRegion3D::bake_navigation_mesh() { void NavigationRegion3D::_bake_finished(Ref<NavigationMesh> p_nav_mesh) { set_navigation_mesh(p_nav_mesh); bake_thread = nullptr; + emit_signal("bake_finished"); } String NavigationRegion3D::get_configuration_warning() const { diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 0ae1c0e3b6..4425af26f9 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -848,7 +848,7 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { skin_bindings.insert(skin_ref.operator->()); - skin->connect_compat("changed", skin_ref.operator->(), "_skin_changed"); + skin->connect("changed", Callable(skin_ref.operator->(), "_skin_changed")); _make_dirty(); //skin needs to be updated, so update skeleton diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index e633b1eb4a..d811b2e852 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -480,7 +480,6 @@ void SoftBody3D::become_mesh_owner() { Dictionary surface_lods = mesh->surface_get_lods(0); uint32_t surface_format = mesh->surface_get_format(0); - surface_format &= ~(Mesh::ARRAY_COMPRESS_NORMAL); surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; Ref<ArrayMesh> soft_mesh; diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index c0015aa338..674868a04c 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -282,7 +282,7 @@ String XRController3D::get_controller_name() const { return String("Not connected"); }; - return tracker->get_name(); + return tracker->get_tracker_name(); }; int XRController3D::get_joystick_id() const { @@ -480,7 +480,7 @@ String XRAnchor3D::get_anchor_name() const { return String("Not connected"); }; - return tracker->get_name(); + return tracker->get_tracker_name(); }; bool XRAnchor3D::get_is_active() const { diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 17ce05f130..36552c966d 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -565,7 +565,7 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima { Ref<AnimationNode> node = states[p_name].node; if (node.is_valid()) { - node->disconnect_compat("tree_changed", this, "_tree_changed"); + node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); } } @@ -574,7 +574,7 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima emit_changed(); emit_signal("tree_changed"); - p_node->connect_compat("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); } Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 46c3a44e98..f9b7d828f4 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2983,7 +2983,6 @@ void Control::_bind_methods() { BIND_VMETHOD(MethodInfo("_structured_text_parser", PropertyInfo(Variant::ARRAY, "args"), PropertyInfo(Variant::STRING, "text"))); BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size")); MethodInfo get_drag_data = MethodInfo("get_drag_data", PropertyInfo(Variant::VECTOR2, "position")); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 62ccd55e89..3a54ac7443 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -431,6 +431,7 @@ void ScrollContainer::update_scrollbars() { v_scroll->set_max(min.height); if (hide_scroll_v) { + v_scroll->set_page(size.height); v_scroll->hide(); scroll.y = 0; } else { @@ -446,6 +447,7 @@ void ScrollContainer::update_scrollbars() { h_scroll->set_max(min.width); if (hide_scroll_h) { + h_scroll->set_page(size.width); h_scroll->hide(); scroll.x = 0; } else { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 7082d70ae9..a711d28c76 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -670,8 +670,8 @@ void register_scene_types() { #ifndef _3D_DISABLED ClassDB::register_virtual_class<PrimitiveMesh>(); + ClassDB::register_class<BoxMesh>(); ClassDB::register_class<CapsuleMesh>(); - ClassDB::register_class<CubeMesh>(); ClassDB::register_class<CylinderMesh>(); ClassDB::register_class<PlaneMesh>(); ClassDB::register_class<PrismMesh>(); @@ -835,6 +835,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("CSGShape", "CSGShape3D"); ClassDB::add_compatibility_class("CSGSphere", "CSGSphere3D"); ClassDB::add_compatibility_class("CSGTorus", "CSGTorus3D"); + ClassDB::add_compatibility_class("CubeMesh", "BoxMesh"); ClassDB::add_compatibility_class("CylinderShape", "CylinderShape3D"); ClassDB::add_compatibility_class("DirectionalLight", "DirectionalLight3D"); ClassDB::add_compatibility_class("EditorSpatialGizmo", "EditorNode3DGizmo"); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 35c967ce27..6e08af23f5 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -2417,10 +2417,10 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Height", "heightmap_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_heightmap_scale", "get_heightmap_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_heightmap_scale", "get_heightmap_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax"), "set_heightmap_deep_parallax", "is_heightmap_deep_parallax_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,64,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,64,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent"), "set_heightmap_deep_parallax_flip_tangent", "get_heightmap_deep_parallax_flip_tangent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal"), "set_heightmap_deep_parallax_flip_binormal", "get_heightmap_deep_parallax_flip_binormal"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 97c0c7a81d..c6815c8ecc 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -157,7 +157,7 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { bool Mesh::surface_is_softbody_friendly(int p_idx) const { const uint32_t surface_format = surface_get_format(p_idx); - return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL))); + return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE); } Vector<Face3> Mesh::get_faces() const { @@ -480,8 +480,30 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES); BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP); - BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); - BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); + BIND_ENUM_CONSTANT(ARRAY_VERTEX); + BIND_ENUM_CONSTANT(ARRAY_NORMAL); + BIND_ENUM_CONSTANT(ARRAY_TANGENT); + BIND_ENUM_CONSTANT(ARRAY_COLOR); + BIND_ENUM_CONSTANT(ARRAY_TEX_UV); + BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM3); + BIND_ENUM_CONSTANT(ARRAY_BONES); + BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); + BIND_ENUM_CONSTANT(ARRAY_INDEX); + BIND_ENUM_CONSTANT(ARRAY_MAX); + + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX); BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); @@ -489,31 +511,28 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3); BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK); - BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE); - BIND_ENUM_CONSTANT(ARRAY_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COLOR); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_BONES); - BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_INDEX); - BIND_ENUM_CONSTANT(ARRAY_MAX); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS); } void Mesh::clear_cache() const { @@ -560,11 +579,50 @@ Vector<Ref<Shape3D>> Mesh::convex_decompose() const { Mesh::Mesh() { } +#if 0 static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) { - bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE))); - bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES); - bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2)); - bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2)); + enum ArrayType { + OLD_ARRAY_VERTEX = 0, + OLD_ARRAY_NORMAL = 1, + OLD_ARRAY_TANGENT = 2, + OLD_ARRAY_COLOR = 3, + OLD_ARRAY_TEX_UV = 4, + OLD_ARRAY_TEX_UV2 = 5, + OLD_ARRAY_BONES = 6, + OLD_ARRAY_WEIGHTS = 7, + OLD_ARRAY_INDEX = 8, + OLD_ARRAY_MAX = 9 + }; + + enum ArrayFormat { + /* OLD_ARRAY FORMAT FLAGS */ + OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory + OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL, + OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT, + OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR, + OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV, + OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2, + OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES, + OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS, + OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, + + OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), + OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_DEFAULT = OLD_ARRAY_COMPRESS_NORMAL | OLD_ARRAY_COMPRESS_TANGENT | OLD_ARRAY_COMPRESS_COLOR | OLD_ARRAY_COMPRESS_TEX_UV | OLD_ARRAY_COMPRESS_TEX_UV2, + + OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, + OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, + }; + + bool vertex_16bit = p_format & ((1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE))); + bool has_bones = (p_format & OLD_ARRAY_FORMAT_BONES); + bool bone_8 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_INDEX << 2)); + bool weight_32 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_TEX_UV2 << 2)); print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32)); @@ -572,7 +630,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui return p_src; } - bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1)); + bool vertex_2d = (p_format & (OLD_ARRAY_COMPRESS_INDEX << 1)); uint32_t src_stride = p_src.size() / p_elements; uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0); @@ -671,6 +729,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui return ret; } +#endif bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; @@ -727,6 +786,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]); } else if (d.has("array_data")) { +#if 0 //print_line("array data (old style"); //older format (3.x) Vector<uint8_t> array_data = d["array_data"]; @@ -793,6 +853,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } add_surface(format, PrimitiveType(primitive), array_data, vertex_count, array_index_data, index_count, aabb, blend_shapes, bone_aabb); +#endif } else { ERR_FAIL_V(false); } @@ -824,6 +885,12 @@ Array ArrayMesh::_get_surfaces() const { data["primitive"] = surface.primitive; data["vertex_data"] = surface.vertex_data; data["vertex_count"] = surface.vertex_count; + if (surface.skin_data.size()) { + data["skin_data"] = surface.skin_data; + } + if (surface.attribute_data.size()) { + data["attribute_data"] = surface.attribute_data; + } data["aabb"] = surface.aabb; if (surface.index_count) { data["index_data"] = surface.index_data; @@ -848,9 +915,9 @@ Array ArrayMesh::_get_surfaces() const { data["bone_aabbs"] = bone_aabbs; } - Array blend_shapes; - for (int j = 0; j < surface.blend_shapes.size(); j++) { - blend_shapes.push_back(surface.blend_shapes[j]); + if (surface.blend_shape_data.size()) { + data["blend_shapes"] = surface.blend_shape_data; + data["blend_shapes_count"] = surface.blend_shape_count; } if (surfaces[i].material.is_valid()) { @@ -896,6 +963,12 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { surface.primitive = RS::PrimitiveType(int(d["primitive"])); surface.vertex_data = d["vertex_data"]; surface.vertex_count = d["vertex_count"]; + if (d.has("attribute_data")) { + surface.attribute_data = d["attribute_data"]; + } + if (d.has("skin_data")) { + surface.skin_data = d["skin_data"]; + } surface.aabb = d["aabb"]; if (d.has("index_data")) { @@ -922,11 +995,9 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { } } - if (d.has("blend_shapes")) { - Array blend_shapes; - for (int j = 0; j < blend_shapes.size(); j++) { - surface.blend_shapes.push_back(blend_shapes[j]); - } + if (d.has("blend_shapes") && d.has("blend_shape_count")) { + surface.blend_shape_data = d["blend_shapes"]; + surface.blend_shape_count = d["blend_shape_count"]; } Ref<Material> material; @@ -982,7 +1053,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { s.aabb = surface_data[i].aabb; if (i == 0) { aabb = s.aabb; - blend_shapes.resize(surface_data[i].blend_shapes.size()); + blend_shapes.resize(surface_data[i].blend_shape_count); } else { aabb.merge_with(s.aabb); } @@ -1070,7 +1141,7 @@ void ArrayMesh::_recompute_aabb() { #ifndef _MSC_VER #warning need to add binding to add_surface using future MeshSurfaceData object #endif -void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<RS::SurfaceData::LOD> &p_lods) { +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, uint32_t p_blend_shape_count, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) { _create_if_empty(); Surface s; @@ -1090,10 +1161,13 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const sd.aabb = p_aabb; sd.vertex_count = p_vertex_count; sd.vertex_data = p_array; + sd.attribute_data = p_attribute_array; + sd.skin_data = p_skin_array; sd.index_count = p_index_count; sd.index_data = p_index_array; - sd.blend_shapes = p_blend_shapes; - sd.bone_aabbs = p_bone_aabb; + sd.blend_shape_data = p_blend_shape_data; + sd.blend_shape_count = p_blend_shape_count; + sd.bone_aabbs = p_bone_aabbs; sd.lods = p_lods; RenderingServer::get_singleton()->mesh_add_surface(mesh, sd); @@ -1111,15 +1185,17 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & Error err = RS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (RenderingServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags); ERR_FAIL_COND(err != OK); - /* print_line("format: " + itos(surface.format)); + /* Debug code. + print_line("format: " + itos(surface.format)); print_line("aabb: " + surface.aabb); print_line("array size: " + itos(surface.vertex_data.size())); print_line("vertex count: " + itos(surface.vertex_count)); print_line("index size: " + itos(surface.index_data.size())); print_line("index count: " + itos(surface.index_count)); print_line("primitive: " + itos(surface.primitive)); -*/ - add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods); + */ + + add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.attribute_data, surface.skin_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shape_data, surface.blend_shape_count, surface.bone_aabbs, surface.lods); } Array ArrayMesh::surface_get_arrays(int p_surface) const { @@ -1452,29 +1528,29 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second]; if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) { - surfaces_tools.write[surface]->add_color(v.color); + surfaces_tools.write[surface]->set_color(v.color); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { - surfaces_tools.write[surface]->add_uv(v.uv); + surfaces_tools.write[surface]->set_uv(v.uv); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) { - surfaces_tools.write[surface]->add_normal(v.normal); + surfaces_tools.write[surface]->set_normal(v.normal); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) { Plane t; t.normal = v.tangent; t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; - surfaces_tools.write[surface]->add_tangent(t); + surfaces_tools.write[surface]->set_tangent(t); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) { - surfaces_tools.write[surface]->add_bones(v.bones); + surfaces_tools.write[surface]->set_bones(v.bones); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { - surfaces_tools.write[surface]->add_weights(v.weights); + surfaces_tools.write[surface]->set_weights(v.weights); } Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); - surfaces_tools.write[surface]->add_uv2(uv2); + surfaces_tools.write[surface]->set_uv2(uv2); surfaces_tools.write[surface]->add_vertex(v.vertex); } @@ -1507,7 +1583,7 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces); ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); @@ -1537,29 +1613,8 @@ void ArrayMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); - BIND_CONSTANT(NO_INDEX_ARRAY); - BIND_CONSTANT(ARRAY_WEIGHTS_SIZE); - - BIND_ENUM_CONSTANT(ARRAY_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COLOR); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_BONES); - BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_INDEX); - BIND_ENUM_CONSTANT(ARRAY_MAX); - - BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); } void ArrayMesh::reload_from_file() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 642ae7e1b0..ae2139a0cf 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -61,6 +61,10 @@ public: ARRAY_COLOR = RenderingServer::ARRAY_COLOR, ARRAY_TEX_UV = RenderingServer::ARRAY_TEX_UV, ARRAY_TEX_UV2 = RenderingServer::ARRAY_TEX_UV2, + ARRAY_CUSTOM0 = RenderingServer::ARRAY_CUSTOM0, + ARRAY_CUSTOM1 = RenderingServer::ARRAY_CUSTOM1, + ARRAY_CUSTOM2 = RenderingServer::ARRAY_CUSTOM2, + ARRAY_CUSTOM3 = RenderingServer::ARRAY_CUSTOM3, ARRAY_BONES = RenderingServer::ARRAY_BONES, ARRAY_WEIGHTS = RenderingServer::ARRAY_WEIGHTS, ARRAY_INDEX = RenderingServer::ARRAY_INDEX, @@ -68,30 +72,47 @@ public: }; + enum ArrayCustomFormat { + ARRAY_CUSTOM_RGBA8_UNORM, + ARRAY_CUSTOM_RGBA8_SNORM, + ARRAY_CUSTOM_RG_HALF, + ARRAY_CUSTOM_RGBA_HALF, + ARRAY_CUSTOM_R_FLOAT, + ARRAY_CUSTOM_RG_FLOAT, + ARRAY_CUSTOM_RGB_FLOAT, + ARRAY_CUSTOM_RGBA_FLOAT, + ARRAY_CUSTOM_MAX + }; + enum ArrayFormat { - /* ARRAY FORMAT FLAGS */ - ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory - ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL, - ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT, - ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR, - ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV, - ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2, - ARRAY_FORMAT_BONES = 1 << ARRAY_BONES, - ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS, - ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX, - - ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1), - ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), - - ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, - ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 + ARRAY_FORMAT_VERTEX = RS::ARRAY_FORMAT_VERTEX, + ARRAY_FORMAT_NORMAL = RS::ARRAY_FORMAT_NORMAL, + ARRAY_FORMAT_TANGENT = RS::ARRAY_FORMAT_TANGENT, + ARRAY_FORMAT_COLOR = RS::ARRAY_FORMAT_COLOR, + ARRAY_FORMAT_TEX_UV = RS::ARRAY_FORMAT_TEX_UV, + ARRAY_FORMAT_TEX_UV2 = RS::ARRAY_FORMAT_TEX_UV2, + ARRAY_FORMAT_CUSTOM0 = RS::ARRAY_FORMAT_CUSTOM0, + ARRAY_FORMAT_CUSTOM1 = RS::ARRAY_FORMAT_CUSTOM1, + ARRAY_FORMAT_CUSTOM2 = RS::ARRAY_FORMAT_CUSTOM2, + ARRAY_FORMAT_CUSTOM3 = RS::ARRAY_FORMAT_CUSTOM3, + ARRAY_FORMAT_BONES = RS::ARRAY_FORMAT_BONES, + ARRAY_FORMAT_WEIGHTS = RS::ARRAY_FORMAT_WEIGHTS, + ARRAY_FORMAT_INDEX = RS::ARRAY_FORMAT_INDEX, + + ARRAY_FORMAT_BLEND_SHAPE_MASK = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK, + + ARRAY_FORMAT_CUSTOM_BASE = RS::ARRAY_FORMAT_CUSTOM_BASE, + ARRAY_FORMAT_CUSTOM0_SHIFT = RS::ARRAY_FORMAT_CUSTOM0_SHIFT, + ARRAY_FORMAT_CUSTOM1_SHIFT = RS::ARRAY_FORMAT_CUSTOM1_SHIFT, + ARRAY_FORMAT_CUSTOM2_SHIFT = RS::ARRAY_FORMAT_CUSTOM2_SHIFT, + ARRAY_FORMAT_CUSTOM3_SHIFT = RS::ARRAY_FORMAT_CUSTOM3_SHIFT, + + ARRAY_FORMAT_CUSTOM_MASK = RS::ARRAY_FORMAT_CUSTOM_MASK, + ARRAY_COMPRESS_FLAGS_BASE = RS::ARRAY_COMPRESS_FLAGS_BASE, + + ARRAY_FLAG_USE_2D_VERTICES = RS::ARRAY_FLAG_USE_2D_VERTICES, + ARRAY_FLAG_USE_DYNAMIC_UPDATE = RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE, + ARRAY_FLAG_USE_8_BONE_WEIGHTS = RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS, }; @@ -104,11 +125,6 @@ public: PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX, }; - enum BlendShapeMode { - BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED, - BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE, - }; - virtual int get_surface_count() const = 0; virtual int surface_get_array_len(int p_idx) const = 0; virtual int surface_get_array_index_len(int p_idx) const = 0; @@ -155,6 +171,12 @@ class ArrayMesh : public Mesh { Array _get_surfaces() const; void _set_surfaces(const Array &p_data); +public: + enum BlendShapeMode { + BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED, + BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE, + }; + private: struct Surface { uint32_t format; @@ -187,9 +209,9 @@ protected: static void _bind_methods(); public: - void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); - void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); + void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data = Vector<uint8_t>(), uint32_t p_blend_shape_count = 0, const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); Array surface_get_arrays(int p_surface) const override; Array surface_get_blend_shape_arrays(int p_surface) const override; @@ -244,7 +266,8 @@ public: VARIANT_ENUM_CAST(Mesh::ArrayType); VARIANT_ENUM_CAST(Mesh::ArrayFormat); +VARIANT_ENUM_CAST(Mesh::ArrayCustomFormat); VARIANT_ENUM_CAST(Mesh::PrimitiveType); -VARIANT_ENUM_CAST(Mesh::BlendShapeMode); +VARIANT_ENUM_CAST(ArrayMesh::BlendShapeMode); #endif diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index a286184aee..e2f96c54cb 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -329,7 +329,7 @@ void ParticlesMaterial::_update_shader() { code += " float tex_linear_velocity = 0.0;\n"; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n"; code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; @@ -377,7 +377,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n"; if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) { - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " mat2 rotm;"; code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n"; code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n"; @@ -398,7 +398,7 @@ void ParticlesMaterial::_update_shader() { code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } @@ -413,7 +413,7 @@ void ParticlesMaterial::_update_shader() { code += " float tex_linear_velocity = 0.0;\n"; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; } else { @@ -471,7 +471,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 force = gravity;\n"; code += " vec3 pos = TRANSFORM[3].xyz;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " pos.z = 0.0;\n"; } code += " // apply linear acceleration\n"; @@ -481,7 +481,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 diff = pos - org;\n"; code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel + tex_radial_accel) * mix(1.0, rand_from_seed(alt_seed), radial_accel_random) : vec3(0.0);\n"; code += " // apply tangential acceleration;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n"; } else { @@ -495,7 +495,7 @@ void ParticlesMaterial::_update_shader() { code += " // apply attractor forces\n"; code += " VELOCITY += force * DELTA;\n"; code += " // orbit velocity\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n"; code += " if (orbit_amount != 0.0) {\n"; code += " float ang = orbit_amount * DELTA * pi * 2.0;\n"; @@ -562,8 +562,8 @@ void ParticlesMaterial::_update_shader() { } code += "\n"; - if (flags[FLAG_DISABLE_Z]) { - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { code += " if (length(VELOCITY) > 0.0) {\n"; code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; code += " } else {\n"; @@ -579,7 +579,7 @@ void ParticlesMaterial::_update_shader() { } else { // orient particle Y towards velocity - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { code += " if (length(VELOCITY) > 0.0) {\n"; code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; code += " } else {\n"; @@ -598,7 +598,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n"; } // turn particle by rotation in Y - if (flags[FLAG_ROTATE_Y]) { + if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) { code += " TRANSFORM = TRANSFORM * mat4(vec4(cos(CUSTOM.x), 0.0, -sin(CUSTOM.x), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(sin(CUSTOM.x), 0.0, cos(CUSTOM.x), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } } @@ -611,7 +611,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[0].xyz *= base_scale;\n"; code += " TRANSFORM[1].xyz *= base_scale;\n"; code += " TRANSFORM[2].xyz *= base_scale;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } @@ -916,18 +916,18 @@ Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { return color_ramp; } -void ParticlesMaterial::set_flag(Flags p_flag, bool p_enable) { - ERR_FAIL_INDEX(p_flag, FLAG_MAX); - flags[p_flag] = p_enable; +void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { + ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); + particle_flags[p_particle_flag] = p_enable; _queue_shader_change(); - if (p_flag == FLAG_DISABLE_Z) { + if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { _change_notify(); } } -bool ParticlesMaterial::get_flag(Flags p_flag) const { - ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); - return flags[p_flag]; +bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { + ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false); + return particle_flags[p_particle_flag]; } void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { @@ -1056,7 +1056,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { + if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { property.usage = 0; } } @@ -1170,8 +1170,8 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &ParticlesMaterial::set_flag); - ClassDB::bind_method(D_METHOD("get_flag", "flag"), &ParticlesMaterial::get_flag); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticlesMaterial::set_particle_flag); + ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticlesMaterial::get_particle_flag); ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticlesMaterial::set_emission_shape); ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticlesMaterial::get_emission_shape); @@ -1238,10 +1238,10 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_normal_texture", "get_emission_normal_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_color_texture", "get_emission_color_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count"); - ADD_GROUP("Flags", "flag_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); + ADD_GROUP("ParticleFlags", "particle_flag_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); @@ -1327,10 +1327,10 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_MAX); - BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY); - BIND_ENUM_CONSTANT(FLAG_ROTATE_Y); - BIND_ENUM_CONSTANT(FLAG_DISABLE_Z); - BIND_ENUM_CONSTANT(FLAG_MAX); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ROTATE_Y); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_DISABLE_Z); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_MAX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); @@ -1385,8 +1385,8 @@ ParticlesMaterial::ParticlesMaterial() : set_param_randomness(Parameter(i), 0); } - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + particle_flags[i] = false; } set_color(Color(1, 1, 1, 1)); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 12fa53ef29..7e8f05b706 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -61,11 +61,11 @@ public: PARAM_MAX }; - enum Flags { - FLAG_ALIGN_Y_TO_VELOCITY, - FLAG_ROTATE_Y, - FLAG_DISABLE_Z, - FLAG_MAX + enum ParticleFlags { + PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, + PARTICLE_FLAG_ROTATE_Y, + PARTICLE_FLAG_DISABLE_Z, + PARTICLE_FLAG_MAX }; enum EmissionShape { @@ -90,7 +90,7 @@ private: struct { uint32_t texture_mask : 16; uint32_t texture_color : 1; - uint32_t flags : 4; + uint32_t particle_flags : 4; uint32_t emission_shape : 2; uint32_t invalid_key : 1; uint32_t has_emission_color : 1; @@ -124,9 +124,9 @@ private: mk.texture_mask |= (1 << i); } } - for (int i = 0; i < FLAG_MAX; i++) { - if (flags[i]) { - mk.flags |= (1 << i); + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + if (particle_flags[i]) { + mk.particle_flags |= (1 << i); } } @@ -227,7 +227,7 @@ private: Color color; Ref<Texture2D> color_ramp; - bool flags[FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX]; EmissionShape emission_shape; float emission_sphere_radius; @@ -284,8 +284,8 @@ public: void set_color_ramp(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_color_ramp() const; - void set_flag(Flags p_flag, bool p_enable); - bool get_flag(Flags p_flag) const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); + bool get_particle_flag(ParticleFlags p_particle_flag) const; void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); @@ -349,7 +349,7 @@ public: }; VARIANT_ENUM_CAST(ParticlesMaterial::Parameter) -VARIANT_ENUM_CAST(ParticlesMaterial::Flags) +VARIANT_ENUM_CAST(ParticlesMaterial::ParticleFlags) VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape) VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode) diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 8d9c5f07b2..06e181cb99 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -148,7 +148,7 @@ Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const { uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); - return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX | RS::ARRAY_COMPRESS_DEFAULT; + return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX; } Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { @@ -477,10 +477,10 @@ CapsuleMesh::CapsuleMesh() { } /** - CubeMesh + BoxMesh */ -void CubeMesh::_create_mesh_array(Array &p_arr) const { +void BoxMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; float onethird = 1.0 / 3.0; @@ -672,16 +672,16 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { p_arr[RS::ARRAY_INDEX] = indices; } -void CubeMesh::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_size", "size"), &CubeMesh::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &CubeMesh::get_size); +void BoxMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_size", "size"), &BoxMesh::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &BoxMesh::get_size); - ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &CubeMesh::set_subdivide_width); - ClassDB::bind_method(D_METHOD("get_subdivide_width"), &CubeMesh::get_subdivide_width); - ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &CubeMesh::set_subdivide_height); - ClassDB::bind_method(D_METHOD("get_subdivide_height"), &CubeMesh::get_subdivide_height); - ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &CubeMesh::set_subdivide_depth); - ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &CubeMesh::get_subdivide_depth); + ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &BoxMesh::set_subdivide_width); + ClassDB::bind_method(D_METHOD("get_subdivide_width"), &BoxMesh::get_subdivide_width); + ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &BoxMesh::set_subdivide_height); + ClassDB::bind_method(D_METHOD("get_subdivide_height"), &BoxMesh::get_subdivide_height); + ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &BoxMesh::set_subdivide_depth); + ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &BoxMesh::get_subdivide_depth); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width"); @@ -689,43 +689,43 @@ void CubeMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth"); } -void CubeMesh::set_size(const Vector3 &p_size) { +void BoxMesh::set_size(const Vector3 &p_size) { size = p_size; _request_update(); } -Vector3 CubeMesh::get_size() const { +Vector3 BoxMesh::get_size() const { return size; } -void CubeMesh::set_subdivide_width(const int p_divisions) { +void BoxMesh::set_subdivide_width(const int p_divisions) { subdivide_w = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_width() const { +int BoxMesh::get_subdivide_width() const { return subdivide_w; } -void CubeMesh::set_subdivide_height(const int p_divisions) { +void BoxMesh::set_subdivide_height(const int p_divisions) { subdivide_h = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_height() const { +int BoxMesh::get_subdivide_height() const { return subdivide_h; } -void CubeMesh::set_subdivide_depth(const int p_divisions) { +void BoxMesh::set_subdivide_depth(const int p_divisions) { subdivide_d = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_depth() const { +int BoxMesh::get_subdivide_depth() const { return subdivide_d; } -CubeMesh::CubeMesh() { +BoxMesh::BoxMesh() { // defaults size = Vector3(2.0, 2.0, 2.0); subdivide_w = 0; diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index f0ae611b5e..02aea9c5c8 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -130,10 +130,10 @@ public: }; /** - Similar to test cube but with subdivision support and different texture coordinates + A box */ -class CubeMesh : public PrimitiveMesh { - GDCLASS(CubeMesh, PrimitiveMesh); +class BoxMesh : public PrimitiveMesh { + GDCLASS(BoxMesh, PrimitiveMesh); private: Vector3 size; @@ -158,7 +158,7 @@ public: void set_subdivide_depth(const int p_divisions); int get_subdivide_depth() const; - CubeMesh(); + BoxMesh(); }; /** diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index ff14a5a292..3166067573 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -74,6 +74,12 @@ bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { } } + for (int i = 0; i < RS::ARRAY_CUSTOM_MAX; i++) { + if (custom[i] != p_vertex.custom[i]) { + return false; + } + } + return true; } @@ -87,6 +93,7 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { h = hash_djb2_buffer((const uint8_t *)&p_vtx.color, sizeof(real_t) * 4, h); h = hash_djb2_buffer((const uint8_t *)p_vtx.bones.ptr(), p_vtx.bones.size() * sizeof(int), h); h = hash_djb2_buffer((const uint8_t *)p_vtx.weights.ptr(), p_vtx.weights.size() * sizeof(float), h); + h = hash_djb2_buffer((const uint8_t *)&p_vtx.custom[0], sizeof(Color) * RS::ARRAY_CUSTOM_COUNT, h); return h; } @@ -111,8 +118,11 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { vtx.bones = last_bones; vtx.tangent = last_tangent.normal; vtx.binormal = last_normal.cross(last_tangent.normal).normalized() * last_tangent.d; + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + vtx.custom[i] = last_custom[i]; + } - const int expected_vertices = 4; + const int expected_vertices = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; if ((format & Mesh::ARRAY_FORMAT_WEIGHTS || format & Mesh::ARRAY_FORMAT_BONES) && (vtx.weights.size() != expected_vertices || vtx.bones.size() != expected_vertices)) { //ensure vertices are the expected amount @@ -163,7 +173,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { format |= Mesh::ARRAY_FORMAT_VERTEX; } -void SurfaceTool::add_color(Color p_color) { +void SurfaceTool::set_color(Color p_color) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_COLOR)); @@ -172,7 +182,7 @@ void SurfaceTool::add_color(Color p_color) { last_color = p_color; } -void SurfaceTool::add_normal(const Vector3 &p_normal) { +void SurfaceTool::set_normal(const Vector3 &p_normal) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_NORMAL)); @@ -181,7 +191,7 @@ void SurfaceTool::add_normal(const Vector3 &p_normal) { last_normal = p_normal; } -void SurfaceTool::add_tangent(const Plane &p_tangent) { +void SurfaceTool::set_tangent(const Plane &p_tangent) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TANGENT)); @@ -189,7 +199,7 @@ void SurfaceTool::add_tangent(const Plane &p_tangent) { last_tangent = p_tangent; } -void SurfaceTool::add_uv(const Vector2 &p_uv) { +void SurfaceTool::set_uv(const Vector2 &p_uv) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV)); @@ -197,7 +207,7 @@ void SurfaceTool::add_uv(const Vector2 &p_uv) { last_uv = p_uv; } -void SurfaceTool::add_uv2(const Vector2 &p_uv2) { +void SurfaceTool::set_uv2(const Vector2 &p_uv2) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV2)); @@ -205,19 +215,40 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) { last_uv2 = p_uv2; } -void SurfaceTool::add_bones(const Vector<int> &p_bones) { +void SurfaceTool::set_custom(int p_index, const Color &p_custom) { + ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT); + ERR_FAIL_COND(!begun); + ERR_FAIL_COND(last_custom_format[p_index] == CUSTOM_MAX); + static const uint32_t mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 }; + static const uint32_t shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + ERR_FAIL_COND(!first && !(format & mask[p_index])); + + if (first) { + format |= mask[p_index]; + format |= last_custom_format[p_index] << shift[p_index]; + } + last_custom[p_index] = p_custom; +} + +void SurfaceTool::set_bones(const Vector<int> &p_bones) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES)); format |= Mesh::ARRAY_FORMAT_BONES; + if (skin_weights == SKIN_8_WEIGHTS) { + format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } last_bones = p_bones; } -void SurfaceTool::add_weights(const Vector<float> &p_weights) { +void SurfaceTool::set_weights(const Vector<float> &p_weights) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS)); format |= Mesh::ARRAY_FORMAT_WEIGHTS; + if (skin_weights == SKIN_8_WEIGHTS) { + format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } last_weights = p_weights; } @@ -238,15 +269,15 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect #define ADD_POINT(n) \ { \ if (p_colors.size() > n) \ - add_color(p_colors[n]); \ + set_color(p_colors[n]); \ if (p_uvs.size() > n) \ - add_uv(p_uvs[n]); \ + set_uv(p_uvs[n]); \ if (p_uv2s.size() > n) \ - add_uv2(p_uv2s[n]); \ + set_uv2(p_uv2s[n]); \ if (p_normals.size() > n) \ - add_normal(p_normals[n]); \ + set_normal(p_normals[n]); \ if (p_tangents.size() > n) \ - add_tangent(p_tangents[n]); \ + set_tangent(p_tangents[n]); \ add_vertex(p_vertices[n]); \ } @@ -358,18 +389,157 @@ Array SurfaceTool::commit_to_arrays() { a[i] = array; } break; + case Mesh::ARRAY_CUSTOM0: + case Mesh::ARRAY_CUSTOM1: + case Mesh::ARRAY_CUSTOM2: + case Mesh::ARRAY_CUSTOM3: { + int fmt = i - Mesh::ARRAY_CUSTOM0; + switch (last_custom_format[fmt]) { + case CUSTOM_RGBA8_UNORM: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint8_t *w = array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = CLAMP(int32_t(c.r * 255.0), 0, 255); + w[idx * 4 + 1] = CLAMP(int32_t(c.g * 255.0), 0, 255); + w[idx * 4 + 2] = CLAMP(int32_t(c.b * 255.0), 0, 255); + w[idx * 4 + 3] = CLAMP(int32_t(c.a * 255.0), 0, 255); + } + + a[i] = array; + } break; + case CUSTOM_RGBA8_SNORM: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint8_t *w = array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = uint8_t(int8_t(CLAMP(int32_t(c.r * 127.0), -128, 127))); + w[idx * 4 + 1] = uint8_t(int8_t(CLAMP(int32_t(c.g * 127.0), -128, 127))); + w[idx * 4 + 2] = uint8_t(int8_t(CLAMP(int32_t(c.b * 127.0), -128, 127))); + w[idx * 4 + 3] = uint8_t(int8_t(CLAMP(int32_t(c.a * 127.0), -128, 127))); + } + + a[i] = array; + } break; + case CUSTOM_RG_HALF: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint16_t *w = (uint16_t *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 2 + 0] = Math::make_half_float(c.r); + w[idx * 2 + 1] = Math::make_half_float(c.g); + } + + a[i] = array; + } break; + case CUSTOM_RGBA_HALF: { + Vector<uint8_t> array; + array.resize(varr_len * 8); + uint16_t *w = (uint16_t *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = Math::make_half_float(c.r); + w[idx * 4 + 1] = Math::make_half_float(c.g); + w[idx * 4 + 2] = Math::make_half_float(c.b); + w[idx * 4 + 3] = Math::make_half_float(c.a); + } + + a[i] = array; + } break; + case CUSTOM_R_FLOAT: { + Vector<float> array; + array.resize(varr_len); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx] = c.r; + } + + a[i] = array; + } break; + case CUSTOM_RG_FLOAT: { + Vector<float> array; + array.resize(varr_len * 2); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 2 + 0] = c.r; + w[idx * 2 + 1] = c.g; + } + + a[i] = array; + } break; + case CUSTOM_RGB_FLOAT: { + Vector<float> array; + array.resize(varr_len * 3); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 3 + 0] = c.r; + w[idx * 3 + 1] = c.g; + w[idx * 3 + 2] = c.b; + } + + a[i] = array; + } break; + case CUSTOM_RGBA_FLOAT: { + Vector<float> array; + array.resize(varr_len * 4); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = c.r; + w[idx * 4 + 1] = c.g; + w[idx * 4 + 2] = c.b; + w[idx * 4 + 3] = c.a; + } + + a[i] = array; + } break; + default: { + } //unreachable but compiler warning anyway + } + } break; case Mesh::ARRAY_BONES: { + int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; Vector<int> array; - array.resize(varr_len * 4); + array.resize(varr_len * count); int *w = array.ptrw(); int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += count) { const Vertex &v = E->get(); - ERR_CONTINUE(v.bones.size() != 4); + ERR_CONTINUE(v.bones.size() != count); - for (int j = 0; j < 4; j++) { + for (int j = 0; j < count; j++) { w[idx + j] = v.bones[j]; } } @@ -379,15 +549,17 @@ Array SurfaceTool::commit_to_arrays() { } break; case Mesh::ARRAY_WEIGHTS: { Vector<float> array; - array.resize(varr_len * 4); + int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; + + array.resize(varr_len * count); float *w = array.ptrw(); int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += count) { const Vertex &v = E->get(); - ERR_CONTINUE(v.weights.size() != 4); + ERR_CONTINUE(v.weights.size() != count); - for (int j = 0; j < 4; j++) { + for (int j = 0; j < count; j++) { w[idx + j] = v.weights[j]; } } @@ -492,13 +664,13 @@ void SurfaceTool::deindex() { index_array.clear(); } -void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { +void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat) { Array arr = p_existing->surface_get_arrays(p_surface); ERR_FAIL_COND(arr.size() != RS::ARRAY_MAX); _create_list_from_arrays(arr, r_vertex, r_index, lformat); } -Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) { +Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, uint32_t *r_format) { Vector<SurfaceTool::Vertex> ret; Vector<Vector3> varr = p_arrays[RS::ARRAY_VERTEX]; @@ -509,9 +681,13 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array Vector<Vector2> uv2arr = p_arrays[RS::ARRAY_TEX_UV2]; Vector<int> barr = p_arrays[RS::ARRAY_BONES]; Vector<float> warr = p_arrays[RS::ARRAY_WEIGHTS]; + Vector<float> custom_float[RS::ARRAY_CUSTOM_COUNT]; int vc = varr.size(); if (vc == 0) { + if (r_format) { + *r_format = 0; + } return ret; } @@ -534,12 +710,40 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array if (uv2arr.size()) { lformat |= RS::ARRAY_FORMAT_TEX_UV2; } - if (barr.size()) { + int wcount = 0; + if (barr.size() && warr.size()) { lformat |= RS::ARRAY_FORMAT_BONES; + lformat |= RS::ARRAY_FORMAT_WEIGHTS; + + wcount = barr.size() / varr.size(); + if (wcount == 8) { + lformat |= RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } } + if (warr.size()) { lformat |= RS::ARRAY_FORMAT_WEIGHTS; } + static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 }; + static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + ERR_CONTINUE_MSG(p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY, "Extracting Byte/Half formats is not supported"); + if (p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_FLOAT32_ARRAY) { + lformat |= custom_mask[i]; + custom_float[i] = p_arrays[RS::ARRAY_CUSTOM0 + i]; + int fmt = custom_float[i].size() / varr.size(); + if (fmt == 1) { + lformat |= CUSTOM_R_FLOAT << custom_shift[i]; + } else if (fmt == 2) { + lformat |= CUSTOM_RG_FLOAT << custom_shift[i]; + } else if (fmt == 3) { + lformat |= CUSTOM_RGB_FLOAT << custom_shift[i]; + } else if (fmt == 4) { + lformat |= CUSTOM_RGBA_FLOAT << custom_shift[i]; + } + } + } for (int i = 0; i < vc; i++) { Vertex v; @@ -565,112 +769,46 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array } if (lformat & RS::ARRAY_FORMAT_BONES) { Vector<int> b; - b.resize(4); - b.write[0] = barr[i * 4 + 0]; - b.write[1] = barr[i * 4 + 1]; - b.write[2] = barr[i * 4 + 2]; - b.write[3] = barr[i * 4 + 3]; + b.resize(wcount); + for (int j = 0; j < wcount; j++) { + b.write[j] = barr[i * wcount + j]; + } v.bones = b; } if (lformat & RS::ARRAY_FORMAT_WEIGHTS) { Vector<float> w; - w.resize(4); - w.write[0] = warr[i * 4 + 0]; - w.write[1] = warr[i * 4 + 1]; - w.write[2] = warr[i * 4 + 2]; - w.write[3] = warr[i * 4 + 3]; + w.resize(wcount); + for (int j = 0; j < wcount; j++) { + w.write[j] = warr[i * wcount + j]; + } v.weights = w; } + for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) { + if (lformat & custom_mask[j]) { + int cc = custom_float[j].size() / varr.size(); + for (int k = 0; k < cc; k++) { + v.custom[j][k] = custom_float[j][i * cc + k]; + } + } + } + ret.push_back(v); } - return ret; -} - -void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { - Vector<Vector3> varr = arr[RS::ARRAY_VERTEX]; - Vector<Vector3> narr = arr[RS::ARRAY_NORMAL]; - Vector<float> tarr = arr[RS::ARRAY_TANGENT]; - Vector<Color> carr = arr[RS::ARRAY_COLOR]; - Vector<Vector2> uvarr = arr[RS::ARRAY_TEX_UV]; - Vector<Vector2> uv2arr = arr[RS::ARRAY_TEX_UV2]; - Vector<int> barr = arr[RS::ARRAY_BONES]; - Vector<float> warr = arr[RS::ARRAY_WEIGHTS]; - - int vc = varr.size(); - if (vc == 0) { - return; + if (r_format) { + *r_format = lformat; } - lformat = 0; - if (varr.size()) { - lformat |= RS::ARRAY_FORMAT_VERTEX; - } - if (narr.size()) { - lformat |= RS::ARRAY_FORMAT_NORMAL; - } - if (tarr.size()) { - lformat |= RS::ARRAY_FORMAT_TANGENT; - } - if (carr.size()) { - lformat |= RS::ARRAY_FORMAT_COLOR; - } - if (uvarr.size()) { - lformat |= RS::ARRAY_FORMAT_TEX_UV; - } - if (uv2arr.size()) { - lformat |= RS::ARRAY_FORMAT_TEX_UV2; - } - if (barr.size()) { - lformat |= RS::ARRAY_FORMAT_BONES; - } - if (warr.size()) { - lformat |= RS::ARRAY_FORMAT_WEIGHTS; - } + return ret; +} - for (int i = 0; i < vc; i++) { - Vertex v; - if (lformat & RS::ARRAY_FORMAT_VERTEX) { - v.vertex = varr[i]; - } - if (lformat & RS::ARRAY_FORMAT_NORMAL) { - v.normal = narr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TANGENT) { - Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]); - v.tangent = p.normal; - v.binormal = p.normal.cross(v.tangent).normalized() * p.d; - } - if (lformat & RS::ARRAY_FORMAT_COLOR) { - v.color = carr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TEX_UV) { - v.uv = uvarr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TEX_UV2) { - v.uv2 = uv2arr[i]; - } - if (lformat & RS::ARRAY_FORMAT_BONES) { - Vector<int> b; - b.resize(4); - b.write[0] = barr[i * 4 + 0]; - b.write[1] = barr[i * 4 + 1]; - b.write[2] = barr[i * 4 + 2]; - b.write[3] = barr[i * 4 + 3]; - v.bones = b; - } - if (lformat & RS::ARRAY_FORMAT_WEIGHTS) { - Vector<float> w; - w.resize(4); - w.write[0] = warr[i * 4 + 0]; - w.write[1] = warr[i * 4 + 1]; - w.write[2] = warr[i * 4 + 2]; - w.write[3] = warr[i * 4 + 3]; - v.weights = w; - } +void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat) { + Vector<Vertex> arrays = create_vertex_array_from_triangle_arrays(arr, &lformat); + ERR_FAIL_COND(arrays.size() == 0); - r_vertex->push_back(v); + for (int i = 0; i < arrays.size(); i++) { + r_vertex->push_back(arrays[i]); } //indices @@ -725,7 +863,7 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const format = 0; } - int nformat; + uint32_t nformat; List<Vertex> nvertices; List<int> nindices; _create_list(p_existing, p_surface, &nvertices, &nindices, nformat); @@ -975,19 +1113,48 @@ void SurfaceTool::clear() { vertex_array.clear(); smooth_groups.clear(); material.unref(); + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + last_custom_format[i] = CUSTOM_MAX; + } + skin_weights = SKIN_4_WEIGHTS; +} + +void SurfaceTool::set_skin_weight_count(SkinWeightCount p_weights) { + ERR_FAIL_COND(begun); + skin_weights = p_weights; +} +SurfaceTool::SkinWeightCount SurfaceTool::get_skin_weight_count() const { + return skin_weights; +} + +void SurfaceTool::set_custom_format(int p_index, CustomFormat p_format) { + ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT); + ERR_FAIL_COND(begun); + last_custom_format[p_index] = p_format; +} +SurfaceTool::CustomFormat SurfaceTool::get_custom_format(int p_index) const { + ERR_FAIL_INDEX_V(p_index, RS::ARRAY_CUSTOM_COUNT, CUSTOM_MAX); + return last_custom_format[p_index]; } void SurfaceTool::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_skin_weight_count", "count"), &SurfaceTool::set_skin_weight_count); + ClassDB::bind_method(D_METHOD("get_skin_weight_count"), &SurfaceTool::get_skin_weight_count); + + ClassDB::bind_method(D_METHOD("set_custom_format", "index", "format"), &SurfaceTool::set_custom_format); + ClassDB::bind_method(D_METHOD("get_custom_format", "index"), &SurfaceTool::get_custom_format); + ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin); ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex); - ClassDB::bind_method(D_METHOD("add_color", "color"), &SurfaceTool::add_color); - ClassDB::bind_method(D_METHOD("add_normal", "normal"), &SurfaceTool::add_normal); - ClassDB::bind_method(D_METHOD("add_tangent", "tangent"), &SurfaceTool::add_tangent); - ClassDB::bind_method(D_METHOD("add_uv", "uv"), &SurfaceTool::add_uv); - ClassDB::bind_method(D_METHOD("add_uv2", "uv2"), &SurfaceTool::add_uv2); - ClassDB::bind_method(D_METHOD("add_bones", "bones"), &SurfaceTool::add_bones); - ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights); + ClassDB::bind_method(D_METHOD("set_color", "color"), &SurfaceTool::set_color); + ClassDB::bind_method(D_METHOD("set_normal", "normal"), &SurfaceTool::set_normal); + ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &SurfaceTool::set_tangent); + ClassDB::bind_method(D_METHOD("set_uv", "uv"), &SurfaceTool::set_uv); + ClassDB::bind_method(D_METHOD("set_uv2", "uv2"), &SurfaceTool::set_uv2); + ClassDB::bind_method(D_METHOD("set_bones", "bones"), &SurfaceTool::set_bones); + ClassDB::bind_method(D_METHOD("set_weights", "weights"), &SurfaceTool::set_weights); + ClassDB::bind_method(D_METHOD("set_custom", "index", "custom"), &SurfaceTool::set_custom); ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group); ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); @@ -1006,13 +1173,29 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from); ClassDB::bind_method(D_METHOD("create_from_blend_shape", "existing", "surface", "blend_shape"), &SurfaceTool::create_from_blend_shape); ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from); - ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("commit_to_arrays"), &SurfaceTool::commit_to_arrays); + + BIND_ENUM_CONSTANT(CUSTOM_RGBA8_UNORM); + BIND_ENUM_CONSTANT(CUSTOM_RGBA8_SNORM); + BIND_ENUM_CONSTANT(CUSTOM_RG_HALF); + BIND_ENUM_CONSTANT(CUSTOM_RGBA_HALF); + BIND_ENUM_CONSTANT(CUSTOM_R_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RG_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RGB_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RGBA_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_MAX); + BIND_ENUM_CONSTANT(SKIN_4_WEIGHTS); + BIND_ENUM_CONSTANT(SKIN_8_WEIGHTS); } SurfaceTool::SurfaceTool() { first = false; begun = false; + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + last_custom_format[i] = CUSTOM_MAX; + } primitive = Mesh::PRIMITIVE_LINES; + skin_weights = SKIN_4_WEIGHTS; format = 0; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index d7b255e695..4a5c7d990c 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -49,12 +49,30 @@ public: Vector2 uv2; Vector<int> bones; Vector<float> weights; + Color custom[RS::ARRAY_CUSTOM_COUNT]; bool operator==(const Vertex &p_vertex) const; Vertex() {} }; + enum CustomFormat { + CUSTOM_RGBA8_UNORM = RS::ARRAY_CUSTOM_RGBA8_UNORM, + CUSTOM_RGBA8_SNORM = RS::ARRAY_CUSTOM_RGBA8_SNORM, + CUSTOM_RG_HALF = RS::ARRAY_CUSTOM_RG_HALF, + CUSTOM_RGBA_HALF = RS::ARRAY_CUSTOM_RGBA_HALF, + CUSTOM_R_FLOAT = RS::ARRAY_CUSTOM_R_FLOAT, + CUSTOM_RG_FLOAT = RS::ARRAY_CUSTOM_RG_FLOAT, + CUSTOM_RGB_FLOAT = RS::ARRAY_CUSTOM_RGB_FLOAT, + CUSTOM_RGBA_FLOAT = RS::ARRAY_CUSTOM_RGBA_FLOAT, + CUSTOM_MAX = RS::ARRAY_CUSTOM_MAX + }; + + enum SkinWeightCount { + SKIN_4_WEIGHTS, + SKIN_8_WEIGHTS + }; + private: struct VertexHasher { static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx); @@ -71,7 +89,7 @@ private: bool begun; bool first; Mesh::PrimitiveType primitive; - int format; + uint32_t format; Ref<Material> material; //arrays List<Vertex> vertex_array; @@ -87,8 +105,14 @@ private: Vector<float> last_weights; Plane last_tangent; - void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat); - void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat); + SkinWeightCount skin_weights; + + Color last_custom[RS::ARRAY_CUSTOM_COUNT]; + + CustomFormat last_custom_format[RS::ARRAY_CUSTOM_COUNT]; + + void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat); + void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat); //mikktspace callbacks static int mikktGetNumFaces(const SMikkTSpaceContext *pContext); @@ -103,18 +127,26 @@ protected: static void _bind_methods(); public: + void set_skin_weight_count(SkinWeightCount p_weights); + SkinWeightCount get_skin_weight_count() const; + + void set_custom_format(int p_index, CustomFormat p_format); + CustomFormat get_custom_format(int p_index) const; + void begin(Mesh::PrimitiveType p_primitive); + void set_color(Color p_color); + void set_normal(const Vector3 &p_normal); + void set_tangent(const Plane &p_tangent); + void set_uv(const Vector2 &p_uv); + void set_uv2(const Vector2 &p_uv2); + void set_custom(int p_index, const Color &p_custom); + void set_bones(const Vector<int> &p_bones); + void set_weights(const Vector<float> &p_weights); + void add_vertex(const Vector3 &p_vertex); - void add_color(Color p_color); - void add_normal(const Vector3 &p_normal); - void add_tangent(const Plane &p_tangent); - void add_uv(const Vector2 &p_uv); - void add_uv2(const Vector2 &p_uv2); - void add_bones(const Vector<int> &p_bones); - void add_weights(const Vector<float> &p_weights); - void add_smooth_group(bool p_smooth); + void add_smooth_group(bool p_smooth); void add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); void add_index(int p_index); @@ -131,14 +163,17 @@ public: List<Vertex> &get_vertex_array() { return vertex_array; } void create_from_triangle_arrays(const Array &p_arrays); - static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays); + static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays, uint32_t *r_format = nullptr); Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); - Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT); + Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = 0); SurfaceTool(); }; +VARIANT_ENUM_CAST(SurfaceTool::CustomFormat) +VARIANT_ENUM_CAST(SurfaceTool::SkinWeightCount) + #endif diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 09478e98b2..34129e35da 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -811,8 +811,12 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port #define IS_SYMBOL_CHAR(m_d) (((m_d) >= 'a' && (m_d) <= 'z') || ((m_d) >= 'A' && (m_d) <= 'Z') || ((m_d) >= '0' && (m_d) <= '9') || (m_d) == '_') -String VisualShader::validate_port_name(const String &p_name, const List<String> &p_input_ports, const List<String> &p_output_ports) const { - String name = p_name; +String VisualShader::validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const { + String name = p_port_name; + + if (name == String()) { + return String(); + } while (name.length() && !IS_INITIAL_CHAR(name[0])) { name = name.substr(1, name.length() - 1); @@ -830,29 +834,28 @@ String VisualShader::validate_port_name(const String &p_name, const List<String> } name = valid_name; + } else { + return String(); } - String valid_name = name; - bool is_equal = false; + List<String> input_names; + List<String> output_names; - for (int i = 0; i < p_input_ports.size(); i++) { - if (name == p_input_ports[i]) { - is_equal = true; - break; + for (int i = 0; i < p_node->get_input_port_count(); i++) { + if (!p_output && i == p_port_id) { + continue; } - } - - if (!is_equal) { - for (int i = 0; i < p_output_ports.size(); i++) { - if (name == p_output_ports[i]) { - is_equal = true; - break; - } + if (name == p_node->get_input_port_name(i)) { + return String(); } } - - if (is_equal) { - name = ""; + for (int i = 0; i < p_node->get_output_port_count(); i++) { + if (p_output && i == p_port_id) { + continue; + } + if (name == p_node->get_output_port_name(i)) { + return String(); + } } return name; @@ -2767,8 +2770,10 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) { inputs.erase(index, count); inputs_strings = inputs.split(";", false); + inputs = inputs.substr(0, index); + for (int i = p_id; i < inputs_strings.size(); i++) { - inputs = inputs.replace_first(inputs_strings[i].split(",")[0], itos(i)); + inputs += inputs_strings[i].replace_first(inputs_strings[i].split(",")[0], itos(i)) + ";"; } _apply_port_changes(); @@ -2837,8 +2842,10 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) { outputs.erase(index, count); outputs_strings = outputs.split(";", false); + outputs = outputs.substr(0, index); + for (int i = p_id; i < outputs_strings.size(); i++) { - outputs = outputs.replace_first(outputs_strings[i].split(",")[0], itos(i)); + outputs += outputs_strings[i].replace_first(outputs_strings[i].split(",")[0], itos(i)) + ";"; } _apply_port_changes(); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 41c4642ee3..a38c2886e2 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -175,7 +175,7 @@ public: String generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &r_default_tex_params) const; - String validate_port_name(const String &p_name, const List<String> &p_input_ports, const List<String> &p_output_ports) const; + String validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const; String validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const; VisualShader(); diff --git a/servers/display_server.h b/servers/display_server.h index 59bee794b8..42b1562153 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -83,7 +83,7 @@ protected: static DisplayServerCreate server_create_functions[MAX_SERVERS]; static int server_create_count; - friend class RenderingServerRaster; + friend class RenderingServerDefault; virtual void _set_use_vsync(bool p_enable); public: diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 0ba9ce9e76..29e5ca3f77 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -62,7 +62,7 @@ #include "physics_3d/physics_server_3d_sw.h" #include "physics_server_2d.h" #include "physics_server_3d.h" -#include "rendering/rasterizer.h" +#include "rendering/renderer_compositor.h" #include "rendering/rendering_device.h" #include "rendering/rendering_device_binds.h" #include "rendering_server.h" diff --git a/servers/rendering/SCsub b/servers/rendering/SCsub index 5ea0d40486..0939b68482 100644 --- a/servers/rendering/SCsub +++ b/servers/rendering/SCsub @@ -4,4 +4,4 @@ Import("env") env.add_source_files(env.servers_sources, "*.cpp") -SConscript("rasterizer_rd/SCsub") +SConscript("renderer_rd/SCsub") diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h deleted file mode 100644 index 30577e6247..0000000000 --- a/servers/rendering/rasterizer.h +++ /dev/null @@ -1,1415 +0,0 @@ -/*************************************************************************/ -/* rasterizer.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef RASTERIZER_H -#define RASTERIZER_H - -#include "core/math/camera_matrix.h" -#include "core/templates/pair.h" -#include "core/templates/self_list.h" -#include "servers/rendering_server.h" - -class RasterizerScene { -public: - /* SHADOW ATLAS API */ - - virtual RID shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; - virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; - virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0; - - virtual void directional_shadow_atlas_set_size(int p_size) = 0; - virtual int get_directional_light_shadow_size(RID p_light_intance) = 0; - virtual void set_directional_shadow_count(int p_count) = 0; - - /* SDFGI UPDATE */ - - struct InstanceBase; - - virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0; - virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0; - virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0; - virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0; - virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0; - - /* SKY API */ - - virtual RID sky_create() = 0; - virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; - virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; - virtual void sky_set_material(RID p_sky, RID p_material) = 0; - virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0; - - /* ENVIRONMENT API */ - - virtual RID environment_create() = 0; - - virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; - virtual void environment_set_sky(RID p_env, RID p_sky) = 0; - virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; - virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0; - virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0; - virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0; - virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; - virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) = 0; -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; -#endif - - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; - virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; - - virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; - virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; - - virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; - virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; - - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0; - - virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0; - - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; - - virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; - virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; - - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; - - virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0; - - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; - - virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; - - virtual bool is_environment(RID p_env) const = 0; - virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; - virtual int environment_get_canvas_max_layer(RID p_env) const = 0; - - virtual RID camera_effects_create() = 0; - - virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; - virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; - - virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; - virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; - - virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0; - virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; - - struct InstanceDependency { - void instance_notify_changed(bool p_aabb, bool p_dependencies); - void instance_notify_deleted(RID p_deleted); - - ~InstanceDependency(); - - private: - friend struct InstanceBase; - Map<InstanceBase *, uint32_t> instances; - }; - - struct InstanceBase { - RS::InstanceType base_type; - RID base; - - RID skeleton; - RID material_override; - - RID instance_data; - - Transform transform; - - int depth_layer; - uint32_t layer_mask; - uint32_t instance_version; - - //RID sampled_light; - - Vector<RID> materials; - Vector<RID> light_instances; - Vector<RID> reflection_probe_instances; - Vector<RID> gi_probe_instances; - - Vector<float> blend_values; - - RS::ShadowCastingSetting cast_shadows; - - //fit in 32 bits - bool mirror : 8; - bool receive_shadows : 8; - bool visible : 8; - bool baked_light : 2; //this flag is only to know if it actually did use baked light - bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light - bool redraw_if_visible : 4; - - float depth; //used for sorting - - SelfList<InstanceBase> dependency_item; - - InstanceBase *lightmap; - Rect2 lightmap_uv_scale; - int lightmap_slice_index; - uint32_t lightmap_cull_index; - Vector<Color> lightmap_sh; //spherical harmonic - - AABB aabb; - AABB transformed_aabb; - - struct InstanceShaderParameter { - int32_t index = -1; - Variant value; - Variant default_value; - PropertyInfo info; - }; - - Map<StringName, InstanceShaderParameter> instance_shader_parameters; - bool instance_allocated_shader_parameters = false; - int32_t instance_allocated_shader_parameters_offset = -1; - - virtual void dependency_deleted(RID p_dependency) {} - virtual void dependency_changed(bool p_aabb, bool p_dependencies) {} - - Set<InstanceDependency *> dependencies; - - void instance_increase_version() { - instance_version++; - } - - void update_dependency(InstanceDependency *p_dependency) { - dependencies.insert(p_dependency); - p_dependency->instances[this] = instance_version; - } - - void clean_up_dependencies() { - List<Pair<InstanceDependency *, Map<InstanceBase *, uint32_t>::Element *>> to_clean_up; - for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { - InstanceDependency *dep = E->get(); - Map<InstanceBase *, uint32_t>::Element *F = dep->instances.find(this); - ERR_CONTINUE(!F); - if (F->get() != instance_version) { - Pair<InstanceDependency *, Map<InstanceBase *, uint32_t>::Element *> p; - p.first = dep; - p.second = F; - to_clean_up.push_back(p); - } - } - - while (to_clean_up.size()) { - to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second); - to_clean_up.pop_front(); - } - } - - void clear_dependencies() { - for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { - InstanceDependency *dep = E->get(); - dep->instances.erase(this); - } - dependencies.clear(); - } - - InstanceBase() : - dependency_item(this) { - base_type = RS::INSTANCE_NONE; - cast_shadows = RS::SHADOW_CASTING_SETTING_ON; - receive_shadows = true; - visible = true; - depth_layer = 0; - layer_mask = 1; - instance_version = 0; - baked_light = false; - dynamic_gi = false; - redraw_if_visible = false; - lightmap_slice_index = 0; - lightmap = nullptr; - lightmap_cull_index = 0; - } - - virtual ~InstanceBase() { - clear_dependencies(); - } - }; - - virtual RID light_instance_create(RID p_light) = 0; - virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; - virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; - virtual void light_instance_mark_visible(RID p_light_instance) = 0; - virtual bool light_instances_can_render_shadow_cube() const { - return true; - } - - virtual RID reflection_atlas_create() = 0; - virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0; - - virtual RID reflection_probe_instance_create(RID p_probe) = 0; - virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) = 0; - virtual void reflection_probe_release_atlas_index(RID p_instance) = 0; - virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0; - virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0; - virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0; - virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0; - - virtual RID decal_instance_create(RID p_decal) = 0; - virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0; - - virtual RID gi_probe_instance_create(RID p_gi_probe) = 0; - virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0; - virtual bool gi_probe_needs_update(RID p_probe) const = 0; - virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0; - - virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; - - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; - - virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0; - virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) = 0; - virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) = 0; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) = 0; - - virtual void set_scene_pass(uint64_t p_pass) = 0; - virtual void set_time(double p_time, double p_step) = 0; - virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; - - virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; - - virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; - virtual bool screen_space_roughness_limiter_is_active() const = 0; - - virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; - virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; - - virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; - - virtual bool free(RID p_rid) = 0; - - virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0; - - virtual void update() = 0; - virtual ~RasterizerScene() {} -}; - -class RasterizerStorage { - Color default_clear_color; - -public: - /* TEXTURE API */ - - virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; - virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent - - virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming - virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; - virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0; - virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; - - //these two APIs can be used together or in combination with the others. - virtual RID texture_2d_placeholder_create() = 0; - virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_placeholder_create() = 0; - - virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; - virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; - virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0; - - virtual void texture_replace(RID p_texture, RID p_by_texture) = 0; - virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0; - - virtual void texture_set_path(RID p_texture, const String &p_path) = 0; - virtual String texture_get_path(RID p_texture) const = 0; - - virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; - virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; - virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) = 0; - - virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) = 0; - - virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; - - virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; - - virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; - virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; - - /* CANVAS TEXTURE API */ - - virtual RID canvas_texture_create() = 0; - virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0; - virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0; - - virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0; - virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0; - - /* SHADER API */ - - virtual RID shader_create() = 0; - - virtual void shader_set_code(RID p_shader, const String &p_code) = 0; - virtual String shader_get_code(RID p_shader) const = 0; - virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; - - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0; - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0; - virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0; - - /* COMMON MATERIAL API */ - - virtual RID material_create() = 0; - - virtual void material_set_render_priority(RID p_material, int priority) = 0; - virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; - - virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0; - virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0; - - virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0; - - virtual bool material_is_animated(RID p_material) = 0; - virtual bool material_casts_shadows(RID p_material) = 0; - - struct InstanceShaderParam { - PropertyInfo info; - int index; - Variant default_value; - }; - - virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; - - virtual void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) = 0; - - /* MESH API */ - - virtual RID mesh_create() = 0; - - /// Returns stride - virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) = 0; - - virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; - - virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) = 0; - virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; - - virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0; - - virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; - virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; - - virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const = 0; - - virtual int mesh_get_surface_count(RID p_mesh) const = 0; - - virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; - virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; - - virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0; - - virtual void mesh_clear(RID p_mesh) = 0; - - /* MULTIMESH API */ - - virtual RID multimesh_create() = 0; - - virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; - - virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; - - virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; - virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0; - virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0; - virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0; - virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0; - - virtual RID multimesh_get_mesh(RID p_multimesh) const = 0; - - virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; - virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0; - virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0; - virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0; - - virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) = 0; - virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const = 0; - - virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0; - virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0; - - virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; - - /* IMMEDIATE API */ - - virtual RID immediate_create() = 0; - virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0; - virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0; - virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0; - virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) = 0; - virtual void immediate_color(RID p_immediate, const Color &p_color) = 0; - virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) = 0; - virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) = 0; - virtual void immediate_end(RID p_immediate) = 0; - virtual void immediate_clear(RID p_immediate) = 0; - virtual void immediate_set_material(RID p_immediate, RID p_material) = 0; - virtual RID immediate_get_material(RID p_immediate) const = 0; - virtual AABB immediate_get_aabb(RID p_immediate) const = 0; - - /* SKELETON API */ - - virtual RID skeleton_create() = 0; - virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; - virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; - virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; - virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; - virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0; - virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0; - virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0; - - /* Light API */ - - virtual RID light_create(RS::LightType p_type) = 0; - - RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); } - RID omni_light_create() { return light_create(RS::LIGHT_OMNI); } - RID spot_light_create() { return light_create(RS::LIGHT_SPOT); } - - virtual void light_set_color(RID p_light, const Color &p_color) = 0; - virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; - virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; - virtual void light_set_projector(RID p_light, RID p_texture) = 0; - virtual void light_set_negative(RID p_light, bool p_enable) = 0; - virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; - virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; - virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0; - virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0; - - virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) = 0; - - virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0; - virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; - virtual bool light_directional_get_blend_splits(RID p_light) const = 0; - virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0; - virtual bool light_directional_is_sky_only(RID p_light) const = 0; - virtual void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0; - virtual RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0; - - virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0; - virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0; - - virtual bool light_has_shadow(RID p_light) const = 0; - - virtual RS::LightType light_get_type(RID p_light) const = 0; - virtual AABB light_get_aabb(RID p_light) const = 0; - virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0; - virtual Color light_get_color(RID p_light) = 0; - virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0; - virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0; - virtual uint64_t light_get_version(RID p_light) const = 0; - - /* PROBE API */ - - virtual RID reflection_probe_create() = 0; - - virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0; - virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0; - virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0; - virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) = 0; - virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) = 0; - virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) = 0; - virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) = 0; - virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) = 0; - virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) = 0; - virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) = 0; - virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0; - virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0; - virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0; - - virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0; - virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0; - virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0; - virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0; - virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const = 0; - virtual float reflection_probe_get_origin_max_distance(RID p_probe) const = 0; - virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0; - - virtual void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0; - virtual void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0; - - /* DECAL API */ - - virtual RID decal_create() = 0; - virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0; - virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0; - virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0; - virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0; - virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0; - virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0; - virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0; - virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0; - virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0; - - virtual AABB decal_get_aabb(RID p_decal) const = 0; - - /* GI PROBE API */ - - virtual RID gi_probe_create() = 0; - - virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; - - virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; - virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const = 0; - - virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const = 0; - virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_propagation(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_energy(RID p_gi_probe, float p_energy) = 0; - virtual float gi_probe_get_energy(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) = 0; - virtual float gi_probe_get_ao(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) = 0; - virtual float gi_probe_get_ao_size(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_bias(RID p_gi_probe, float p_bias) = 0; - virtual float gi_probe_get_bias(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_normal_bias(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_interior(RID p_gi_probe, bool p_enable) = 0; - virtual bool gi_probe_is_interior(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) = 0; - virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const = 0; - - virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0; - virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0; - - virtual uint32_t gi_probe_get_version(RID p_probe) = 0; - - /* LIGHTMAP CAPTURE */ - - virtual RID lightmap_create() = 0; - - virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; - virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; - virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0; - virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0; - virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0; - virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0; - virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0; - virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0; - virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0; - virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0; - virtual bool lightmap_is_interior(RID p_lightmap) const = 0; - virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0; - virtual float lightmap_get_probe_capture_update_speed() const = 0; - - /* PARTICLES */ - - virtual RID particles_create() = 0; - - virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; - virtual bool particles_get_emitting(RID p_particles) = 0; - - virtual void particles_set_amount(RID p_particles, int p_amount) = 0; - virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0; - virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0; - virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; - virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; - virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; - virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0; - virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0; - virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; - virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; - virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0; - virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0; - virtual void particles_set_collision_base_size(RID p_particles, float p_size) = 0; - virtual void particles_restart(RID p_particles) = 0; - virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0; - virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0; - - virtual bool particles_is_inactive(RID p_particles) const = 0; - - virtual void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) = 0; - - virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0; - virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0; - - virtual void particles_request_process(RID p_particles) = 0; - virtual AABB particles_get_current_aabb(RID p_particles) = 0; - virtual AABB particles_get_aabb(RID p_particles) const = 0; - - virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; - - virtual int particles_get_draw_passes(RID p_particles) const = 0; - virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0; - - virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0; - - virtual void particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) = 0; - virtual void particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) = 0; - - virtual void update_particles() = 0; - - /* PARTICLES COLLISION */ - - virtual RID particles_collision_create() = 0; - virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0; - virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0; - virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres - virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres - virtual void particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) = 0; - virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) = 0; - virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) = 0; - virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic - virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field - virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field - virtual AABB particles_collision_get_aabb(RID p_particles_collision) const = 0; - virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0; - virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0; - - /* GLOBAL VARIABLES */ - - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0; - virtual void global_variable_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_variable_get_list() const = 0; - - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_variable_get(const StringName &p_name) const = 0; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; - - virtual void global_variables_load_settings(bool p_load_textures = true) = 0; - virtual void global_variables_clear() = 0; - - virtual int32_t global_variables_instance_allocate(RID p_instance) = 0; - virtual void global_variables_instance_free(RID p_instance) = 0; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; - - /* RENDER TARGET */ - - enum RenderTargetFlags { - RENDER_TARGET_TRANSPARENT, - RENDER_TARGET_DIRECT_TO_SCREEN, - RENDER_TARGET_FLAG_MAX - }; - - virtual RID render_target_create() = 0; - virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0; - virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0; - virtual RID render_target_get_texture(RID p_render_target) = 0; - virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0; - virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0; - virtual bool render_target_was_used(RID p_render_target) = 0; - virtual void render_target_set_as_unused(RID p_render_target) = 0; - - virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0; - virtual bool render_target_is_clear_requested(RID p_render_target) = 0; - virtual Color render_target_get_clear_request_color(RID p_render_target) = 0; - virtual void render_target_disable_clear_request(RID p_render_target) = 0; - virtual void render_target_do_clear_request(RID p_render_target) = 0; - - virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0; - virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0; - - virtual RS::InstanceType get_base_type(RID p_rid) const = 0; - virtual bool free(RID p_rid) = 0; - - virtual bool has_os_feature(const String &p_feature) const = 0; - - virtual void update_dirty_resources() = 0; - - virtual void set_debug_generate_wireframes(bool p_generate) = 0; - - virtual void render_info_begin_capture() = 0; - virtual void render_info_end_capture() = 0; - virtual int get_captured_render_info(RS::RenderInfo p_info) = 0; - - virtual int get_render_info(RS::RenderInfo p_info) = 0; - virtual String get_video_adapter_name() const = 0; - virtual String get_video_adapter_vendor() const = 0; - - static RasterizerStorage *base_singleton; - - void set_default_clear_color(const Color &p_color) { - default_clear_color = p_color; - } - - Color get_default_clear_color() const { - return default_clear_color; - } -#define TIMESTAMP_BEGIN() \ - { \ - if (RSG::storage->capturing_timestamps) \ - RSG::storage->capture_timestamps_begin(); \ - } - -#define RENDER_TIMESTAMP(m_text) \ - { \ - if (RSG::storage->capturing_timestamps) \ - RSG::storage->capture_timestamp(m_text); \ - } - - bool capturing_timestamps = false; - - virtual void capture_timestamps_begin() = 0; - virtual void capture_timestamp(const String &p_name) = 0; - virtual uint32_t get_captured_timestamps_count() const = 0; - virtual uint64_t get_captured_timestamps_frame() const = 0; - virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0; - virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0; - virtual String get_captured_timestamp_name(uint32_t p_index) const = 0; - - RasterizerStorage(); - virtual ~RasterizerStorage() {} -}; - -class RasterizerCanvas { -public: - static RasterizerCanvas *singleton; - - enum CanvasRectFlags { - CANVAS_RECT_REGION = 1, - CANVAS_RECT_TILE = 2, - CANVAS_RECT_FLIP_H = 4, - CANVAS_RECT_FLIP_V = 8, - CANVAS_RECT_TRANSPOSE = 16, - CANVAS_RECT_CLIP_UV = 32, - CANVAS_RECT_IS_GROUP = 64, - }; - - struct Light { - bool enabled; - Color color; - Transform2D xform; - float height; - float energy; - float scale; - int z_min; - int z_max; - int layer_min; - int layer_max; - int item_mask; - int item_shadow_mask; - float directional_distance; - RS::CanvasLightMode mode; - RS::CanvasLightBlendMode blend_mode; - RID texture; - Vector2 texture_offset; - RID canvas; - bool use_shadow; - int shadow_buffer_size; - RS::CanvasLightShadowFilter shadow_filter; - Color shadow_color; - float shadow_smooth; - - //void *texture_cache; // implementation dependent - Rect2 rect_cache; - Transform2D xform_cache; - float radius_cache; //used for shadow far plane - //CameraMatrix shadow_matrix_cache; - - Transform2D light_shader_xform; - //Vector2 light_shader_pos; - - Light *shadows_next_ptr; - Light *filter_next_ptr; - Light *next_ptr; - Light *directional_next_ptr; - - RID light_internal; - uint64_t version; - - int32_t render_index_cache; - - Light() { - version = 0; - enabled = true; - color = Color(1, 1, 1); - shadow_color = Color(0, 0, 0, 0); - height = 0; - z_min = -1024; - z_max = 1024; - layer_min = 0; - layer_max = 0; - item_mask = 1; - scale = 1.0; - energy = 1.0; - item_shadow_mask = 1; - mode = RS::CANVAS_LIGHT_MODE_POINT; - blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD; - // texture_cache = nullptr; - next_ptr = nullptr; - directional_next_ptr = nullptr; - filter_next_ptr = nullptr; - use_shadow = false; - shadow_buffer_size = 2048; - shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE; - shadow_smooth = 0.0; - render_index_cache = -1; - directional_distance = 10000.0; - } - }; - - //easier wrap to avoid mistakes - - struct Item; - - typedef uint64_t PolygonID; - virtual PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) = 0; - virtual void free_polygon(PolygonID p_polygon) = 0; - - //also easier to wrap to avoid mistakes - struct Polygon { - PolygonID polygon_id; - Rect2 rect_cache; - - _FORCE_INLINE_ void create(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) { - ERR_FAIL_COND(polygon_id != 0); - { - uint32_t pc = p_points.size(); - const Vector2 *v2 = p_points.ptr(); - rect_cache.position = *v2; - for (uint32_t i = 1; i < pc; i++) { - rect_cache.expand_to(v2[i]); - } - } - polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights); - } - - _FORCE_INLINE_ Polygon() { polygon_id = 0; } - _FORCE_INLINE_ ~Polygon() { - if (polygon_id) { - singleton->free_polygon(polygon_id); - } - } - }; - - //item - - struct Item { - //commands are allocated in blocks of 4k to improve performance - //and cache coherence. - //blocks always grow but never shrink. - - struct CommandBlock { - enum { - MAX_SIZE = 4096 - }; - uint32_t usage; - uint8_t *memory; - }; - - struct Command { - enum Type { - TYPE_RECT, - TYPE_NINEPATCH, - TYPE_POLYGON, - TYPE_PRIMITIVE, - TYPE_MESH, - TYPE_MULTIMESH, - TYPE_PARTICLES, - TYPE_TRANSFORM, - TYPE_CLIP_IGNORE, - }; - - Command *next; - Type type; - virtual ~Command() {} - }; - - struct CommandRect : public Command { - Rect2 rect; - Color modulate; - Rect2 source; - uint8_t flags; - - RID texture; - - CommandRect() { - flags = 0; - type = TYPE_RECT; - } - }; - - struct CommandNinePatch : public Command { - Rect2 rect; - Rect2 source; - float margin[4]; - bool draw_center; - Color color; - RS::NinePatchAxisMode axis_x; - RS::NinePatchAxisMode axis_y; - - RID texture; - - CommandNinePatch() { - draw_center = true; - type = TYPE_NINEPATCH; - } - }; - - struct CommandPolygon : public Command { - RS::PrimitiveType primitive; - Polygon polygon; - - RID texture; - - CommandPolygon() { - type = TYPE_POLYGON; - } - }; - - struct CommandPrimitive : public Command { - uint32_t point_count; - Vector2 points[4]; - Vector2 uvs[4]; - Color colors[4]; - - RID texture; - - CommandPrimitive() { - type = TYPE_PRIMITIVE; - } - }; - - struct CommandMesh : public Command { - RID mesh; - Transform2D transform; - Color modulate; - - RID texture; - - CommandMesh() { type = TYPE_MESH; } - }; - - struct CommandMultiMesh : public Command { - RID multimesh; - - RID texture; - - CommandMultiMesh() { type = TYPE_MULTIMESH; } - }; - - struct CommandParticles : public Command { - RID particles; - - RID texture; - - CommandParticles() { type = TYPE_PARTICLES; } - }; - - struct CommandTransform : public Command { - Transform2D xform; - CommandTransform() { type = TYPE_TRANSFORM; } - }; - - struct CommandClipIgnore : public Command { - bool ignore; - CommandClipIgnore() { - type = TYPE_CLIP_IGNORE; - ignore = false; - } - }; - - struct ViewportRender { - RenderingServer *owner; - void *udata; - Rect2 rect; - }; - - Transform2D xform; - bool clip; - bool visible; - bool behind; - bool update_when_visible; - - struct CanvasGroup { - RS::CanvasGroupMode mode; - bool fit_empty; - float fit_margin; - bool blur_mipmaps; - float clear_margin; - }; - - CanvasGroup *canvas_group = nullptr; - int light_mask; - int z_final; - - mutable bool custom_rect; - mutable bool rect_dirty; - mutable Rect2 rect; - RID material; - RID skeleton; - - Item *next; - - struct CopyBackBuffer { - Rect2 rect; - Rect2 screen_rect; - bool full; - }; - CopyBackBuffer *copy_back_buffer; - - Color final_modulate; - Transform2D final_transform; - Rect2 final_clip_rect; - Item *final_clip_owner; - Item *material_owner; - Item *canvas_group_owner; - ViewportRender *vp_render; - bool distance_field; - bool light_masked; - - Rect2 global_rect_cache; - - const Rect2 &get_rect() const { - if (custom_rect || (!rect_dirty && !update_when_visible)) { - return rect; - } - - //must update rect - - if (commands == nullptr) { - rect = Rect2(); - rect_dirty = false; - return rect; - } - - Transform2D xf; - bool found_xform = false; - bool first = true; - - const Item::Command *c = commands; - - while (c) { - Rect2 r; - - switch (c->type) { - case Item::Command::TYPE_RECT: { - const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c); - r = crect->rect; - - } break; - case Item::Command::TYPE_NINEPATCH: { - const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c); - r = style->rect; - } break; - - case Item::Command::TYPE_POLYGON: { - const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); - r = polygon->polygon.rect_cache; - } break; - case Item::Command::TYPE_PRIMITIVE: { - const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); - for (uint32_t j = 0; j < primitive->point_count; j++) { - if (j == 0) { - r.position = primitive->points[0]; - } else { - r.expand_to(primitive->points[j]); - } - } - } break; - case Item::Command::TYPE_MESH: { - const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); - AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID()); - - r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); - - } break; - case Item::Command::TYPE_MULTIMESH: { - const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c); - AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); - - r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); - - } break; - case Item::Command::TYPE_PARTICLES: { - const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); - if (particles_cmd->particles.is_valid()) { - AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); - r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); - } - - } break; - case Item::Command::TYPE_TRANSFORM: { - const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); - xf = transform->xform; - found_xform = true; - [[fallthrough]]; - } - default: { - c = c->next; - continue; - } - } - - if (found_xform) { - r = xf.xform(r); - found_xform = false; - } - - if (first) { - rect = r; - first = false; - } else { - rect = rect.merge(r); - } - c = c->next; - } - - rect_dirty = false; - return rect; - } - - Command *commands; - Command *last_command; - Vector<CommandBlock> blocks; - uint32_t current_block; - - template <class T> - T *alloc_command() { - T *command; - if (commands == nullptr) { - // As the most common use case of canvas items is to - // use only one command, the first is done with it's - // own allocation. The rest of them use blocks. - command = memnew(T); - command->next = nullptr; - commands = command; - last_command = command; - } else { - //Subsequent commands go into a block. - - while (true) { - if (unlikely(current_block == (uint32_t)blocks.size())) { - // If we need more blocks, we allocate them - // (they won't be freed until this CanvasItem is - // deleted, though). - CommandBlock cb; - cb.memory = (uint8_t *)memalloc(CommandBlock::MAX_SIZE); - cb.usage = 0; - blocks.push_back(cb); - } - - CommandBlock *c = &blocks.write[current_block]; - size_t space_left = CommandBlock::MAX_SIZE - c->usage; - if (space_left < sizeof(T)) { - current_block++; - continue; - } - - //allocate block and add to the linked list - void *memory = c->memory + c->usage; - command = memnew_placement(memory, T); - command->next = nullptr; - last_command->next = command; - last_command = command; - c->usage += sizeof(T); - break; - } - } - - rect_dirty = true; - return command; - } - - void clear() { - // The first one is always allocated on heap - // the rest go in the blocks - Command *c = commands; - while (c) { - Command *n = c->next; - if (c == commands) { - memdelete(commands); - commands = nullptr; - } else { - c->~Command(); - } - c = n; - } - { - uint32_t cbc = MIN((current_block + 1), (uint32_t)blocks.size()); - CommandBlock *blockptr = blocks.ptrw(); - for (uint32_t i = 0; i < cbc; i++) { - blockptr[i].usage = 0; - } - } - - last_command = nullptr; - commands = nullptr; - current_block = 0; - clip = false; - rect_dirty = true; - final_clip_owner = nullptr; - material_owner = nullptr; - light_masked = false; - } - - RS::CanvasItemTextureFilter texture_filter; - RS::CanvasItemTextureRepeat texture_repeat; - - Item() { - commands = nullptr; - last_command = nullptr; - current_block = 0; - light_mask = 1; - vp_render = nullptr; - next = nullptr; - final_clip_owner = nullptr; - canvas_group_owner = nullptr; - clip = false; - final_modulate = Color(1, 1, 1, 1); - visible = true; - rect_dirty = true; - custom_rect = false; - behind = false; - material_owner = nullptr; - copy_back_buffer = nullptr; - distance_field = false; - light_masked = false; - update_when_visible = false; - z_final = 0; - texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; - texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; - } - virtual ~Item() { - clear(); - for (int i = 0; i < blocks.size(); i++) { - memfree(blocks[i].memory); - } - if (copy_back_buffer) { - memdelete(copy_back_buffer); - } - } - }; - - virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) = 0; - virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; - - struct LightOccluderInstance { - bool enabled; - RID canvas; - RID polygon; - RID occluder; - Rect2 aabb_cache; - Transform2D xform; - Transform2D xform_cache; - int light_mask; - bool sdf_collision; - RS::CanvasOccluderPolygonCullMode cull_cache; - - LightOccluderInstance *next; - - LightOccluderInstance() { - enabled = true; - sdf_collision = false; - next = nullptr; - light_mask = 1; - cull_cache = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; - } - }; - - virtual RID light_create() = 0; - virtual void light_set_texture(RID p_rid, RID p_texture) = 0; - virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0; - virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0; - virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0; - - virtual void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) = 0; - - virtual RID occluder_polygon_create() = 0; - virtual void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) = 0; - virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) = 0; - virtual void set_shadow_texture_size(int p_size) = 0; - - virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0; - - virtual bool free(RID p_rid) = 0; - virtual void update() = 0; - - RasterizerCanvas() { singleton = this; } - virtual ~RasterizerCanvas() {} -}; - -class Rasterizer { -protected: - static Rasterizer *(*_create_func)(); - -public: - static Rasterizer *create(); - - virtual RasterizerStorage *get_storage() = 0; - virtual RasterizerCanvas *get_canvas() = 0; - virtual RasterizerScene *get_scene() = 0; - - virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) = 0; - - virtual void initialize() = 0; - virtual void begin_frame(double frame_step) = 0; - - struct BlitToScreen { - RID render_target; - Rect2i rect; - //lens distorted parameters for VR should go here - }; - - virtual void prepare_for_blitting_render_targets() = 0; - virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0; - - virtual void end_frame(bool p_swap_buffers) = 0; - virtual void finalize() = 0; - virtual uint64_t get_frame_number() const = 0; - virtual float get_frame_delta_time() const = 0; - - virtual bool is_low_end() const = 0; - - virtual ~Rasterizer() {} -}; - -#endif // RASTERIZER_H diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/renderer_canvas_cull.cpp index 0e61d53866..a397ba4389 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_canvas.cpp */ +/* renderer_canvas_cull.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rendering_server_canvas.h" +#include "renderer_canvas_cull.h" #include "core/math/geometry_2d.h" +#include "renderer_viewport.h" +#include "rendering_server_default.h" #include "rendering_server_globals.h" -#include "rendering_server_raster.h" -#include "rendering_server_viewport.h" static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; -void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { +void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { RENDER_TIMESTAMP("Cull CanvasItem Tree"); - memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); - memset(z_last_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); + memset(z_list, 0, z_range * sizeof(RendererCanvasRender::Item *)); + memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *)); for (int i = 0; i < p_child_item_count; i++) { _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr); @@ -50,8 +50,8 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr); } - RasterizerCanvas::Item *list = nullptr; - RasterizerCanvas::Item *list_end = nullptr; + RendererCanvasRender::Item *list = nullptr; + RendererCanvasRender::Item *list_end = nullptr; for (int i = 0; i < z_range; i++) { if (!z_list[i]) { @@ -75,9 +75,9 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can } } -void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) { +void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index) { int child_item_count = p_canvas_item->child_items.size(); - RenderingServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw(); + RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { if (child_items[i]->visible) { if (r_items) { @@ -97,14 +97,14 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo } } -void _mark_ysort_dirty(RenderingServerCanvas::Item *ysort_owner, RID_PtrOwner<RenderingServerCanvas::Item> &canvas_item_owner) { +void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item> &canvas_item_owner) { do { ysort_owner->ysort_children_count = -1; ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr; } while (ysort_owner && ysort_owner->sort_y); } -void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) { +void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) { Item *ci = p_canvas_item; if (!ci->visible) { @@ -176,7 +176,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo p_z = ci->z_index; } - RasterizerCanvas::Item *canvas_group_from = nullptr; + RendererCanvasRender::Item *canvas_group_from = nullptr; bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr); if (use_canvas_group) { int zidx = p_z - RS::CANVAS_ITEM_Z_MIN; @@ -213,7 +213,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo //compute a global rect (in global coords) for children in the same z layer Rect2 rect_accum; - RasterizerCanvas::Item *c = canvas_group_from; + RendererCanvasRender::Item *c = canvas_group_from; while (c) { if (c == canvas_group_from) { rect_accum = c->global_rect_cache; @@ -227,7 +227,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo // We have two choices now, if user has drawn something, we must assume users wants to draw the "mask", so compute the size based on this. // If nothing has been drawn, we just take it over and draw it ourselves. if (ci->canvas_group->fit_empty && (ci->commands == nullptr || - (ci->commands->next == nullptr && ci->commands->type == Item::Command::TYPE_RECT && (static_cast<Item::CommandRect *>(ci->commands)->flags & RasterizerCanvas::CANVAS_RECT_IS_GROUP)))) { + (ci->commands->next == nullptr && ci->commands->type == Item::Command::TYPE_RECT && (static_cast<Item::CommandRect *>(ci->commands)->flags & RendererCanvasRender::CANVAS_RECT_IS_GROUP)))) { // No commands, or sole command is the one used to draw, so we (re)create the draw command. ci->clear(); @@ -238,9 +238,9 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo rect_accum = rect_accum.grow(ci->canvas_group->fit_margin); //draw it? - RasterizerCanvas::Item::CommandRect *crect = ci->alloc_command<RasterizerCanvas::Item::CommandRect>(); + RendererCanvasRender::Item::CommandRect *crect = ci->alloc_command<RendererCanvasRender::Item::CommandRect>(); - crect->flags = RasterizerCanvas::CANVAS_RECT_IS_GROUP; // so we can recognize it later + crect->flags = RendererCanvasRender::CANVAS_RECT_IS_GROUP; // so we can recognize it later crect->rect = xform.affine_inverse().xform(rect_accum); crect->modulate = Color(1, 1, 1, 1); @@ -256,14 +256,14 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo global_rect.position += p_clip_rect.position; } - // Very important that this is cleared after used in RasterizerCanvas to avoid + // Very important that this is cleared after used in RendererCanvasRender to avoid // potential crashes. canvas_group_from->canvas_group_owner = ci; } } if (ci->update_when_visible) { - RenderingServerRaster::redraw_request(); + RenderingServerDefault::redraw_request(); } if ((ci->commands != nullptr && p_clip_rect.intersects(global_rect, true)) || ci->vp_render || ci->copy_back_buffer) { @@ -302,7 +302,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } } -void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { +void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { RENDER_TIMESTAMP(">Render Canvas"); sdf_used = false; @@ -352,11 +352,11 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, RENDER_TIMESTAMP("<End Render Canvas"); } -bool RenderingServerCanvas::was_sdf_used() { +bool RendererCanvasCull::was_sdf_used() { return sdf_used; } -RID RenderingServerCanvas::canvas_create() { +RID RendererCanvasCull::canvas_create() { Canvas *canvas = memnew(Canvas); ERR_FAIL_COND_V(!canvas, RID()); RID rid = canvas_owner.make_rid(canvas); @@ -364,7 +364,7 @@ RID RenderingServerCanvas::canvas_create() { return rid; } -void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { +void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); Item *canvas_item = canvas_item_owner.getornull(p_item); @@ -375,17 +375,17 @@ void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, canvas->child_items.write[idx].mirror = p_mirroring; } -void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) { +void RendererCanvasCull::canvas_set_modulate(RID p_canvas, const Color &p_color) { Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); canvas->modulate = p_color; } -void RenderingServerCanvas::canvas_set_disable_scale(bool p_disable) { +void RendererCanvasCull::canvas_set_disable_scale(bool p_disable) { disable_scale = p_disable; } -void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { +void RendererCanvasCull::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); @@ -393,14 +393,14 @@ void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float canvas->parent_scale = p_scale; } -RID RenderingServerCanvas::canvas_item_create() { +RID RendererCanvasCull::canvas_item_create() { Item *canvas_item = memnew(Item); ERR_FAIL_COND_V(!canvas_item, RID()); return canvas_item_owner.make_rid(canvas_item); } -void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { +void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -444,7 +444,7 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { canvas_item->parent = p_parent; } -void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { +void RendererCanvasCull::canvas_item_set_visible(RID p_item, bool p_visible) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -453,35 +453,35 @@ void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) _mark_ysort_dirty(canvas_item, canvas_item_owner); } -void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { +void RendererCanvasCull::canvas_item_set_light_mask(RID p_item, int p_mask) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->light_mask = p_mask; } -void RenderingServerCanvas::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) { +void RendererCanvasCull::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->xform = p_transform; } -void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) { +void RendererCanvasCull::canvas_item_set_clip(RID p_item, bool p_clip) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clip = p_clip; } -void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { +void RendererCanvasCull::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->distance_field = p_enable; } -void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { +void RendererCanvasCull::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -489,35 +489,35 @@ void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custo canvas_item->rect = p_rect; } -void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) { +void RendererCanvasCull::canvas_item_set_modulate(RID p_item, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->modulate = p_color; } -void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { +void RendererCanvasCull::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->self_modulate = p_color; } -void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) { +void RendererCanvasCull::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->behind = p_enable; } -void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool p_update) { +void RendererCanvasCull::canvas_item_set_update_when_visible(RID p_item, bool p_update) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->update_when_visible = p_update; } -void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { +void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -540,7 +540,7 @@ void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_fro } } -void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { +void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { ERR_FAIL_COND(p_points.size() < 2); Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -679,7 +679,7 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po pline->polygon.create(indices, points, colors); } -void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { +void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { ERR_FAIL_COND(p_points.size() < 2); Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -696,7 +696,7 @@ void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<P } } -void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { +void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -706,7 +706,7 @@ void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect rect->rect = p_rect; } -void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { +void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -740,7 +740,7 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p circle->polygon.create(indices, points, color); } -void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) { +void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -750,28 +750,28 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 rect->rect = p_rect; rect->flags = 0; if (p_tile) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE; - rect->flags |= RasterizerCanvas::CANVAS_RECT_REGION; + rect->flags |= RendererCanvasRender::CANVAS_RECT_TILE; + rect->flags |= RendererCanvasRender::CANVAS_RECT_REGION; rect->source = Rect2(0, 0, fabsf(p_rect.size.width), fabsf(p_rect.size.height)); } if (p_rect.size.x < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H; + rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_H; rect->rect.size.x = -rect->rect.size.x; } if (p_rect.size.y < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V; + rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } if (p_transpose) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_TRANSPOSE; + rect->flags |= RendererCanvasRender::CANVAS_RECT_TRANSPOSE; SWAP(rect->rect.size.x, rect->rect.size.y); } rect->texture = p_texture; } -void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) { +void RendererCanvasCull::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -783,36 +783,36 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons rect->texture = p_texture; rect->source = p_src_rect; - rect->flags = RasterizerCanvas::CANVAS_RECT_REGION; + rect->flags = RendererCanvasRender::CANVAS_RECT_REGION; if (p_rect.size.x < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H; + rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_H; rect->rect.size.x = -rect->rect.size.x; } if (p_src_rect.size.x < 0) { - rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_H; + rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_H; rect->source.size.x = -rect->source.size.x; } if (p_rect.size.y < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V; + rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } if (p_src_rect.size.y < 0) { - rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_V; + rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_V; rect->source.size.y = -rect->source.size.y; } if (p_transpose) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_TRANSPOSE; + rect->flags |= RendererCanvasRender::CANVAS_RECT_TRANSPOSE; SWAP(rect->rect.size.x, rect->rect.size.y); } if (p_clip_uv) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_CLIP_UV; + rect->flags |= RendererCanvasRender::CANVAS_RECT_CLIP_UV; } } -void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) { +void RendererCanvasCull::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -833,7 +833,7 @@ void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 & style->axis_y = p_y_axis_mode; } -void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) { +void RendererCanvasCull::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) { uint32_t pc = p_points.size(); ERR_FAIL_COND(pc == 0 || pc > 4); @@ -862,7 +862,7 @@ void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<P prim->texture = p_texture; } -void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) { +void RendererCanvasCull::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); #ifdef DEBUG_ENABLED @@ -883,7 +883,7 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi polygon->polygon.create(indices, p_points, p_colors, p_uvs); } -void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count) { +void RendererCanvasCull::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -906,7 +906,7 @@ void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vec polygon->primitive = RS::PRIMITIVE_TRIANGLES; } -void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) { +void RendererCanvasCull::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -915,7 +915,7 @@ void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Tran tr->xform = p_transform; } -void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) { +void RendererCanvasCull::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -929,7 +929,7 @@ void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, m->modulate = p_modulate; } -void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) { +void RendererCanvasCull::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -943,7 +943,7 @@ void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particle RSG::storage->particles_request_process(p_particles); } -void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture) { +void RendererCanvasCull::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -954,7 +954,7 @@ void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RI mm->texture = p_texture; } -void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { +void RendererCanvasCull::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -963,7 +963,7 @@ void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignor ci->ignore = p_ignore; } -void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { +void RendererCanvasCull::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -972,7 +972,7 @@ void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool _mark_ysort_dirty(canvas_item, canvas_item_owner); } -void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { +void RendererCanvasCull::canvas_item_set_z_index(RID p_item, int p_z) { ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN || p_z > RS::CANVAS_ITEM_Z_MAX); Item *canvas_item = canvas_item_owner.getornull(p_item); @@ -981,25 +981,25 @@ void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { canvas_item->z_index = p_z; } -void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { +void RendererCanvasCull::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->z_relative = p_enable; } -void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { +void RendererCanvasCull::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->skeleton = p_skeleton; } -void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { +void RendererCanvasCull::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); if (p_enable && (canvas_item->copy_back_buffer == nullptr)) { - canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer); + canvas_item->copy_back_buffer = memnew(RendererCanvasRender::Item::CopyBackBuffer); } if (!p_enable && (canvas_item->copy_back_buffer != nullptr)) { memdelete(canvas_item->copy_back_buffer); @@ -1012,14 +1012,14 @@ void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool } } -void RenderingServerCanvas::canvas_item_clear(RID p_item) { +void RendererCanvasCull::canvas_item_clear(RID p_item) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clear(); } -void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) { +void RendererCanvasCull::canvas_item_set_draw_index(RID p_item, int p_index) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -1038,21 +1038,21 @@ void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) } } -void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) { +void RendererCanvasCull::canvas_item_set_material(RID p_item, RID p_material) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->material = p_material; } -void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { +void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->use_parent_material = p_enable; } -void RenderingServerCanvas::canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin, bool p_fit_empty, float p_fit_margin, bool p_blur_mipmaps) { +void RendererCanvasCull::canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin, bool p_fit_empty, float p_fit_margin, bool p_blur_mipmaps) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -1063,7 +1063,7 @@ void RenderingServerCanvas::canvas_item_set_canvas_group_mode(RID p_item, RS::Ca } } else { if (canvas_item->canvas_group == nullptr) { - canvas_item->canvas_group = memnew(RasterizerCanvas::Item::CanvasGroup); + canvas_item->canvas_group = memnew(RendererCanvasRender::Item::CanvasGroup); } canvas_item->canvas_group->mode = p_mode; canvas_item->canvas_group->fit_empty = p_fit_empty; @@ -1073,14 +1073,14 @@ void RenderingServerCanvas::canvas_item_set_canvas_group_mode(RID p_item, RS::Ca } } -RID RenderingServerCanvas::canvas_light_create() { - RasterizerCanvas::Light *clight = memnew(RasterizerCanvas::Light); +RID RendererCanvasCull::canvas_light_create() { + RendererCanvasRender::Light *clight = memnew(RendererCanvasRender::Light); clight->light_internal = RSG::canvas_render->light_create(); return canvas_light_owner.make_rid(clight); } -void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->mode == p_mode) { @@ -1100,8 +1100,8 @@ void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMo } } -void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->canvas.is_valid()) { @@ -1129,29 +1129,29 @@ void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_can } } -void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_enabled(RID p_light, bool p_enabled) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_set_texture_scale(RID p_light, float p_scale) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_texture_scale(RID p_light, float p_scale) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->scale = p_scale; } -void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->xform = p_transform; } -void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_texture(RID p_light, RID p_texture) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->texture == p_texture) { @@ -1162,80 +1162,80 @@ void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) RSG::canvas_render->light_set_texture(clight->light_internal, p_texture); } -void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->texture_offset = p_offset; } -void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_color(RID p_light, const Color &p_color) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->color = p_color; } -void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_height(RID p_light, float p_height) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->height = p_height; } -void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_energy(RID p_light, float p_energy) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->energy = p_energy; } -void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->z_min = p_min_z; clight->z_max = p_max_z; } -void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->layer_max = p_max_layer; clight->layer_min = p_min_layer; } -void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->item_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->item_shadow_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_directional_distance(RID p_light, float p_distance) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_directional_distance(RID p_light, float p_distance) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->directional_distance = p_distance; } -void RenderingServerCanvas::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->blend_mode = p_mode; } -void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->use_shadow == p_enabled) { @@ -1246,34 +1246,34 @@ void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_ RSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow); } -void RenderingServerCanvas::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_filter = p_filter; } -void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_color = p_color; } -void RenderingServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); +void RendererCanvasCull::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) { + RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_smooth = p_smooth; } -RID RenderingServerCanvas::canvas_light_occluder_create() { - RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance); +RID RendererCanvasCull::canvas_light_occluder_create() { + RendererCanvasRender::LightOccluderInstance *occluder = memnew(RendererCanvasRender::LightOccluderInstance); return canvas_light_occluder_owner.make_rid(occluder); } -void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); +void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); if (occluder->canvas.is_valid()) { @@ -1293,15 +1293,15 @@ void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occlude } } -void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); +void RendererCanvasCull::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); +void RendererCanvasCull::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); if (occluder->polygon.is_valid()) { @@ -1328,32 +1328,32 @@ void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RI } } -void RenderingServerCanvas::canvas_light_occluder_set_as_sdf_collision(RID p_occluder, bool p_enable) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); +void RendererCanvasCull::canvas_light_occluder_set_as_sdf_collision(RID p_occluder, bool p_enable) { + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); } -void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); +void RendererCanvasCull::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->xform = p_xform; } -void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); +void RendererCanvasCull::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->light_mask = p_mask; } -RID RenderingServerCanvas::canvas_occluder_polygon_create() { +RID RendererCanvasCull::canvas_occluder_polygon_create() { LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon); occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create(); return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); } -void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { +void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); @@ -1372,66 +1372,66 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol RSG::canvas_render->occluder_polygon_set_shape(occluder_poly->occluder, p_shape, p_closed); - for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) { + for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) { E->get()->aabb_cache = occluder_poly->aabb; } } -void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) { +void RendererCanvasCull::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) { LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); occluder_poly->cull_mode = p_mode; RSG::canvas_render->occluder_polygon_set_cull_mode(occluder_poly->occluder, p_mode); - for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) { + for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) { E->get()->cull_cache = p_mode; } } -void RenderingServerCanvas::canvas_set_shadow_texture_size(int p_size) { +void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) { RSG::canvas_render->set_shadow_texture_size(p_size); } -RID RenderingServerCanvas::canvas_texture_create() { +RID RendererCanvasCull::canvas_texture_create() { return RSG::storage->canvas_texture_create(); } -void RenderingServerCanvas::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { +void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { RSG::storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture); } -void RenderingServerCanvas::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) { +void RendererCanvasCull::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) { RSG::storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess); } -void RenderingServerCanvas::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { +void RendererCanvasCull::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { RSG::storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter); } -void RenderingServerCanvas::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { +void RendererCanvasCull::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { RSG::storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat); } -void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { +void RendererCanvasCull::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { Item *ci = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!ci); ci->texture_filter = p_filter; } -void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) { +void RendererCanvasCull::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) { Item *ci = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!ci); ci->texture_repeat = p_repeat; } -bool RenderingServerCanvas::free(RID p_rid) { +bool RendererCanvasCull::free(RID p_rid) { if (canvas_owner.owns(p_rid)) { Canvas *canvas = canvas_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas, false); while (canvas->viewports.size()) { - RenderingServerViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get()); + RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get()); ERR_FAIL_COND_V(!vp, true); - Map<RID, RenderingServerViewport::Viewport::CanvasData>::Element *E = vp->canvas_map.find(p_rid); + Map<RID, RendererViewport::Viewport::CanvasData>::Element *E = vp->canvas_map.find(p_rid); ERR_FAIL_COND_V(!E, true); vp->canvas_map.erase(p_rid); @@ -1442,11 +1442,11 @@ bool RenderingServerCanvas::free(RID p_rid) { canvas->child_items[i].item->parent = RID(); } - for (Set<RasterizerCanvas::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) { + for (Set<RendererCanvasRender::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) { E->get()->canvas = RID(); } - for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) { + for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) { E->get()->canvas = RID(); } @@ -1487,7 +1487,7 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas_item); } else if (canvas_light_owner.owns(p_rid)) { - RasterizerCanvas::Light *canvas_light = canvas_light_owner.getornull(p_rid); + RendererCanvasRender::Light *canvas_light = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas_light, true); if (canvas_light->canvas.is_valid()) { @@ -1503,7 +1503,7 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas_light); } else if (canvas_light_occluder_owner.owns(p_rid)) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid); ERR_FAIL_COND_V(!occluder, true); if (occluder->polygon.is_valid()) { @@ -1540,14 +1540,14 @@ bool RenderingServerCanvas::free(RID p_rid) { return true; } -RenderingServerCanvas::RenderingServerCanvas() { - z_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); - z_last_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); +RendererCanvasCull::RendererCanvasCull() { + z_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *)); + z_last_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *)); disable_scale = false; } -RenderingServerCanvas::~RenderingServerCanvas() { +RendererCanvasCull::~RendererCanvasCull() { memfree(z_list); memfree(z_last_list); } diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/renderer_canvas_cull.h index 89f511a8fb..ec2389bcb5 100644 --- a/servers/rendering/rendering_server_canvas.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_canvas.h */ +/* renderer_canvas_cull.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUALSERVERCANVAS_H -#define VISUALSERVERCANVAS_H +#ifndef RENDERING_SERVER_CANVAS_CULL_H +#define RENDERING_SERVER_CANVAS_CULL_H -#include "rasterizer.h" -#include "rendering_server_viewport.h" +#include "renderer_compositor.h" +#include "renderer_viewport.h" -class RenderingServerCanvas { +class RendererCanvasCull { public: - struct Item : public RasterizerCanvas::Item { + struct Item : public RendererCanvasRender::Item { RID parent; // canvas it belongs to List<Item *>::Element *E; int z_index; @@ -93,7 +93,7 @@ public: Rect2 aabb; RS::CanvasOccluderPolygonCullMode cull_mode; RID occluder; - Set<RasterizerCanvas::LightOccluderInstance *> owners; + Set<RendererCanvasRender::LightOccluderInstance *> owners; LightOccluderPolygon() { active = false; @@ -103,9 +103,9 @@ public: RID_PtrOwner<LightOccluderPolygon> canvas_light_occluder_polygon_owner; - RID_PtrOwner<RasterizerCanvas::LightOccluderInstance> canvas_light_occluder_owner; + RID_PtrOwner<RendererCanvasRender::LightOccluderInstance> canvas_light_occluder_owner; - struct Canvas : public RenderingServerViewport::CanvasBase { + struct Canvas : public RendererViewport::CanvasBase { Set<RID> viewports; struct ChildItem { Point2 mirror; @@ -115,10 +115,10 @@ public: } }; - Set<RasterizerCanvas::Light *> lights; - Set<RasterizerCanvas::Light *> directional_lights; + Set<RendererCanvasRender::Light *> lights; + Set<RendererCanvasRender::Light *> directional_lights; - Set<RasterizerCanvas::LightOccluderInstance *> occluders; + Set<RendererCanvasRender::LightOccluderInstance *> occluders; bool children_order_dirty; Vector<ChildItem> child_items; @@ -150,21 +150,21 @@ public: mutable RID_PtrOwner<Canvas> canvas_owner; RID_PtrOwner<Item> canvas_item_owner; - RID_PtrOwner<RasterizerCanvas::Light> canvas_light_owner; + RID_PtrOwner<RendererCanvasRender::Light> canvas_light_owner; bool disable_scale; bool sdf_used = false; bool snapping_2d_transforms_to_pixel = false; private: - void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); - void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner); + void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); + void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner); - RasterizerCanvas::Item **z_list; - RasterizerCanvas::Item **z_last_list; + RendererCanvasRender::Item **z_list; + RendererCanvasRender::Item **z_last_list; public: - void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); + void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); bool was_sdf_used(); @@ -272,8 +272,8 @@ public: void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat); bool free(RID p_rid); - RenderingServerCanvas(); - ~RenderingServerCanvas(); + RendererCanvasCull(); + ~RendererCanvasCull(); }; #endif // VISUALSERVERCANVAS_H diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp new file mode 100644 index 0000000000..9c7251763d --- /dev/null +++ b/servers/rendering/renderer_canvas_render.cpp @@ -0,0 +1,31 @@ +/*************************************************************************/ +/* renderer_canvas_render.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "renderer_canvas_render.h" diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h new file mode 100644 index 0000000000..ca95abcf65 --- /dev/null +++ b/servers/rendering/renderer_canvas_render.h @@ -0,0 +1,604 @@ +/*************************************************************************/ +/* renderer_canvas_render.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef RENDERINGSERVERCANVASRENDER_H +#define RENDERINGSERVERCANVASRENDER_H + +#include "servers/rendering/renderer_storage.h" + +class RendererCanvasRender { +public: + static RendererCanvasRender *singleton; + + enum CanvasRectFlags { + CANVAS_RECT_REGION = 1, + CANVAS_RECT_TILE = 2, + CANVAS_RECT_FLIP_H = 4, + CANVAS_RECT_FLIP_V = 8, + CANVAS_RECT_TRANSPOSE = 16, + CANVAS_RECT_CLIP_UV = 32, + CANVAS_RECT_IS_GROUP = 64, + }; + + struct Light { + bool enabled; + Color color; + Transform2D xform; + float height; + float energy; + float scale; + int z_min; + int z_max; + int layer_min; + int layer_max; + int item_mask; + int item_shadow_mask; + float directional_distance; + RS::CanvasLightMode mode; + RS::CanvasLightBlendMode blend_mode; + RID texture; + Vector2 texture_offset; + RID canvas; + bool use_shadow; + int shadow_buffer_size; + RS::CanvasLightShadowFilter shadow_filter; + Color shadow_color; + float shadow_smooth; + + //void *texture_cache; // implementation dependent + Rect2 rect_cache; + Transform2D xform_cache; + float radius_cache; //used for shadow far plane + //CameraMatrix shadow_matrix_cache; + + Transform2D light_shader_xform; + //Vector2 light_shader_pos; + + Light *shadows_next_ptr; + Light *filter_next_ptr; + Light *next_ptr; + Light *directional_next_ptr; + + RID light_internal; + uint64_t version; + + int32_t render_index_cache; + + Light() { + version = 0; + enabled = true; + color = Color(1, 1, 1); + shadow_color = Color(0, 0, 0, 0); + height = 0; + z_min = -1024; + z_max = 1024; + layer_min = 0; + layer_max = 0; + item_mask = 1; + scale = 1.0; + energy = 1.0; + item_shadow_mask = 1; + mode = RS::CANVAS_LIGHT_MODE_POINT; + blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD; + // texture_cache = nullptr; + next_ptr = nullptr; + directional_next_ptr = nullptr; + filter_next_ptr = nullptr; + use_shadow = false; + shadow_buffer_size = 2048; + shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE; + shadow_smooth = 0.0; + render_index_cache = -1; + directional_distance = 10000.0; + } + }; + + //easier wrap to avoid mistakes + + struct Item; + + typedef uint64_t PolygonID; + virtual PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) = 0; + virtual void free_polygon(PolygonID p_polygon) = 0; + + //also easier to wrap to avoid mistakes + struct Polygon { + PolygonID polygon_id; + Rect2 rect_cache; + + _FORCE_INLINE_ void create(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) { + ERR_FAIL_COND(polygon_id != 0); + { + uint32_t pc = p_points.size(); + const Vector2 *v2 = p_points.ptr(); + rect_cache.position = *v2; + for (uint32_t i = 1; i < pc; i++) { + rect_cache.expand_to(v2[i]); + } + } + polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights); + } + + _FORCE_INLINE_ Polygon() { polygon_id = 0; } + _FORCE_INLINE_ ~Polygon() { + if (polygon_id) { + singleton->free_polygon(polygon_id); + } + } + }; + + //item + + struct Item { + //commands are allocated in blocks of 4k to improve performance + //and cache coherence. + //blocks always grow but never shrink. + + struct CommandBlock { + enum { + MAX_SIZE = 4096 + }; + uint32_t usage; + uint8_t *memory; + }; + + struct Command { + enum Type { + TYPE_RECT, + TYPE_NINEPATCH, + TYPE_POLYGON, + TYPE_PRIMITIVE, + TYPE_MESH, + TYPE_MULTIMESH, + TYPE_PARTICLES, + TYPE_TRANSFORM, + TYPE_CLIP_IGNORE, + }; + + Command *next; + Type type; + virtual ~Command() {} + }; + + struct CommandRect : public Command { + Rect2 rect; + Color modulate; + Rect2 source; + uint8_t flags; + + RID texture; + + CommandRect() { + flags = 0; + type = TYPE_RECT; + } + }; + + struct CommandNinePatch : public Command { + Rect2 rect; + Rect2 source; + float margin[4]; + bool draw_center; + Color color; + RS::NinePatchAxisMode axis_x; + RS::NinePatchAxisMode axis_y; + + RID texture; + + CommandNinePatch() { + draw_center = true; + type = TYPE_NINEPATCH; + } + }; + + struct CommandPolygon : public Command { + RS::PrimitiveType primitive; + Polygon polygon; + + RID texture; + + CommandPolygon() { + type = TYPE_POLYGON; + } + }; + + struct CommandPrimitive : public Command { + uint32_t point_count; + Vector2 points[4]; + Vector2 uvs[4]; + Color colors[4]; + + RID texture; + + CommandPrimitive() { + type = TYPE_PRIMITIVE; + } + }; + + struct CommandMesh : public Command { + RID mesh; + Transform2D transform; + Color modulate; + + RID texture; + + CommandMesh() { type = TYPE_MESH; } + }; + + struct CommandMultiMesh : public Command { + RID multimesh; + + RID texture; + + CommandMultiMesh() { type = TYPE_MULTIMESH; } + }; + + struct CommandParticles : public Command { + RID particles; + + RID texture; + + CommandParticles() { type = TYPE_PARTICLES; } + }; + + struct CommandTransform : public Command { + Transform2D xform; + CommandTransform() { type = TYPE_TRANSFORM; } + }; + + struct CommandClipIgnore : public Command { + bool ignore; + CommandClipIgnore() { + type = TYPE_CLIP_IGNORE; + ignore = false; + } + }; + + struct ViewportRender { + RenderingServer *owner; + void *udata; + Rect2 rect; + }; + + Transform2D xform; + bool clip; + bool visible; + bool behind; + bool update_when_visible; + + struct CanvasGroup { + RS::CanvasGroupMode mode; + bool fit_empty; + float fit_margin; + bool blur_mipmaps; + float clear_margin; + }; + + CanvasGroup *canvas_group = nullptr; + int light_mask; + int z_final; + + mutable bool custom_rect; + mutable bool rect_dirty; + mutable Rect2 rect; + RID material; + RID skeleton; + + Item *next; + + struct CopyBackBuffer { + Rect2 rect; + Rect2 screen_rect; + bool full; + }; + CopyBackBuffer *copy_back_buffer; + + Color final_modulate; + Transform2D final_transform; + Rect2 final_clip_rect; + Item *final_clip_owner; + Item *material_owner; + Item *canvas_group_owner; + ViewportRender *vp_render; + bool distance_field; + bool light_masked; + + Rect2 global_rect_cache; + + const Rect2 &get_rect() const { + if (custom_rect || (!rect_dirty && !update_when_visible)) { + return rect; + } + + //must update rect + + if (commands == nullptr) { + rect = Rect2(); + rect_dirty = false; + return rect; + } + + Transform2D xf; + bool found_xform = false; + bool first = true; + + const Item::Command *c = commands; + + while (c) { + Rect2 r; + + switch (c->type) { + case Item::Command::TYPE_RECT: { + const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c); + r = crect->rect; + + } break; + case Item::Command::TYPE_NINEPATCH: { + const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c); + r = style->rect; + } break; + + case Item::Command::TYPE_POLYGON: { + const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); + r = polygon->polygon.rect_cache; + } break; + case Item::Command::TYPE_PRIMITIVE: { + const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); + for (uint32_t j = 0; j < primitive->point_count; j++) { + if (j == 0) { + r.position = primitive->points[0]; + } else { + r.expand_to(primitive->points[j]); + } + } + } break; + case Item::Command::TYPE_MESH: { + const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); + AABB aabb = RendererStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID()); + + r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); + + } break; + case Item::Command::TYPE_MULTIMESH: { + const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c); + AABB aabb = RendererStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); + + r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); + + } break; + case Item::Command::TYPE_PARTICLES: { + const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); + if (particles_cmd->particles.is_valid()) { + AABB aabb = RendererStorage::base_singleton->particles_get_aabb(particles_cmd->particles); + r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); + } + + } break; + case Item::Command::TYPE_TRANSFORM: { + const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); + xf = transform->xform; + found_xform = true; + [[fallthrough]]; + } + default: { + c = c->next; + continue; + } + } + + if (found_xform) { + r = xf.xform(r); + found_xform = false; + } + + if (first) { + rect = r; + first = false; + } else { + rect = rect.merge(r); + } + c = c->next; + } + + rect_dirty = false; + return rect; + } + + Command *commands; + Command *last_command; + Vector<CommandBlock> blocks; + uint32_t current_block; + + template <class T> + T *alloc_command() { + T *command; + if (commands == nullptr) { + // As the most common use case of canvas items is to + // use only one command, the first is done with it's + // own allocation. The rest of them use blocks. + command = memnew(T); + command->next = nullptr; + commands = command; + last_command = command; + } else { + //Subsequent commands go into a block. + + while (true) { + if (unlikely(current_block == (uint32_t)blocks.size())) { + // If we need more blocks, we allocate them + // (they won't be freed until this CanvasItem is + // deleted, though). + CommandBlock cb; + cb.memory = (uint8_t *)memalloc(CommandBlock::MAX_SIZE); + cb.usage = 0; + blocks.push_back(cb); + } + + CommandBlock *c = &blocks.write[current_block]; + size_t space_left = CommandBlock::MAX_SIZE - c->usage; + if (space_left < sizeof(T)) { + current_block++; + continue; + } + + //allocate block and add to the linked list + void *memory = c->memory + c->usage; + command = memnew_placement(memory, T); + command->next = nullptr; + last_command->next = command; + last_command = command; + c->usage += sizeof(T); + break; + } + } + + rect_dirty = true; + return command; + } + + void clear() { + // The first one is always allocated on heap + // the rest go in the blocks + Command *c = commands; + while (c) { + Command *n = c->next; + if (c == commands) { + memdelete(commands); + commands = nullptr; + } else { + c->~Command(); + } + c = n; + } + { + uint32_t cbc = MIN((current_block + 1), (uint32_t)blocks.size()); + CommandBlock *blockptr = blocks.ptrw(); + for (uint32_t i = 0; i < cbc; i++) { + blockptr[i].usage = 0; + } + } + + last_command = nullptr; + commands = nullptr; + current_block = 0; + clip = false; + rect_dirty = true; + final_clip_owner = nullptr; + material_owner = nullptr; + light_masked = false; + } + + RS::CanvasItemTextureFilter texture_filter; + RS::CanvasItemTextureRepeat texture_repeat; + + Item() { + commands = nullptr; + last_command = nullptr; + current_block = 0; + light_mask = 1; + vp_render = nullptr; + next = nullptr; + final_clip_owner = nullptr; + canvas_group_owner = nullptr; + clip = false; + final_modulate = Color(1, 1, 1, 1); + visible = true; + rect_dirty = true; + custom_rect = false; + behind = false; + material_owner = nullptr; + copy_back_buffer = nullptr; + distance_field = false; + light_masked = false; + update_when_visible = false; + z_final = 0; + texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; + texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; + } + virtual ~Item() { + clear(); + for (int i = 0; i < blocks.size(); i++) { + memfree(blocks[i].memory); + } + if (copy_back_buffer) { + memdelete(copy_back_buffer); + } + } + }; + + virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) = 0; + virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; + + struct LightOccluderInstance { + bool enabled; + RID canvas; + RID polygon; + RID occluder; + Rect2 aabb_cache; + Transform2D xform; + Transform2D xform_cache; + int light_mask; + bool sdf_collision; + RS::CanvasOccluderPolygonCullMode cull_cache; + + LightOccluderInstance *next; + + LightOccluderInstance() { + enabled = true; + sdf_collision = false; + next = nullptr; + light_mask = 1; + cull_cache = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; + } + }; + + virtual RID light_create() = 0; + virtual void light_set_texture(RID p_rid, RID p_texture) = 0; + virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0; + virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0; + virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0; + + virtual void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) = 0; + + virtual RID occluder_polygon_create() = 0; + virtual void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) = 0; + virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) = 0; + virtual void set_shadow_texture_size(int p_size) = 0; + + virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0; + + virtual bool free(RID p_rid) = 0; + virtual void update() = 0; + + RendererCanvasRender() { singleton = this; } + virtual ~RendererCanvasRender() {} +}; + +#endif // RENDERINGSERVERCANVASRENDER_H diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp new file mode 100644 index 0000000000..e8c4a236fa --- /dev/null +++ b/servers/rendering/renderer_compositor.cpp @@ -0,0 +1,42 @@ +/*************************************************************************/ +/* renderer_compositor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "renderer_compositor.h" + +#include "core/os/os.h" +#include "core/string/print_string.h" + +RendererCompositor *(*RendererCompositor::_create_func)() = nullptr; + +RendererCompositor *RendererCompositor::create() { + return _create_func(); +} + +RendererCanvasRender *RendererCanvasRender::singleton = nullptr; diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h new file mode 100644 index 0000000000..f328330efa --- /dev/null +++ b/servers/rendering/renderer_compositor.h @@ -0,0 +1,78 @@ +/*************************************************************************/ +/* renderer_compositor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef RENDERING_SERVER_COMPOSITOR_H +#define RENDERING_SERVER_COMPOSITOR_H + +#include "core/math/camera_matrix.h" +#include "core/templates/pair.h" +#include "core/templates/self_list.h" +#include "servers/rendering/renderer_canvas_render.h" +#include "servers/rendering/renderer_scene.h" +#include "servers/rendering/renderer_scene_render.h" +#include "servers/rendering/renderer_storage.h" +#include "servers/rendering_server.h" + +class RendererCompositor { +protected: + static RendererCompositor *(*_create_func)(); + +public: + static RendererCompositor *create(); + + virtual RendererStorage *get_storage() = 0; + virtual RendererCanvasRender *get_canvas() = 0; + virtual RendererSceneRender *get_scene() = 0; + + virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) = 0; + + virtual void initialize() = 0; + virtual void begin_frame(double frame_step) = 0; + + struct BlitToScreen { + RID render_target; + Rect2i rect; + //lens distorted parameters for VR should go here + }; + + virtual void prepare_for_blitting_render_targets() = 0; + virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0; + + virtual void end_frame(bool p_swap_buffers) = 0; + virtual void finalize() = 0; + virtual uint64_t get_frame_number() const = 0; + virtual float get_frame_delta_time() const = 0; + + virtual bool is_low_end() const = 0; + + virtual ~RendererCompositor() {} +}; + +#endif // RASTERIZER_H diff --git a/servers/rendering/rasterizer_rd/SCsub b/servers/rendering/renderer_rd/SCsub index 6a2e682c67..6a2e682c67 100644 --- a/servers/rendering/rasterizer_rd/SCsub +++ b/servers/rendering/renderer_rd/SCsub diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index df94921652..cbb000cb8c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_effects_rd.cpp */ +/* effects_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer_effects_rd.h" +#include "effects_rd.h" #include "core/config/project_settings.h" #include "core/os/os.h" @@ -58,7 +58,7 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_arra } } -RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { +RID EffectsRD::_get_uniform_set_from_image(RID p_image) { if (image_to_uniform_set_cache.has(p_image)) { RID uniform_set = image_to_uniform_set_cache[p_image]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -67,7 +67,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { } Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(p_image); uniforms.push_back(u); @@ -79,7 +79,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { return uniform_set; } -RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { +RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { if (texture_to_uniform_set_cache.has(p_texture)) { RID uniform_set = texture_to_uniform_set_cache[p_texture]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -89,7 +89,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); u.ids.push_back(p_texture); @@ -102,7 +102,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use return uniform_set; } -RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { +RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { if (texture_to_compute_uniform_set_cache.has(p_texture)) { RID uniform_set = texture_to_compute_uniform_set_cache[p_texture]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -112,7 +112,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); u.ids.push_back(p_texture); @@ -125,7 +125,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo return uniform_set; } -RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) { +RID EffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) { TexturePair tp; tp.texture1 = p_texture1; tp.texture2 = p_texture2; @@ -140,7 +140,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); u.ids.push_back(p_texture1); @@ -148,7 +148,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); u.ids.push_back(p_texture2); @@ -162,7 +162,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur return uniform_set; } -RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) { +RID EffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) { TexturePair tp; tp.texture1 = p_texture1; tp.texture2 = p_texture2; @@ -177,14 +177,14 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1 Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(p_texture1); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(p_texture2); uniforms.push_back(u); @@ -197,7 +197,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1 return uniform_set; } -void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { +void EffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { zeromem(©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); copy_to_fb.push_constant.use_section = true; @@ -218,7 +218,7 @@ void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_f RD::get_singleton()->draw_list_draw(draw_list, true); } -void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary) { +void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary) { zeromem(©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); if (p_flip_y) { @@ -246,7 +246,7 @@ void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_fr RD::get_singleton()->draw_list_end(); } -void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) { +void EffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) { zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -283,7 +283,7 @@ void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_textu RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) { +void EffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) { zeromem(©.push_constant, sizeof(CopyPushConstant)); copy.push_constant.section[0] = 0; @@ -306,7 +306,7 @@ void RasterizerEffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { +void EffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -333,7 +333,7 @@ void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_textu RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { +void EffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -358,7 +358,7 @@ void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) { +void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) { zeromem(©.push_constant, sizeof(CopyPushConstant)); copy.push_constant.section[0] = 0; @@ -383,7 +383,7 @@ void RasterizerEffectsRD::set_color(RID p_dest_texture, const Color &p_color, co RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { +void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { zeromem(©.push_constant, sizeof(CopyPushConstant)); uint32_t base_flags = 0; @@ -418,7 +418,7 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { +void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { zeromem(©.push_constant, sizeof(CopyPushConstant)); CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; @@ -455,7 +455,7 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_text RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { +void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; @@ -578,7 +578,7 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_ro RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { +void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; @@ -624,7 +624,7 @@ void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, } } -void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) { +void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) { RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>()); if (p_reflection.is_valid()) { @@ -654,7 +654,7 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RD::get_singleton()->draw_list_end(); } -void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { +void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { zeromem(©.push_constant, sizeof(CopyPushConstant)); copy.push_constant.section[0] = 0; @@ -674,7 +674,7 @@ void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_textur RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { +void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { CopyToDPPushConstant push_constant; push_constant.screen_size[0] = p_rect.size.x; push_constant.screen_size[1] = p_rect.size.y; @@ -697,7 +697,7 @@ void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { +void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { zeromem(&tonemap.push_constant, sizeof(TonemapPushConstant)); tonemap.push_constant.use_bcs = p_settings.use_bcs; @@ -749,7 +749,7 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, RD::get_singleton()->draw_list_end(); } -void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { +void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { luminance_reduce.push_constant.source_size[0] = p_source_size.x; luminance_reduce.push_constant.source_size[1] = p_source_size.y; luminance_reduce.push_constant.max_luminance = p_max_luminance; @@ -791,7 +791,7 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { +void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { bokeh.push_constant.blur_far_active = p_dof_far; bokeh.push_constant.blur_far_begin = p_dof_far_begin; bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; @@ -951,7 +951,7 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness) { +void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness) { //minify first ssao.minify_push_constant.orthogonal = p_projection.is_orthogonal(); ssao.minify_push_constant.z_near = p_projection.get_z_near(); @@ -1104,7 +1104,7 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) { +void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) { roughness_limiter.push_constant.screen_size[0] = p_size.x; roughness_limiter.push_constant.screen_size[1] = p_size.y; roughness_limiter.push_constant.curve = p_curve; @@ -1124,7 +1124,7 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { +void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; @@ -1149,7 +1149,7 @@ void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_ RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) { +void EffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) { cubemap_downsampler.push_constant.face_size = p_size.x; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -1167,11 +1167,11 @@ void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cu RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { +void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { Vector<RD::Uniform> uniforms; for (int i = 0; i < p_dest_cubemap.size(); i++) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = i; u.ids.push_back(p_dest_cubemap[i]); uniforms.push_back(u); @@ -1196,7 +1196,7 @@ void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_des RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) { +void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) { SkyPushConstant sky_push_constant; zeromem(&sky_push_constant, sizeof(SkyPushConstant)); @@ -1232,7 +1232,7 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ RD::get_singleton()->draw_list_draw(draw_list, true); } -void RasterizerEffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) { +void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) { ResolvePushConstant push_constant; push_constant.screen_size[0] = p_screen_size.x; push_constant.screen_size[1] = p_screen_size.y; @@ -1254,7 +1254,7 @@ void RasterizerEffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_rou RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) { +void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) { uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 }; RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]); @@ -1263,7 +1263,7 @@ void RasterizerEffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); } -void RasterizerEffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) { +void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) { uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 }; switch (p_filter) { @@ -1299,7 +1299,7 @@ void RasterizerEffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, cons } } -void RasterizerEffectsRD::sort_buffer(RID p_uniform_set, int p_size) { +void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { Sort::PushConstant push_constant; push_constant.total_elements = p_size; @@ -1368,7 +1368,7 @@ void RasterizerEffectsRD::sort_buffer(RID p_uniform_set, int p_size) { RD::get_singleton()->compute_list_end(); } -RasterizerEffectsRD::RasterizerEffectsRD() { +EffectsRD::EffectsRD() { { // Initialize copy Vector<String> copy_modes; copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); @@ -1591,7 +1591,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() { Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(filter.coefficient_buffer); uniforms.push_back(u); @@ -1763,7 +1763,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() { } } -RasterizerEffectsRD::~RasterizerEffectsRD() { +EffectsRD::~EffectsRD() { if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { RD::get_singleton()->free(filter.image_uniform_set); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 0b8d3a8f27..3afc111b9d 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_effects_rd.h */ +/* effects_rd.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,36 +28,36 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_EFFECTS_RD_H -#define RASTERIZER_EFFECTS_RD_H +#ifndef EFFECTS_RD_H +#define EFFECTS_RD_H #include "core/math/camera_matrix.h" -#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h" -#include "servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/copy.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/resolve.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sort.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/specular_merge.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/ssao.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/tonemap.glsl.gen.h" +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/shaders/bokeh_dof.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/copy.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/copy_to_fb.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/cube_to_dp.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/cubemap_filter.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/resolve.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/ssao_blur.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/ssao_minify.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/tonemap.glsl.gen.h" #include "servers/rendering_server.h" -class RasterizerEffectsRD { +class EffectsRD { enum CopyMode { COPY_MODE_GAUSSIAN_COPY, COPY_MODE_GAUSSIAN_COPY_8BIT, @@ -144,7 +144,7 @@ class RasterizerEffectsRD { CopyToFbPushConstant push_constant; CopyToFbShaderRD shader; RID shader_version; - RenderPipelineVertexFormatCacheRD pipelines[COPY_TO_FB_MAX]; + PipelineCacheRD pipelines[COPY_TO_FB_MAX]; } copy_to_fb; @@ -206,7 +206,7 @@ class RasterizerEffectsRD { TonemapPushConstant push_constant; TonemapShaderRD shader; RID shader_version; - RenderPipelineVertexFormatCacheRD pipelines[TONEMAP_MODE_MAX]; + PipelineCacheRD pipelines[TONEMAP_MODE_MAX]; } tonemap; enum LuminanceReduceMode { @@ -426,7 +426,7 @@ class RasterizerEffectsRD { struct SpecularMerge { SpecularMergeShaderRD shader; RID shader_version; - RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX]; + PipelineCacheRD pipelines[SPECULAR_MERGE_MAX]; } specular_merge; @@ -671,7 +671,7 @@ public: void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve); void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size); void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array); - void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position); + void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position); void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera); void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection); @@ -684,8 +684,8 @@ public: void sort_buffer(RID p_uniform_set, int p_size); - RasterizerEffectsRD(); - ~RasterizerEffectsRD(); + EffectsRD(); + ~EffectsRD(); }; #endif // !RASTERIZER_EFFECTS_RD_H diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/renderer_rd/light_cluster_builder.cpp index efb48e6df7..b76b41ba26 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp +++ b/servers/rendering/renderer_rd/light_cluster_builder.cpp @@ -190,7 +190,7 @@ void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_ { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R32G32B32A32_UINT; - tf.type = RD::TEXTURE_TYPE_3D; + tf.texture_type = RD::TEXTURE_TYPE_3D; tf.width = width; tf.height = height; tf.depth = depth; diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/renderer_rd/light_cluster_builder.h index b1da083dad..0767a96817 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.h +++ b/servers/rendering/renderer_rd/light_cluster_builder.h @@ -31,7 +31,7 @@ #ifndef LIGHT_CLUSTER_BUILDER_H #define LIGHT_CLUSTER_BUILDER_H -#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h" +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" class LightClusterBuilder { public: diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp index 5cc3da8d4e..8319e3eed1 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* render_pipeline_vertex_format_cache_rd.cpp */ +/* pipeline_cache_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "render_pipeline_vertex_format_cache_rd.h" +#include "pipeline_cache_rd.h" #include "core/os/memory.h" -RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) { +RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) { RD::PipelineMultisampleState multisample_state_version = multisample_state; multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id); @@ -49,7 +49,7 @@ RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_ve return pipeline; } -void RenderPipelineVertexFormatCacheRD::_clear() { +void PipelineCacheRD::_clear() { if (versions) { for (uint32_t i = 0; i < version_count; i++) { //shader may be gone, so this may not be valid @@ -63,7 +63,7 @@ void RenderPipelineVertexFormatCacheRD::_clear() { } } -void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) { +void PipelineCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) { ERR_FAIL_COND(p_shader.is_null()); _clear(); shader = p_shader; @@ -76,24 +76,24 @@ void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive dynamic_state_flags = p_dynamic_state_flags; } -void RenderPipelineVertexFormatCacheRD::update_shader(RID p_shader) { +void PipelineCacheRD::update_shader(RID p_shader) { ERR_FAIL_COND(p_shader.is_null()); _clear(); setup(p_shader, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags); } -void RenderPipelineVertexFormatCacheRD::clear() { +void PipelineCacheRD::clear() { _clear(); shader = RID(); //clear shader input_mask = 0; } -RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() { +PipelineCacheRD::PipelineCacheRD() { version_count = 0; versions = nullptr; input_mask = 0; } -RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() { +PipelineCacheRD::~PipelineCacheRD() { _clear(); } diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h index 6a72dbc77c..2f91c3c3b5 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* render_pipeline_vertex_format_cache_rd.h */ +/* pipeline_cache_rd.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDER_PIPELINE_CACHE_RD_H -#define RENDER_PIPELINE_CACHE_RD_H +#ifndef PIPELINE_CACHE_RD_H +#define PIPELINE_CACHE_RD_H #include "core/os/spin_lock.h" #include "servers/rendering/rendering_device.h" -class RenderPipelineVertexFormatCacheRD { +class PipelineCacheRD { SpinLock spin_lock; RID shader; @@ -89,8 +89,8 @@ public: return input_mask; } void clear(); - RenderPipelineVertexFormatCacheRD(); - ~RenderPipelineVertexFormatCacheRD(); + PipelineCacheRD(); + ~PipelineCacheRD(); }; #endif // RENDER_PIPELINE_CACHE_RD_H diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 921a7b966e..8fa56b182c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_canvas_rd.cpp */ +/* renderer_canvas_render_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer_canvas_rd.h" +#include "renderer_canvas_render_rd.h" #include "core/config/project_settings.h" #include "core/math/geometry_2d.h" #include "core/math/math_funcs.h" -#include "rasterizer_rd.h" +#include "renderer_compositor_rd.h" -void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { +void RendererCanvasRenderRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { p_mat4[0] = p_transform.elements[0][0]; p_mat4[1] = p_transform.elements[0][1]; p_mat4[2] = 0; @@ -53,7 +53,7 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_trans p_mat4[15] = 1; } -void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) { +void RendererCanvasRenderRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) { p_mat2x4[0] = p_transform.elements[0][0]; p_mat2x4[1] = p_transform.elements[1][0]; p_mat2x4[2] = 0; @@ -65,7 +65,7 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_tra p_mat2x4[7] = p_transform.elements[2][1]; } -void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) { +void RendererCanvasRenderRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) { p_mat2x3[0] = p_transform.elements[0][0]; p_mat2x3[1] = p_transform.elements[0][1]; p_mat2x3[2] = p_transform.elements[1][0]; @@ -74,7 +74,7 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_tra p_mat2x3[5] = p_transform.elements[2][1]; } -void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) { +void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) { p_mat4[0] = p_transform.basis.elements[0][0]; p_mat4[1] = p_transform.basis.elements[1][0]; p_mat4[2] = p_transform.basis.elements[2][0]; @@ -93,7 +93,7 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, p_mat4[15] = 1; } -RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) { +RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) { // Care must be taken to generate array formats // in ways where they could be reused, so we will // put single-occuring elements first, and repeated @@ -119,9 +119,9 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int Vector<uint8_t> polygon_buffer; polygon_buffer.resize(buffer_size * sizeof(float)); Vector<RD::VertexAttribute> descriptions; - descriptions.resize(4); + descriptions.resize(5); Vector<RID> buffers; - buffers.resize(4); + buffers.resize(5); { const uint8_t *r = polygon_buffer.ptr(); @@ -184,7 +184,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int vd.stride = 0; descriptions.write[1] = vd; - buffers.write[1] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_COLOR); + buffers.write[1] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_COLOR); } //uvs @@ -212,13 +212,13 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int vd.stride = 0; descriptions.write[2] = vd; - buffers.write[2] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_TEX_UV); + buffers.write[2] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_TEX_UV); } //bones if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) { RD::VertexAttribute vd; - vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; + vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_BONES; vd.stride = stride * sizeof(float); @@ -226,16 +226,42 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int descriptions.write[3] = vd; const int *bone_ptr = p_bones.ptr(); - const float *weight_ptr = p_weights.ptr(); for (uint32_t i = 0; i < vertex_count; i++) { uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride]; - uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2]; bone16w[0] = bone_ptr[i * 4 + 0]; bone16w[1] = bone_ptr[i * 4 + 1]; bone16w[2] = bone_ptr[i * 4 + 2]; bone16w[3] = bone_ptr[i * 4 + 3]; + } + + base_offset += 2; + } else { + RD::VertexAttribute vd; + vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; + vd.offset = 0; + vd.location = RS::ARRAY_BONES; + vd.stride = 0; + + descriptions.write[3] = vd; + buffers.write[3] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_BONES); + } + + //weights + if ((uint32_t)p_weights.size() == vertex_count * 4) { + RD::VertexAttribute vd; + vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM; + vd.offset = base_offset * sizeof(float); + vd.location = RS::ARRAY_WEIGHTS; + vd.stride = stride * sizeof(float); + + descriptions.write[4] = vd; + + const float *weight_ptr = p_weights.ptr(); + + for (uint32_t i = 0; i < vertex_count; i++) { + uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride]; weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535); weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535); @@ -243,16 +269,16 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535); } - base_offset += 4; + base_offset += 2; } else { RD::VertexAttribute vd; - vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; + vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = 0; - vd.location = RS::ARRAY_BONES; + vd.location = RS::ARRAY_WEIGHTS; vd.stride = 0; - descriptions.write[3] = vd; - buffers.write[3] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES); + descriptions.write[4] = vd; + buffers.write[4] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_BONES); } //check that everything is as it should be @@ -293,7 +319,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int return id; } -void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) { +void RendererCanvasRenderRD::free_polygon(PolygonID p_polygon) { PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon); ERR_FAIL_COND(!pb_ptr); @@ -314,7 +340,7 @@ void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) { //////////////////// -void RasterizerCanvasRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size) { +void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size) { if (p_texture == RID()) { p_texture = default_canvas_texture; } @@ -364,7 +390,7 @@ void RasterizerCanvasRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_ r_last_texture = p_texture; } -void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { +void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { //create an empty push constant RS::CanvasItemTextureFilter current_filter = default_filter; @@ -848,7 +874,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); //not used, so keep white - RenderingServerRaster::redraw_request(); + RenderingServerDefault::redraw_request(); storage->particles_request_process(particles_cmd->particles); //enable instancing @@ -990,13 +1016,13 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } } -RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) { +RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) { //re create canvas state Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 1; u.ids.push_back(state.canvas_state_buffer); uniforms.push_back(u); @@ -1004,7 +1030,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; u.ids.push_back(state.lights_uniform_buffer); uniforms.push_back(u); @@ -1012,7 +1038,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; u.ids.push_back(storage->decal_atlas_get_texture()); uniforms.push_back(u); @@ -1020,7 +1046,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 4; u.ids.push_back(state.shadow_texture); uniforms.push_back(u); @@ -1028,7 +1054,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 5; u.ids.push_back(state.shadow_sampler); uniforms.push_back(u); @@ -1036,7 +1062,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 6; RID screen; if (p_backbuffer) { @@ -1044,7 +1070,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ } else { screen = storage->render_target_get_rd_backbuffer(p_to_render_target); if (screen.is_null()) { //unallocated backbuffer - screen = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); + screen = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); } } u.ids.push_back(screen); @@ -1053,7 +1079,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 7; RID sdf = storage->render_target_get_sdf_texture(p_to_render_target); u.ids.push_back(sdf); @@ -1063,7 +1089,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { //needs samplers for the material (uses custom textures) create them RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 8; u.ids.resize(12); RID *ids_ptr = u.ids.ptrw(); @@ -1084,7 +1110,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 9; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); @@ -1100,7 +1126,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_ return uniform_set; } -void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) { +void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) { Item *current_clip = nullptr; Transform2D canvas_transform_inverse = p_canvas_transform_inverse; @@ -1167,7 +1193,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, if (material != prev_material) { MaterialData *material_data = nullptr; if (material.is_valid()) { - material_data = (MaterialData *)storage->material_get_data(material, RasterizerStorageRD::SHADER_TYPE_2D); + material_data = (MaterialData *)storage->material_get_data(material, RendererStorageRD::SHADER_TYPE_2D); } if (material_data) { @@ -1192,7 +1218,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, RD::get_singleton()->draw_list_end(); } -void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { +void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { r_sdf_used = false; int item_count = 0; @@ -1423,7 +1449,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } if (ci->material.is_valid()) { - MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); + MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RendererStorageRD::SHADER_TYPE_2D); if (md && md->shader_data->valid) { if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) { if (!material_screen_texture_found) { @@ -1435,12 +1461,12 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite if (md->shader_data->uses_sdf) { r_sdf_used = true; } - if (md->last_frame != RasterizerRD::singleton->get_frame_number()) { - md->last_frame = RasterizerRD::singleton->get_frame_number(); + if (md->last_frame != RendererCompositorRD::singleton->get_frame_number()) { + md->last_frame = RendererCompositorRD::singleton->get_frame_number(); if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) { // uniform set may be gone because a dependency was erased. In this case, it will happen // if a texture is deleted, so just re-create it. - storage->material_force_update_textures(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); + storage->material_force_update_textures(ci->material, RendererStorageRD::SHADER_TYPE_2D); } } } @@ -1501,12 +1527,12 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } } -RID RasterizerCanvasRD::light_create() { +RID RendererCanvasRenderRD::light_create() { CanvasLight canvas_light; return canvas_light_owner.make_rid(canvas_light); } -void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) { +void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(!cl); if (cl->texture == p_texture) { @@ -1522,14 +1548,14 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) { } } -void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable) { +void RendererCanvasRenderRD::light_set_use_shadow(RID p_rid, bool p_enable) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(!cl); cl->shadow.enabled = p_enable; } -void RasterizerCanvasRD::_update_shadow_atlas() { +void RendererCanvasRenderRD::_update_shadow_atlas() { if (state.shadow_fb == RID()) { //ah, we lack the shadow texture.. RD::get_singleton()->free(state.shadow_texture); //erase placeholder @@ -1538,7 +1564,7 @@ void RasterizerCanvasRD::_update_shadow_atlas() { { //texture RD::TextureFormat tf; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.width = state.shadow_texture_size; tf.height = state.max_lights_per_render * 2; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; @@ -1549,7 +1575,7 @@ void RasterizerCanvasRD::_update_shadow_atlas() { } { RD::TextureFormat tf; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.width = state.shadow_texture_size; tf.height = state.max_lights_per_render * 2; tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -1562,7 +1588,7 @@ void RasterizerCanvasRD::_update_shadow_atlas() { state.shadow_fb = RD::get_singleton()->framebuffer_create(fb_textures); } } -void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { +void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(!cl->shadow.enabled); @@ -1640,7 +1666,7 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, cons } } -void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { +void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(!cl->shadow.enabled); @@ -1720,7 +1746,7 @@ void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow cl->shadow.directional_xform = to_shadow * to_light_xform; } -void RasterizerCanvasRD::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) { +void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) { RID fb = storage->render_target_get_sdf_framebuffer(p_render_target); Rect2i rect = storage->render_target_get_sdf_rect(p_render_target); @@ -1782,7 +1808,7 @@ void RasterizerCanvasRD::render_sdf(RID p_render_target, LightOccluderInstance * storage->render_target_sdf_process(p_render_target); //done rendering, process it } -RID RasterizerCanvasRD::occluder_polygon_create() { +RID RendererCanvasRenderRD::occluder_polygon_create() { OccluderPolygon occluder; occluder.line_point_count = 0; occluder.sdf_point_count = 0; @@ -1791,27 +1817,30 @@ RID RasterizerCanvasRD::occluder_polygon_create() { return occluder_polygon_owner.make_rid(occluder); } -void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) { +void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) { OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); ERR_FAIL_COND(!oc); Vector<Vector2> lines; - int lc = p_points.size() * 2; - lines.resize(lc - (p_closed ? 0 : 2)); - { - Vector2 *w = lines.ptrw(); - const Vector2 *r = p_points.ptr(); + if (p_points.size()) { + int lc = p_points.size() * 2; - int max = lc / 2; - if (!p_closed) { - max--; - } - for (int i = 0; i < max; i++) { - Vector2 a = r[i]; - Vector2 b = r[(i + 1) % (lc / 2)]; - w[i * 2 + 0] = a; - w[i * 2 + 1] = b; + lines.resize(lc - (p_closed ? 0 : 2)); + { + Vector2 *w = lines.ptrw(); + const Vector2 *r = p_points.ptr(); + + int max = lc / 2; + if (!p_closed) { + max--; + } + for (int i = 0; i < max; i++) { + Vector2 a = r[i]; + Vector2 b = r[(i + 1) % (lc / 2)]; + w[i * 2 + 0] = a; + w[i * 2 + 1] = b; + } } } @@ -1832,7 +1861,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector if (lines.size()) { Vector<uint8_t> geometry; Vector<uint8_t> indices; - lc = lines.size(); + int lc = lines.size(); geometry.resize(lc * 6 * sizeof(float)); indices.resize(lc * 3 * sizeof(uint16_t)); @@ -1902,19 +1931,21 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector Vector<int> sdf_indices; - if (p_closed) { - sdf_indices = Geometry2D::triangulate_polygon(p_points); - oc->sdf_is_lines = false; - } else { - int max = p_points.size(); - sdf_indices.resize(max * 2); + if (p_points.size()) { + if (p_closed) { + sdf_indices = Geometry2D::triangulate_polygon(p_points); + oc->sdf_is_lines = false; + } else { + int max = p_points.size(); + sdf_indices.resize(max * 2); - int *iw = sdf_indices.ptrw(); - for (int i = 0; i < max; i++) { - iw[i * 2 + 0] = i; - iw[i * 2 + 1] = (i + 1) % max; + int *iw = sdf_indices.ptrw(); + for (int i = 0; i < max; i++) { + iw[i * 2 + 0] = i; + iw[i * 2 + 1] = (i + 1) % max; + } + oc->sdf_is_lines = true; } - oc->sdf_is_lines = true; } if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array.is_valid()) { @@ -1955,13 +1986,13 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector } } -void RasterizerCanvasRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { +void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); ERR_FAIL_COND(!oc); oc->cull_mode = p_mode; } -void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { +void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { //compile code = p_code; @@ -1994,7 +2025,7 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { actions.uniforms = &uniforms; - RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton; + RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton; Error err = canvas_singleton->shader.compiler.compile(RS::SHADER_CANVAS_ITEM, code, &actions, path, gen_code); @@ -2139,7 +2170,7 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { valid = true; } -void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { +void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { if (!p_texture.is_valid()) { default_texture_params.erase(p_name); } else { @@ -2147,7 +2178,7 @@ void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName } } -void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RendererCanvasRenderRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { @@ -2168,13 +2199,13 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ } } -void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { +void RendererCanvasRenderRD::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - RasterizerStorage::InstanceShaderParam p; + RendererStorage::InstanceShaderParam p; p.info = ShaderLanguage::uniform_to_property_info(E->get()); p.info.name = E->key(); //supply name p.index = E->get().instance_index; @@ -2183,7 +2214,7 @@ void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStor } } -bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) const { +bool RendererCanvasRenderRD::ShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -2191,15 +2222,15 @@ bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) return uniforms[p_param].texture_order >= 0; } -bool RasterizerCanvasRD::ShaderData::is_animated() const { +bool RendererCanvasRenderRD::ShaderData::is_animated() const { return false; } -bool RasterizerCanvasRD::ShaderData::casts_shadows() const { +bool RendererCanvasRenderRD::ShaderData::casts_shadows() const { return false; } -Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { +Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; @@ -2208,14 +2239,14 @@ Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName & return Variant(); } -RasterizerCanvasRD::ShaderData::ShaderData() { +RendererCanvasRenderRD::ShaderData::ShaderData() { valid = false; uses_screen_texture = false; uses_sdf = false; } -RasterizerCanvasRD::ShaderData::~ShaderData() { - RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton; +RendererCanvasRenderRD::ShaderData::~ShaderData() { + RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton; ERR_FAIL_COND(!canvas_singleton); //pipeline variants will clear themselves if shader is gone if (version.is_valid()) { @@ -2223,13 +2254,13 @@ RasterizerCanvasRD::ShaderData::~ShaderData() { } } -RasterizerStorageRD::ShaderData *RasterizerCanvasRD::_create_shader_func() { +RendererStorageRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() { ShaderData *shader_data = memnew(ShaderData); return shader_data; } -void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton; +void RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { + RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { p_uniform_dirty = true; @@ -2289,7 +2320,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V { if (shader_data->ubo_size) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; u.ids.push_back(uniform_buffer); uniforms.push_back(u); @@ -2298,7 +2329,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V const RID *textures = texture_cache.ptrw(); for (uint32_t i = 0; i < tex_uniform_count; i++) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1 + i; u.ids.push_back(textures[i]); uniforms.push_back(u); @@ -2308,7 +2339,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET); } -RasterizerCanvasRD::MaterialData::~MaterialData() { +RendererCanvasRenderRD::MaterialData::~MaterialData() { if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { RD::get_singleton()->free(uniform_set); } @@ -2318,7 +2349,7 @@ RasterizerCanvasRD::MaterialData::~MaterialData() { } } -RasterizerStorageRD::MaterialData *RasterizerCanvasRD::_create_material_func(ShaderData *p_shader) { +RendererStorageRD::MaterialData *RendererCanvasRenderRD::_create_material_func(ShaderData *p_shader) { MaterialData *material_data = memnew(MaterialData); material_data->shader_data = p_shader; material_data->last_frame = false; @@ -2326,14 +2357,14 @@ RasterizerStorageRD::MaterialData *RasterizerCanvasRD::_create_material_func(Sha return material_data; } -void RasterizerCanvasRD::set_time(double p_time) { +void RendererCanvasRenderRD::set_time(double p_time) { state.time = p_time; } -void RasterizerCanvasRD::update() { +void RendererCanvasRenderRD::update() { } -RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { +RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { storage = p_storage; { //create default samplers @@ -2636,7 +2667,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { { //default shadow texture to keep uniform set happy RD::TextureFormat tf; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.width = 4; tf.height = 4; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; @@ -2650,7 +2681,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(storage->get_default_rd_storage_buffer()); uniforms.push_back(u); @@ -2664,8 +2695,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { state.shadow_texture_size = GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"); //create functions for shader and material - storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_2D, _create_shader_funcs); - storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_2D, _create_material_funcs); + storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_shader_funcs); + storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_material_funcs); state.time = 0; @@ -2679,7 +2710,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { static_assert(sizeof(PushConstant) == 128); } -bool RasterizerCanvasRD::free(RID p_rid) { +bool RendererCanvasRenderRD::free(RID p_rid) { if (canvas_light_owner.owns(p_rid)) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND_V(!cl, false); @@ -2695,7 +2726,7 @@ bool RasterizerCanvasRD::free(RID p_rid) { return true; } -void RasterizerCanvasRD::set_shadow_texture_size(int p_size) { +void RendererCanvasRenderRD::set_shadow_texture_size(int p_size) { p_size = nearest_power_of_2_templated(p_size); if (p_size == state.shadow_texture_size) { return; @@ -2709,7 +2740,7 @@ void RasterizerCanvasRD::set_shadow_texture_size(int p_size) { { //create a default shadow texture to keep uniform set happy (and that it gets erased when a new one is created) RD::TextureFormat tf; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.width = 4; tf.height = 4; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; @@ -2720,7 +2751,7 @@ void RasterizerCanvasRD::set_shadow_texture_size(int p_size) { } } -RasterizerCanvasRD::~RasterizerCanvasRD() { +RendererCanvasRenderRD::~RendererCanvasRenderRD() { //canvas state storage->free(default_canvas_group_material); diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index b09d6578f3..203d7a4890 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_canvas_rd.h */ +/* renderer_canvas_render_rd.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_CANVAS_RD_H -#define RASTERIZER_CANVAS_RD_H +#ifndef RENDERING_SERVER_CANVAS_RENDER_RD_H +#define RENDERING_SERVER_CANVAS_RENDER_RD_H -#include "servers/rendering/rasterizer.h" -#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h" -#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h" -#include "servers/rendering/rasterizer_rd/shader_compiler_rd.h" -#include "servers/rendering/rasterizer_rd/shaders/canvas.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl.gen.h" +#include "servers/rendering/renderer_canvas_render.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" +#include "servers/rendering/renderer_rd/shader_compiler_rd.h" +#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h" #include "servers/rendering/rendering_device.h" -class RasterizerCanvasRD : public RasterizerCanvas { - RasterizerStorageRD *storage; +class RendererCanvasRenderRD : public RendererCanvasRender { + RendererStorageRD *storage; enum { BASE_UNIFORM_SET = 0, @@ -133,7 +134,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { }; struct PipelineVariants { - RenderPipelineVertexFormatCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX]; + PipelineCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX]; }; struct { @@ -151,7 +152,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { ShaderCompilerRD compiler; } shader; - struct ShaderData : public RasterizerStorageRD::ShaderData { + struct ShaderData : public RendererStorageRD::ShaderData { enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -181,7 +182,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; + virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; @@ -191,12 +192,12 @@ class RasterizerCanvasRD : public RasterizerCanvas { virtual ~ShaderData(); }; - RasterizerStorageRD::ShaderData *_create_shader_func(); - static RasterizerStorageRD::ShaderData *_create_shader_funcs() { - return static_cast<RasterizerCanvasRD *>(singleton)->_create_shader_func(); + RendererStorageRD::ShaderData *_create_shader_func(); + static RendererStorageRD::ShaderData *_create_shader_funcs() { + return static_cast<RendererCanvasRenderRD *>(singleton)->_create_shader_func(); } - struct MaterialData : public RasterizerStorageRD::MaterialData { + struct MaterialData : public RendererStorageRD::MaterialData { uint64_t last_frame; ShaderData *shader_data; RID uniform_buffer; @@ -210,9 +211,9 @@ class RasterizerCanvasRD : public RasterizerCanvas { virtual ~MaterialData(); }; - RasterizerStorageRD::MaterialData *_create_material_func(ShaderData *p_shader); - static RasterizerStorageRD::MaterialData *_create_material_funcs(RasterizerStorageRD::ShaderData *p_shader) { - return static_cast<RasterizerCanvasRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); + RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader); + static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) { + return static_cast<RendererCanvasRenderRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); } /**************************/ @@ -462,8 +463,8 @@ public: void set_time(double p_time); void update(); bool free(RID p_rid); - RasterizerCanvasRD(RasterizerStorageRD *p_storage); - ~RasterizerCanvasRD(); + RendererCanvasRenderRD(RendererStorageRD *p_storage); + ~RendererCanvasRenderRD(); }; #endif // RASTERIZER_CANVAS_RD_H diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index 5f8cf0ee8c..4ae7e68219 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_rd.cpp */ +/* renderer_compositor_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer_rd.h" +#include "renderer_compositor_rd.h" #include "core/config/project_settings.h" -void RasterizerRD::prepare_for_blitting_render_targets() { +void RendererCompositorRD::prepare_for_blitting_render_targets() { RD::get_singleton()->prepare_screen_for_drawing(); } -void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { +void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); for (int i = 0; i < p_amount; i++) { @@ -47,7 +47,7 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree if (!render_target_descriptors.has(rd_texture) || !RD::get_singleton()->uniform_set_is_valid(render_target_descriptors[rd_texture])) { Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; u.ids.push_back(copy_viewports_sampler); u.ids.push_back(rd_texture); @@ -76,7 +76,7 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree RD::get_singleton()->draw_list_end(); } -void RasterizerRD::begin_frame(double frame_step) { +void RendererCompositorRD::begin_frame(double frame_step) { frame++; delta = frame_step; time += frame_step; @@ -88,14 +88,14 @@ void RasterizerRD::begin_frame(double frame_step) { scene->set_time(time, frame_step); } -void RasterizerRD::end_frame(bool p_swap_buffers) { +void RendererCompositorRD::end_frame(bool p_swap_buffers) { #ifndef _MSC_VER #warning TODO: likely pass a bool to swap buffers to avoid display? #endif RD::get_singleton()->swap_buffers(); //probably should pass some bool to avoid display? } -void RasterizerRD::initialize() { +void RendererCompositorRD::initialize() { { //create framebuffer copy shader RenderingDevice::ShaderStageData vert; vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX; @@ -154,10 +154,10 @@ void RasterizerRD::initialize() { } } -ThreadWorkPool RasterizerRD::thread_work_pool; -uint64_t RasterizerRD::frame = 1; +ThreadWorkPool RendererCompositorRD::thread_work_pool; +uint64_t RendererCompositorRD::frame = 1; -void RasterizerRD::finalize() { +void RendererCompositorRD::finalize() { thread_work_pool.finish(); memdelete(scene); @@ -170,14 +170,14 @@ void RasterizerRD::finalize() { RD::get_singleton()->free(copy_viewports_sampler); } -RasterizerRD *RasterizerRD::singleton = nullptr; +RendererCompositorRD *RendererCompositorRD::singleton = nullptr; -RasterizerRD::RasterizerRD() { +RendererCompositorRD::RendererCompositorRD() { singleton = this; thread_work_pool.init(); time = 0; - storage = memnew(RasterizerStorageRD); - canvas = memnew(RasterizerCanvasRD(storage)); - scene = memnew(RasterizerSceneHighEndRD(storage)); + storage = memnew(RendererStorageRD); + canvas = memnew(RendererCanvasRenderRD(storage)); + scene = memnew(RendererSceneRenderForward(storage)); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 59fb8d2049..877f47d702 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_rd.h */ +/* renderer_compositor_rd.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_RD_H -#define RASTERIZER_RD_H +#ifndef RENDERING_SERVER_COMPOSITOR_RD_H +#define RENDERING_SERVER_COMPOSITOR_RD_H #include "core/os/os.h" #include "core/templates/thread_work_pool.h" -#include "servers/rendering/rasterizer.h" -#include "servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h" -#include "servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h" -#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h" +#include "servers/rendering/renderer_rd/renderer_scene_render_forward.h" +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" -class RasterizerRD : public Rasterizer { +class RendererCompositorRD : public RendererCompositor { protected: - RasterizerCanvasRD *canvas; - RasterizerStorageRD *storage; - RasterizerSceneHighEndRD *scene; + RendererCanvasRenderRD *canvas; + RendererStorageRD *storage; + RendererSceneRenderForward *scene; RID copy_viewports_rd_shader; RID copy_viewports_rd_pipeline; @@ -58,9 +58,9 @@ protected: static uint64_t frame; public: - RasterizerStorage *get_storage() { return storage; } - RasterizerCanvas *get_canvas() { return canvas; } - RasterizerScene *get_scene() { return scene; } + RendererStorage *get_storage() { return storage; } + RendererCanvasRender *get_canvas() { return canvas; } + RendererSceneRender *get_scene() { return scene; } void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {} @@ -80,8 +80,8 @@ public: return OK; } - static Rasterizer *_create_current() { - return memnew(RasterizerRD); + static RendererCompositor *_create_current() { + return memnew(RendererCompositorRD); } static void make_current() { @@ -92,8 +92,8 @@ public: static ThreadWorkPool thread_work_pool; - static RasterizerRD *singleton; - RasterizerRD(); - ~RasterizerRD() {} + static RendererCompositorRD *singleton; + RendererCompositorRD(); + ~RendererCompositorRD() {} }; #endif // RASTERIZER_RD_H diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp index 313188ba87..d603d32de8 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_scene_high_end_rd.cpp */ +/* renderer_scene_render_forward.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer_scene_high_end_rd.h" +#include "renderer_scene_render_forward.h" #include "core/config/project_settings.h" #include "servers/rendering/rendering_device.h" -#include "servers/rendering/rendering_server_raster.h" +#include "servers/rendering/rendering_server_default.h" /* SCENE SHADER */ -void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { +void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) { //compile code = p_code; @@ -123,7 +123,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { actions.uniforms = &uniforms; - RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton; + RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton; Error err = scene_singleton->shader.compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code); @@ -321,7 +321,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { valid = true; } -void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { +void RendererSceneRenderForward::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { if (!p_texture.is_valid()) { default_texture_params.erase(p_name); } else { @@ -329,7 +329,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin } } -void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RendererSceneRenderForward::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { @@ -351,13 +351,13 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ } } -void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { +void RendererSceneRenderForward::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - RasterizerStorage::InstanceShaderParam p; + RendererStorage::InstanceShaderParam p; p.info = ShaderLanguage::uniform_to_property_info(E->get()); p.info.name = E->key(); //supply name p.index = E->get().instance_index; @@ -366,7 +366,7 @@ void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<Rasteriz } } -bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_param) const { +bool RendererSceneRenderForward::ShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -374,15 +374,15 @@ bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_ return uniforms[p_param].texture_order >= 0; } -bool RasterizerSceneHighEndRD::ShaderData::is_animated() const { +bool RendererSceneRenderForward::ShaderData::is_animated() const { return false; } -bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const { +bool RendererSceneRenderForward::ShaderData::casts_shadows() const { return false; } -Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { +Variant RendererSceneRenderForward::ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; @@ -391,13 +391,13 @@ Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const String return Variant(); } -RasterizerSceneHighEndRD::ShaderData::ShaderData() { +RendererSceneRenderForward::ShaderData::ShaderData() { valid = false; uses_screen_texture = false; } -RasterizerSceneHighEndRD::ShaderData::~ShaderData() { - RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton; +RendererSceneRenderForward::ShaderData::~ShaderData() { + RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton; ERR_FAIL_COND(!scene_singleton); //pipeline variants will clear themselves if shader is gone if (version.is_valid()) { @@ -405,21 +405,21 @@ RasterizerSceneHighEndRD::ShaderData::~ShaderData() { } } -RasterizerStorageRD::ShaderData *RasterizerSceneHighEndRD::_create_shader_func() { +RendererStorageRD::ShaderData *RendererSceneRenderForward::_create_shader_func() { ShaderData *shader_data = memnew(ShaderData); return shader_data; } -void RasterizerSceneHighEndRD::MaterialData::set_render_priority(int p_priority) { +void RendererSceneRenderForward::MaterialData::set_render_priority(int p_priority) { priority = p_priority - RS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits } -void RasterizerSceneHighEndRD::MaterialData::set_next_pass(RID p_pass) { +void RendererSceneRenderForward::MaterialData::set_next_pass(RID p_pass) { next_pass = p_pass; } -void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton; +void RendererSceneRenderForward::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { + RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { p_uniform_dirty = true; @@ -479,7 +479,7 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN { if (shader_data->ubo_size) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; u.ids.push_back(uniform_buffer); uniforms.push_back(u); @@ -488,7 +488,7 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN const RID *textures = texture_cache.ptrw(); for (uint32_t i = 0; i < tex_uniform_count; i++) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1 + i; u.ids.push_back(textures[i]); uniforms.push_back(u); @@ -498,7 +498,7 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET); } -RasterizerSceneHighEndRD::MaterialData::~MaterialData() { +RendererSceneRenderForward::MaterialData::~MaterialData() { if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { RD::get_singleton()->free(uniform_set); } @@ -508,7 +508,7 @@ RasterizerSceneHighEndRD::MaterialData::~MaterialData() { } } -RasterizerStorageRD::MaterialData *RasterizerSceneHighEndRD::_create_material_func(ShaderData *p_shader) { +RendererStorageRD::MaterialData *RendererSceneRenderForward::_create_material_func(ShaderData *p_shader) { MaterialData *material_data = memnew(MaterialData); material_data->shader_data = p_shader; material_data->last_frame = false; @@ -516,11 +516,11 @@ RasterizerStorageRD::MaterialData *RasterizerSceneHighEndRD::_create_material_fu return material_data; } -RasterizerSceneHighEndRD::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() { +RendererSceneRenderForward::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() { clear(); } -void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { +void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_specular() { if (!specular.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; @@ -574,7 +574,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { } } -void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_gi() { +void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_gi() { if (!reflection_buffer.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; @@ -587,7 +587,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_gi() { } } -void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_giprobe() { +void RendererSceneRenderForward::RenderBufferDataHighEnd::ensure_giprobe() { if (!giprobe_buffer.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8G8_UINT; @@ -623,7 +623,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_giprobe() { } } -void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { +void RendererSceneRenderForward::RenderBufferDataHighEnd::clear() { if (ambient_buffer != RID() && ambient_buffer != color) { RD::get_singleton()->free(ambient_buffer); ambient_buffer = RID(); @@ -687,7 +687,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { } } -void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) { +void RendererSceneRenderForward::RenderBufferDataHighEnd::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) { clear(); msaa = p_msaa; @@ -717,7 +717,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = p_width; tf.height = p_height; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { @@ -754,7 +754,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu } } -void RasterizerSceneHighEndRD::_allocate_normal_roughness_texture(RenderBufferDataHighEnd *rb) { +void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBufferDataHighEnd *rb) { if (rb->normal_roughness_buffer.is_valid()) { return; } @@ -792,18 +792,18 @@ void RasterizerSceneHighEndRD::_allocate_normal_roughness_texture(RenderBufferDa _render_buffers_clear_uniform_set(rb); } -RasterizerSceneRD::RenderBufferData *RasterizerSceneHighEndRD::_create_render_buffer_data() { +RendererSceneRenderRD::RenderBufferData *RendererSceneRenderForward::_create_render_buffer_data() { return memnew(RenderBufferDataHighEnd); } -bool RasterizerSceneHighEndRD::free(RID p_rid) { - if (RasterizerSceneRD::free(p_rid)) { +bool RendererSceneRenderForward::free(RID p_rid) { + if (RendererSceneRenderRD::free(p_rid)) { return true; } return false; } -void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi, bool p_has_opaque_gi) { +void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi, bool p_has_opaque_gi) { uint32_t lightmap_captures_used = 0; for (int i = 0; i < p_element_count; i++) { @@ -862,11 +862,11 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, } if (store_transform) { - RasterizerStorageRD::store_transform(e->instance->transform, id.transform); - RasterizerStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform); + RendererStorageRD::store_transform(e->instance->transform, id.transform); + RendererStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform); } else { - RasterizerStorageRD::store_transform(Transform(), id.transform); - RasterizerStorageRD::store_transform(Transform(), id.normal_transform); + RendererStorageRD::store_transform(Transform(), id.transform); + RendererStorageRD::store_transform(Transform(), id.normal_transform); } if (p_for_depth) { @@ -950,7 +950,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, /// RENDERING /// -void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) { +void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) { RD::DrawListID draw_list = p_draw_list; RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format; @@ -1076,7 +1076,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l } break; } - RenderPipelineVertexFormatCacheRD *pipeline = nullptr; + PipelineCacheRD *pipeline = nullptr; pipeline = &shader->pipelines[cull_variant][primitive][shader_version]; @@ -1165,7 +1165,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l } } -void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { +void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; @@ -1173,20 +1173,20 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende CameraMatrix projection = correction * p_cam_projection; //store camera into ubo - RasterizerStorageRD::store_camera(projection, scene_state.ubo.projection_matrix); - RasterizerStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RasterizerStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix); - RasterizerStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); + RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix); + RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); + RendererStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix); + RendererStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); scene_state.ubo.z_far = p_zfar; scene_state.ubo.z_near = p_znear; scene_state.ubo.pancake_shadows = p_pancake_shadows; - RasterizerStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); - RasterizerStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); - RasterizerStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); - RasterizerStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); + RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); + RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); + RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); + RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); scene_state.ubo.directional_penumbra_shadow_samples = directional_penumbra_shadow_samples_get(); scene_state.ubo.directional_soft_shadow_samples = directional_soft_shadow_samples_get(); @@ -1330,7 +1330,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende Basis sky_transform = environment_get_sky_orientation(p_environment); sky_transform = sky_transform.inverse() * p_cam_transform.basis; - RasterizerStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); + RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; @@ -1397,7 +1397,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true); } -void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) { +void RendererSceneRenderForward::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) { RID m_src; m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material; @@ -1413,14 +1413,14 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t MaterialData *material = nullptr; if (m_src.is_valid()) { - material = (MaterialData *)storage->material_get_data(m_src, RasterizerStorageRD::SHADER_TYPE_3D); + material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D); if (!material || !material->shader_data->valid) { material = nullptr; } } if (!material) { - material = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D); + material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); m_src = default_material; } @@ -1429,7 +1429,7 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t _add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index, p_using_sdfgi); while (material->next_pass.is_valid()) { - material = (MaterialData *)storage->material_get_data(material->next_pass, RasterizerStorageRD::SHADER_TYPE_3D); + material = (MaterialData *)storage->material_get_data(material->next_pass, RendererStorageRD::SHADER_TYPE_3D); if (!material || !material->shader_data->valid) { break; } @@ -1437,7 +1437,7 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t } } -void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) { +void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) { bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; @@ -1468,9 +1468,9 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta if ((p_pass_mode != PASS_MODE_DEPTH_MATERIAL && p_pass_mode != PASS_MODE_SDF) && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) { //shader does not use discard and does not write a vertex position, use generic material if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_DEPTH) { - p_material = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D); + p_material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); } else if ((p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) && !p_material->shader_data->uses_normal && !p_material->shader_data->uses_roughness) { - p_material = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D); + p_material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); } } @@ -1493,7 +1493,7 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta if (e->material->last_pass != render_pass) { if (!RD::get_singleton()->uniform_set_is_valid(e->material->uniform_set)) { //uniform set no longer valid, probably a texture changed - storage->material_force_update_textures(p_material_rid, RasterizerStorageRD::SHADER_TYPE_3D); + storage->material_force_update_textures(p_material_rid, RendererStorageRD::SHADER_TYPE_3D); } e->material->last_pass = render_pass; e->material->index = scene_state.current_material_index++; @@ -1512,11 +1512,11 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta e->priority = p_material->priority; if (p_material->shader_data->uses_time) { - RenderingServerRaster::redraw_request(); + RenderingServerDefault::redraw_request(); } } -void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_using_sdfgi) { +void RendererSceneRenderForward::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_using_sdfgi) { scene_state.current_shader_index = 0; scene_state.current_material_index = 0; scene_state.used_sss = false; @@ -1619,7 +1619,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } } -void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) { +void RendererSceneRenderForward::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) { uint32_t lightmaps_used = 0; for (int i = 0; i < p_lightmap_cull_count; i++) { if (i >= (int)scene_state.max_lightmaps) { @@ -1629,7 +1629,7 @@ void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_r InstanceBase *lm = p_lightmap_cull_result[i]; Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis; to_lm = to_lm.inverse().transposed(); //will transform normals - RasterizerStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); + RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); lm->lightmap_cull_index = i; lightmaps_used++; } @@ -1638,7 +1638,7 @@ void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_r } } -void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { +void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { RenderBufferDataHighEnd *render_buffer = nullptr; if (p_render_buffer.is_valid()) { render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer); @@ -2011,7 +2011,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } } -void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake) { +void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake) { RENDER_TIMESTAMP("Setup Rendering Shadow"); _update_render_base_uniform_set(); @@ -2044,7 +2044,7 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase ** } } -void RasterizerSceneHighEndRD::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count) { +void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count) { RENDER_TIMESTAMP("Setup Render Collider Heightfield"); _update_render_base_uniform_set(); @@ -2077,7 +2077,7 @@ void RasterizerSceneHighEndRD::_render_particle_collider_heightfield(RID p_fb, c } } -void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering Material"); _update_render_base_uniform_set(); @@ -2116,7 +2116,7 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform } } -void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderForward::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); _update_render_base_uniform_set(); @@ -2177,7 +2177,7 @@ void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_c } } -void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { RENDER_TIMESTAMP("Render SDFGI"); _update_render_base_uniform_set(); @@ -2202,28 +2202,28 @@ void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3 Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; u.ids.push_back(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; u.ids.push_back(p_geom_facing_texture); uniforms.push_back(u); @@ -2276,7 +2276,7 @@ void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3 to_bounds.origin = p_bounds.position; to_bounds.basis.scale(p_bounds.size); - RasterizerStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds); + RendererStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds); _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); @@ -2292,14 +2292,14 @@ void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3 } } -void RasterizerSceneHighEndRD::_base_uniforms_changed() { +void RendererSceneRenderForward::_base_uniforms_changed() { if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { RD::get_singleton()->free(render_base_uniform_set); } render_base_uniform_set = RID(); } -void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { +void RendererSceneRenderForward::_update_render_base_uniform_set() { if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) { if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { RD::get_singleton()->free(render_base_uniform_set); @@ -2311,7 +2311,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; u.ids.resize(12); RID *ids_ptr = u.ids.ptrw(); @@ -2333,7 +2333,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.ids.push_back(shadow_sampler); uniforms.push_back(u); } @@ -2341,14 +2341,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(scene_state.uniform_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.instance_buffer); uniforms.push_back(u); } @@ -2356,7 +2356,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 5; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_positional_light_buffer()); uniforms.push_back(u); } @@ -2364,42 +2364,42 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 6; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 7; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids = storage->lightmap_array_get_textures(); uniforms.push_back(u); } { RD::Uniform u; u.binding = 12; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 13; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); uniforms.push_back(u); @@ -2407,7 +2407,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 14; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); u.ids.push_back(decal_atlas); uniforms.push_back(u); @@ -2415,7 +2415,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 15; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_decal_buffer()); uniforms.push_back(u); } @@ -2423,14 +2423,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 16; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(get_cluster_builder_texture()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 17; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_cluster_builder_indices_buffer()); uniforms.push_back(u); } @@ -2438,18 +2438,18 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 18; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (directional_shadow_get_texture().is_valid()) { u.ids.push_back(directional_shadow_get_texture()); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 19; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); @@ -2457,7 +2457,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 20; u.ids.push_back(sdfgi_get_ubo()); uniforms.push_back(u); @@ -2467,7 +2467,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } } -void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) { +void RendererSceneRenderForward::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) { if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) { RD::get_singleton()->free(view_dependant_uniform_set); } @@ -2480,11 +2480,11 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); RD::Uniform u; u.binding = 0; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { u.ids.push_back(ref_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -2492,13 +2492,13 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; if (p_shadow_atlas.is_valid()) { texture = shadow_atlas_get_texture(p_shadow_atlas); } if (!texture.is_valid()) { - texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); + texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); } u.ids.push_back(texture); uniforms.push_back(u); @@ -2507,8 +2507,8 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID default_tex = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_GI_PROBES; i++) { if (i < p_gi_probe_cull_count) { RID tex = gi_probe_instance_get_texture(p_gi_probe_cull_result[i]); @@ -2526,38 +2526,38 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at view_dependant_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, VIEW_DEPENDANT_UNIFORM_SET); } -void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb) { +void RendererSceneRenderForward::_render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb) { if (!rb->uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) { RD::get_singleton()->free(rb->uniform_set); } rb->uniform_set = RID(); } -void RasterizerSceneHighEndRD::_render_buffers_uniform_set_changed(RID p_render_buffers) { +void RendererSceneRenderForward::_render_buffers_uniform_set_changed(RID p_render_buffers) { RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); _render_buffers_clear_uniform_set(rb); } -RID RasterizerSceneHighEndRD::_render_buffers_get_normal_texture(RID p_render_buffers) { +RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_buffers) { RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); return rb->normal_roughness_buffer; } -RID RasterizerSceneHighEndRD::_render_buffers_get_ambient_texture(RID p_render_buffers) { +RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) { RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); return rb->ambient_buffer; } -RID RasterizerSceneHighEndRD::_render_buffers_get_reflection_texture(RID p_render_buffers) { +RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) { RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); return rb->reflection_buffer; } -void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_buffers) { +void RendererSceneRenderForward::_update_render_buffers_uniform_set(RID p_render_buffers) { RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); if (rb->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) { @@ -2565,25 +2565,25 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b { RD::Uniform u; u.binding = 0; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = false && rb->depth.is_valid() ? rb->depth : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = false && rb->depth.is_valid() ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = render_buffers_get_back_buffer_texture(p_render_buffers); - RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL); u.ids.push_back(texture); uniforms.push_back(u); } @@ -2591,9 +2591,9 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = render_buffers_get_ao_texture(p_render_buffers); - RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); + RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } @@ -2601,8 +2601,8 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b { RD::Uniform u; u.binding = 5; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } @@ -2610,20 +2610,20 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b { RD::Uniform u; u.binding = 6; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 7; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID t; if (render_buffers_is_sdfgi_enabled(p_render_buffers)) { t = render_buffers_get_sdfgi_irradiance_probes(p_render_buffers); } else { - t = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } u.ids.push_back(t); uniforms.push_back(u); @@ -2631,33 +2631,33 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b { RD::Uniform u; u.binding = 8; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (render_buffers_is_sdfgi_enabled(p_render_buffers)) { u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers)); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = RID(); if (p_render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_buffers)) { vfog = render_buffers_get_volumetric_fog_texture(p_render_buffers); if (vfog.is_null()) { - vfog = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); } } else { - vfog = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); } u.ids.push_back(vfog); uniforms.push_back(u); @@ -2666,15 +2666,15 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b } } -RasterizerSceneHighEndRD *RasterizerSceneHighEndRD::singleton = nullptr; +RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr; -void RasterizerSceneHighEndRD::set_time(double p_time, double p_step) { +void RendererSceneRenderForward::set_time(double p_time, double p_step) { time = p_time; - RasterizerSceneRD::set_time(p_time, p_step); + RendererSceneRenderRD::set_time(p_time, p_step); } -RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storage) : - RasterizerSceneRD(p_storage) { +RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_storage) : + RendererSceneRenderRD(p_storage) { singleton = this; storage = p_storage; @@ -2723,8 +2723,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag shader.scene_shader.initialize(shader_versions, defines); } - storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_3D, _create_shader_funcs); - storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_3D, _create_material_funcs); + storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs); + storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_material_funcs); { //shader compiler @@ -2795,6 +2795,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.renames["FOG"] = "custom_fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; + actions.renames["BONE_INDICES"] = "bone_attrib"; + actions.renames["BONE_WEIGHTS"] = "weight_attrib"; + actions.renames["CUSTOM0"] = "custom0_attrib"; + actions.renames["CUSTOM1"] = "custom1_attrib"; + actions.renames["CUSTOM2"] = "custom2_attrib"; + actions.renames["CUSTOM3"] = "custom3_attrib"; //for light actions.renames["VIEW"] = "view"; @@ -2817,6 +2823,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n"; actions.usage_defines["UV"] = "#define UV_USED\n"; actions.usage_defines["UV2"] = "#define UV2_USED\n"; + actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n"; + actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n"; + actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n"; + actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n"; + actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n"; + actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n"; actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n"; actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP"; actions.usage_defines["COLOR"] = "#define COLOR_USED\n"; @@ -2910,7 +2922,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag default_material = storage->material_create(); storage->material_set_shader(default_material, default_shader); - MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D); + MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); default_shader_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS); default_shader_sdfgi_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF); } @@ -2931,7 +2943,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256); Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(default_vec4_xform_buffer); u.binding = 0; uniforms.push_back(u); @@ -2952,8 +2964,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag RD::Uniform u; u.binding = 0; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); u.ids.push_back(texture); uniforms.push_back(u); @@ -2965,38 +2977,38 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag for (int i = 0; i < 7; i++) { RD::Uniform u; u.binding = i; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = storage->texture_rd_get_default(i == 0 ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE : (i == 2 ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL : RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = storage->texture_rd_get_default(i == 0 ? RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE : (i == 2 ? RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL : RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 7; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; - u.type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(render_buffers_get_default_gi_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; - u.type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); uniforms.push_back(u); } @@ -3004,7 +3016,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag } } -RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { +RendererSceneRenderForward::~RendererSceneRenderForward() { directional_shadow_atlas_set_size(0); //clear base uniform set if still valid diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h index db083a75cc..7cea44cd38 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_scene_high_end_rd.h */ +/* renderer_scene_render_forward.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_SCENE_HIGHEND_RD_H -#define RASTERIZER_SCENE_HIGHEND_RD_H +#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_H +#define RENDERING_SERVER_SCENE_RENDER_FORWARD_H -#include "servers/rendering/rasterizer_rd/rasterizer_scene_rd.h" -#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h" -#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h" -#include "servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl.gen.h" +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" +#include "servers/rendering/renderer_rd/shaders/scene_high_end.glsl.gen.h" -class RasterizerSceneHighEndRD : public RasterizerSceneRD { +class RendererSceneRenderForward : public RendererSceneRenderRD { enum { SCENE_UNIFORM_SET = 0, RADIANCE_UNIFORM_SET = 1, @@ -73,11 +73,11 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { ShaderCompilerRD compiler; } shader; - RasterizerStorageRD *storage; + RendererStorageRD *storage; /* Material */ - struct ShaderData : public RasterizerStorageRD::ShaderData { + struct ShaderData : public RendererStorageRD::ShaderData { enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -120,7 +120,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { bool valid; RID version; uint32_t vertex_input_mask; - RenderPipelineVertexFormatCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX]; + PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX]; String path; @@ -162,7 +162,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; - void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; + void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; @@ -172,12 +172,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { virtual ~ShaderData(); }; - RasterizerStorageRD::ShaderData *_create_shader_func(); - static RasterizerStorageRD::ShaderData *_create_shader_funcs() { - return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_shader_func(); + RendererStorageRD::ShaderData *_create_shader_func(); + static RendererStorageRD::ShaderData *_create_shader_funcs() { + return static_cast<RendererSceneRenderForward *>(singleton)->_create_shader_func(); } - struct MaterialData : public RasterizerStorageRD::MaterialData { + struct MaterialData : public RendererStorageRD::MaterialData { uint64_t last_frame; ShaderData *shader_data; RID uniform_buffer; @@ -194,9 +194,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { virtual ~MaterialData(); }; - RasterizerStorageRD::MaterialData *_create_material_func(ShaderData *p_shader); - static RasterizerStorageRD::MaterialData *_create_material_funcs(RasterizerStorageRD::ShaderData *p_shader) { - return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); + RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader); + static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) { + return static_cast<RendererSceneRenderForward *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); } /* Push Constant */ @@ -415,7 +415,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { int max_elements; struct Element { - RasterizerScene::InstanceBase *instance; + RendererSceneRender::InstanceBase *instance; MaterialData *material; union { struct { @@ -541,7 +541,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RenderList render_list; - static RasterizerSceneHighEndRD *singleton; + static RendererSceneRenderForward *singleton; uint64_t render_pass; double time; RID default_shader; @@ -596,7 +596,7 @@ public: virtual bool free(RID p_rid); - RasterizerSceneHighEndRD(RasterizerStorageRD *p_storage); - ~RasterizerSceneHighEndRD(); + RendererSceneRenderForward(RendererStorageRD *p_storage); + ~RendererSceneRenderForward(); }; #endif // RASTERIZER_SCENE_HIGHEND_RD_H diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 3c4cac7ba9..13fc61eee6 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_scene_rd.cpp */ +/* renderer_scene_render_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer_scene_rd.h" +#include "renderer_scene_render_rd.h" #include "core/config/project_settings.h" #include "core/os/os.h" -#include "rasterizer_rd.h" -#include "servers/rendering/rendering_server_raster.h" +#include "renderer_compositor_rd.h" +#include "servers/rendering/rendering_server_default.h" -uint64_t RasterizerSceneRD::auto_exposure_counter = 2; +uint64_t RendererSceneRenderRD::auto_exposure_counter = 2; void get_vogel_disk(float *r_kernel, int p_sample_count) { const float golden_angle = 2.4; @@ -49,7 +49,7 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } } -void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) { +void RendererSceneRenderRD::_clear_reflection_data(ReflectionData &rd) { rd.layers.clear(); rd.radiance_base_cubemap = RID(); if (rd.downsampled_radiance_cubemap.is_valid()) { @@ -60,7 +60,7 @@ void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) { rd.coefficient_buffer = RID(); } -void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality) { +void RendererSceneRenderRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality) { //recreate radiance and all data int mipmaps = p_mipmaps; @@ -129,7 +129,7 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = 64; // Always 64x64 tf.height = 64; - tf.type = RD::TEXTURE_TYPE_CUBE; + tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.array_layers = 6; tf.mipmaps = 7; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; @@ -151,7 +151,7 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, } } -void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) { +void RendererSceneRenderRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) { storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { @@ -172,7 +172,7 @@ void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, views, p_use_arrays); } -void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) { +void RendererSceneRenderRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) { if (p_use_arrays) { //render directly to the layers storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x); @@ -181,7 +181,7 @@ void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd, } } -void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) { +void RendererSceneRenderRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) { for (int i = p_start; i < p_end; i++) { for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) { for (int k = 0; k < 6; k++) { @@ -194,7 +194,7 @@ void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd, int p_sta } } -void RasterizerSceneRD::_sdfgi_erase(RenderBuffers *rb) { +void RendererSceneRenderRD::_sdfgi_erase(RenderBuffers *rb) { for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { const SDFGI::Cascade &c = rb->sdfgi->cascades[i]; RD::get_singleton()->free(c.light_data); @@ -236,9 +236,9 @@ void RasterizerSceneRD::_sdfgi_erase(RenderBuffers *rb) { rb->sdfgi = nullptr; } -const Vector3i RasterizerSceneRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF); +const Vector3i RendererSceneRenderRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF); -void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) { +void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) { Environment *env = environment_owner.getornull(p_environment); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); bool needs_sdfgi = env && env->sdfgi_enabled; @@ -284,7 +284,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co tf_sdf.width = sdfgi->cascade_size; // Always 64x64 tf_sdf.height = sdfgi->cascade_size; tf_sdf.depth = sdfgi->cascade_size; - tf_sdf.type = RD::TEXTURE_TYPE_3D; + tf_sdf.texture_type = RD::TEXTURE_TYPE_3D; tf_sdf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; { @@ -341,7 +341,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co tf_probes.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count; tf_probes.height = sdfgi->probe_axis_count * SDFGI::SH_SIZE; tf_probes.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - tf_probes.type = RD::TEXTURE_TYPE_2D_ARRAY; + tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; sdfgi->history_size = requested_history_size; @@ -351,7 +351,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co RD::TextureFormat tf_probe_average = tf_probes; tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed - tf_probe_average.type = RD::TEXTURE_TYPE_2D; + tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D; sdfgi->lightprobe_history_scroll = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView()); sdfgi->lightprobe_average_scroll = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView()); @@ -378,7 +378,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE tf_ambient.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count; tf_ambient.height = sdfgi->probe_axis_count; - tf_ambient.type = RD::TEXTURE_TYPE_2D_ARRAY; + tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; //lightprobe texture is an octahedral texture sdfgi->ambient_texture = RD::get_singleton()->texture_create(tf_ambient, RD::TextureView()); } @@ -443,21 +443,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1 uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; for (int j = 0; j < 8; j++) { u.ids.push_back(sdfgi->render_occlusion[j]); @@ -466,21 +466,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; u.ids.push_back(sdfgi->render_emission); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; u.ids.push_back(sdfgi->render_emission_aniso); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; u.ids.push_back(sdfgi->render_geom_facing); uniforms.push_back(u); @@ -488,28 +488,28 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; u.ids.push_back(cascade.sdf_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; u.ids.push_back(sdfgi->occlusion_data); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 10; u.ids.push_back(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 11; u.ids.push_back(cascade.solid_cell_buffer); uniforms.push_back(u); @@ -522,42 +522,42 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_geom_facing); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; u.ids.push_back(sdfgi->render_emission); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; u.ids.push_back(sdfgi->render_emission_aniso); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 5; u.ids.push_back(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; u.ids.push_back(cascade.solid_cell_buffer); uniforms.push_back(u); @@ -569,7 +569,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; for (int j = 0; j < 8; j++) { u.ids.push_back(sdfgi->render_occlusion[j]); @@ -578,7 +578,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->occlusion_data); uniforms.push_back(u); @@ -596,12 +596,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -609,63 +609,63 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(cascade.solid_cell_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 5; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.ids.push_back(cascade.light_data); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.ids.push_back(cascade.light_aniso_0_tex); uniforms.push_back(u); } { RD::Uniform u; u.binding = 7; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.ids.push_back(cascade.light_aniso_1_tex); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(rb->sdfgi->cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(cascade.lights_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(rb->sdfgi->lightprobe_texture); uniforms.push_back(u); } @@ -678,14 +678,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_sdf[0]); uniforms.push_back(u); @@ -698,14 +698,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_sdf_half[0]); uniforms.push_back(u); @@ -719,14 +719,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_sdf[0]); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_sdf[1]); uniforms.push_back(u); @@ -741,14 +741,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_sdf_half[0]); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_sdf_half[1]); uniforms.push_back(u); @@ -764,21 +764,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(sdfgi->render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; u.ids.push_back(sdfgi->render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass uniforms.push_back(u); @@ -793,14 +793,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(sdfgi->render_albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; for (int i = 0; i < 8; i++) { u.ids.push_back(sdfgi->render_occlusion[i]); @@ -809,7 +809,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; u.ids.push_back(sdfgi->render_geom_facing); uniforms.push_back(u); @@ -826,12 +826,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < sdfgi->cascades.size()) { u.ids.push_back(sdfgi->cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -839,12 +839,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < sdfgi->cascades.size()) { u.ids.push_back(sdfgi->cascades[j].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -852,12 +852,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < sdfgi->cascades.size()) { u.ids.push_back(sdfgi->cascades[j].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -865,19 +865,19 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < sdfgi->cascades.size()) { u.ids.push_back(sdfgi->cascades[j].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 6; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -885,14 +885,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 7; u.ids.push_back(sdfgi->cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; u.ids.push_back(sdfgi->lightprobe_data); uniforms.push_back(u); @@ -900,14 +900,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; u.ids.push_back(sdfgi->cascades[i].lightprobe_history_tex); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; u.ids.push_back(sdfgi->cascades[i].lightprobe_average_tex); uniforms.push_back(u); @@ -915,21 +915,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; u.ids.push_back(sdfgi->lightprobe_history_scroll); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; u.ids.push_back(sdfgi->lightprobe_average_scroll); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 13; RID parent_average; if (i < sdfgi->cascades.size() - 1) { @@ -942,7 +942,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 14; u.ids.push_back(sdfgi->ambient_texture); uniforms.push_back(u); @@ -1021,7 +1021,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co } } -int RasterizerSceneRD::sdfgi_get_pending_region_count(RID p_render_buffers) const { +int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers) const { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, 0); @@ -1048,7 +1048,7 @@ int RasterizerSceneRD::sdfgi_get_pending_region_count(RID p_render_buffers) cons return dirty_count; } -int RasterizerSceneRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const { +int RendererSceneRenderRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, -1); ERR_FAIL_COND_V(rb->sdfgi == nullptr, -1); @@ -1108,7 +1108,7 @@ int RasterizerSceneRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int return -1; } -AABB RasterizerSceneRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const { +AABB RendererSceneRenderRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const { AABB bounds; Vector3i from; Vector3i size; @@ -1118,7 +1118,7 @@ AABB RasterizerSceneRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, in return bounds; } -uint32_t RasterizerSceneRD::sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const { +uint32_t RendererSceneRenderRD::sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const { AABB bounds; Vector3i from; Vector3i size; @@ -1126,7 +1126,7 @@ uint32_t RasterizerSceneRD::sdfgi_get_pending_region_cascade(RID p_render_buffer return _sdfgi_get_pending_region_data(p_render_buffers, p_region, from, size, bounds); } -void RasterizerSceneRD::_sdfgi_update_cascades(RID p_render_buffers) { +void RendererSceneRenderRD::_sdfgi_update_cascades(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { @@ -1153,7 +1153,7 @@ void RasterizerSceneRD::_sdfgi_update_cascades(RID p_render_buffers) { RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, true); } -void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) { +void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { @@ -1338,7 +1338,7 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; u.ids.push_back(sky->radiance); uniforms.push_back(u); @@ -1346,7 +1346,7 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -1402,7 +1402,7 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm RENDER_TIMESTAMP("<SDFGI Update Probes"); } -void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, uint32_t &r_gi_probes_used) { +void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, uint32_t &r_gi_probes_used) { r_gi_probes_used = 0; RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); @@ -1465,7 +1465,7 @@ void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p } if (texture == RID()) { - texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); } if (texture != rb->giprobe_textures[i]) { @@ -1494,7 +1494,7 @@ void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p } } -void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) { +void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) { RENDER_TIMESTAMP("Render GI"); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); @@ -1614,12 +1614,12 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1627,12 +1627,12 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[j].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1640,12 +1640,12 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1653,37 +1653,37 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; if (rb->sdfgi) { u.ids.push_back(rb->sdfgi->occlusion_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 6; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 7; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -1691,7 +1691,7 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; u.ids.push_back(p_ambient_buffer); uniforms.push_back(u); @@ -1699,7 +1699,7 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; u.ids.push_back(p_reflection_buffer); uniforms.push_back(u); @@ -1707,54 +1707,54 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 11; if (rb->sdfgi) { u.ids.push_back(rb->sdfgi->lightprobe_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; u.ids.push_back(rb->depth_texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 13; u.ids.push_back(p_normal_roughness_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 14; - RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); + RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 15; u.ids.push_back(gi.sdfgi_ubo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 16; u.ids.push_back(rb->giprobe_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 17; for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) { u.ids.push_back(rb->giprobe_textures[i]); @@ -1773,11 +1773,11 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness RD::get_singleton()->compute_list_end(); } -RID RasterizerSceneRD::sky_create() { +RID RendererSceneRenderRD::sky_create() { return sky_owner.make_rid(Sky()); } -void RasterizerSceneRD::_sky_invalidate(Sky *p_sky) { +void RendererSceneRenderRD::_sky_invalidate(Sky *p_sky) { if (!p_sky->dirty) { p_sky->dirty = true; p_sky->dirty_list = dirty_sky_list; @@ -1785,7 +1785,7 @@ void RasterizerSceneRD::_sky_invalidate(Sky *p_sky) { } } -void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { +void RendererSceneRenderRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND(!sky); ERR_FAIL_COND(p_radiance_size < 32 || p_radiance_size > 2048); @@ -1807,7 +1807,7 @@ void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { _clear_reflection_data(sky->reflection); } -void RasterizerSceneRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { +void RendererSceneRenderRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND(!sky); @@ -1830,14 +1830,14 @@ void RasterizerSceneRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { _clear_reflection_data(sky->reflection); } -void RasterizerSceneRD::sky_set_material(RID p_sky, RID p_material) { +void RendererSceneRenderRD::sky_set_material(RID p_sky, RID p_material) { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND(!sky); sky->material = p_material; _sky_invalidate(sky); } -Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { +Ref<Image> RendererSceneRenderRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND_V(!sky, Ref<Image>()); @@ -1873,7 +1873,7 @@ Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool return Ref<Image>(); } -void RasterizerSceneRD::_update_dirty_skys() { +void RendererSceneRenderRD::_update_dirty_skys() { Sky *sky = dirty_sky_list; while (sky) { @@ -1897,7 +1897,7 @@ void RasterizerSceneRD::_update_dirty_skys() { RD::TextureFormat tf; tf.array_layers = layers * 6; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY; + tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY; tf.mipmaps = mipmaps; tf.width = w; tf.height = h; @@ -1912,7 +1912,7 @@ void RasterizerSceneRD::_update_dirty_skys() { RD::TextureFormat tf; tf.array_layers = 6; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.type = RD::TEXTURE_TYPE_CUBE; + tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.mipmaps = MIN(mipmaps, layers); tf.width = w; tf.height = h; @@ -1932,7 +1932,7 @@ void RasterizerSceneRD::_update_dirty_skys() { tformat.width = sky->screen_size.x / 2; tformat.height = sky->screen_size.y / 2; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - tformat.type = RD::TEXTURE_TYPE_2D; + tformat.texture_type = RD::TEXTURE_TYPE_2D; sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView()); Vector<RID> texs; @@ -1947,7 +1947,7 @@ void RasterizerSceneRD::_update_dirty_skys() { tformat.width = sky->screen_size.x / 4; tformat.height = sky->screen_size.y / 4; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - tformat.type = RD::TEXTURE_TYPE_2D; + tformat.texture_type = RD::TEXTURE_TYPE_2D; sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView()); Vector<RID> texs; @@ -1977,14 +1977,14 @@ void RasterizerSceneRD::_update_dirty_skys() { dirty_sky_list = nullptr; } -RID RasterizerSceneRD::sky_get_radiance_texture_rd(RID p_sky) const { +RID RendererSceneRenderRD::sky_get_radiance_texture_rd(RID p_sky) const { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND_V(!sky, RID()); return sky->radiance; } -RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const { +RID RendererSceneRenderRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND_V(!sky, RID()); @@ -1994,7 +1994,7 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; u.ids.push_back(sky->radiance); uniforms.push_back(u); @@ -2007,25 +2007,25 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, return sky->uniform_set; } -RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) { +RID RendererSceneRenderRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) { if (p_sky->texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(p_sky->texture_uniform_sets[p_version])) { return p_sky->texture_uniform_sets[p_version]; } Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; if (p_sky->radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) { u.ids.push_back(p_sky->radiance); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; // half res if (p_sky->half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) { if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { @@ -2035,16 +2035,16 @@ RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_vers } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; // quarter res if (p_sky->quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) { if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { @@ -2054,9 +2054,9 @@ RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_vers } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -2066,14 +2066,14 @@ RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_vers return p_sky->texture_uniform_sets[p_version]; } -RID RasterizerSceneRD::sky_get_material(RID p_sky) const { +RID RendererSceneRenderRD::sky_get_material(RID p_sky) const { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND_V(!sky, RID()); return sky->material; } -void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { +void RendererSceneRenderRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { ERR_FAIL_COND(!is_environment(p_environment)); SkyMaterialData *material = nullptr; @@ -2089,7 +2089,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue sky_material = sky_get_material(environment_get_sky(p_environment)); if (sky_material.is_valid()) { - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -2097,13 +2097,13 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue if (!material) { sky_material = sky_shader.default_material; - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); } } if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) { sky_material = sky_scene_state.fog_material; - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); } ERR_FAIL_COND(!material); @@ -2134,7 +2134,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue sky_transform = p_transform.basis * sky_transform; if (shader_data->uses_quarter_res) { - RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES]; RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_QUARTER_RES); @@ -2147,7 +2147,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue } if (shader_data->uses_half_res) { - RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES]; RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_HALF_RES); @@ -2159,7 +2159,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue RD::get_singleton()->draw_list_end(); } - RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND]; + PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND]; RID texture_uniform_set; if (sky) { @@ -2173,7 +2173,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue RD::get_singleton()->draw_list_end(); } -void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size) { +void RendererSceneRenderRD::_setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size) { ERR_FAIL_COND(!is_environment(p_environment)); SkyMaterialData *material = nullptr; @@ -2191,7 +2191,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons sky_material = sky_get_material(environment_get_sky(p_environment)); if (sky_material.is_valid()) { - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -2199,7 +2199,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons if (!material) { sky_material = sky_shader.default_material; - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); } ERR_FAIL_COND(!material); @@ -2242,7 +2242,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons if (shader_data->uses_time && time - sky->prev_time > 0.00001) { sky->prev_time = time; sky->reflection.dirty = true; - RenderingServerRaster::redraw_request(); + RenderingServerDefault::redraw_request(); } if (material != sky->prev_material) { @@ -2290,7 +2290,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons if (light_data_dirty) { RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true); - RasterizerSceneRD::SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights; + RendererSceneRenderRD::SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights; sky_scene_state.last_frame_directional_lights = sky_scene_state.directional_lights; sky_scene_state.directional_lights = temp; sky_scene_state.last_frame_directional_light_count = sky_scene_state.ubo.directional_light_count; @@ -2343,7 +2343,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo, true); } -void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { +void RendererSceneRenderRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -2354,7 +2354,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro SkyMaterialData *material = nullptr; if (sky_material.is_valid()) { - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); if (!material || !material->shader_data->valid) { material = nullptr; } @@ -2362,7 +2362,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro if (!material) { sky_material = sky_shader.default_material; - material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); + material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY); } ERR_FAIL_COND(!material); @@ -2423,7 +2423,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro cm = correction * cm; if (shader_data->uses_quarter_res) { - RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES]; Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); @@ -2441,7 +2441,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro } if (shader_data->uses_half_res) { - RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES]; Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); @@ -2459,7 +2459,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro } RD::DrawListID cubemap_draw_list; - RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP]; + PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP]; for (int i = 0; i < 6; i++) { Transform local_view; @@ -2510,7 +2510,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro /* SKY SHADER */ -void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) { +void RendererSceneRenderRD::SkyShaderData::set_code(const String &p_code) { //compile code = p_code; @@ -2559,7 +2559,7 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) { actions.uniforms = &uniforms; - RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton; + RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton; Error err = scene_singleton->sky_shader.compiler.compile(RS::SHADER_SKY, code, &actions, path, gen_code); @@ -2604,7 +2604,7 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) { valid = true; } -void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { +void RendererSceneRenderRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { if (!p_texture.is_valid()) { default_texture_params.erase(p_name); } else { @@ -2612,7 +2612,7 @@ void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringNam } } -void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RendererSceneRenderRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { @@ -2634,13 +2634,13 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para } } -void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { +void RendererSceneRenderRD::SkyShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - RasterizerStorage::InstanceShaderParam p; + RendererStorage::InstanceShaderParam p; p.info = ShaderLanguage::uniform_to_property_info(E->get()); p.info.name = E->key(); //supply name p.index = E->get().instance_index; @@ -2649,7 +2649,7 @@ void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerSt } } -bool RasterizerSceneRD::SkyShaderData::is_param_texture(const StringName &p_param) const { +bool RendererSceneRenderRD::SkyShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -2657,15 +2657,15 @@ bool RasterizerSceneRD::SkyShaderData::is_param_texture(const StringName &p_para return uniforms[p_param].texture_order >= 0; } -bool RasterizerSceneRD::SkyShaderData::is_animated() const { +bool RendererSceneRenderRD::SkyShaderData::is_animated() const { return false; } -bool RasterizerSceneRD::SkyShaderData::casts_shadows() const { +bool RendererSceneRenderRD::SkyShaderData::casts_shadows() const { return false; } -Variant RasterizerSceneRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { +Variant RendererSceneRenderRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; @@ -2674,12 +2674,12 @@ Variant RasterizerSceneRD::SkyShaderData::get_default_parameter(const StringName return Variant(); } -RasterizerSceneRD::SkyShaderData::SkyShaderData() { +RendererSceneRenderRD::SkyShaderData::SkyShaderData() { valid = false; } -RasterizerSceneRD::SkyShaderData::~SkyShaderData() { - RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton; +RendererSceneRenderRD::SkyShaderData::~SkyShaderData() { + RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton; ERR_FAIL_COND(!scene_singleton); //pipeline variants will clear themselves if shader is gone if (version.is_valid()) { @@ -2687,13 +2687,13 @@ RasterizerSceneRD::SkyShaderData::~SkyShaderData() { } } -RasterizerStorageRD::ShaderData *RasterizerSceneRD::_create_sky_shader_func() { +RendererStorageRD::ShaderData *RendererSceneRenderRD::_create_sky_shader_func() { SkyShaderData *shader_data = memnew(SkyShaderData); return shader_data; } -void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton; +void RendererSceneRenderRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { + RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton; uniform_set_updated = true; @@ -2755,7 +2755,7 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, { if (shader_data->ubo_size) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; u.ids.push_back(uniform_buffer); uniforms.push_back(u); @@ -2764,7 +2764,7 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, const RID *textures = texture_cache.ptrw(); for (uint32_t i = 0; i < tex_uniform_count; i++) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1 + i; u.ids.push_back(textures[i]); uniforms.push_back(u); @@ -2774,7 +2774,7 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL); } -RasterizerSceneRD::SkyMaterialData::~SkyMaterialData() { +RendererSceneRenderRD::SkyMaterialData::~SkyMaterialData() { if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { RD::get_singleton()->free(uniform_set); } @@ -2784,7 +2784,7 @@ RasterizerSceneRD::SkyMaterialData::~SkyMaterialData() { } } -RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func(SkyShaderData *p_shader) { +RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_sky_material_func(SkyShaderData *p_shader) { SkyMaterialData *material_data = memnew(SkyMaterialData); material_data->shader_data = p_shader; material_data->last_frame = false; @@ -2792,53 +2792,53 @@ RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func( return material_data; } -RID RasterizerSceneRD::environment_create() { +RID RendererSceneRenderRD::environment_create() { return environment_owner.make_rid(Environment()); } -void RasterizerSceneRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { +void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->background = p_bg; } -void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) { +void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky = p_sky; } -void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { +void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky_custom_fov = p_scale; } -void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { +void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky_orientation = p_orientation; } -void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) { +void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->bg_color = p_color; } -void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) { +void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->bg_energy = p_energy; } -void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { +void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->canvas_max_layer = p_max_layer; } -void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) { +void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->ambient_light = p_color; @@ -2849,85 +2849,85 @@ void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_ env->ao_color = p_ao_color; } -RS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const { +RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); return env->background; } -RID RasterizerSceneRD::environment_get_sky(RID p_env) const { +RID RendererSceneRenderRD::environment_get_sky(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RID()); return env->sky; } -float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const { +float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->sky_custom_fov; } -Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const { +Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Basis()); return env->sky_orientation; } -Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const { +Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->bg_color; } -float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const { +float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->bg_energy; } -int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const { +int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->canvas_max_layer; } -Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const { +Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ambient_light; } -RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const { +RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); return env->ambient_source; } -float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const { +float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_light_energy; } -float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const { +float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_sky_contribution; } -RS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const { +RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); return env->reflection_source; } -Color RasterizerSceneRD::environment_get_ao_color(RID p_env) const { +Color RendererSceneRenderRD::environment_get_ao_color(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ao_color; } -void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { +void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->exposure = p_exposure; @@ -2943,7 +2943,7 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa env->auto_exp_scale = p_auto_exp_scale; } -void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { +void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); @@ -2959,15 +2959,15 @@ void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, Vector<fl env->glow_hdr_luminance_cap = p_hdr_luminance_cap; } -void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable) { +void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; } -void RasterizerSceneRD::environment_glow_set_use_high_quality(bool p_enable) { +void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) { glow_high_quality = p_enable; } -void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { +void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -2983,7 +2983,7 @@ void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::Envi env->sdfgi_y_scale = p_y_scale; } -void RasterizerSceneRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { +void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -2997,51 +2997,51 @@ void RasterizerSceneRD::environment_set_fog(RID p_env, bool p_enable, const Colo env->fog_aerial_perspective = p_fog_aerial_perspective; } -bool RasterizerSceneRD::environment_is_fog_enabled(RID p_env) const { +bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->fog_enabled; } -Color RasterizerSceneRD::environment_get_fog_light_color(RID p_env) const { +Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->fog_light_color; } -float RasterizerSceneRD::environment_get_fog_light_energy(RID p_env) const { +float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_light_energy; } -float RasterizerSceneRD::environment_get_fog_sun_scatter(RID p_env) const { +float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_sun_scatter; } -float RasterizerSceneRD::environment_get_fog_density(RID p_env) const { +float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_density; } -float RasterizerSceneRD::environment_get_fog_height(RID p_env) const { +float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_height; } -float RasterizerSceneRD::environment_get_fog_height_density(RID p_env) const { +float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_height_density; } -float RasterizerSceneRD::environment_get_fog_aerial_perspective(RID p_env) const { +float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const { const Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_aerial_perspective; } -void RasterizerSceneRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) { +void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3055,15 +3055,15 @@ void RasterizerSceneRD::environment_set_volumetric_fog(RID p_env, bool p_enable, env->volumetric_fog_gi_inject = p_gi_inject; } -void RasterizerSceneRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { +void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { volumetric_fog_size = p_size; volumetric_fog_depth = p_depth; } -void RasterizerSceneRD::environment_set_volumetric_fog_filter_active(bool p_enable) { +void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) { volumetric_fog_filter_active = p_enable; } -void RasterizerSceneRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) { +void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) { p_shrink_size = nearest_power_of_2_templated(p_shrink_size); if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) { return; @@ -3071,7 +3071,7 @@ void RasterizerSceneRD::environment_set_volumetric_fog_directional_shadow_shrink _clear_shadow_shrink_stages(directional_shadow.shrink_stages); } -void RasterizerSceneRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) { +void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) { p_shrink_size = nearest_power_of_2_templated(p_shrink_size); if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) { return; @@ -3083,15 +3083,15 @@ void RasterizerSceneRD::environment_set_volumetric_fog_positional_shadow_shrink_ } } -void RasterizerSceneRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { +void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { sdfgi_ray_count = p_ray_count; } -void RasterizerSceneRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) { +void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) { sdfgi_frames_to_converge = p_frames; } -void RasterizerSceneRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { +void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3102,15 +3102,15 @@ void RasterizerSceneRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_ env->ssr_depth_tolerance = p_depth_tolerance; } -void RasterizerSceneRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { +void RendererSceneRenderRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { ssr_roughness_quality = p_quality; } -RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughness_quality() const { +RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_roughness_quality() const { return ssr_roughness_quality; } -void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { +void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3123,45 +3123,45 @@ void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_r env->ssao_blur = p_blur; } -void RasterizerSceneRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) { +void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) { ssao_quality = p_quality; ssao_half_size = p_half_size; } -bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const { +bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_enabled; } -float RasterizerSceneRD::environment_get_ssao_ao_affect(RID p_env) const { +float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_ao_channel_affect; } -float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const { +float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_direct_light_affect; } -bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const { +bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssr_enabled; } -bool RasterizerSceneRD::environment_is_sdfgi_enabled(RID p_env) const { +bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->sdfgi_enabled; } -bool RasterizerSceneRD::is_environment(RID p_env) const { +bool RendererSceneRenderRD::is_environment(RID p_env) const { return environment_owner.owns(p_env); } -Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { +Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Ref<Image>()); @@ -3200,7 +3200,7 @@ Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_i //////////////////////////////////////////////////////////// -RID RasterizerSceneRD::reflection_atlas_create() { +RID RendererSceneRenderRD::reflection_atlas_create() { ReflectionAtlas ra; ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count"); ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size"); @@ -3208,7 +3208,7 @@ RID RasterizerSceneRD::reflection_atlas_create() { return reflection_atlas_owner.make_rid(ra); } -void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { +void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); ERR_FAIL_COND(!ra); @@ -3240,13 +3240,13 @@ void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflect } //////////////////////// -RID RasterizerSceneRD::reflection_probe_instance_create(RID p_probe) { +RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) { ReflectionProbeInstance rpi; rpi.probe = p_probe; return reflection_probe_instance_owner.make_rid(rpi); } -void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) { +void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND(!rpi); @@ -3254,7 +3254,7 @@ void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance, rpi->dirty = true; } -void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) { +void RendererSceneRenderRD::reflection_probe_release_atlas_index(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND(!rpi); @@ -3269,7 +3269,7 @@ void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) { rpi->atlas = RID(); } -bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) { +bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); @@ -3288,14 +3288,14 @@ bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) { return rpi->atlas_index == -1; } -bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) { +bool RendererSceneRenderRD::reflection_probe_instance_has_reflection(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); return rpi->atlas.is_valid(); } -bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { +bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas); ERR_FAIL_COND_V(!atlas, false); @@ -3331,7 +3331,7 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R RD::TextureFormat tf; tf.array_layers = 6 * atlas->count; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY; + tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY; tf.mipmaps = mipmaps; tf.width = atlas->size; tf.height = atlas->size; @@ -3394,7 +3394,7 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R return true; } -bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instance) { +bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); ERR_FAIL_COND_V(!rpi->rendering, false); @@ -3440,7 +3440,7 @@ bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instanc return false; } -uint32_t RasterizerSceneRD::reflection_probe_instance_get_resolution(RID p_instance) { +uint32_t RendererSceneRenderRD::reflection_probe_instance_get_resolution(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, 0); @@ -3449,7 +3449,7 @@ uint32_t RasterizerSceneRD::reflection_probe_instance_get_resolution(RID p_insta return atlas->size; } -RID RasterizerSceneRD::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) { +RID RendererSceneRenderRD::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, RID()); ERR_FAIL_INDEX_V(p_index, 6, RID()); @@ -3459,7 +3459,7 @@ RID RasterizerSceneRD::reflection_probe_instance_get_framebuffer(RID p_instance, return atlas->reflections[rpi->atlas_index].fbs[p_index]; } -RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) { +RID RendererSceneRenderRD::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, RID()); ERR_FAIL_INDEX_V(p_index, 6, RID()); @@ -3471,11 +3471,11 @@ RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_ins /////////////////////////////////////////////////////////// -RID RasterizerSceneRD::shadow_atlas_create() { +RID RendererSceneRenderRD::shadow_atlas_create() { return shadow_atlas_owner.make_rid(ShadowAtlas()); } -void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { +void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); @@ -3520,7 +3520,7 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { } } -void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { +void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_INDEX(p_quadrant, 4); @@ -3582,7 +3582,7 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p } while (swaps > 0); } -bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) { +bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) { for (int i = p_quadrant_count - 1; i >= 0; i--) { int qidx = p_in_quadrants[i]; @@ -3637,7 +3637,7 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int return false; } -bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { +bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND_V(!shadow_atlas, false); @@ -3772,7 +3772,7 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan return false; } -void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { +void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) { p_size = nearest_power_of_2_templated(p_size); if (directional_shadow.size == p_size) { @@ -3800,7 +3800,7 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { _base_uniforms_changed(); } -void RasterizerSceneRD::set_directional_shadow_count(int p_count) { +void RendererSceneRenderRD::set_directional_shadow_count(int p_count) { directional_shadow.light_count = p_count; directional_shadow.current_light = 0; } @@ -3827,7 +3827,7 @@ static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p return rect; } -int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { +int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance) { ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0); Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0); @@ -3851,20 +3851,20 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { ////////////////////////////////////////////////// -RID RasterizerSceneRD::camera_effects_create() { +RID RendererSceneRenderRD::camera_effects_create() { return camera_effects_owner.make_rid(CameraEffects()); } -void RasterizerSceneRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { +void RendererSceneRenderRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { dof_blur_quality = p_quality; dof_blur_use_jitter = p_use_jitter; } -void RasterizerSceneRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) { +void RendererSceneRenderRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) { dof_blur_bokeh_shape = p_shape; } -void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) { +void RendererSceneRenderRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) { CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); ERR_FAIL_COND(!camfx); @@ -3879,7 +3879,7 @@ void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p camfx->dof_blur_amount = p_amount; } -void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { +void RendererSceneRenderRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); ERR_FAIL_COND(!camfx); @@ -3887,7 +3887,7 @@ void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, camfx->override_exposure = p_exposure; } -RID RasterizerSceneRD::light_instance_create(RID p_light) { +RID RendererSceneRenderRD::light_instance_create(RID p_light) { RID li = light_instance_owner.make_rid(LightInstance()); LightInstance *light_instance = light_instance_owner.getornull(li); @@ -3899,21 +3899,21 @@ RID RasterizerSceneRD::light_instance_create(RID p_light) { return li; } -void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { +void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->transform = p_transform; } -void RasterizerSceneRD::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) { +void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->aabb = p_aabb; } -void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { +void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -3933,14 +3933,14 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale; } -void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { +void RendererSceneRenderRD::light_instance_mark_visible(RID p_light_instance) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->last_scene_pass = scene_pass; } -RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_size) { +RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap(int p_size) { if (!shadow_cubemaps.has(p_size)) { ShadowCubemap sc; { @@ -3948,7 +3948,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; tf.width = p_size; tf.height = p_size; - tf.type = RD::TEXTURE_TYPE_CUBE; + tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.array_layers = 6; tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; sc.cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -3967,7 +3967,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s return &shadow_cubemaps[p_size]; } -RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p_size) { +RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) { if (!shadow_maps.has(p_size)) { ShadowMap sm; { @@ -3992,13 +3992,13 @@ RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p ////////////////////////// -RID RasterizerSceneRD::decal_instance_create(RID p_decal) { +RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { DecalInstance di; di.decal = p_decal; return decal_instance_owner.make_rid(di); } -void RasterizerSceneRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) { +void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) { DecalInstance *di = decal_instance_owner.getornull(p_decal); ERR_FAIL_COND(!di); di->transform = p_transform; @@ -4006,21 +4006,21 @@ void RasterizerSceneRD::decal_instance_set_transform(RID p_decal, const Transfor ///////////////////////////////// -RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) { +RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) { GIProbeInstance gi_probe; gi_probe.probe = p_base; RID rid = gi_probe_instance_owner.make_rid(gi_probe); return rid; } -void RasterizerSceneRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { +void RendererSceneRenderRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); gi_probe->transform = p_xform; } -bool RasterizerSceneRD::gi_probe_needs_update(RID p_probe) const { +bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND_V(!gi_probe, false); @@ -4028,7 +4028,7 @@ bool RasterizerSceneRD::gi_probe_needs_update(RID p_probe) const { return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe); } -void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) { +void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); @@ -4062,7 +4062,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc tf.width = octree_size.x; tf.height = octree_size.y; tf.depth = octree_size.z; - tf.type = RD::TEXTURE_TYPE_3D; + tf.texture_type = RD::TEXTURE_TYPE_3D; tf.mipmaps = levels.size(); tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; @@ -4093,14 +4093,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(storage->gi_probe_get_octree_buffer(gi_probe->probe)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; u.ids.push_back(storage->gi_probe_get_data_buffer(gi_probe->probe)); uniforms.push_back(u); @@ -4108,21 +4108,21 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; u.ids.push_back(gi_probe->write_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -4133,7 +4133,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc if (i == 0) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; u.ids.push_back(gi_probe_lights_uniform); copy_uniforms.push_back(u); @@ -4145,7 +4145,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; u.ids.push_back(gi_probe->texture); copy_uniforms.push_back(u); @@ -4158,7 +4158,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; u.ids.push_back(mipmap.texture); uniforms.push_back(u); @@ -4232,7 +4232,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; u.ids.push_back(gi_probe_lights_uniform); uniforms.push_back(u); @@ -4240,56 +4240,56 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; u.ids.push_back(dmap.albedo); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; u.ids.push_back(dmap.normal); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; u.ids.push_back(dmap.orm); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 8; u.ids.push_back(dmap.fb_depth); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; u.ids.push_back(dmap.texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; u.ids.push_back(dmap.depth); uniforms.push_back(u); @@ -4305,14 +4305,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; u.ids.push_back(gi_probe->dynamic_maps[gi_probe->dynamic_maps.size() - 1].texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; u.ids.push_back(gi_probe->dynamic_maps[gi_probe->dynamic_maps.size() - 1].depth); uniforms.push_back(u); @@ -4321,14 +4321,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc if (write) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; u.ids.push_back(dmap.texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; u.ids.push_back(dmap.depth); uniforms.push_back(u); @@ -4337,14 +4337,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -4353,7 +4353,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc if (plot) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; u.ids.push_back(gi_probe->mipmaps[dmap.mipmap].texture); uniforms.push_back(u); @@ -4728,7 +4728,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc gi_probe->last_probe_version = storage->gi_probe_get_version(gi_probe->probe); } -void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void RendererSceneRenderRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -4764,21 +4764,21 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(storage->gi_probe_get_data_buffer(gi_probe->probe)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; u.ids.push_back(gi_probe->texture); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 3; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -4798,7 +4798,7 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36); } -void RasterizerSceneRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { +void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -4837,28 +4837,28 @@ void RasterizerSceneRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(rb->sdfgi->cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(rb->sdfgi->lightprobe_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(rb->sdfgi->occlusion_texture); uniforms.push_back(u); } @@ -4935,13 +4935,13 @@ void RasterizerSceneRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID } //////////////////////////////// -RID RasterizerSceneRD::render_buffers_create() { +RID RendererSceneRenderRD::render_buffers_create() { RenderBuffers rb; rb.data = _create_render_buffer_data(); return render_buffers_owner.make_rid(rb); } -void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { +void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { ERR_FAIL_COND(!rb->blur[0].texture.is_null()); uint32_t mipmaps_required = Image::get_image_required_mipmaps(rb->width, rb->height, Image::FORMAT_RGBAH); @@ -4950,7 +4950,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = rb->width; tf.height = rb->height; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.mipmaps = mipmaps_required; @@ -4984,7 +4984,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { } } -void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) { +void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) { ERR_FAIL_COND(!rb->luminance.current.is_null()); int w = rb->width; @@ -5017,7 +5017,7 @@ void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) { } } -void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { +void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { if (rb->texture.is_valid()) { RD::get_singleton()->free(rb->texture); rb->texture = RID(); @@ -5082,7 +5082,7 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { } } -void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { +void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -5101,7 +5101,7 @@ void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p storage->get_effects()->sub_surface_scattering(rb->texture, rb->blur[0].mipmaps[0].texture, rb->depth_texture, p_camera, Size2i(rb->width, rb->height), sss_scale, sss_depth_scale, sss_quality); } -void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { +void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -5123,7 +5123,7 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = rb->width / 2; tf.height = rb->height / 2; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; rb->ssr.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -5138,7 +5138,7 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe tf.format = RD::DATA_FORMAT_R8_UNORM; tf.width = rb->width / 2; tf.height = rb->height / 2; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; rb->ssr.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -5154,7 +5154,7 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->texture, rb->blur[0].mipmaps[1].texture); } -void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { +void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -5223,7 +5223,7 @@ void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, R storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, Size2i(rb->width, rb->height), rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao[0], rb->ssao.ao_full.is_valid(), rb->ssao.ao[1], rb->ssao.ao_full, env->ssao_intensity, env->ssao_radius, env->ssao_bias, p_projection, ssao_quality, env->ssao_blur, env->ssao_blur_edge_sharpness); } -void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { +void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -5257,7 +5257,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu //swap final reduce with prev luminance SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]); - RenderingServerRaster::redraw_request(); //redraw all the time if auto exposure rendering is on + RenderingServerDefault::redraw_request(); //redraw all the time if auto exposure rendering is on } int max_glow_level = -1; @@ -5298,19 +5298,19 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu { //tonemap - RasterizerEffectsRD::TonemapSettings tonemap; + EffectsRD::TonemapSettings tonemap; if (can_use_effects && env && env->auto_exposure && rb->luminance.current.is_valid()) { tonemap.use_auto_exposure = true; tonemap.exposure_texture = rb->luminance.current; tonemap.auto_exposure_grey = env->auto_exp_scale; } else { - tonemap.exposure_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.exposure_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); } if (can_use_effects && env && env->glow_enabled) { tonemap.use_glow = true; - tonemap.glow_mode = RasterizerEffectsRD::TonemapSettings::GlowMode(env->glow_blend_mode); + tonemap.glow_mode = EffectsRD::TonemapSettings::GlowMode(env->glow_blend_mode); tonemap.glow_intensity = env->glow_blend_mode == RS::ENV_GLOW_BLEND_MODE_MIX ? env->glow_mix : env->glow_intensity; for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { tonemap.glow_levels[i] = env->glow_levels[i]; @@ -5320,7 +5320,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; tonemap.glow_texture = rb->blur[1].texture; } else { - tonemap.glow_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); + tonemap.glow_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); } if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { @@ -5336,18 +5336,19 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.exposure = env->exposure; } + tonemap.use_color_correction = false; + tonemap.use_1d_color_correction = false; + tonemap.color_correction_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + if (can_use_effects && env) { tonemap.use_bcs = env->adjustments_enabled; tonemap.brightness = env->adjustments_brightness; tonemap.contrast = env->adjustments_contrast; tonemap.saturation = env->adjustments_saturation; - tonemap.use_1d_color_correction = env->use_1d_color_correction; if (env->adjustments_enabled && env->color_correction.is_valid()) { tonemap.use_color_correction = true; + tonemap.use_1d_color_correction = env->use_1d_color_correction; tonemap.color_correction_texture = storage->texture_get_rd_texture(env->color_correction); - } else { - tonemap.use_color_correction = false; - tonemap.color_correction_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); } } @@ -5357,8 +5358,8 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu storage->render_target_disable_clear_request(rb->render_target); } -void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas) { - RasterizerEffectsRD *effects = storage->get_effects(); +void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas) { + EffectsRD *effects = storage->get_effects(); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -5418,7 +5419,7 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s } } -void RasterizerSceneRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { +void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -5430,7 +5431,7 @@ void RasterizerSceneRD::environment_set_adjustment(RID p_env, bool p_enable, flo env->color_correction = p_color_correction; } -void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform) { +void RendererSceneRenderRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -5443,12 +5444,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr { RD::Uniform u; u.binding = 1; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[i].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -5456,12 +5457,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[i].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -5469,12 +5470,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[i].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -5482,12 +5483,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr { RD::Uniform u; u.binding = 4; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < rb->sdfgi->cascades.size()) { u.ids.push_back(rb->sdfgi->cascades[i].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -5495,35 +5496,35 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr { RD::Uniform u; u.binding = 5; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(rb->sdfgi->occlusion_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(rb->sdfgi->cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.ids.push_back(rb->texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(rb->sdfgi->lightprobe_texture); uniforms.push_back(u); } @@ -5576,7 +5577,7 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr storage->get_effects()->copy_to_fb_rect(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), true); } -RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { +RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->blur[0].texture.is_valid()) { @@ -5585,14 +5586,14 @@ RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffe return rb->blur[0].texture; } -RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) { +RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0]; } -RID RasterizerSceneRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) { +RID RendererSceneRenderRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (rb->giprobe_buffer.is_null()) { @@ -5601,24 +5602,24 @@ RID RasterizerSceneRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) return rb->giprobe_buffer; } -RID RasterizerSceneRD::render_buffers_get_default_gi_probe_buffer() { +RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() { return default_giprobe_buffer; } -uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const { +uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); return rb->sdfgi->cascades.size(); } -bool RasterizerSceneRD::render_buffers_is_sdfgi_enabled(RID p_render_buffers) const { +bool RendererSceneRenderRD::render_buffers_is_sdfgi_enabled(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, false); return rb->sdfgi != nullptr; } -RID RasterizerSceneRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_buffers) const { +RID RendererSceneRenderRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); ERR_FAIL_COND_V(!rb->sdfgi, RID()); @@ -5626,7 +5627,7 @@ RID RasterizerSceneRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_b return rb->sdfgi->lightprobe_texture; } -Vector3 RasterizerSceneRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_buffers, uint32_t p_cascade) const { +Vector3 RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_buffers, uint32_t p_cascade) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, Vector3()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3()); @@ -5635,7 +5636,7 @@ Vector3 RasterizerSceneRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_ return Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + rb->sdfgi->cascades[p_cascade].position)) * rb->sdfgi->cascades[p_cascade].cell_size; } -Vector3i RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_render_buffers, uint32_t p_cascade) const { +Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_render_buffers, uint32_t p_cascade) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, Vector3i()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3i()); @@ -5645,14 +5646,14 @@ Vector3i RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_ return rb->sdfgi->cascades[p_cascade].position / probe_divisor; } -float RasterizerSceneRD::render_buffers_get_sdfgi_normal_bias(RID p_render_buffers) const { +float RendererSceneRenderRD::render_buffers_get_sdfgi_normal_bias(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); return rb->sdfgi->normal_bias; } -float RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_render_buffers, uint32_t p_cascade) const { +float RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_render_buffers, uint32_t p_cascade) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -5660,7 +5661,7 @@ float RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_rende return float(rb->sdfgi->cascade_size) * rb->sdfgi->cascades[p_cascade].cell_size / float(rb->sdfgi->probe_axis_count - 1); } -uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_render_buffers) const { +uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -5668,7 +5669,7 @@ uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_r return rb->sdfgi->probe_axis_count; } -uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_size(RID p_render_buffers) const { +uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_size(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -5676,7 +5677,7 @@ uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_size(RID p_render_b return rb->sdfgi->cascade_size; } -bool RasterizerSceneRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buffers) const { +bool RendererSceneRenderRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, false); ERR_FAIL_COND_V(!rb->sdfgi, false); @@ -5684,14 +5685,14 @@ bool RasterizerSceneRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buf return rb->sdfgi->uses_occlusion; } -float RasterizerSceneRD::render_buffers_get_sdfgi_energy(RID p_render_buffers) const { +float RendererSceneRenderRD::render_buffers_get_sdfgi_energy(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, false); return rb->sdfgi->energy; } -RID RasterizerSceneRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_buffers) const { +RID RendererSceneRenderRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); ERR_FAIL_COND_V(!rb->sdfgi, RID()); @@ -5699,20 +5700,20 @@ RID RasterizerSceneRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_b return rb->sdfgi->occlusion_texture; } -bool RasterizerSceneRD::render_buffers_has_volumetric_fog(RID p_render_buffers) const { +bool RendererSceneRenderRD::render_buffers_has_volumetric_fog(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, false); return rb->volumetric_fog != nullptr; } -RID RasterizerSceneRD::render_buffers_get_volumetric_fog_texture(RID p_render_buffers) { +RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_texture(RID p_render_buffers) { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, RID()); return rb->volumetric_fog->fog_map; } -RID RasterizerSceneRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_render_buffers) { +RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_render_buffers) { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); @@ -5723,18 +5724,18 @@ RID RasterizerSceneRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_r return rb->volumetric_fog->sky_uniform_set; } -float RasterizerSceneRD::render_buffers_get_volumetric_fog_end(RID p_render_buffers) { +float RendererSceneRenderRD::render_buffers_get_volumetric_fog_end(RID p_render_buffers) { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0); return rb->volumetric_fog->length; } -float RasterizerSceneRD::render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers) { +float RendererSceneRenderRD::render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers) { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0); return rb->volumetric_fog->spread; } -void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) { +void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; rb->height = p_height; @@ -5784,20 +5785,20 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren _render_buffers_uniform_set_changed(p_render_buffers); } -void RasterizerSceneRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) { +void RendererSceneRenderRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) { sss_quality = p_quality; } -RS::SubSurfaceScatteringQuality RasterizerSceneRD::sub_surface_scattering_get_quality() const { +RS::SubSurfaceScatteringQuality RendererSceneRenderRD::sub_surface_scattering_get_quality() const { return sss_quality; } -void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) { +void RendererSceneRenderRD::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) { sss_scale = p_scale; sss_depth_scale = p_depth_scale; } -void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { +void RendererSceneRenderRD::shadows_quality_set(RS::ShadowQuality p_quality) { ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); if (shadows_quality != p_quality) { @@ -5837,7 +5838,7 @@ void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { } } -void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) { +void RendererSceneRenderRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) { ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); if (directional_shadow_quality != p_quality) { @@ -5877,21 +5878,21 @@ void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quali } } -int RasterizerSceneRD::get_roughness_layers() const { +int RendererSceneRenderRD::get_roughness_layers() const { return roughness_layers; } -bool RasterizerSceneRD::is_using_radiance_cubemap_array() const { +bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const { return sky_use_cubemap_array; } -RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data(RID p_render_buffers) { +RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_get_data(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, nullptr); return rb->data; } -void RasterizerSceneRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) { +void RendererSceneRenderRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) { for (int i = 0; i < p_reflection_probe_cull_count; i++) { RID rpi = p_reflection_probe_cull_result[i]; @@ -5939,7 +5940,7 @@ void RasterizerSceneRD::_setup_reflections(RID *p_reflection_probe_cull_result, Transform transform = reflection_probe_instance_get_transform(rpi); Transform proj = (p_camera_inverse_transform * transform).inverse(); - RasterizerStorageRD::store_transform(proj, reflection_ubo.local_matrix); + RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix); cluster.builder.add_reflection_probe(transform, extents); @@ -5951,7 +5952,7 @@ void RasterizerSceneRD::_setup_reflections(RID *p_reflection_probe_cull_result, } } -void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { +void RendererSceneRenderRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { uint32_t light_count = 0; r_directional_light_count = 0; r_positional_light_count = 0; @@ -6105,7 +6106,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale; light_data.shadow_z_range[j] = light_instance_get_shadow_range(li, j); light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j); - RasterizerStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]); + RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]); Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j); uv_scale *= atlas_rect.size; //adapt to atlas size @@ -6258,7 +6259,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform proj = (p_camera_inverse_transform * light_transform).inverse(); - RasterizerStorageRD::store_transform(proj, light_data.shadow_matrix); + RendererStorageRD::store_transform(proj, light_data.shadow_matrix); if (size > 0.0) { light_data.soft_shadow_size = size; @@ -6273,7 +6274,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull bias.set_light_bias(); CameraMatrix shadow_mtx = bias * light_instance_get_shadow_camera(li, 0) * modelview; - RasterizerStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix); + RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix); if (size > 0.0) { CameraMatrix cm = light_instance_get_shadow_camera(li, 0); @@ -6311,7 +6312,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull } } -void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) { +void RendererSceneRenderRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) { Transform uv_xform; uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0)); uv_xform.origin = Vector3(-1.0, 0.0, -1.0); @@ -6347,7 +6348,7 @@ void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_ Transform scale_xform; scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z)); Transform to_decal_xform = (p_camera_inverse_xform * decal_instance_get_transform(di) * scale_xform * uv_xform).affine_inverse(); - RasterizerStorageRD::store_transform(to_decal_xform, dd.xform); + RendererStorageRD::store_transform(to_decal_xform, dd.xform); Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized(); normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine @@ -6385,7 +6386,7 @@ void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_ dd.normal_rect[3] = rect.size.y; Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized(); - RasterizerStorageRD::store_basis_3x4(normal_xform, dd.normal_xform); + RendererStorageRD::store_basis_3x4(normal_xform, dd.normal_xform); } else { dd.normal_rect[0] = 0; dd.normal_rect[1] = 0; @@ -6441,7 +6442,7 @@ void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_ } } -void RasterizerSceneRD::_volumetric_fog_erase(RenderBuffers *rb) { +void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { ERR_FAIL_COND(!rb->volumetric_fog); RD::get_singleton()->free(rb->volumetric_fog->light_density_map); @@ -6465,7 +6466,7 @@ void RasterizerSceneRD::_volumetric_fog_erase(RenderBuffers *rb) { rb->volumetric_fog = nullptr; } -void RasterizerSceneRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) { +void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) { //create fog mipmaps uint32_t fog_texture_size = p_target_size; uint32_t base_texture_size = p_base_size; @@ -6498,7 +6499,7 @@ void RasterizerSceneRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_si } } -void RasterizerSceneRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) { +void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) { for (int i = 1; i < shrink_stages.size(); i++) { RD::get_singleton()->free(shrink_stages[i].texture); if (shrink_stages[i].filter_texture.is_valid()) { @@ -6508,7 +6509,7 @@ void RasterizerSceneRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &s shrink_stages.clear(); } -void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) { +void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); Environment *env = environment_owner.getornull(p_environment); @@ -6542,7 +6543,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir tf.width = target_width; tf.height = target_height; tf.depth = volumetric_fog_depth; - tf.type = RD::TEXTURE_TYPE_3D; + tf.texture_type = RD::TEXTURE_TYPE_3D; tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -6556,7 +6557,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; u.binding = 0; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(rb->volumetric_fog->fog_map); uniforms.push_back(u); } @@ -6729,10 +6730,10 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture); } @@ -6742,10 +6743,10 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; if (directional_shadow.shrink_stages.size() == 0) { - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture); } @@ -6754,7 +6755,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; u.ids.push_back(get_positional_light_buffer()); uniforms.push_back(u); @@ -6762,7 +6763,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 4; u.ids.push_back(get_directional_light_buffer()); uniforms.push_back(u); @@ -6770,7 +6771,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; u.ids.push_back(get_cluster_builder_texture()); uniforms.push_back(u); @@ -6778,7 +6779,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; u.ids.push_back(get_cluster_builder_indices_buffer()); uniforms.push_back(u); @@ -6786,7 +6787,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 7; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -6794,7 +6795,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; u.ids.push_back(rb->volumetric_fog->light_density_map); uniforms.push_back(u); @@ -6802,7 +6803,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; u.ids.push_back(rb->volumetric_fog->fog_map); uniforms.push_back(u); @@ -6810,7 +6811,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; u.ids.push_back(shadow_sampler); uniforms.push_back(u); @@ -6818,7 +6819,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 11; u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers)); uniforms.push_back(u); @@ -6826,7 +6827,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) { u.ids.push_back(rb->giprobe_textures[i]); @@ -6835,7 +6836,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 13; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -6856,7 +6857,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; u.ids.push_back(gi.sdfgi_ubo); uniforms.push_back(u); @@ -6864,7 +6865,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; u.ids.push_back(rb->sdfgi->ambient_texture); uniforms.push_back(u); @@ -6872,7 +6873,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; u.ids.push_back(rb->sdfgi->occlusion_texture); uniforms.push_back(u); @@ -6987,7 +6988,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir RD::get_singleton()->compute_list_end(); } -void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { Color clear_color; if (p_render_buffers.is_valid()) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); @@ -7057,7 +7058,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca } } -void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { +void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { LightInstance *light_instance = light_instance_owner.getornull(p_light); ERR_FAIL_COND(!light_instance); @@ -7233,11 +7234,11 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } } -void RasterizerSceneRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_framebuffer, p_region); } -void RasterizerSceneRD::render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) { +void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) { //print_line("rendering region " + itos(p_region)); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -7575,7 +7576,7 @@ void RasterizerSceneRD::render_sdfgi(RID p_render_buffers, int p_region, Instanc } } -void RasterizerSceneRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) { +void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) { ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider)); Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); CameraMatrix cm; @@ -7592,7 +7593,7 @@ void RasterizerSceneRD::render_particle_collider_heightfield(RID p_collider, con _render_particle_collider_heightfield(fb, cam_xform, cm, p_cull_result, p_cull_count); } -void RasterizerSceneRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) { +void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); ERR_FAIL_COND(!rb->sdfgi); @@ -7699,7 +7700,7 @@ void RasterizerSceneRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_ RD::get_singleton()->compute_list_end(); } -bool RasterizerSceneRD::free(RID p_rid) { +bool RendererSceneRenderRD::free(RID p_rid) { if (render_buffers_owner.owns(p_rid)) { RenderBuffers *rb = render_buffers_owner.getornull(p_rid); _free_render_buffer_data(rb); @@ -7798,38 +7799,38 @@ bool RasterizerSceneRD::free(RID p_rid) { return true; } -void RasterizerSceneRD::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) { +void RendererSceneRenderRD::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) { debug_draw = p_debug_draw; } -void RasterizerSceneRD::update() { +void RendererSceneRenderRD::update() { _update_dirty_skys(); } -void RasterizerSceneRD::set_time(double p_time, double p_step) { +void RendererSceneRenderRD::set_time(double p_time, double p_step) { time = p_time; time_step = p_step; } -void RasterizerSceneRD::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) { +void RendererSceneRenderRD::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) { screen_space_roughness_limiter = p_enable; screen_space_roughness_limiter_amount = p_amount; screen_space_roughness_limiter_limit = p_limit; } -bool RasterizerSceneRD::screen_space_roughness_limiter_is_active() const { +bool RendererSceneRenderRD::screen_space_roughness_limiter_is_active() const { return screen_space_roughness_limiter; } -float RasterizerSceneRD::screen_space_roughness_limiter_get_amount() const { +float RendererSceneRenderRD::screen_space_roughness_limiter_get_amount() const { return screen_space_roughness_limiter_amount; } -float RasterizerSceneRD::screen_space_roughness_limiter_get_limit() const { +float RendererSceneRenderRD::screen_space_roughness_limiter_get_limit() const { return screen_space_roughness_limiter_limit; } -TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { +TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; tf.width = p_image_size.width; // Always 64x64 @@ -7920,38 +7921,38 @@ TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RI return ret; } -void RasterizerSceneRD::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { +void RendererSceneRenderRD::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { sdfgi_debug_probe_pos = p_position; sdfgi_debug_probe_dir = p_dir; } -RasterizerSceneRD *RasterizerSceneRD::singleton = nullptr; +RendererSceneRenderRD *RendererSceneRenderRD::singleton = nullptr; -RID RasterizerSceneRD::get_cluster_builder_texture() { +RID RendererSceneRenderRD::get_cluster_builder_texture() { return cluster.builder.get_cluster_texture(); } -RID RasterizerSceneRD::get_cluster_builder_indices_buffer() { +RID RendererSceneRenderRD::get_cluster_builder_indices_buffer() { return cluster.builder.get_cluster_indices_buffer(); } -RID RasterizerSceneRD::get_reflection_probe_buffer() { +RID RendererSceneRenderRD::get_reflection_probe_buffer() { return cluster.reflection_buffer; } -RID RasterizerSceneRD::get_positional_light_buffer() { +RID RendererSceneRenderRD::get_positional_light_buffer() { return cluster.light_buffer; } -RID RasterizerSceneRD::get_directional_light_buffer() { +RID RendererSceneRenderRD::get_directional_light_buffer() { return cluster.directional_light_buffer; } -RID RasterizerSceneRD::get_decal_buffer() { +RID RendererSceneRenderRD::get_decal_buffer() { return cluster.decal_buffer; } -int RasterizerSceneRD::get_max_directional_lights() const { +int RendererSceneRenderRD::get_max_directional_lights() const { return cluster.max_directional_lights; } -RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { +RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { storage = p_storage; singleton = this; @@ -8040,8 +8041,8 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { } // register our shader funds - storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs); - storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs); + storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs); + storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs); { ShaderCompilerRD::DefaultIdentifierActions actions; @@ -8105,7 +8106,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { sky_shader.default_material = storage->material_create(); storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader); - SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RasterizerStorageRD::SHADER_TYPE_SKY); + SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY); sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND); sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO)); @@ -8114,7 +8115,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 0; u.ids.resize(12); RID *ids_ptr = u.ids.ptrw(); @@ -8135,7 +8136,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); @@ -8144,7 +8145,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; u.binding = 2; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(sky_scene_state.uniform_buffer); uniforms.push_back(u); } @@ -8152,7 +8153,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; u.binding = 3; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(sky_scene_state.directional_light_buffer); uniforms.push_back(u); } @@ -8165,8 +8166,8 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; u.binding = 0; - u.type = RD::UNIFORM_TYPE_TEXTURE; - RID vfog = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); u.ids.push_back(vfog); uniforms.push_back(u); } @@ -8184,23 +8185,23 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } @@ -8262,14 +8263,14 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); @@ -8414,7 +8415,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); } -RasterizerSceneRD::~RasterizerSceneRD() { +RendererSceneRenderRD::~RendererSceneRenderRD() { for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) { RD::get_singleton()->free(E->get().depth); } @@ -8442,7 +8443,7 @@ RasterizerSceneRD::~RasterizerSceneRD() { volumetric_fog.shader.version_free(volumetric_fog.shader_version); memdelete_arr(gi_probe_lights); - SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RasterizerStorageRD::SHADER_TYPE_SKY); + SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY); sky_shader.shader.version_free(md->shader_data->version); RD::get_singleton()->free(sky_scene_state.directional_light_buffer); RD::get_singleton()->free(sky_scene_state.uniform_buffer); diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 6aa79208ea..8c994849c3 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_scene_rd.h */ +/* renderer_scene_render_rd.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,27 +28,28 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_SCENE_RD_H -#define RASTERIZER_SCENE_RD_H +#ifndef RENDERING_SERVER_SCENE_RENDER_RD_H +#define RENDERING_SERVER_SCENE_RENDER_RD_H #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" -#include "servers/rendering/rasterizer.h" -#include "servers/rendering/rasterizer_rd/light_cluster_builder.h" -#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h" -#include "servers/rendering/rasterizer_rd/shaders/gi.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/giprobe.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/sky.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl.gen.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/light_cluster_builder.h" +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" +#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/giprobe_debug.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h" +#include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" -class RasterizerSceneRD : public RasterizerScene { +class RendererSceneRenderRD : public RendererSceneRender { protected: double time; @@ -138,11 +139,11 @@ protected: private: RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED; double time_step = 0; - static RasterizerSceneRD *singleton; + static RendererSceneRenderRD *singleton; int roughness_layers; - RasterizerStorageRD *storage; + RendererStorageRD *storage; struct ReflectionData { struct Layer { @@ -200,11 +201,11 @@ private: RID default_shader_rd; } sky_shader; - struct SkyShaderData : public RasterizerStorageRD::ShaderData { + struct SkyShaderData : public RendererStorageRD::ShaderData { bool valid; RID version; - RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX]; + PipelineCacheRD pipelines[SKY_VERSION_MAX]; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; @@ -224,7 +225,7 @@ private: virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; + virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; @@ -233,12 +234,12 @@ private: virtual ~SkyShaderData(); }; - RasterizerStorageRD::ShaderData *_create_sky_shader_func(); - static RasterizerStorageRD::ShaderData *_create_sky_shader_funcs() { - return static_cast<RasterizerSceneRD *>(singleton)->_create_sky_shader_func(); + RendererStorageRD::ShaderData *_create_sky_shader_func(); + static RendererStorageRD::ShaderData *_create_sky_shader_funcs() { + return static_cast<RendererSceneRenderRD *>(singleton)->_create_sky_shader_func(); }; - struct SkyMaterialData : public RasterizerStorageRD::MaterialData { + struct SkyMaterialData : public RendererStorageRD::MaterialData { uint64_t last_frame; SkyShaderData *shader_data; RID uniform_buffer; @@ -253,9 +254,9 @@ private: virtual ~SkyMaterialData(); }; - RasterizerStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader); - static RasterizerStorageRD::MaterialData *_create_sky_material_funcs(RasterizerStorageRD::ShaderData *p_shader) { - return static_cast<RasterizerSceneRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader)); + RendererStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader); + static RendererStorageRD::MaterialData *_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader) { + return static_cast<RendererSceneRenderRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader)); }; enum SkyTextureSetVersion { @@ -512,7 +513,7 @@ private: GiprobeDebugShaderRD giprobe_debug_shader; RID giprobe_debug_shader_version; RID giprobe_debug_shader_version_shaders[GI_PROBE_DEBUG_MAX]; - RenderPipelineVertexFormatCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX]; + PipelineCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX]; RID giprobe_debug_uniform_set; /* SHADOW ATLAS */ @@ -1077,7 +1078,7 @@ private: RID debug_probes_shader; RID debug_probes_shader_version; - RenderPipelineVertexFormatCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX]; + PipelineCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX]; struct Light { float color[3]; @@ -1951,8 +1952,8 @@ public: void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir); - RasterizerSceneRD(RasterizerStorageRD *p_storage); - ~RasterizerSceneRD(); + RendererSceneRenderRD(RendererStorageRD *p_storage); + ~RendererSceneRenderRD(); }; #endif // RASTERIZER_SCENE_RD_H diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index a4d79ffc87..96f6d5ea32 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_storage_rd.cpp */ +/* renderer_storage_rd.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer_storage_rd.h" +#include "renderer_storage_rd.h" #include "core/config/engine.h" #include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "rasterizer_rd.h" +#include "renderer_compositor_rd.h" #include "servers/rendering/shader_language.h" -Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { +Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { Ref<Image> image = p_image->duplicate(); switch (p_image->get_format()) { @@ -535,7 +535,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima return image; } -RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { +RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { ERR_FAIL_COND_V(p_image.is_null(), RID()); ERR_FAIL_COND_V(p_image->empty(), RID()); @@ -567,7 +567,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { rd_format.depth = 1; rd_format.array_layers = 1; rd_format.mipmaps = texture.mipmaps; - rd_format.type = texture.rd_type; + rd_format.texture_type = texture.rd_type; rd_format.samples = RD::TEXTURE_SAMPLES_1; rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { @@ -605,7 +605,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { +RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { ERR_FAIL_COND_V(p_layers.size() == 0, RID()); ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID()); @@ -675,7 +675,7 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l rd_format.depth = 1; rd_format.array_layers = texture.layers; rd_format.mipmaps = texture.mipmaps; - rd_format.type = texture.rd_type; + rd_format.texture_type = texture.rd_type; rd_format.samples = RD::TEXTURE_SAMPLES_1; rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { @@ -715,7 +715,7 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { +RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { ERR_FAIL_COND_V(p_data.size() == 0, RID()); Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); if (verr != Image::VALIDATE_3D_OK) { @@ -793,7 +793,7 @@ RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width, rd_format.depth = texture.depth; rd_format.array_layers = 1; rd_format.mipmaps = texture.mipmaps; - rd_format.type = texture.rd_type; + rd_format.texture_type = texture.rd_type; rd_format.samples = RD::TEXTURE_SAMPLES_1; rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { @@ -831,7 +831,7 @@ RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width, return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_proxy_create(RID p_base) { +RID RendererStorageRD::texture_proxy_create(RID p_base) { Texture *tex = texture_owner.getornull(p_base); ERR_FAIL_COND_V(!tex, RID()); Texture proxy_tex = *tex; @@ -854,7 +854,7 @@ RID RasterizerStorageRD::texture_proxy_create(RID p_base) { return rid; } -void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { +void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { ERR_FAIL_COND(p_image.is_null() || p_image->empty()); Texture *tex = texture_owner.getornull(p_texture); @@ -876,15 +876,15 @@ void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_ RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data(), !p_immediate); } -void RasterizerStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) { +void RendererStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) { _texture_2d_update(p_texture, p_image, p_layer, true); } -void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { +void RendererStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { _texture_2d_update(p_texture, p_image, p_layer, false); } -void RasterizerStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { +void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->type != Texture::TYPE_3D); @@ -921,7 +921,7 @@ void RasterizerStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Imag RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data, true); } -void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { +void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(!tex->is_proxy); @@ -961,7 +961,7 @@ void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { } //these two APIs can be used together or in combination with the others. -RID RasterizerStorageRD::texture_2d_placeholder_create() { +RID RendererStorageRD::texture_2d_placeholder_create() { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -977,7 +977,7 @@ RID RasterizerStorageRD::texture_2d_placeholder_create() { return texture_2d_create(image); } -RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) { +RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -1003,7 +1003,7 @@ RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayere return texture_2d_layered_create(images, p_layered_type); } -RID RasterizerStorageRD::texture_3d_placeholder_create() { +RID RendererStorageRD::texture_3d_placeholder_create() { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -1025,7 +1025,7 @@ RID RasterizerStorageRD::texture_3d_placeholder_create() { return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images); } -Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { +Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, Ref<Image>()); @@ -1053,7 +1053,7 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { return image; } -Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { +Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, Ref<Image>()); @@ -1070,7 +1070,7 @@ Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) return image; } -Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const { +Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>()); ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>()); @@ -1101,7 +1101,7 @@ Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const { return ret; } -void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { +void RendererStorageRD::texture_replace(RID p_texture, RID p_by_texture) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->proxy_to.is_valid()); //can't replace proxy @@ -1150,7 +1150,7 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { } } -void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { +void RendererStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->type != Texture::TYPE_2D); @@ -1158,53 +1158,53 @@ void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, tex->height_2d = p_height; } -void RasterizerStorageRD::texture_set_path(RID p_texture, const String &p_path) { +void RendererStorageRD::texture_set_path(RID p_texture, const String &p_path) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->path = p_path; } -String RasterizerStorageRD::texture_get_path(RID p_texture) const { +String RendererStorageRD::texture_get_path(RID p_texture) const { return String(); } -void RasterizerStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { +void RendererStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_3d_callback_ud = p_userdata; tex->detect_3d_callback = p_callback; } -void RasterizerStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { +void RendererStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_normal_callback_ud = p_userdata; tex->detect_normal_callback = p_callback; } -void RasterizerStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { +void RendererStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_roughness_callback_ud = p_userdata; tex->detect_roughness_callback = p_callback; } -void RasterizerStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) { +void RendererStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) { } -void RasterizerStorageRD::texture_set_proxy(RID p_proxy, RID p_base) { +void RendererStorageRD::texture_set_proxy(RID p_proxy, RID p_base) { } -void RasterizerStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { +void RendererStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { } -Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) { +Size2 RendererStorageRD::texture_size_with_proxy(RID p_proxy) { return texture_2d_get_size(p_proxy); } /* CANVAS TEXTURE */ -void RasterizerStorageRD::CanvasTexture::clear_sets() { +void RendererStorageRD::CanvasTexture::clear_sets() { if (cleared_cache) { return; } @@ -1219,15 +1219,15 @@ void RasterizerStorageRD::CanvasTexture::clear_sets() { cleared_cache = true; } -RasterizerStorageRD::CanvasTexture::~CanvasTexture() { +RendererStorageRD::CanvasTexture::~CanvasTexture() { clear_sets(); } -RID RasterizerStorageRD::canvas_texture_create() { +RID RendererStorageRD::canvas_texture_create() { return canvas_texture_owner.make_rid(memnew(CanvasTexture)); } -void RasterizerStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { +void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); switch (p_channel) { case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { @@ -1244,7 +1244,7 @@ void RasterizerStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::C ct->clear_sets(); } -void RasterizerStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { +void RendererStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); ct->specular_color.r = p_specular_color.r; ct->specular_color.g = p_specular_color.g; @@ -1253,19 +1253,19 @@ void RasterizerStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_tex ct->clear_sets(); } -void RasterizerStorageRD::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { +void RendererStorageRD::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); ct->texture_filter = p_filter; ct->clear_sets(); } -void RasterizerStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { +void RendererStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); ct->texture_repeat = p_repeat; ct->clear_sets(); } -bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { +bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { CanvasTexture *ct = nullptr; Texture *t = texture_owner.getornull(p_texture); @@ -1298,7 +1298,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv Vector<RD::Uniform> uniforms; { //diffuse RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; t = texture_owner.getornull(ct->diffuse); @@ -1313,7 +1313,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv } { //normal RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; t = texture_owner.getornull(ct->normalmap); @@ -1328,7 +1328,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv } { //specular RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; t = texture_owner.getornull(ct->specular); @@ -1343,7 +1343,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv } { //sampler RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 3; u.ids.push_back(sampler_rd_get_default(filter, repeat)); uniforms.push_back(u); @@ -1365,7 +1365,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv /* SHADER API */ -RID RasterizerStorageRD::shader_create() { +RID RendererStorageRD::shader_create() { Shader shader; shader.data = nullptr; shader.type = SHADER_TYPE_MAX; @@ -1373,7 +1373,7 @@ RID RasterizerStorageRD::shader_create() { return shader_owner.make_rid(shader); } -void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { +void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); @@ -1443,13 +1443,13 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { } } -String RasterizerStorageRD::shader_get_code(RID p_shader) const { +String RendererStorageRD::shader_get_code(RID p_shader) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND_V(!shader, String()); return shader->code; } -void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void RendererStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { @@ -1457,7 +1457,7 @@ void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> } } -void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) { +void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); @@ -1475,7 +1475,7 @@ void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const S } } -RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const { +RID RendererStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND_V(!shader, RID()); if (shader->default_texture_parameter.has(p_name)) { @@ -1485,7 +1485,7 @@ RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const St return RID(); } -Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const { +Variant RendererStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND_V(!shader, Variant()); if (shader->data) { @@ -1494,14 +1494,14 @@ Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const String return Variant(); } -void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) { +void RendererStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) { ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX); shader_data_request_func[p_shader_type] = p_function; } /* COMMON MATERIAL API */ -RID RasterizerStorageRD::material_create() { +RID RendererStorageRD::material_create() { Material material; material.data = nullptr; material.shader = nullptr; @@ -1519,7 +1519,7 @@ RID RasterizerStorageRD::material_create() { return id; } -void RasterizerStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) { +void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) { if (material->update_requested) { return; } @@ -1531,7 +1531,7 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif material->texture_dirty = material->texture_dirty || p_texture; } -void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { +void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1572,7 +1572,7 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { _material_queue_update(material, true, true); } -void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { +void RendererStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1590,7 +1590,7 @@ void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p } } -Variant RasterizerStorageRD::material_get_param(RID p_material, const StringName &p_param) const { +Variant RendererStorageRD::material_get_param(RID p_material, const StringName &p_param) const { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND_V(!material, Variant()); if (material->params.has(p_param)) { @@ -1600,7 +1600,7 @@ Variant RasterizerStorageRD::material_get_param(RID p_material, const StringName } } -void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_material) { +void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_material) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1616,7 +1616,7 @@ void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_mate material->instance_dependency.instance_notify_changed(false, true); } -void RasterizerStorageRD::material_set_render_priority(RID p_material, int priority) { +void RendererStorageRD::material_set_render_priority(RID p_material, int priority) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); material->priority = priority; @@ -1625,7 +1625,7 @@ void RasterizerStorageRD::material_set_render_priority(RID p_material, int prior } } -bool RasterizerStorageRD::material_is_animated(RID p_material) { +bool RendererStorageRD::material_is_animated(RID p_material) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND_V(!material, false); if (material->shader && material->shader->data) { @@ -1638,7 +1638,7 @@ bool RasterizerStorageRD::material_is_animated(RID p_material) { return false; //by default nothing is animated } -bool RasterizerStorageRD::material_casts_shadows(RID p_material) { +bool RendererStorageRD::material_casts_shadows(RID p_material) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND_V(!material, true); if (material->shader && material->shader->data) { @@ -1651,7 +1651,7 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } -void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { +void RendererStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { @@ -1663,7 +1663,7 @@ void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material } } -void RasterizerStorageRD::material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) { +void RendererStorageRD::material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); p_instance->update_dependency(&material->instance_dependency); @@ -1672,7 +1672,7 @@ void RasterizerStorageRD::material_update_dependency(RID p_material, RasterizerS } } -void RasterizerStorageRD::material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function) { +void RendererStorageRD::material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function) { ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX); material_data_request_func[p_shader_type] = p_function; } @@ -2119,7 +2119,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, } } -void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { +void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { bool uses_global_buffer = false; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) { @@ -2133,7 +2133,7 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { //this is a global variable, get the index to it - RasterizerStorageRD *rs = base_singleton; + RendererStorageRD *rs = base_singleton; GlobalVariables::Variable *gv = rs->global_variables.variables.getptr(E->key()); uint32_t index = 0; @@ -2180,7 +2180,7 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa } if (uses_global_buffer != (global_buffer_E != nullptr)) { - RasterizerStorageRD *rs = base_singleton; + RendererStorageRD *rs = base_singleton; if (uses_global_buffer) { global_buffer_E = rs->global_variables.materials_using_buffer.push_back(self); } else { @@ -2190,16 +2190,16 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa } } -RasterizerStorageRD::MaterialData::~MaterialData() { +RendererStorageRD::MaterialData::~MaterialData() { if (global_buffer_E) { //unregister global buffers - RasterizerStorageRD *rs = base_singleton; + RendererStorageRD *rs = base_singleton; rs->global_variables.materials_using_buffer.erase(global_buffer_E); } if (global_texture_E) { //unregister global textures - RasterizerStorageRD *rs = base_singleton; + RendererStorageRD *rs = base_singleton; for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) { GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key()); @@ -2212,8 +2212,8 @@ RasterizerStorageRD::MaterialData::~MaterialData() { } } -void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { - RasterizerStorageRD *singleton = (RasterizerStorageRD *)RasterizerStorage::base_singleton; +void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { + RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton; #ifdef TOOLS_ENABLED Texture *roughness_detect_texture = nullptr; RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGNHESS_R; @@ -2229,7 +2229,7 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va RID texture; if (p_texture_uniforms[i].global) { - RasterizerStorageRD *rs = base_singleton; + RendererStorageRD *rs = base_singleton; uses_global_textures = true; @@ -2330,7 +2330,7 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va { //for textures no longer used, unregister them List<Map<StringName, uint64_t>::Element *> to_delete; - RasterizerStorageRD *rs = base_singleton; + RendererStorageRD *rs = base_singleton; for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) { if (E->get() != global_textures_pass) { @@ -2359,7 +2359,7 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va } } -void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) { +void RendererStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) { Material *material = material_owner.getornull(p_material); if (material->shader_type != p_shader_type) { return; @@ -2369,7 +2369,7 @@ void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderT } } -void RasterizerStorageRD::_update_queued_materials() { +void RendererStorageRD::_update_queued_materials() { Material *material = material_update_list; while (material) { Material *next = material->update_next; @@ -2388,23 +2388,25 @@ void RasterizerStorageRD::_update_queued_materials() { /* MESH API */ -RID RasterizerStorageRD::mesh_create() { +RID RendererStorageRD::mesh_create() { return mesh_owner.make_rid(Mesh()); } /// Returns stride -void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { +void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); //ensure blend shape consistency - ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shapes.size() != (int)mesh->blend_shape_count); + ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shape_count != mesh->blend_shape_count); ERR_FAIL_COND(mesh->blend_shape_count && p_surface.bone_aabbs.size() != mesh->bone_aabbs.size()); #ifdef DEBUG_ENABLED //do a validation, to catch errors first { uint32_t stride = 0; + uint32_t attrib_stride = 0; + uint32_t skin_stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { if ((p_surface.format & (1 << i))) { @@ -2418,59 +2420,54 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_NORMAL: { - if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) { - stride += sizeof(int8_t) * 4; - } else { - stride += sizeof(float) * 4; - } + stride += sizeof(int32_t); } break; case RS::ARRAY_TANGENT: { - if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) { - stride += sizeof(int8_t) * 4; - } else { - stride += sizeof(float) * 4; - } + stride += sizeof(int32_t); } break; case RS::ARRAY_COLOR: { - if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) { - stride += sizeof(int8_t) * 4; - } else { - stride += sizeof(float) * 4; - } - + attrib_stride += sizeof(int16_t) * 4; } break; case RS::ARRAY_TEX_UV: { - if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) { - stride += sizeof(int16_t) * 2; - } else { - stride += sizeof(float) * 2; - } + attrib_stride += sizeof(float) * 2; } break; case RS::ARRAY_TEX_UV2: { - if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) { - stride += sizeof(int16_t) * 2; - } else { - stride += sizeof(float) * 2; - } + attrib_stride += sizeof(float) * 2; } break; - case RS::ARRAY_BONES: { - //assumed weights too - - //unique format, internally 16 bits, exposed as single array for 32 - - stride += sizeof(int32_t) * 4; + case RS::ARRAY_CUSTOM0: + case RS::ARRAY_CUSTOM1: + case RS::ARRAY_CUSTOM2: + case RS::ARRAY_CUSTOM3: { + int idx = i - RS::ARRAY_CUSTOM0; + uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT }; + uint32_t fmt = (p_surface.format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK; + uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 }; + attrib_stride += fmtsize[fmt]; } break; + case RS::ARRAY_WEIGHTS: + case RS::ARRAY_BONES: { + //uses a separate array + bool use_8 = p_surface.format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + skin_stride += sizeof(int16_t) * (use_8 ? 8 : 4); + } break; } } } int expected_size = stride * p_surface.vertex_count; - ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")"); + ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of vertex data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")"); + int expected_attrib_size = attrib_stride * p_surface.vertex_count; + ERR_FAIL_COND_MSG(expected_attrib_size != p_surface.attribute_data.size(), "Size of attribute data provided (" + itos(p_surface.attribute_data.size()) + ") does not match expected (" + itos(expected_attrib_size) + ")"); + + if ((p_surface.format & RS::ARRAY_FORMAT_WEIGHTS) && (p_surface.format & RS::ARRAY_FORMAT_BONES)) { + expected_size = skin_stride * p_surface.vertex_count; + ERR_FAIL_COND_MSG(expected_size != p_surface.skin_data.size(), "Size of skin data provided (" + itos(p_surface.skin_data.size()) + ") does not match expected (" + itos(expected_size) + ")"); + } } #endif @@ -2481,6 +2478,12 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ s->primitive = p_surface.primitive; s->vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.vertex_data.size(), p_surface.vertex_data); + if (p_surface.attribute_data.size()) { + s->attribute_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.attribute_data.size(), p_surface.attribute_data); + } + if (p_surface.skin_data.size()) { + s->skin_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.skin_data.size(), p_surface.skin_data); + } s->vertex_count = p_surface.vertex_count; if (p_surface.index_count) { @@ -2504,7 +2507,7 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ s->aabb = p_surface.aabb; s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them. - +#if 0 for (int i = 0; i < p_surface.blend_shapes.size(); i++) { if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) { memdelete(s); @@ -2513,8 +2516,8 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ RID vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.blend_shapes[i].size(), p_surface.blend_shapes[i]); s->blend_shapes.push_back(vertex_buffer); } - - mesh->blend_shape_count = p_surface.blend_shapes.size(); +#endif + mesh->blend_shape_count = p_surface.blend_shape_count; if (mesh->surface_count == 0) { mesh->bone_aabbs = p_surface.bone_aabbs; @@ -2537,13 +2540,13 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ mesh->material_cache.clear(); } -int RasterizerStorageRD::mesh_get_blend_shape_count(RID p_mesh) const { +int RendererStorageRD::mesh_get_blend_shape_count(RID p_mesh) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, -1); return mesh->blend_shape_count; } -void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) { +void RendererStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_INDEX((int)p_mode, 2); @@ -2551,13 +2554,13 @@ void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMo mesh->blend_shape_mode = p_mode; } -RS::BlendShapeMode RasterizerStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const { +RS::BlendShapeMode RendererStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED); return mesh->blend_shape_mode; } -void RasterizerStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { +void RendererStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); @@ -2568,7 +2571,7 @@ void RasterizerStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->vertex_buffer, p_offset, data_size, r); } -void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { +void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); @@ -2578,7 +2581,7 @@ void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, R mesh->material_cache.clear(); } -RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const { +RID RendererStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RID()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID()); @@ -2586,7 +2589,7 @@ RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) co return mesh->surfaces[p_surface]->material; } -RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const { +RS::SurfaceData RendererStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RS::SurfaceData()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData()); @@ -2596,6 +2599,12 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) RS::SurfaceData sd; sd.format = s.format; sd.vertex_data = RD::get_singleton()->buffer_get_data(s.vertex_buffer); + if (s.attribute_buffer.is_valid()) { + sd.attribute_data = RD::get_singleton()->buffer_get_data(s.attribute_buffer); + } + if (s.skin_buffer.is_valid()) { + sd.skin_data = RD::get_singleton()->buffer_get_data(s.skin_buffer); + } sd.vertex_count = s.vertex_count; sd.index_count = s.index_count; sd.primitive = s.primitive; @@ -2613,33 +2622,32 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) sd.bone_aabbs = s.bone_aabbs; - for (int i = 0; i < s.blend_shapes.size(); i++) { - Vector<uint8_t> bs = RD::get_singleton()->buffer_get_data(s.blend_shapes[i]); - sd.blend_shapes.push_back(bs); + if (s.blend_shape_buffer.is_valid()) { + sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer); } return sd; } -int RasterizerStorageRD::mesh_get_surface_count(RID p_mesh) const { +int RendererStorageRD::mesh_get_surface_count(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, 0); return mesh->surface_count; } -void RasterizerStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { +void RendererStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; } -AABB RasterizerStorageRD::mesh_get_custom_aabb(RID p_mesh) const { +AABB RendererStorageRD::mesh_get_custom_aabb(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); return mesh->custom_aabb; } -AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { +AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); @@ -2744,12 +2752,18 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { return aabb; } -void RasterizerStorageRD::mesh_clear(RID p_mesh) { +void RendererStorageRD::mesh_clear(RID p_mesh) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); for (uint32_t i = 0; i < mesh->surface_count; i++) { Mesh::Surface &s = *mesh->surfaces[i]; RD::get_singleton()->free(s.vertex_buffer); //clears arrays as dependency automatically, including all versions + if (s.attribute_buffer.is_valid()) { + RD::get_singleton()->free(s.attribute_buffer); + } + if (s.skin_buffer.is_valid()) { + RD::get_singleton()->free(s.skin_buffer); + } if (s.versions) { memfree(s.versions); //reallocs, so free with memfree. } @@ -2765,12 +2779,8 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) { memdelete_arr(s.lods); } - for (int32_t j = 0; j < s.blend_shapes.size(); j++) { - RD::get_singleton()->free(s.blend_shapes[j]); - } - - if (s.blend_shape_base_buffer.is_valid()) { - RD::get_singleton()->free(s.blend_shape_base_buffer); + if (s.blend_shape_buffer.is_valid()) { + RD::get_singleton()->free(s.blend_shape_buffer); } memdelete(mesh->surfaces[i]); @@ -2785,7 +2795,7 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) { mesh->instance_dependency.instance_notify_changed(true, true); } -void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surface *s, uint32_t p_input_mask) { +void RendererStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surface *s, uint32_t p_input_mask) { uint32_t version = s->version_count; s->version_count++; s->versions = (Mesh::Surface::Version *)memrealloc(s->versions, sizeof(Mesh::Surface::Version) * s->version_count); @@ -2796,8 +2806,10 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su Vector<RID> buffers; uint32_t stride = 0; + uint32_t attribute_stride = 0; + uint32_t skin_stride = 0; - for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { + for (int i = 0; i < RS::ARRAY_INDEX; i++) { RD::VertexAttribute vd; RID buffer; vd.location = i; @@ -2805,6 +2817,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su if (!(s->format & (1 << i))) { // Not supplied by surface, use default value buffer = mesh_default_rd_buffers[i]; + vd.stride = 0; switch (i) { case RS::ARRAY_VERTEX: { vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; @@ -2827,20 +2840,31 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su case RS::ARRAY_TEX_UV2: { vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; } break; + case RS::ARRAY_CUSTOM0: + case RS::ARRAY_CUSTOM1: + case RS::ARRAY_CUSTOM2: + case RS::ARRAY_CUSTOM3: { + //assumed weights too + vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; + } break; case RS::ARRAY_BONES: { //assumed weights too vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; } break; + case RS::ARRAY_WEIGHTS: { + //assumed weights too + vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; + } break; } } else { //Supplied, use it - vd.offset = stride; - vd.stride = 1; //mark that it needs a stride set - buffer = s->vertex_buffer; + vd.stride = 1; //mark that it needs a stride set (default uses 0) switch (i) { case RS::ARRAY_VERTEX: { + vd.offset = stride; + if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) { vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; stride += sizeof(float) * 2; @@ -2849,71 +2873,80 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su stride += sizeof(float) * 3; } + buffer = s->vertex_buffer; + } break; case RS::ARRAY_NORMAL: { - if (s->format & RS::ARRAY_COMPRESS_NORMAL) { - vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM; - stride += sizeof(int8_t) * 4; - } else { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - stride += sizeof(float) * 4; - } + vd.offset = stride; + + vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; + stride += sizeof(uint32_t); + buffer = s->vertex_buffer; } break; case RS::ARRAY_TANGENT: { - if (s->format & RS::ARRAY_COMPRESS_TANGENT) { - vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM; - stride += sizeof(int8_t) * 4; - } else { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - stride += sizeof(float) * 4; - } + vd.offset = stride; + vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; + stride += sizeof(uint32_t); + buffer = s->vertex_buffer; } break; case RS::ARRAY_COLOR: { - if (s->format & RS::ARRAY_COMPRESS_COLOR) { - vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - stride += sizeof(int8_t) * 4; - } else { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - stride += sizeof(float) * 4; - } + vd.offset = attribute_stride; + vd.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + attribute_stride += sizeof(int16_t) * 4; + buffer = s->attribute_buffer; } break; case RS::ARRAY_TEX_UV: { - if (s->format & RS::ARRAY_COMPRESS_TEX_UV) { - vd.format = RD::DATA_FORMAT_R16G16_SFLOAT; - stride += sizeof(int16_t) * 2; - } else { - vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; - stride += sizeof(float) * 2; - } + vd.offset = attribute_stride; + + vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; + attribute_stride += sizeof(float) * 2; + buffer = s->attribute_buffer; } break; case RS::ARRAY_TEX_UV2: { - if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) { - vd.format = RD::DATA_FORMAT_R16G16_SFLOAT; - stride += sizeof(int16_t) * 2; - } else { - vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; - stride += sizeof(float) * 2; - } + vd.offset = attribute_stride; + vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; + attribute_stride += sizeof(float) * 2; + buffer = s->attribute_buffer; + } break; + case RS::ARRAY_CUSTOM0: + case RS::ARRAY_CUSTOM1: + case RS::ARRAY_CUSTOM2: + case RS::ARRAY_CUSTOM3: { + vd.offset = attribute_stride; + + int idx = i - RS::ARRAY_CUSTOM0; + uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT }; + uint32_t fmt = (s->format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK; + uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 }; + RD::DataFormat fmtrd[RS::ARRAY_CUSTOM_MAX] = { RD::DATA_FORMAT_R8G8B8A8_UNORM, RD::DATA_FORMAT_R8G8B8A8_SNORM, RD::DATA_FORMAT_R16G16_SFLOAT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::DATA_FORMAT_R32_SFLOAT, RD::DATA_FORMAT_R32G32_SFLOAT, RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::DATA_FORMAT_R32G32B32A32_SFLOAT }; + vd.format = fmtrd[fmt]; + attribute_stride += fmtsize[fmt]; + buffer = s->attribute_buffer; } break; case RS::ARRAY_BONES: { - //assumed weights too + vd.offset = skin_stride; - //unique format, internally 16 bits, exposed as single array for 32 - - vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; - stride += sizeof(int32_t) * 4; + vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT; + skin_stride += sizeof(int16_t) * 4; + buffer = s->skin_buffer; + } break; + case RS::ARRAY_WEIGHTS: { + vd.offset = skin_stride; + vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM; + skin_stride += sizeof(int16_t) * 4; + buffer = s->skin_buffer; } break; } } if (!(p_input_mask & (1 << i))) { - continue; // Shader does not need this, skip it + continue; // Shader does not need this, skip it (but computing stride was important anyway) } attributes.push_back(vd); @@ -2922,8 +2955,17 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su //update final stride for (int i = 0; i < attributes.size(); i++) { - if (attributes[i].stride == 1) { + if (attributes[i].stride == 0) { + continue; //default location + } + int loc = attributes[i].location; + + if (loc < RS::ARRAY_COLOR) { attributes.write[i].stride = stride; + } else if (loc < RS::ARRAY_BONES) { + attributes.write[i].stride = attribute_stride; + } else { + attributes.write[i].stride = skin_stride; } } @@ -2934,11 +2976,11 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su ////////////////// MULTIMESH -RID RasterizerStorageRD::multimesh_create() { +RID RendererStorageRD::multimesh_create() { return multimesh_owner.make_rid(MultiMesh()); } -void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -2978,13 +3020,13 @@ void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, R } } -int RasterizerStorageRD::multimesh_get_instance_count(RID p_multimesh) const { +int RendererStorageRD::multimesh_get_instance_count(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); return multimesh->instances; } -void RasterizerStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { +void RendererStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); if (multimesh->mesh == p_mesh) { @@ -3014,7 +3056,7 @@ void RasterizerStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { #define MULTIMESH_DIRTY_REGION_SIZE 512 -void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { +void RendererStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { if (multimesh->data_cache.size() > 0) { return; //already local } @@ -3043,7 +3085,7 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { multimesh->data_cache_used_dirty_regions = 0; } -void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) { +void RendererStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) { uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE; #ifdef DEBUG_ENABLED uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; @@ -3065,7 +3107,7 @@ void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_inde } } -void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) { +void RendererStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) { if (p_data) { uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; @@ -3088,7 +3130,7 @@ void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p } } -void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) { +void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) { ERR_FAIL_COND(multimesh->mesh.is_null()); AABB aabb; AABB mesh_aabb = mesh_get_aabb(multimesh->mesh); @@ -3130,7 +3172,7 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const multimesh->aabb = aabb; } -void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { +void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -3160,7 +3202,7 @@ void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int _multimesh_mark_dirty(multimesh, p_index, true); } -void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { +void RendererStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -3186,7 +3228,7 @@ void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, i _multimesh_mark_dirty(multimesh, p_index, true); } -void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { +void RendererStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -3208,7 +3250,7 @@ void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_in _multimesh_mark_dirty(multimesh, p_index, false); } -void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { +void RendererStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -3230,14 +3272,14 @@ void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, in _multimesh_mark_dirty(multimesh, p_index, false); } -RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const { +RID RendererStorageRD::multimesh_get_mesh(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, RID()); return multimesh->mesh; } -Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { +Transform RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform()); @@ -3268,7 +3310,7 @@ Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, return t; } -Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { +Transform2D RendererStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform2D()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D()); @@ -3293,7 +3335,7 @@ Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multi return t; } -Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { +Color RendererStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); @@ -3316,7 +3358,7 @@ Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_i return c; } -Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { +Color RendererStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); @@ -3339,7 +3381,7 @@ Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, i return c; } -void RasterizerStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) { +void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache)); @@ -3372,7 +3414,7 @@ void RasterizerStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<flo } } -Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const { +Vector<float> RendererStorageRD::multimesh_get_buffer(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Vector<float>()); if (multimesh->buffer.is_null()) { @@ -3395,7 +3437,7 @@ Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const { } } -void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { +void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances); @@ -3411,22 +3453,22 @@ void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p multimesh->visible_instances = p_visible; } -int RasterizerStorageRD::multimesh_get_visible_instances(RID p_multimesh) const { +int RendererStorageRD::multimesh_get_visible_instances(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); return multimesh->visible_instances; } -AABB RasterizerStorageRD::multimesh_get_aabb(RID p_multimesh) const { +AABB RendererStorageRD::multimesh_get_aabb(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, AABB()); if (multimesh->aabb_dirty) { - const_cast<RasterizerStorageRD *>(this)->_update_dirty_multimeshes(); + const_cast<RendererStorageRD *>(this)->_update_dirty_multimeshes(); } return multimesh->aabb; } -void RasterizerStorageRD::_update_dirty_multimeshes() { +void RendererStorageRD::_update_dirty_multimeshes() { while (multimesh_dirty_list) { MultiMesh *multimesh = multimesh_dirty_list; @@ -3481,25 +3523,25 @@ void RasterizerStorageRD::_update_dirty_multimeshes() { /* PARTICLES */ -RID RasterizerStorageRD::particles_create() { +RID RendererStorageRD::particles_create() { return particles_owner.make_rid(Particles()); } -void RasterizerStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) { +void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->emitting = p_emitting; } -bool RasterizerStorageRD::particles_get_emitting(RID p_particles) { +bool RendererStorageRD::particles_get_emitting(RID p_particles) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, false); return particles->emitting; } -void RasterizerStorageRD::_particles_free_data(Particles *particles) { +void RendererStorageRD::_particles_free_data(Particles *particles) { if (!particles->particle_buffer.is_valid()) { return; } @@ -3526,7 +3568,7 @@ void RasterizerStorageRD::_particles_free_data(Particles *particles) { } } -void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) { +void RendererStorageRD::particles_set_amount(RID p_particles, int p_amount) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); @@ -3549,14 +3591,14 @@ void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(particles->particle_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; u.ids.push_back(particles->particle_instance_buffer); uniforms.push_back(u); @@ -3572,111 +3614,111 @@ void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) { particles->clear = true; } -void RasterizerStorageRD::particles_set_lifetime(RID p_particles, float p_lifetime) { +void RendererStorageRD::particles_set_lifetime(RID p_particles, float p_lifetime) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->lifetime = p_lifetime; } -void RasterizerStorageRD::particles_set_one_shot(RID p_particles, bool p_one_shot) { +void RendererStorageRD::particles_set_one_shot(RID p_particles, bool p_one_shot) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->one_shot = p_one_shot; } -void RasterizerStorageRD::particles_set_pre_process_time(RID p_particles, float p_time) { +void RendererStorageRD::particles_set_pre_process_time(RID p_particles, float p_time) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->pre_process_time = p_time; } -void RasterizerStorageRD::particles_set_explosiveness_ratio(RID p_particles, float p_ratio) { +void RendererStorageRD::particles_set_explosiveness_ratio(RID p_particles, float p_ratio) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->explosiveness = p_ratio; } -void RasterizerStorageRD::particles_set_randomness_ratio(RID p_particles, float p_ratio) { +void RendererStorageRD::particles_set_randomness_ratio(RID p_particles, float p_ratio) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->randomness = p_ratio; } -void RasterizerStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { +void RendererStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->custom_aabb = p_aabb; particles->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) { +void RendererStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->speed_scale = p_scale; } -void RasterizerStorageRD::particles_set_use_local_coordinates(RID p_particles, bool p_enable) { +void RendererStorageRD::particles_set_use_local_coordinates(RID p_particles, bool p_enable) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->use_local_coords = p_enable; } -void RasterizerStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) { +void RendererStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->fixed_fps = p_fps; } -void RasterizerStorageRD::particles_set_fractional_delta(RID p_particles, bool p_enable) { +void RendererStorageRD::particles_set_fractional_delta(RID p_particles, bool p_enable) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->fractional_delta = p_enable; } -void RasterizerStorageRD::particles_set_collision_base_size(RID p_particles, float p_size) { +void RendererStorageRD::particles_set_collision_base_size(RID p_particles, float p_size) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->collision_base_size = p_size; } -void RasterizerStorageRD::particles_set_process_material(RID p_particles, RID p_material) { +void RendererStorageRD::particles_set_process_material(RID p_particles, RID p_material) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->process_material = p_material; } -void RasterizerStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) { +void RendererStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->draw_order = p_order; } -void RasterizerStorageRD::particles_set_draw_passes(RID p_particles, int p_passes) { +void RendererStorageRD::particles_set_draw_passes(RID p_particles, int p_passes) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->draw_passes.resize(p_passes); } -void RasterizerStorageRD::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) { +void RendererStorageRD::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_INDEX(p_pass, particles->draw_passes.size()); particles->draw_passes.write[p_pass] = p_mesh; } -void RasterizerStorageRD::particles_restart(RID p_particles) { +void RendererStorageRD::particles_restart(RID p_particles) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->restart_request = true; } -void RasterizerStorageRD::_particles_allocate_emission_buffer(Particles *particles) { +void RendererStorageRD::_particles_allocate_emission_buffer(Particles *particles) { ERR_FAIL_COND(particles->emission_buffer != nullptr); particles->emission_buffer_data.resize(sizeof(ParticleEmissionBuffer::Data) * particles->amount + sizeof(uint32_t) * 4); @@ -3693,7 +3735,7 @@ void RasterizerStorageRD::_particles_allocate_emission_buffer(Particles *particl } } -void RasterizerStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) { +void RendererStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_COND(p_particles == p_subemitter_particles); @@ -3706,7 +3748,7 @@ void RasterizerStorageRD::particles_set_subemitter(RID p_particles, RID p_subemi } } -void RasterizerStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { +void RendererStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_COND(particles->amount == 0); @@ -3749,7 +3791,7 @@ void RasterizerStorageRD::particles_emit(RID p_particles, const Transform &p_tra } } -void RasterizerStorageRD::particles_request_process(RID p_particles) { +void RendererStorageRD::particles_request_process(RID p_particles) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); @@ -3760,7 +3802,7 @@ void RasterizerStorageRD::particles_request_process(RID p_particles) { } } -AABB RasterizerStorageRD::particles_get_current_aabb(RID p_particles) { +AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) { const Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, AABB()); @@ -3804,28 +3846,28 @@ AABB RasterizerStorageRD::particles_get_current_aabb(RID p_particles) { return aabb; } -AABB RasterizerStorageRD::particles_get_aabb(RID p_particles) const { +AABB RendererStorageRD::particles_get_aabb(RID p_particles) const { const Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, AABB()); return particles->custom_aabb; } -void RasterizerStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) { +void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->emission_transform = p_transform; } -int RasterizerStorageRD::particles_get_draw_passes(RID p_particles) const { +int RendererStorageRD::particles_get_draw_passes(RID p_particles) const { const Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, 0); return particles->draw_passes.size(); } -RID RasterizerStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { +RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { const Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, RID()); ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID()); @@ -3833,36 +3875,40 @@ RID RasterizerStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pas return particles->draw_passes[p_pass]; } -void RasterizerStorageRD::particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) { +void RendererStorageRD::particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) { + RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance); + Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); - ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_PARTICLES_COLLISION); + ERR_FAIL_COND(instance->base_type != RS::INSTANCE_PARTICLES_COLLISION); - particles->collisions.insert(p_instance); + particles->collisions.insert(instance); } -void RasterizerStorageRD::particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) { +void RendererStorageRD::particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) { + RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance); + Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); - particles->collisions.erase(p_instance); + particles->collisions.erase(instance); } -void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_delta) { +void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) { if (p_particles->particles_material_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_particles->particles_material_uniform_set)) { Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(p_particles->frame_params_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(p_particles->particle_buffer); uniforms.push_back(u); @@ -3870,7 +3916,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; if (p_particles->emission_storage_buffer.is_valid()) { u.ids.push_back(p_particles->emission_storage_buffer); @@ -3881,7 +3927,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; Particles *sub_emitter = particles_owner.getornull(p_particles->sub_emitter); if (sub_emitter) { @@ -3918,7 +3964,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del p_particles->phase = new_phase; - frame_params.time = RasterizerRD::singleton->get_total_time(); + frame_params.time = RendererCompositorRD::singleton->get_total_time(); frame_params.delta = p_delta * p_particles->speed_scale; frame_params.random_seed = p_particles->random_seed; frame_params.explosiveness = p_particles->explosiveness; @@ -3946,7 +3992,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del to_particles = p_particles->emission_transform.affine_inverse(); } uint32_t collision_3d_textures_used = 0; - for (const Set<RasterizerScene::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) { + for (const Set<RendererSceneRender::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) { ParticlesCollision *pc = particles_collision_owner.getornull(E->get()->base); Transform to_collider = E->get()->transform; if (p_particles->use_local_coords) { @@ -4088,7 +4134,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; for (uint32_t i = 0; i < ParticlesFrameParams::MAX_3D_TEXTURES; i++) { RID rd_tex; @@ -4108,7 +4154,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; if (collision_heightmap_texture.is_valid()) { u.ids.push_back(collision_heightmap_texture); @@ -4188,7 +4234,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del RD::get_singleton()->compute_list_end(); } -void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &p_axis) { +void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &p_axis) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); @@ -4209,7 +4255,7 @@ void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3 { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(particles->particles_sort_buffer); uniforms.push_back(u); @@ -4254,7 +4300,7 @@ void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3 RD::get_singleton()->compute_list_end(); } -void RasterizerStorageRD::update_particles() { +void RendererStorageRD::update_particles() { while (particle_update_list) { //use transform feedback to process particles @@ -4289,7 +4335,7 @@ void RasterizerStorageRD::update_particles() { particles->inactive = false; particles->inactive_time = 0; } else { - particles->inactive_time += particles->speed_scale * RasterizerRD::singleton->get_frame_delta_time(); + particles->inactive_time += particles->speed_scale * RendererCompositorRD::singleton->get_frame_delta_time(); if (particles->inactive_time > particles->lifetime * 1.2) { particles->inactive = true; continue; @@ -4323,7 +4369,7 @@ void RasterizerStorageRD::update_particles() { frame_time = 1.0 / particles->fixed_fps; decr = frame_time; } - float delta = RasterizerRD::singleton->get_frame_delta_time(); + float delta = RendererCompositorRD::singleton->get_frame_delta_time(); if (delta > 0.1) { //avoid recursive stalls if fps goes below 10 delta = 0.1; } else if (delta <= 0.0) { //unlikely but.. @@ -4342,7 +4388,7 @@ void RasterizerStorageRD::update_particles() { if (zero_time_scale) _particles_process(particles, 0.0); else - _particles_process(particles, RasterizerRD::singleton->get_frame_delta_time()); + _particles_process(particles, RendererCompositorRD::singleton->get_frame_delta_time()); } //copy particles to instance buffer @@ -4365,7 +4411,7 @@ void RasterizerStorageRD::update_particles() { } } -bool RasterizerStorageRD::particles_is_inactive(RID p_particles) const { +bool RendererStorageRD::particles_is_inactive(RID p_particles) const { const Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, false); return !particles->emitting && particles->inactive; @@ -4373,7 +4419,7 @@ bool RasterizerStorageRD::particles_is_inactive(RID p_particles) const { /* SKY SHADER */ -void RasterizerStorageRD::ParticlesShaderData::set_code(const String &p_code) { +void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { //compile code = p_code; @@ -4421,7 +4467,7 @@ void RasterizerStorageRD::ParticlesShaderData::set_code(const String &p_code) { valid = true; } -void RasterizerStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { +void RendererStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) { if (!p_texture.is_valid()) { default_texture_params.erase(p_name); } else { @@ -4429,7 +4475,7 @@ void RasterizerStorageRD::ParticlesShaderData::set_default_texture_param(const S } } -void RasterizerStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RendererStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { @@ -4451,13 +4497,13 @@ void RasterizerStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> } } -void RasterizerStorageRD::ParticlesShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { +void RendererStorageRD::ParticlesShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - RasterizerStorage::InstanceShaderParam p; + RendererStorage::InstanceShaderParam p; p.info = ShaderLanguage::uniform_to_property_info(E->get()); p.info.name = E->key(); //supply name p.index = E->get().instance_index; @@ -4466,7 +4512,7 @@ void RasterizerStorageRD::ParticlesShaderData::get_instance_param_list(List<Rast } } -bool RasterizerStorageRD::ParticlesShaderData::is_param_texture(const StringName &p_param) const { +bool RendererStorageRD::ParticlesShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -4474,15 +4520,15 @@ bool RasterizerStorageRD::ParticlesShaderData::is_param_texture(const StringName return uniforms[p_param].texture_order >= 0; } -bool RasterizerStorageRD::ParticlesShaderData::is_animated() const { +bool RendererStorageRD::ParticlesShaderData::is_animated() const { return false; } -bool RasterizerStorageRD::ParticlesShaderData::casts_shadows() const { +bool RendererStorageRD::ParticlesShaderData::casts_shadows() const { return false; } -Variant RasterizerStorageRD::ParticlesShaderData::get_default_parameter(const StringName &p_parameter) const { +Variant RendererStorageRD::ParticlesShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; @@ -4491,23 +4537,23 @@ Variant RasterizerStorageRD::ParticlesShaderData::get_default_parameter(const St return Variant(); } -RasterizerStorageRD::ParticlesShaderData::ParticlesShaderData() { +RendererStorageRD::ParticlesShaderData::ParticlesShaderData() { valid = false; } -RasterizerStorageRD::ParticlesShaderData::~ParticlesShaderData() { +RendererStorageRD::ParticlesShaderData::~ParticlesShaderData() { //pipeline variants will clear themselves if shader is gone if (version.is_valid()) { base_singleton->particles_shader.shader.version_free(version); } } -RasterizerStorageRD::ShaderData *RasterizerStorageRD::_create_particles_shader_func() { +RendererStorageRD::ShaderData *RendererStorageRD::_create_particles_shader_func() { ParticlesShaderData *shader_data = memnew(ParticlesShaderData); return shader_data; } -void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +void RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { uniform_set_updated = true; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { @@ -4568,7 +4614,7 @@ void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<Str { if (shader_data->ubo_size) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; u.ids.push_back(uniform_buffer); uniforms.push_back(u); @@ -4577,7 +4623,7 @@ void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<Str const RID *textures = texture_cache.ptrw(); for (uint32_t i = 0; i < tex_uniform_count; i++) { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1 + i; u.ids.push_back(textures[i]); uniforms.push_back(u); @@ -4587,7 +4633,7 @@ void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<Str uniform_set = RD::get_singleton()->uniform_set_create(uniforms, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3); } -RasterizerStorageRD::ParticlesMaterialData::~ParticlesMaterialData() { +RendererStorageRD::ParticlesMaterialData::~ParticlesMaterialData() { if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { RD::get_singleton()->free(uniform_set); } @@ -4597,7 +4643,7 @@ RasterizerStorageRD::ParticlesMaterialData::~ParticlesMaterialData() { } } -RasterizerStorageRD::MaterialData *RasterizerStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) { +RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) { ParticlesMaterialData *material_data = memnew(ParticlesMaterialData); material_data->shader_data = p_shader; material_data->last_frame = false; @@ -4608,11 +4654,11 @@ RasterizerStorageRD::MaterialData *RasterizerStorageRD::_create_particles_materi /* PARTICLES COLLISION API */ -RID RasterizerStorageRD::particles_collision_create() { +RID RendererStorageRD::particles_collision_create() { return particles_collision_owner.make_rid(ParticlesCollision()); } -RID RasterizerStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { +RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, RID()); ERR_FAIL_COND_V(particles_collision->type != RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE, RID()); @@ -4633,7 +4679,7 @@ RID RasterizerStorageRD::particles_collision_get_heightfield_framebuffer(RID p_p tf.format = RD::DATA_FORMAT_D32_SFLOAT; tf.width = size.x; tf.height = size.y; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; particles_collision->heightfield_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -4647,7 +4693,7 @@ RID RasterizerStorageRD::particles_collision_get_heightfield_framebuffer(RID p_p return particles_collision->heightfield_fb; } -void RasterizerStorageRD::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) { +void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); @@ -4663,13 +4709,13 @@ void RasterizerStorageRD::particles_collision_set_collision_type(RID p_particles particles_collision->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { +void RendererStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->cull_mask = p_cull_mask; } -void RasterizerStorageRD::particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) { +void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); @@ -4677,7 +4723,7 @@ void RasterizerStorageRD::particles_collision_set_sphere_radius(RID p_particles_ particles_collision->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { +void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); @@ -4685,41 +4731,41 @@ void RasterizerStorageRD::particles_collision_set_box_extents(RID p_particles_co particles_collision->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) { +void RendererStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->attractor_strength = p_strength; } -void RasterizerStorageRD::particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) { +void RendererStorageRD::particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->attractor_directionality = p_directionality; } -void RasterizerStorageRD::particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) { +void RendererStorageRD::particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->attractor_attenuation = p_curve; } -void RasterizerStorageRD::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) { +void RendererStorageRD::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->field_texture = p_texture; } -void RasterizerStorageRD::particles_collision_height_field_update(RID p_particles_collision) { +void RendererStorageRD::particles_collision_height_field_update(RID p_particles_collision) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { +void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); @@ -4735,7 +4781,7 @@ void RasterizerStorageRD::particles_collision_set_height_field_resolution(RID p_ } } -AABB RasterizerStorageRD::particles_collision_get_aabb(RID p_particles_collision) const { +AABB RendererStorageRD::particles_collision_get_aabb(RID p_particles_collision) const { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, AABB()); @@ -4758,13 +4804,13 @@ AABB RasterizerStorageRD::particles_collision_get_aabb(RID p_particles_collision return AABB(); } -Vector3 RasterizerStorageRD::particles_collision_get_extents(RID p_particles_collision) const { +Vector3 RendererStorageRD::particles_collision_get_extents(RID p_particles_collision) const { const ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, Vector3()); return particles_collision->extents; } -bool RasterizerStorageRD::particles_collision_is_heightfield(RID p_particles_collision) const { +bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_collision) const { const ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, false); return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE; @@ -4772,11 +4818,11 @@ bool RasterizerStorageRD::particles_collision_is_heightfield(RID p_particles_col /* SKELETON API */ -RID RasterizerStorageRD::skeleton_create() { +RID RendererStorageRD::skeleton_create() { return skeleton_owner.make_rid(Skeleton()); } -void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { +void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { if (!skeleton->dirty) { skeleton->dirty = true; skeleton->dirty_list = skeleton_dirty_list; @@ -4784,7 +4830,7 @@ void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { } } -void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { +void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_COND(p_bones < 0); @@ -4812,14 +4858,14 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_ } } -int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { +int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, 0); return skeleton->size; } -void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { +void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -4844,7 +4890,7 @@ void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone _skeleton_make_dirty(skeleton); } -Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { +Transform RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform()); @@ -4871,7 +4917,7 @@ Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p return t; } -void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { +void RendererStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -4892,7 +4938,7 @@ void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_b _skeleton_make_dirty(skeleton); } -Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { +Transform2D RendererStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform2D()); @@ -4912,7 +4958,7 @@ Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, return t; } -void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { +void RendererStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton->use_2d); @@ -4920,7 +4966,7 @@ void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const T skeleton->base_transform_2d = p_base_transform; } -void RasterizerStorageRD::_update_dirty_skeletons() { +void RendererStorageRD::_update_dirty_skeletons() { while (skeleton_dirty_list) { Skeleton *skeleton = skeleton_dirty_list; @@ -4941,7 +4987,7 @@ void RasterizerStorageRD::_update_dirty_skeletons() { /* LIGHT */ -RID RasterizerStorageRD::light_create(RS::LightType p_type) { +RID RendererStorageRD::light_create(RS::LightType p_type) { Light light; light.type = p_type; @@ -4965,14 +5011,14 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) { return light_owner.make_rid(light); } -void RasterizerStorageRD::light_set_color(RID p_light, const Color &p_color) { +void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->color = p_color; } -void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { +void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX); @@ -4997,7 +5043,7 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f light->param[p_param] = p_value; } -void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { +void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->shadow = p_enabled; @@ -5006,13 +5052,13 @@ void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { +void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->shadow_color = p_color; } -void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { +void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5031,14 +5077,14 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { } } -void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) { +void RendererStorageRD::light_set_negative(RID p_light, bool p_enable) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->negative = p_enable; } -void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { +void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5048,7 +5094,7 @@ void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { +void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5058,7 +5104,7 @@ void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_e light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { +void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5068,7 +5114,7 @@ void RasterizerStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_b light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { +void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5078,7 +5124,7 @@ void RasterizerStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_ca light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { +void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5088,14 +5134,14 @@ void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniS light->instance_dependency.instance_notify_changed(true, false); } -RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_light) { +RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE); return light->omni_shadow_mode; } -void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { +void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5104,7 +5150,7 @@ void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Lig light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) { +void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -5113,70 +5159,70 @@ void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p light->instance_dependency.instance_notify_changed(true, false); } -bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const { +bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, false); return light->directional_blend_splits; } -void RasterizerStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) { +void RendererStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->directional_sky_only = p_sky_only; } -bool RasterizerStorageRD::light_directional_is_sky_only(RID p_light) const { +bool RendererStorageRD::light_directional_is_sky_only(RID p_light) const { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, false); return light->directional_sky_only; } -RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) { +RS::LightDirectionalShadowMode RendererStorageRD::light_directional_get_shadow_mode(RID p_light) { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL); return light->directional_shadow_mode; } -void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) { +void RendererStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->directional_range_mode = p_range_mode; } -RS::LightDirectionalShadowDepthRangeMode RasterizerStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const { +RS::LightDirectionalShadowDepthRangeMode RendererStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE); return light->directional_range_mode; } -uint32_t RasterizerStorageRD::light_get_max_sdfgi_cascade(RID p_light) { +uint32_t RendererStorageRD::light_get_max_sdfgi_cascade(RID p_light) { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); return light->max_sdfgi_cascade; } -RS::LightBakeMode RasterizerStorageRD::light_get_bake_mode(RID p_light) { +RS::LightBakeMode RendererStorageRD::light_get_bake_mode(RID p_light) { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_BAKE_DISABLED); return light->bake_mode; } -uint64_t RasterizerStorageRD::light_get_version(RID p_light) const { +uint64_t RendererStorageRD::light_get_version(RID p_light) const { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); return light->version; } -AABB RasterizerStorageRD::light_get_aabb(RID p_light) const { +AABB RendererStorageRD::light_get_aabb(RID p_light) const { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, AABB()); @@ -5200,11 +5246,11 @@ AABB RasterizerStorageRD::light_get_aabb(RID p_light) const { /* REFLECTION PROBE */ -RID RasterizerStorageRD::reflection_probe_create() { +RID RendererStorageRD::reflection_probe_create() { return reflection_probe_owner.make_rid(ReflectionProbe()); } -void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { +void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5212,35 +5258,35 @@ void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Refl reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) { +void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->intensity = p_intensity; } -void RasterizerStorageRD::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) { +void RendererStorageRD::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->ambient_mode = p_mode; } -void RasterizerStorageRD::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) { +void RendererStorageRD::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->ambient_color = p_color; } -void RasterizerStorageRD::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) { +void RendererStorageRD::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->ambient_color_energy = p_energy; } -void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) { +void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5249,7 +5295,7 @@ void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { +void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5260,7 +5306,7 @@ void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { +void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5268,7 +5314,7 @@ void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { +void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5276,14 +5322,14 @@ void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_e reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { +void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->box_projection = p_enable; } -void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { +void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5291,7 +5337,7 @@ void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { +void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -5299,7 +5345,7 @@ void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) { +void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); ERR_FAIL_COND(p_resolution < 32); @@ -5307,7 +5353,7 @@ void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_res reflection_probe->resolution = p_resolution; } -AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const { +AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, AABB()); @@ -5318,107 +5364,107 @@ AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const { return aabb; } -RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const { +RS::ReflectionProbeUpdateMode RendererStorageRD::reflection_probe_get_update_mode(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS); return reflection_probe->update_mode; } -uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const { +uint32_t RendererStorageRD::reflection_probe_get_cull_mask(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->cull_mask; } -Vector3 RasterizerStorageRD::reflection_probe_get_extents(RID p_probe) const { +Vector3 RendererStorageRD::reflection_probe_get_extents(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); return reflection_probe->extents; } -Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { +Vector3 RendererStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); return reflection_probe->origin_offset; } -bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const { +bool RendererStorageRD::reflection_probe_renders_shadows(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->enable_shadows; } -float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const { +float RendererStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->max_distance; } -int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const { +int RendererStorageRD::reflection_probe_get_resolution(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->resolution; } -float RasterizerStorageRD::reflection_probe_get_intensity(RID p_probe) const { +float RendererStorageRD::reflection_probe_get_intensity(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->intensity; } -bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const { +bool RendererStorageRD::reflection_probe_is_interior(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->interior; } -bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const { +bool RendererStorageRD::reflection_probe_is_box_projection(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->box_projection; } -RS::ReflectionProbeAmbientMode RasterizerStorageRD::reflection_probe_get_ambient_mode(RID p_probe) const { +RS::ReflectionProbeAmbientMode RendererStorageRD::reflection_probe_get_ambient_mode(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_AMBIENT_DISABLED); return reflection_probe->ambient_mode; } -Color RasterizerStorageRD::reflection_probe_get_ambient_color(RID p_probe) const { +Color RendererStorageRD::reflection_probe_get_ambient_color(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Color()); return reflection_probe->ambient_color; } -float RasterizerStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) const { +float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->ambient_color_energy; } -RID RasterizerStorageRD::decal_create() { +RID RendererStorageRD::decal_create() { return decal_owner.make_rid(Decal()); } -void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) { +void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->extents = p_extents; decal->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { +void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX); @@ -5442,32 +5488,32 @@ void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type decal->instance_dependency.instance_notify_changed(false, true); } -void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { +void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->emission_energy = p_energy; } -void RasterizerStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) { +void RendererStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->albedo_mix = p_mix; } -void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) { +void RendererStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->modulate = p_modulate; } -void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { +void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->cull_mask = p_layers; decal->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { +void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->distance_fade = p_enabled; @@ -5475,31 +5521,31 @@ void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, f decal->distance_fade_length = p_length; } -void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) { +void RendererStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->upper_fade = p_above; decal->lower_fade = p_below; } -void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) { +void RendererStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->normal_fade = p_fade; } -AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const { +AABB RendererStorageRD::decal_get_aabb(RID p_decal) const { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND_V(!decal, AABB()); return AABB(-decal->extents, decal->extents * 2.0); } -RID RasterizerStorageRD::gi_probe_create() { +RID RendererStorageRD::gi_probe_create() { return gi_probe_owner.make_rid(GIProbe()); } -void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { +void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -5542,7 +5588,7 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t tf.width = gi_probe->octree_size.x; tf.height = gi_probe->octree_size.y; tf.depth = gi_probe->octree_size.z; - tf.type = RD::TEXTURE_TYPE_3D; + tf.texture_type = RD::TEXTURE_TYPE_3D; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; Vector<Vector<uint8_t>> s; s.push_back(p_distance_field); @@ -5571,21 +5617,21 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; u.ids.push_back(gi_probe->octree_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; u.ids.push_back(gi_probe->data_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; u.ids.push_back(shared_tex); uniforms.push_back(u); @@ -5624,20 +5670,20 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t gi_probe->instance_dependency.instance_notify_changed(true, false); } -AABB RasterizerStorageRD::gi_probe_get_bounds(RID p_gi_probe) const { +AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, AABB()); return gi_probe->bounds; } -Vector3i RasterizerStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const { +Vector3i RendererStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector3i()); return gi_probe->octree_size; } -Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const { +Vector<uint8_t> RendererStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -5647,7 +5693,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) c return Vector<uint8_t>(); } -Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const { +Vector<uint8_t> RendererStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -5657,7 +5703,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) con return Vector<uint8_t>(); } -Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const { +Vector<uint8_t> RendererStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -5667,21 +5713,21 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) return Vector<uint8_t>(); } -Vector<int> RasterizerStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const { +Vector<int> RendererStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<int>()); return gi_probe->level_counts; } -Transform RasterizerStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const { +Transform RendererStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Transform()); return gi_probe->to_cell_xform; } -void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) { +void RendererStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -5689,14 +5735,14 @@ void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_ran gi_probe->version++; } -float RasterizerStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->dynamic_range; } -void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range) { +void RendererStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -5704,98 +5750,98 @@ void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range gi_probe->version++; } -float RasterizerStorageRD::gi_probe_get_propagation(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_propagation(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->propagation; } -void RasterizerStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) { +void RendererStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->energy = p_energy; } -float RasterizerStorageRD::gi_probe_get_energy(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_energy(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->energy; } -void RasterizerStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) { +void RendererStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->ao = p_ao; } -float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_ao(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->ao; } -void RasterizerStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) { +void RendererStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->ao_size = p_strength; } -float RasterizerStorageRD::gi_probe_get_ao_size(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_ao_size(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->ao_size; } -void RasterizerStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) { +void RendererStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->bias = p_bias; } -float RasterizerStorageRD::gi_probe_get_bias(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_bias(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->bias; } -void RasterizerStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_normal_bias) { +void RendererStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_normal_bias) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->normal_bias = p_normal_bias; } -float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->normal_bias; } -void RasterizerStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) { +void RendererStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->anisotropy_strength = p_strength; } -float RasterizerStorageRD::gi_probe_get_anisotropy_strength(RID p_gi_probe) const { +float RendererStorageRD::gi_probe_get_anisotropy_strength(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->anisotropy_strength; } -void RasterizerStorageRD::gi_probe_set_interior(RID p_gi_probe, bool p_enable) { +void RendererStorageRD::gi_probe_set_interior(RID p_gi_probe, bool p_enable) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); gi_probe->interior = p_enable; } -void RasterizerStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) { +void RendererStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -5803,43 +5849,43 @@ void RasterizerStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_en gi_probe->version++; } -bool RasterizerStorageRD::gi_probe_is_using_two_bounces(RID p_gi_probe) const { +bool RendererStorageRD::gi_probe_is_using_two_bounces(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, false); return gi_probe->use_two_bounces; } -bool RasterizerStorageRD::gi_probe_is_interior(RID p_gi_probe) const { +bool RendererStorageRD::gi_probe_is_interior(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->interior; } -uint32_t RasterizerStorageRD::gi_probe_get_version(RID p_gi_probe) { +uint32_t RendererStorageRD::gi_probe_get_version(RID p_gi_probe) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->version; } -uint32_t RasterizerStorageRD::gi_probe_get_data_version(RID p_gi_probe) { +uint32_t RendererStorageRD::gi_probe_get_data_version(RID p_gi_probe) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); return gi_probe->data_version; } -RID RasterizerStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const { +RID RendererStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); return gi_probe->octree_buffer; } -RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { +RID RendererStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); return gi_probe->data_buffer; } -RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { +RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); @@ -5848,11 +5894,11 @@ RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { /* LIGHTMAP API */ -RID RasterizerStorageRD::lightmap_create() { +RID RendererStorageRD::lightmap_create() { return lightmap_owner.make_rid(Lightmap()); } -void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { +void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND(!lm); @@ -5900,19 +5946,19 @@ void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, boo } } -void RasterizerStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { +void RendererStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND(!lm); lm->bounds = p_bounds; } -void RasterizerStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { +void RendererStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND(!lm); lm->interior = p_interior; } -void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { +void RendererStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND(!lm); @@ -5928,36 +5974,36 @@ void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const lm->tetrahedra = p_tetrahedra; } -PackedVector3Array RasterizerStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const { +PackedVector3Array RendererStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND_V(!lm, PackedVector3Array()); return lm->points; } -PackedColorArray RasterizerStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const { +PackedColorArray RendererStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND_V(!lm, PackedColorArray()); return lm->point_sh; } -PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { +PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND_V(!lm, PackedInt32Array()); return lm->tetrahedra; } -PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { +PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND_V(!lm, PackedInt32Array()); return lm->bsp_tree; } -void RasterizerStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) { +void RendererStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) { lightmap_probe_capture_update_speed = p_speed; } -void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { +void RendererStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND(!lm); @@ -6007,13 +6053,13 @@ void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p } } -bool RasterizerStorageRD::lightmap_is_interior(RID p_lightmap) const { +bool RendererStorageRD::lightmap_is_interior(RID p_lightmap) const { const Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND_V(!lm, false); return lm->interior; } -AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const { +AABB RendererStorageRD::lightmap_get_aabb(RID p_lightmap) const { const Lightmap *lm = lightmap_owner.getornull(p_lightmap); ERR_FAIL_COND_V(!lm, AABB()); return lm->bounds; @@ -6021,7 +6067,7 @@ AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const { /* RENDER TARGET API */ -void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { +void RendererStorageRD::_clear_render_target(RenderTarget *rt) { //free in reverse dependency order if (rt->framebuffer.is_valid()) { RD::get_singleton()->free(rt->framebuffer); @@ -6049,7 +6095,7 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { rt->color = RID(); } -void RasterizerStorageRD::_update_render_target(RenderTarget *rt) { +void RendererStorageRD::_update_render_target(RenderTarget *rt) { if (rt->texture.is_null()) { //create a placeholder until updated rt->texture = texture_2d_placeholder_create(); @@ -6076,7 +6122,7 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) { rd_format.depth = 1; rd_format.array_layers = 1; rd_format.mipmaps = 1; - rd_format.type = RD::TEXTURE_TYPE_2D; + rd_format.texture_type = RD::TEXTURE_TYPE_2D; rd_format.samples = RD::TEXTURE_SAMPLES_1; rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; rd_format.shareable_formats.push_back(rt->color_format); @@ -6137,7 +6183,7 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) { } } -void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { +void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { ERR_FAIL_COND(rt->backbuffer.is_valid()); uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8); @@ -6145,7 +6191,7 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { tf.format = rt->color_format; tf.width = rt->size.width; tf.height = rt->size.height; - tf.type = RD::TEXTURE_TYPE_2D; + tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.mipmaps = mipmaps_required; @@ -6185,7 +6231,7 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { } } -RID RasterizerStorageRD::render_target_create() { +RID RendererStorageRD::render_target_create() { RenderTarget render_target; render_target.was_used = false; @@ -6198,11 +6244,11 @@ RID RasterizerStorageRD::render_target_create() { return render_target_owner.make_rid(render_target); } -void RasterizerStorageRD::render_target_set_position(RID p_render_target, int p_x, int p_y) { +void RendererStorageRD::render_target_set_position(RID p_render_target, int p_x, int p_y) { //unused for this render target } -void RasterizerStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height) { +void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->size.x = p_width; @@ -6210,63 +6256,63 @@ void RasterizerStorageRD::render_target_set_size(RID p_render_target, int p_widt _update_render_target(rt); } -RID RasterizerStorageRD::render_target_get_texture(RID p_render_target) { +RID RendererStorageRD::render_target_get_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->texture; } -void RasterizerStorageRD::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { +void RendererStorageRD::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { } -void RasterizerStorageRD::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { +void RendererStorageRD::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->flags[p_flag] = p_value; _update_render_target(rt); } -bool RasterizerStorageRD::render_target_was_used(RID p_render_target) { +bool RendererStorageRD::render_target_was_used(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->was_used; } -void RasterizerStorageRD::render_target_set_as_unused(RID p_render_target) { +void RendererStorageRD::render_target_set_as_unused(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->was_used = false; } -Size2 RasterizerStorageRD::render_target_get_size(RID p_render_target) { +Size2 RendererStorageRD::render_target_get_size(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, Size2()); return rt->size; } -RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) { +RID RendererStorageRD::render_target_get_rd_framebuffer(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->framebuffer; } -RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) { +RID RendererStorageRD::render_target_get_rd_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->color; } -RID RasterizerStorageRD::render_target_get_rd_backbuffer(RID p_render_target) { +RID RendererStorageRD::render_target_get_rd_backbuffer(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->backbuffer; } -RID RasterizerStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) { +RID RendererStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); @@ -6277,32 +6323,32 @@ RID RasterizerStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_rende return rt->backbuffer_fb; } -void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { +void RendererStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = true; rt->clear_color = p_clear_color; } -bool RasterizerStorageRD::render_target_is_clear_requested(RID p_render_target) { +bool RendererStorageRD::render_target_is_clear_requested(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->clear_requested; } -Color RasterizerStorageRD::render_target_get_clear_request_color(RID p_render_target) { +Color RendererStorageRD::render_target_get_clear_request_color(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, Color()); return rt->clear_color; } -void RasterizerStorageRD::render_target_disable_clear_request(RID p_render_target) { +void RendererStorageRD::render_target_disable_clear_request(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = false; } -void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) { +void RendererStorageRD::render_target_do_clear_request(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (!rt->clear_requested) { @@ -6315,7 +6361,7 @@ void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) { rt->clear_requested = false; } -void RasterizerStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { +void RendererStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) { @@ -6328,7 +6374,7 @@ void RasterizerStorageRD::render_target_set_sdf_size_and_scale(RID p_render_targ _render_target_clear_sdf(rt); } -Rect2i RasterizerStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) const { +Rect2i RendererStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) const { Size2i margin; int scale; switch (rt->sdf_oversize) { @@ -6357,14 +6403,14 @@ Rect2i RasterizerStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) return r; } -Rect2i RasterizerStorageRD::render_target_get_sdf_rect(RID p_render_target) const { +Rect2i RendererStorageRD::render_target_get_sdf_rect(RID p_render_target) const { const RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, Rect2i()); return _render_target_get_sdf_rect(rt); } -RID RasterizerStorageRD::render_target_get_sdf_texture(RID p_render_target) { +RID RendererStorageRD::render_target_get_sdf_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); if (rt->sdf_buffer_read.is_null()) { @@ -6374,7 +6420,7 @@ RID RasterizerStorageRD::render_target_get_sdf_texture(RID p_render_target) { tformat.width = 4; tformat.height = 4; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; - tformat.type = RD::TEXTURE_TYPE_2D; + tformat.texture_type = RD::TEXTURE_TYPE_2D; Vector<uint8_t> pv; pv.resize(16 * 4); @@ -6387,7 +6433,7 @@ RID RasterizerStorageRD::render_target_get_sdf_texture(RID p_render_target) { return rt->sdf_buffer_read; } -void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { +void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_valid()); if (rt->sdf_buffer_read.is_valid()) { RD::get_singleton()->free(rt->sdf_buffer_read); @@ -6401,7 +6447,7 @@ void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { tformat.width = size.width; tformat.height = size.height; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - tformat.type = RD::TEXTURE_TYPE_2D; + tformat.texture_type = RD::TEXTURE_TYPE_2D; rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView()); @@ -6448,28 +6494,28 @@ void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; u.ids.push_back(rt->sdf_buffer_write); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; u.ids.push_back(rt->sdf_buffer_read); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; u.ids.push_back(rt->sdf_buffer_process[0]); uniforms.push_back(u); } { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_IMAGE; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; u.ids.push_back(rt->sdf_buffer_process[1]); uniforms.push_back(u); @@ -6481,7 +6527,7 @@ void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { } } -void RasterizerStorageRD::_render_target_clear_sdf(RenderTarget *rt) { +void RendererStorageRD::_render_target_clear_sdf(RenderTarget *rt) { if (rt->sdf_buffer_read.is_valid()) { RD::get_singleton()->free(rt->sdf_buffer_read); rt->sdf_buffer_read = RID(); @@ -6499,7 +6545,7 @@ void RasterizerStorageRD::_render_target_clear_sdf(RenderTarget *rt) { } } -RID RasterizerStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) { +RID RendererStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); @@ -6509,7 +6555,7 @@ RID RasterizerStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) return rt->sdf_buffer_write_fb; } -void RasterizerStorageRD::render_target_sdf_process(RID p_render_target) { +void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null()); @@ -6584,7 +6630,7 @@ void RasterizerStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_end(); } -void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) { +void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (!rt->backbuffer.is_valid()) { @@ -6624,7 +6670,7 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target, } } -void RasterizerStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) { +void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (!rt->backbuffer.is_valid()) { @@ -6645,7 +6691,7 @@ void RasterizerStorageRD::render_target_clear_back_buffer(RID p_render_target, c effects.set_color(rt->backbuffer_mipmap0, p_color, region, true); } -void RasterizerStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) { +void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (!rt->backbuffer.is_valid()) { @@ -6677,29 +6723,29 @@ void RasterizerStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_tar } } -RID RasterizerStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) { +RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->framebuffer_uniform_set; } -RID RasterizerStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) { +RID RendererStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->backbuffer_uniform_set; } -void RasterizerStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) { +void RendererStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->framebuffer_uniform_set = p_uniform_set; } -void RasterizerStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) { +void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->backbuffer_uniform_set = p_uniform_set; } -void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) { +void RendererStorageRD::base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) { if (mesh_owner.owns(p_base)) { Mesh *mesh = mesh_owner.getornull(p_base); p_instance->update_dependency(&mesh->instance_dependency); @@ -6733,14 +6779,14 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In } } -void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { +void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); p_instance->update_dependency(&skeleton->instance_dependency); } -RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { +RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const { if (mesh_owner.owns(p_rid)) { return RS::INSTANCE_MESH; } @@ -6772,7 +6818,7 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { return RS::INSTANCE_NONE; } -void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) { +void RendererStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) { if (!decal_atlas.textures.has(p_texture)) { DecalAtlas::Texture t; t.users = 1; @@ -6788,7 +6834,7 @@ void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panor } } -void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) { +void RendererStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture); ERR_FAIL_COND(!t); t->users--; @@ -6802,15 +6848,15 @@ void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_ } } -RID RasterizerStorageRD::decal_atlas_get_texture() const { +RID RendererStorageRD::decal_atlas_get_texture() const { return decal_atlas.texture; } -RID RasterizerStorageRD::decal_atlas_get_texture_srgb() const { +RID RendererStorageRD::decal_atlas_get_texture_srgb() const { return decal_atlas.texture_srgb; } -void RasterizerStorageRD::_update_decal_atlas() { +void RendererStorageRD::_update_decal_atlas() { if (!decal_atlas.dirty) { return; //nothing to do } @@ -6937,7 +6983,7 @@ void RasterizerStorageRD::_update_decal_atlas() { tformat.width = decal_atlas.size.width; tformat.height = decal_atlas.size.height; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; - tformat.type = RD::TEXTURE_TYPE_2D; + tformat.texture_type = RD::TEXTURE_TYPE_2D; tformat.mipmaps = decal_atlas.mipmaps; tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM); tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB); @@ -7002,7 +7048,7 @@ void RasterizerStorageRD::_update_decal_atlas() { } } -int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { +int32_t RendererStorageRD::_global_variable_allocate(uint32_t p_elements) { int32_t idx = 0; while (idx + p_elements <= global_variables.buffer_size) { if (global_variables.buffer_usage[idx].elements == 0) { @@ -7028,7 +7074,7 @@ int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { return -1; } -void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { +void RendererStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; @@ -7305,7 +7351,7 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } } -void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { +void RendererStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { @@ -7321,7 +7367,7 @@ void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, in } } -void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { +void RendererStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { ERR_FAIL_COND(global_variables.variables.has(p_name)); GlobalVariables::Variable gv; gv.type = p_type; @@ -7359,7 +7405,7 @@ void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::Glob global_variables.variables[p_name] = gv; } -void RasterizerStorageRD::global_variable_remove(const StringName &p_name) { +void RendererStorageRD::global_variable_remove(const StringName &p_name) { if (!global_variables.variables.has(p_name)) { return; } @@ -7375,7 +7421,7 @@ void RasterizerStorageRD::global_variable_remove(const StringName &p_name) { global_variables.variables.erase(p_name); } -Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { +Vector<StringName> RendererStorageRD::global_variable_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -7389,7 +7435,7 @@ Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { return names; } -void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Variant &p_value) { +void RendererStorageRD::global_variable_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND(!global_variables.variables.has(p_name)); GlobalVariables::Variable &gv = global_variables.variables[p_name]; gv.value = p_value; @@ -7409,7 +7455,7 @@ void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Va } } -void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) { +void RendererStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) { if (!global_variables.variables.has(p_name)) { return; //variable may not exist } @@ -7437,7 +7483,7 @@ void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, } } -Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const { +Variant RendererStorageRD::global_variable_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -7449,7 +7495,7 @@ Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const return global_variables.variables[p_name].value; } -RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const { +RS::GlobalVariableType RendererStorageRD::global_variable_get_type_internal(const StringName &p_name) const { if (!global_variables.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } @@ -7457,7 +7503,7 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(co return global_variables.variables[p_name].type; } -RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const StringName &p_name) const { +RS::GlobalVariableType RendererStorageRD::global_variable_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } @@ -7465,7 +7511,7 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const Strin return global_variable_get_type_internal(p_name); } -void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) { +void RendererStorageRD::global_variables_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -7546,15 +7592,15 @@ void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) { } } -void RasterizerStorageRD::global_variables_clear() { +void RendererStorageRD::global_variables_clear() { global_variables.variables.clear(); //not right but for now enough } -RID RasterizerStorageRD::global_variables_get_storage_buffer() const { +RID RendererStorageRD::global_variables_get_storage_buffer() const { return global_variables.buffer; } -int32_t RasterizerStorageRD::global_variables_instance_allocate(RID p_instance) { +int32_t RendererStorageRD::global_variables_instance_allocate(RID p_instance) { ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1); int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); global_variables.instance_buffer_pos[p_instance] = pos; //save anyway @@ -7563,7 +7609,7 @@ int32_t RasterizerStorageRD::global_variables_instance_allocate(RID p_instance) return pos; } -void RasterizerStorageRD::global_variables_instance_free(RID p_instance) { +void RendererStorageRD::global_variables_instance_free(RID p_instance) { ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance)); int32_t pos = global_variables.instance_buffer_pos[p_instance]; if (pos >= 0) { @@ -7572,7 +7618,7 @@ void RasterizerStorageRD::global_variables_instance_free(RID p_instance) { global_variables.instance_buffer_pos.erase(p_instance); } -void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void RendererStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { if (!global_variables.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -7615,7 +7661,7 @@ void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p _global_variable_mark_buffer_dirty(pos, 1); } -void RasterizerStorageRD::_update_global_variables() { +void RendererStorageRD::_update_global_variables() { if (global_variables.buffer_dirty_region_count > 0) { uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; if (total_regions / global_variables.buffer_dirty_region_count <= 4) { @@ -7665,7 +7711,7 @@ void RasterizerStorageRD::_update_global_variables() { } } -void RasterizerStorageRD::update_dirty_resources() { +void RendererStorageRD::update_dirty_resources() { _update_global_variables(); //must do before materials, so it can queue them for update _update_queued_materials(); _update_dirty_multimeshes(); @@ -7673,7 +7719,7 @@ void RasterizerStorageRD::update_dirty_resources() { _update_decal_atlas(); } -bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { +bool RendererStorageRD::has_os_feature(const String &p_feature) const { if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { return true; } @@ -7697,7 +7743,7 @@ bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { return false; } -bool RasterizerStorageRD::free(RID p_rid) { +bool RendererStorageRD::free(RID p_rid) { if (texture_owner.owns(p_rid)) { Texture *t = texture_owner.getornull(p_rid); @@ -7840,41 +7886,41 @@ bool RasterizerStorageRD::free(RID p_rid) { return true; } -RasterizerEffectsRD *RasterizerStorageRD::get_effects() { +EffectsRD *RendererStorageRD::get_effects() { return &effects; } -void RasterizerStorageRD::capture_timestamps_begin() { +void RendererStorageRD::capture_timestamps_begin() { RD::get_singleton()->capture_timestamp("Frame Begin", false); } -void RasterizerStorageRD::capture_timestamp(const String &p_name) { +void RendererStorageRD::capture_timestamp(const String &p_name) { RD::get_singleton()->capture_timestamp(p_name, true); } -uint32_t RasterizerStorageRD::get_captured_timestamps_count() const { +uint32_t RendererStorageRD::get_captured_timestamps_count() const { return RD::get_singleton()->get_captured_timestamps_count(); } -uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const { +uint64_t RendererStorageRD::get_captured_timestamps_frame() const { return RD::get_singleton()->get_captured_timestamps_frame(); } -uint64_t RasterizerStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const { +uint64_t RendererStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index); } -uint64_t RasterizerStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const { +uint64_t RendererStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index); } -String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const { +String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_name(p_index); } -RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr; +RendererStorageRD *RendererStorageRD::base_singleton = nullptr; -RasterizerStorageRD::RasterizerStorageRD() { +RendererStorageRD::RendererStorageRD() { base_singleton = this; for (int i = 0; i < SHADER_TYPE_MAX; i++) { @@ -7900,7 +7946,7 @@ RasterizerStorageRD::RasterizerStorageRD() { tformat.width = 4; tformat.height = 4; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.type = RD::TEXTURE_TYPE_2D; + tformat.texture_type = RD::TEXTURE_TYPE_2D; Vector<uint8_t> pv; pv.resize(16 * 4); @@ -7992,7 +8038,7 @@ RasterizerStorageRD::RasterizerStorageRD() { tformat.height = 4; tformat.array_layers = 6; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.type = RD::TEXTURE_TYPE_CUBE_ARRAY; + tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY; Vector<uint8_t> pv; pv.resize(16 * 4); @@ -8020,7 +8066,7 @@ RasterizerStorageRD::RasterizerStorageRD() { tformat.height = 4; tformat.array_layers = 6; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.type = RD::TEXTURE_TYPE_CUBE; + tformat.texture_type = RD::TEXTURE_TYPE_CUBE; Vector<uint8_t> pv; pv.resize(16 * 4); @@ -8048,7 +8094,7 @@ RasterizerStorageRD::RasterizerStorageRD() { tformat.height = 4; tformat.array_layers = 6; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.type = RD::TEXTURE_TYPE_CUBE; + tformat.texture_type = RD::TEXTURE_TYPE_CUBE; Vector<uint8_t> pv; pv.resize(16 * 4); @@ -8076,7 +8122,7 @@ RasterizerStorageRD::RasterizerStorageRD() { tformat.height = 4; tformat.depth = 4; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.type = RD::TEXTURE_TYPE_3D; + tformat.texture_type = RD::TEXTURE_TYPE_3D; Vector<uint8_t> pv; pv.resize(64 * 4); @@ -8102,7 +8148,7 @@ RasterizerStorageRD::RasterizerStorageRD() { tformat.height = 4; tformat.array_layers = 1; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.type = RD::TEXTURE_TYPE_2D_ARRAY; + tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; Vector<uint8_t> pv; pv.resize(16 * 4); @@ -8263,6 +8309,19 @@ RasterizerStorageRD::RasterizerStorageRD() { mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); } + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + fptr[3] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_CUSTOM0 + i] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } + { //bones buffer.resize(sizeof(uint32_t) * 4); { @@ -8325,8 +8384,8 @@ RasterizerStorageRD::RasterizerStorageRD() { particles_modes.push_back(""); particles_shader.shader.initialize(particles_modes, String()); } - shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_PARTICLES, _create_particles_shader_funcs); - material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs); + shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_shader_funcs); + material_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs); { ShaderCompilerRD::DefaultIdentifierActions actions; @@ -8387,14 +8446,14 @@ RasterizerStorageRD::RasterizerStorageRD() { particles_shader.default_material = material_create(); material_set_shader(particles_shader.default_material, particles_shader.default_shader); - ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RasterizerStorageRD::SHADER_TYPE_PARTICLES); + ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RendererStorageRD::SHADER_TYPE_PARTICLES); particles_shader.default_shader_rd = particles_shader.shader.version_get_shader(md->shader_data->version, 0); Vector<RD::Uniform> uniforms; { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_SAMPLER; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; u.ids.resize(12); RID *ids_ptr = u.ids.ptrw(); @@ -8415,7 +8474,7 @@ RasterizerStorageRD::RasterizerStorageRD() { { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; u.ids.push_back(global_variables_get_storage_buffer()); uniforms.push_back(u); @@ -8460,7 +8519,7 @@ RasterizerStorageRD::RasterizerStorageRD() { } } -RasterizerStorageRD::~RasterizerStorageRD() { +RendererStorageRD::~RendererStorageRD() { memdelete_arr(global_variables.buffer_values); memdelete_arr(global_variables.buffer_usage); memdelete_arr(global_variables.buffer_dirty_regions); @@ -8485,6 +8544,7 @@ RasterizerStorageRD::~RasterizerStorageRD() { giprobe_sdf_shader.version_free(giprobe_sdf_shader_version); particles_shader.copy_shader.version_free(particles_shader.copy_shader_version); + rt_sdf.shader.version_free(rt_sdf.shader_version); RenderingServer::get_singleton()->free(particles_shader.default_material); RenderingServer::get_singleton()->free(particles_shader.default_shader); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 42dd0616b0..b6a26fc9d0 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_storage_rd.h */ +/* renderer_storage_rd.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_STORAGE_RD_H -#define RASTERIZER_STORAGE_RD_H +#ifndef RENDERING_SERVER_STORAGE_RD_H +#define RENDERING_SERVER_STORAGE_RD_H #include "core/templates/rid_owner.h" -#include "servers/rendering/rasterizer.h" -#include "servers/rendering/rasterizer_rd/rasterizer_effects_rd.h" -#include "servers/rendering/rasterizer_rd/shader_compiler_rd.h" -#include "servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/particles.glsl.gen.h" -#include "servers/rendering/rasterizer_rd/shaders/particles_copy.glsl.gen.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/effects_rd.h" +#include "servers/rendering/renderer_rd/shader_compiler_rd.h" +#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h" +#include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" -class RasterizerStorageRD : public RasterizerStorage { +class RendererStorageRD : public RendererStorage { public: static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_array) { p_array[0] = p_mtx.basis.elements[0][0]; @@ -139,7 +140,7 @@ public: virtual ~MaterialData(); private: - friend class RasterizerStorageRD; + friend class RendererStorageRD; RID self; List<RID>::Element *global_buffer_E = nullptr; List<RID>::Element *global_texture_E = nullptr; @@ -170,6 +171,10 @@ public: DEFAULT_RD_BUFFER_COLOR, DEFAULT_RD_BUFFER_TEX_UV, DEFAULT_RD_BUFFER_TEX_UV2, + DEFAULT_RD_BUFFER_CUSTOM0, + DEFAULT_RD_BUFFER_CUSTOM1, + DEFAULT_RD_BUFFER_CUSTOM2, + DEFAULT_RD_BUFFER_CUSTOM3, DEFAULT_RD_BUFFER_BONES, DEFAULT_RD_BUFFER_WEIGHTS, DEFAULT_RD_BUFFER_MAX, @@ -360,7 +365,7 @@ private: Map<StringName, Variant> params; int32_t priority; RID next_pass; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX]; @@ -378,6 +383,8 @@ private: uint32_t format = 0; RID vertex_buffer; + RID attribute_buffer; + RID skin_buffer; uint32_t vertex_count = 0; // A different pipeline needs to be allocated @@ -414,8 +421,7 @@ private: Vector<AABB> bone_aabbs; - Vector<RID> blend_shapes; - RID blend_shape_base_buffer; //source buffer goes here when using blend shapes, and main one is uncompressed + RID blend_shape_buffer; RID material; @@ -442,7 +448,7 @@ private: Vector<RID> material_cache; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<Mesh> mesh_owner; @@ -476,7 +482,7 @@ private: bool dirty = false; MultiMesh *dirty_list = nullptr; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<MultiMesh> multimesh_owner; @@ -647,7 +653,7 @@ private: ParticleEmissionBuffer *emission_buffer = nullptr; RID emission_storage_buffer; - Set<RasterizerScene::InstanceBase *> collisions; + Set<RendererSceneRender::InstanceBase *> collisions; Particles() : inactive(true), @@ -674,7 +680,7 @@ private: clear(true) { } - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; ParticlesFrameParams frame_params; }; @@ -729,7 +735,7 @@ private: bool valid; RID version; - //RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX]; + //PipelineCacheRD pipelines[SKY_VERSION_MAX]; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; @@ -747,7 +753,7 @@ private: virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; + virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; @@ -757,7 +763,7 @@ private: }; ShaderData *_create_particles_shader_func(); - static RasterizerStorageRD::ShaderData *_create_particles_shader_funcs() { + static RendererStorageRD::ShaderData *_create_particles_shader_funcs() { return base_singleton->_create_particles_shader_func(); } @@ -777,7 +783,7 @@ private: }; MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader); - static RasterizerStorageRD::MaterialData *_create_particles_material_funcs(ShaderData *p_shader) { + static RendererStorageRD::MaterialData *_create_particles_material_funcs(ShaderData *p_shader) { return base_singleton->_create_particles_material_func(static_cast<ParticlesShaderData *>(p_shader)); } @@ -802,7 +808,7 @@ private: RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<ParticlesCollision> particles_collision_owner; @@ -821,7 +827,7 @@ private: RID uniform_set_3d; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<Skeleton> skeleton_owner; @@ -853,7 +859,7 @@ private: bool directional_sky_only = false; uint64_t version = 0; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<Light> light_owner; @@ -875,7 +881,7 @@ private: bool enable_shadows = false; uint32_t cull_mask = (1 << 20) - 1; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<ReflectionProbe> reflection_probe_owner; @@ -896,7 +902,7 @@ private: float distance_fade_length = 1; float normal_fade = 0.0; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; mutable RID_Owner<Decal> decal_owner; @@ -934,7 +940,7 @@ private: uint32_t version = 1; uint32_t data_version = 1; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; GiprobeSdfShaderRD giprobe_sdf_shader; @@ -963,7 +969,7 @@ private: int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; }; - RasterizerScene::InstanceDependency instance_dependency; + RendererStorage::InstanceDependency instance_dependency; }; bool using_lightmap_array; //high end uses this @@ -1124,7 +1130,7 @@ private: void _update_global_variables(); /* EFFECTS */ - RasterizerEffectsRD effects; + EffectsRD effects; public: /* TEXTURE API */ @@ -1256,7 +1262,7 @@ public: void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters); - void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance); + void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance); void material_force_update_textures(RID p_material, ShaderType p_shader_type); void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function); @@ -1457,7 +1463,7 @@ public: if (!multimesh->uniform_set_3d.is_valid()) { Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(multimesh->buffer); uniforms.push_back(u); @@ -1505,7 +1511,7 @@ public: if (!skeleton->uniform_set_3d.is_valid()) { Vector<RD::Uniform> uniforms; RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(skeleton->buffer); uniforms.push_back(u); @@ -1655,8 +1661,8 @@ public: Color reflection_probe_get_ambient_color(RID p_probe) const; float reflection_probe_get_ambient_color_energy(RID p_probe) const; - void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance); - void skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); + void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance); + void skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance); /* DECAL API */ @@ -1894,7 +1900,7 @@ public: { RD::Uniform u; - u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; u.ids.push_back(particles->particle_instance_buffer); uniforms.push_back(u); @@ -1906,8 +1912,8 @@ public: return particles->particles_transforms_buffer_uniform_set; } - virtual void particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance); - virtual void particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance); + virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance); + virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance); /* PARTICLES COLLISION */ @@ -2016,12 +2022,12 @@ public: RID get_default_rd_storage_buffer() { return default_rd_storage_buffer; } - static RasterizerStorageRD *base_singleton; + static RendererStorageRD *base_singleton; - RasterizerEffectsRD *get_effects(); + EffectsRD *get_effects(); - RasterizerStorageRD(); - ~RasterizerStorageRD(); + RendererStorageRD(); + ~RendererStorageRD(); }; #endif // RASTERIZER_STORAGE_RD_H diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index df5513435a..2c1d2a84fd 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -32,7 +32,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" -#include "rasterizer_storage_rd.h" +#include "renderer_storage_rd.h" #include "servers/rendering_server.h" #define SL ShaderLanguage @@ -1238,7 +1238,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) { - RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RasterizerStorage::base_singleton))->global_variable_get_type_internal(p_type); + RS::GlobalVariableType gvt = ((RendererStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type); return RS::global_variable_type_get_shader_datatype(gvt); } diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h index 694f8fff91..694f8fff91 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h +++ b/servers/rendering/renderer_rd/shader_compiler_rd.h diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 865a1e1bbe..bf7ec54b9c 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -31,7 +31,7 @@ #include "shader_rd.h" #include "core/string/string_builder.h" -#include "rasterizer_rd.h" +#include "renderer_compositor_rd.h" #include "servers/rendering/rendering_device.h" void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) { @@ -356,7 +356,7 @@ void ShaderRD::_compile_version(Version *p_version) { p_version->variants = memnew_arr(RID, variant_defines.size()); #if 1 - RasterizerRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); + RendererCompositorRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); #else for (int i = 0; i < variant_defines.size(); i++) { _compile_variant(i, p_version); diff --git a/servers/rendering/rasterizer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index 0c379db6f2..0c379db6f2 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub index 4cddf0f685..4cddf0f685 100644 --- a/servers/rendering/rasterizer_rd/shaders/SCsub +++ b/servers/rendering/renderer_rd/shaders/SCsub diff --git a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl index 63f086a83d..63f086a83d 100644 --- a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl +++ b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 51d7193a03..7808e7ed52 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -9,7 +9,8 @@ layout(location = 0) in vec2 vertex_attrib; layout(location = 3) in vec4 color_attrib; layout(location = 4) in vec2 uv_attrib; -layout(location = 6) in uvec4 bones_attrib; +layout(location = 10) in uvec4 bone_attrib; +layout(location = 11) in vec4 weight_attrib; #endif @@ -61,6 +62,7 @@ void main() { color = vec4(unpackHalf2x16(draw_data.colors[4]), unpackHalf2x16(draw_data.colors[5])); } uvec4 bones = uvec4(0, 0, 0, 0); + vec4 bone_weights = vec4(0.0); #elif defined(USE_ATTRIBUTES) @@ -68,7 +70,8 @@ void main() { vec4 color = color_attrib; vec2 uv = uv_attrib; - uvec4 bones = bones_attrib; + uvec4 bones = bone_attrib; + vec4 bone_weights = weight_attrib; #else vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl index 5c25235c58..5c25235c58 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl index 302ad03b41..302ad03b41 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index cf7678ea31..cf7678ea31 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/cluster_data_inc.glsl b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl index e723468dd8..e723468dd8 100644 --- a/servers/rendering/rasterizer_rd/shaders/cluster_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/copy.glsl index cdd35dfb3f..cdd35dfb3f 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/copy.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl index 9751e13b4e..9751e13b4e 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index 54d67db6c6..54d67db6c6 100644 --- a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl index 7f269b7af3..7f269b7af3 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl b/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl index 987545fb76..987545fb76 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl index 5cbb00baa4..5cbb00baa4 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index 8011dadc72..8011dadc72 100644 --- a/servers/rendering/rasterizer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl index ea4237a45e..ea4237a45e 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl b/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl index 515cc35507..515cc35507 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl index 5b3dec0ee7..5b3dec0ee7 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl index 9c794f1bcc..9c794f1bcc 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl index 8a11c35b78..8a11c35b78 100644 --- a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 926c7ef9fc..926c7ef9fc 100644 --- a/servers/rendering/rasterizer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index 6c782b6045..6c782b6045 100644 --- a/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index 9429a66dc9..9429a66dc9 100644 --- a/servers/rendering/rasterizer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl index 464895928a..464895928a 100644 --- a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl +++ b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/renderer_rd/shaders/scene_high_end.glsl index 285698f060..5d87dec79f 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_high_end.glsl @@ -24,7 +24,29 @@ layout(location = 4) in vec2 uv_attrib; layout(location = 5) in vec2 uv2_attrib; #endif -layout(location = 6) in uvec4 bone_attrib; // always bound, even if unused +#if defined(CUSTOM0_USED) +layout(location = 6) in vec4 custom0_attrib; +#endif + +#if defined(CUSTOM1_USED) +layout(location = 7) in vec4 custom1_attrib; +#endif + +#if defined(CUSTOM2_USED) +layout(location = 8) in vec4 custom2_attrib; +#endif + +#if defined(CUSTOM3_USED) +layout(location = 9) in vec4 custom3_attrib; +#endif + +#if defined(BONES_USED) +layout(location = 10) in uvec4 bone_attrib; +#endif + +#if defined(WEIGHTS_USED) +layout(location = 11) in vec4 weight_attrib; +#endif /* Varyings */ @@ -116,14 +138,15 @@ void main() { } vec3 vertex = vertex_attrib; - vec3 normal = normal_attrib; + vec3 normal = normal_attrib * 2.0 - 1.0; #if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED) - vec3 tangent = tangent_attrib.xyz; - float binormalf = tangent_attrib.a; + vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0; + float binormalf = tangent_attrib.a * 2.0 - 1.0; vec3 binormal = normalize(cross(normal, tangent) * binormalf); #endif +#if 0 if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) { //multimesh, instances are for it @@ -147,7 +170,7 @@ void main() { binormal = (vec4(binormal, 0.0) * m).xyz; #endif } - +#endif uv_interp = uv_attrib; #if defined(UV2_USED) || defined(USE_LIGHTMAP) diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_high_end_inc.glsl index e29a490ca1..e29a490ca1 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_high_end_inc.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl index 06dc4b13de..06dc4b13de 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl index a5afe74cb2..a5afe74cb2 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl index 218605a962..218605a962 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl index 813ea29fa1..813ea29fa1 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl index 08da283dad..08da283dad 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index 61e4bf5e18..61e4bf5e18 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_fields.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl index eec0a90c0d..eec0a90c0d 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_fields.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index d516ab22c3..d516ab22c3 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl index 916c60ac89..916c60ac89 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl index 29443ae7db..29443ae7db 100644 --- a/servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl +++ b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl index 6c985e1f5c..6c985e1f5c 100644 --- a/servers/rendering/rasterizer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/sky.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/sort.glsl b/servers/rendering/renderer_rd/shaders/sort.glsl index e5ebb9c64b..e5ebb9c64b 100644 --- a/servers/rendering/rasterizer_rd/shaders/sort.glsl +++ b/servers/rendering/renderer_rd/shaders/sort.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/specular_merge.glsl index 0b8f406213..0b8f406213 100644 --- a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl +++ b/servers/rendering/renderer_rd/shaders/specular_merge.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl index 346338181a..346338181a 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl index 3e63e3cb59..3e63e3cb59 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl b/servers/rendering/renderer_rd/shaders/ssao_minify.glsl index 263fca386f..263fca386f 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_minify.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl index 88a953562f..88a953562f 100644 --- a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl +++ b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl index 7de91fd541..7de91fd541 100644 --- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl diff --git a/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index 13b162f0c9..13b162f0c9 100644 --- a/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl diff --git a/servers/rendering/renderer_scene.cpp b/servers/rendering/renderer_scene.cpp new file mode 100644 index 0000000000..1da8fc59de --- /dev/null +++ b/servers/rendering/renderer_scene.cpp @@ -0,0 +1,37 @@ +/*************************************************************************/ +/* renderer_scene.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "renderer_scene.h" + +RendererScene::RendererScene() { +} + +RendererScene::~RendererScene() { +} diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h new file mode 100644 index 0000000000..3da08f10af --- /dev/null +++ b/servers/rendering/renderer_scene.h @@ -0,0 +1,202 @@ +/*************************************************************************/ +/* renderer_scene.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef RENDERINGSERVERSCENE_H +#define RENDERINGSERVERSCENE_H + +#include "servers/rendering/renderer_compositor.h" +#include "servers/xr/xr_interface.h" + +class RendererScene { +public: + virtual RID camera_create() = 0; + + virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0; + virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0; + virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0; + virtual void camera_set_transform(RID p_camera, const Transform &p_transform) = 0; + virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0; + virtual void camera_set_environment(RID p_camera, RID p_env) = 0; + virtual void camera_set_camera_effects(RID p_camera, RID p_fx) = 0; + virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0; + virtual bool is_camera(RID p_camera) const = 0; + + virtual RID scenario_create() = 0; + + virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) = 0; + virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0; + virtual void scenario_set_camera_effects(RID p_scenario, RID p_fx) = 0; + virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0; + virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) = 0; + virtual bool is_scenario(RID p_scenario) const = 0; + virtual RID scenario_get_environment(RID p_scenario) = 0; + + virtual RID instance_create() = 0; + + virtual void instance_set_base(RID p_instance, RID p_base) = 0; + virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; + virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask) = 0; + virtual void instance_set_transform(RID p_instance, const Transform &p_transform) = 0; + virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id) = 0; + virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0; + virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0; + virtual void instance_set_visible(RID p_instance, bool p_visible) = 0; + + virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb) = 0; + + virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0; + virtual void instance_set_exterior(RID p_instance, bool p_enabled) = 0; + + virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; + + // don't use these in a game! + virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; + virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0; + virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0; + + virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) = 0; + virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) = 0; + virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0; + + virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0; + virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0; + virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0; + + virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0; + virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0; + virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0; + + virtual void directional_shadow_atlas_set_size(int p_size) = 0; + + /* SKY API */ + + virtual RID sky_create() = 0; + virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; + virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; + virtual void sky_set_material(RID p_sky, RID p_material) = 0; + virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0; + + /* ENVIRONMENT API */ + + virtual RID environment_create() = 0; + + virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; + virtual void environment_set_sky(RID p_env, RID p_sky) = 0; + virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; + virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0; + virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0; + virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0; + virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; + virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) = 0; + + virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; + virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; + virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + + virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; + virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; + virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; + virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; + + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; + + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0; + + virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0; + + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + + virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; + virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; + + virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; + + virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0; + + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + + virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; + + virtual RS::EnvironmentBG environment_get_background(RID p_Env) const = 0; + virtual int environment_get_canvas_max_layer(RID p_env) const = 0; + + virtual bool is_environment(RID p_environment) const = 0; + + virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; + virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; + virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; + + /* Camera Effects */ + + virtual RID camera_effects_create() = 0; + + virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; + virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; + + virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; + virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + + virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0; + virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; + + virtual RID shadow_atlas_create() = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; + virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; + + /* Render Buffers */ + + virtual RID render_buffers_create() = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; + + virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; + + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; + + virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0; + + virtual void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) = 0; + virtual void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) = 0; + virtual void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) = 0; + + virtual void update() = 0; + virtual void render_probes() = 0; + + virtual bool free(RID p_rid) = 0; + + RendererScene(); + virtual ~RendererScene(); +}; + +#endif // RENDERINGSERVERSCENE_H diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/renderer_scene_cull.cpp index b933a550e2..26c50d25ca 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_scene.cpp */ +/* renderer_scene_cull.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,22 +28,22 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rendering_server_scene.h" +#include "renderer_scene_cull.h" #include "core/os/os.h" +#include "rendering_server_default.h" #include "rendering_server_globals.h" -#include "rendering_server_raster.h" #include <new> /* CAMERA API */ -RID RenderingServerScene::camera_create() { +RID RendererSceneCull::camera_create() { Camera *camera = memnew(Camera); return camera_owner.make_rid(camera); } -void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { +void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::PERSPECTIVE; @@ -52,7 +52,7 @@ void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_deg camera->zfar = p_z_far; } -void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) { +void RendererSceneCull::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::ORTHOGONAL; @@ -61,7 +61,7 @@ void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, flo camera->zfar = p_z_far; } -void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { +void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::FRUSTUM; @@ -71,41 +71,45 @@ void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector camera->zfar = p_z_far; } -void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) { +void RendererSceneCull::camera_set_transform(RID p_camera, const Transform &p_transform) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->transform = p_transform.orthonormalized(); } -void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) { +void RendererSceneCull::camera_set_cull_mask(RID p_camera, uint32_t p_layers) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->visible_layers = p_layers; } -void RenderingServerScene::camera_set_environment(RID p_camera, RID p_env) { +void RendererSceneCull::camera_set_environment(RID p_camera, RID p_env) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->env = p_env; } -void RenderingServerScene::camera_set_camera_effects(RID p_camera, RID p_fx) { +void RendererSceneCull::camera_set_camera_effects(RID p_camera, RID p_fx) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->effects = p_fx; } -void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) { +void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->vaspect = p_enable; } +bool RendererSceneCull::is_camera(RID p_camera) const { + return camera_owner.owns(p_camera); +} + /* SCENARIO API */ -void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int) { - //RenderingServerScene *self = (RenderingServerScene*)p_self; +void *RendererSceneCull::_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int) { + //RendererSceneCull *self = (RendererSceneCull*)p_self; Instance *A = p_A; Instance *B = p_B; @@ -165,7 +169,7 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan pinfo.geometry = A; pinfo.L = geom->lightmap_captures.push_back(B); List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.push_back(pinfo); - ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + ((RendererSceneCull *)p_self)->_instance_queue_update(A, false, false); //need to update capture return E; //this element should make freeing faster } else { return nullptr; @@ -200,8 +204,8 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan return nullptr; } -void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { - //RenderingServerScene *self = (RenderingServerScene*)p_self; +void RendererSceneCull::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { + //RendererSceneCull *self = (RendererSceneCull*)p_self; Instance *A = p_A; Instance *B = p_B; @@ -253,7 +257,7 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->lightmap_captures.erase(E->get().L); lightmap_data->geometries.erase(E); - ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + ((RendererSceneCull *)p_self)->_instance_queue_update(A, false, false); //need to update capture } } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { @@ -281,7 +285,7 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta } } -RID RenderingServerScene::scenario_create() { +RID RendererSceneCull::scenario_create() { Scenario *scenario = memnew(Scenario); ERR_FAIL_COND_V(!scenario, RID()); RID scenario_rid = scenario_owner.make_rid(scenario); @@ -289,49 +293,59 @@ RID RenderingServerScene::scenario_create() { scenario->octree.set_pair_callback(_instance_pair, this); scenario->octree.set_unpair_callback(_instance_unpair, this); - scenario->reflection_probe_shadow_atlas = RSG::scene_render->shadow_atlas_create(); - RSG::scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest - RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4); - RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4); - RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4); - RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8); - scenario->reflection_atlas = RSG::scene_render->reflection_atlas_create(); + scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create(); + scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest + scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4); + scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4); + scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4); + scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8); + scenario->reflection_atlas = scene_render->reflection_atlas_create(); return scenario_rid; } -void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) { +void RendererSceneCull::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) { Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->debug = p_debug_mode; } -void RenderingServerScene::scenario_set_environment(RID p_scenario, RID p_environment) { +void RendererSceneCull::scenario_set_environment(RID p_scenario, RID p_environment) { Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->environment = p_environment; } -void RenderingServerScene::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) { +void RendererSceneCull::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) { Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->camera_effects = p_camera_effects; } -void RenderingServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) { +void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) { Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->fallback_environment = p_environment; } -void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) { +void RendererSceneCull::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) { Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); - RSG::scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count); + scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count); +} + +bool RendererSceneCull::is_scenario(RID p_scenario) const { + return scenario_owner.owns(p_scenario); +} + +RID RendererSceneCull::scenario_get_environment(RID p_scenario) { + Scenario *scenario = scenario_owner.getornull(p_scenario); + ERR_FAIL_COND_V(!scenario, RID()); + return scenario->environment; } /* INSTANCING API */ -void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) { +void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) { if (p_update_aabb) { p_instance->update_aabb = true; } @@ -346,7 +360,7 @@ void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_u _instance_update_list.add(&p_instance->update_item); } -RID RenderingServerScene::instance_create() { +RID RendererSceneCull::instance_create() { Instance *instance = memnew(Instance); ERR_FAIL_COND_V(!instance, RID()); @@ -356,7 +370,7 @@ RID RenderingServerScene::instance_create() { return instance_rid; } -void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { +void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -387,18 +401,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { scenario->directional_lights.erase(light->D); light->D = nullptr; } - RSG::scene_render->free(light->instance); + scene_render->free(light->instance); } break; case RS::INSTANCE_REFLECTION_PROBE: { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data); - RSG::scene_render->free(reflection_probe->instance); + scene_render->free(reflection_probe->instance); if (reflection_probe->update_list.in_list()) { reflection_probe_render_list.remove(&reflection_probe->update_list); } } break; case RS::INSTANCE_DECAL: { InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data); - RSG::scene_render->free(decal->instance); + scene_render->free(decal->instance); } break; case RS::INSTANCE_LIGHTMAP: { @@ -424,7 +438,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { gi_probe_update_list.remove(&gi_probe->update_element); } - RSG::scene_render->free(gi_probe->probe_instance); + scene_render->free(gi_probe->probe_instance); } break; default: { @@ -455,7 +469,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { light->D = scenario->directional_lights.push_back(instance); } - light->instance = RSG::scene_render->light_instance_create(p_base); + light->instance = scene_render->light_instance_create(p_base); instance->base_data = light; } break; @@ -474,19 +488,19 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { reflection_probe->owner = instance; instance->base_data = reflection_probe; - reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base); + reflection_probe->instance = scene_render->reflection_probe_instance_create(p_base); } break; case RS::INSTANCE_DECAL: { InstanceDecalData *decal = memnew(InstanceDecalData); decal->owner = instance; instance->base_data = decal; - decal->instance = RSG::scene_render->decal_instance_create(p_base); + decal->instance = scene_render->decal_instance_create(p_base); } break; case RS::INSTANCE_LIGHTMAP: { InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData); instance->base_data = lightmap_data; - //lightmap_data->instance = RSG::scene_render->lightmap_data_instance_create(p_base); + //lightmap_data->instance = scene_render->lightmap_data_instance_create(p_base); } break; case RS::INSTANCE_GI_PROBE: { InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData); @@ -497,7 +511,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { gi_probe_update_list.add(&gi_probe->update_element); } - gi_probe->probe_instance = RSG::scene_render->gi_probe_instance_create(p_base); + gi_probe->probe_instance = scene_render->gi_probe_instance_create(p_base); } break; default: { @@ -513,7 +527,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { _instance_queue_update(instance, true, true); } -void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { +void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -540,7 +554,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } break; case RS::INSTANCE_REFLECTION_PROBE: { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data); - RSG::scene_render->reflection_probe_release_atlas_index(reflection_probe->instance); + scene_render->reflection_probe_release_atlas_index(reflection_probe->instance); } break; case RS::INSTANCE_PARTICLES_COLLISION: { @@ -601,14 +615,14 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } } -void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { +void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->layer_mask = p_mask; } -void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) { +void RendererSceneCull::instance_set_transform(RID p_instance, const Transform &p_transform) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -633,14 +647,14 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor _instance_queue_update(instance, true); } -void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { +void RendererSceneCull::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->object_id = p_id; } -void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { +void RendererSceneCull::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -652,7 +666,7 @@ void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p instance->blend_values.write[p_shape] = p_weight; } -void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) { +void RendererSceneCull::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -668,7 +682,7 @@ void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_s _instance_queue_update(instance, false, true); } -void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) { +void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -724,7 +738,7 @@ inline bool is_geometry_instance(RenderingServer::InstanceType p_type) { return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE; } -void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { +void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); ERR_FAIL_COND(!is_geometry_instance(instance->base_type)); @@ -749,7 +763,7 @@ void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) } } -void RenderingServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) { +void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -766,10 +780,10 @@ void RenderingServerScene::instance_attach_skeleton(RID p_instance, RID p_skelet _instance_queue_update(instance, true, true); } -void RenderingServerScene::instance_set_exterior(RID p_instance, bool p_enabled) { +void RendererSceneCull::instance_set_exterior(RID p_instance, bool p_enabled) { } -void RenderingServerScene::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) { +void RendererSceneCull::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -777,12 +791,12 @@ void RenderingServerScene::instance_set_extra_visibility_margin(RID p_instance, _instance_queue_update(instance, true, false); } -Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { +Vector<ObjectID> RendererSceneCull::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); - const_cast<RenderingServerScene *>(this)->update_dirty_instances(); // check dirty instances before culling + const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling int culled = 0; Instance *cull[1024]; @@ -801,11 +815,11 @@ Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, R return instances; } -Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { +Vector<ObjectID> RendererSceneCull::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); - const_cast<RenderingServerScene *>(this)->update_dirty_instances(); // check dirty instances before culling + const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling int culled = 0; Instance *cull[1024]; @@ -824,11 +838,11 @@ Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, return instances; } -Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { +Vector<ObjectID> RendererSceneCull::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); - const_cast<RenderingServerScene *>(this)->update_dirty_instances(); // check dirty instances before culling + const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling int culled = 0; Instance *cull[1024]; @@ -848,7 +862,7 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> return instances; } -void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) { +void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -885,7 +899,7 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan } } -void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { +void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -893,7 +907,7 @@ void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_inst _instance_queue_update(instance, false, true); } -void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) { +void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, RID p_material) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -901,13 +915,13 @@ void RenderingServerScene::instance_geometry_set_material_override(RID p_instanc _instance_queue_update(instance, false, true); } -void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { +void RendererSceneCull::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { } -void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) { +void RendererSceneCull::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) { } -void RenderingServerScene::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) { +void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -929,14 +943,14 @@ void RenderingServerScene::instance_geometry_set_lightmap(RID p_instance, RID p_ } } -void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { +void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter); + Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter); if (!E) { - RasterizerScene::InstanceBase::InstanceShaderParameter isp; + RendererSceneRender::InstanceBase::InstanceShaderParameter isp; isp.index = -1; isp.info = PropertyInfo(); isp.value = p_value; @@ -950,8 +964,8 @@ void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance } } -Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); +Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { + const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!instance, Variant()); if (instance->instance_shader_parameters.has(p_parameter)) { @@ -960,8 +974,8 @@ Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_insta return Variant(); } -Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); +Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { + const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!instance, Variant()); if (instance->instance_shader_parameters.has(p_parameter)) { @@ -970,14 +984,14 @@ Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_val return Variant(); } -void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); +void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const { + const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - const_cast<RenderingServerScene *>(this)->update_dirty_instances(); + const_cast<RendererSceneCull *>(this)->update_dirty_instances(); Vector<StringName> names; - for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) { + for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) { names.push_back(E->key()); } names.sort_custom<StringName::AlphCompare>(); @@ -987,14 +1001,14 @@ void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_ins } } -void RenderingServerScene::_update_instance(Instance *p_instance) { +void RendererSceneCull::_update_instance(Instance *p_instance) { p_instance->version++; if (p_instance->base_type == RS::INSTANCE_LIGHT) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); - RSG::scene_render->light_instance_set_transform(light->instance, p_instance->transform); - RSG::scene_render->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb)); + scene_render->light_instance_set_transform(light->instance, p_instance->transform); + scene_render->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb)); light->shadow_dirty = true; RS::LightBakeMode bake_mode = RSG::storage->light_get_bake_mode(p_instance->base); @@ -1019,20 +1033,20 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); - RSG::scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform); + scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform); reflection_probe->reflection_dirty = true; } if (p_instance->base_type == RS::INSTANCE_DECAL) { InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data); - RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform); + scene_render->decal_instance_set_transform(decal->instance, p_instance->transform); } if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data); - RSG::scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform); + scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform); } if (p_instance->base_type == RS::INSTANCE_PARTICLES) { @@ -1129,7 +1143,7 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } } -void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { +void RendererSceneCull::_update_instance_aabb(Instance *p_instance) { AABB new_aabb; ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid()); @@ -1207,7 +1221,7 @@ void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { p_instance->aabb = new_aabb; } -void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) { +void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) { bool first_set = p_instance->lightmap_sh.size() == 0; p_instance->lightmap_sh.resize(9); //using SH p_instance->lightmap_target_sh.resize(9); //using SH @@ -1285,7 +1299,7 @@ void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instan } } -bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) { +bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform light_transform = p_instance->transform; @@ -1372,7 +1386,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c distances[splits] = max_distance; - real_t texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance); + real_t texture_size = scene_render->get_directional_light_shadow_size(light->instance); bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base); @@ -1654,17 +1668,17 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c cull_max = dir_in_view.dot(max_in_view); } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale); + scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale); } - RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count); } } break; case RS::LIGHT_OMNI: { RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base); - if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::scene_render->light_instances_can_render_shadow_cube()) { + if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) { for (int i = 0; i < 2; i++) { //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); @@ -1700,8 +1714,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); - RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); + scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count); } } else { //shadow cube @@ -1752,12 +1766,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0); - RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0); + scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count); } //restore the regular DP matrix - RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); + scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); } } break; @@ -1789,8 +1803,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0); - RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0); + scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, cull_count); } break; } @@ -1798,7 +1812,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c return animated_material_found; } -void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { +void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { // render to mono camera #ifndef _3D_DISABLED @@ -1848,7 +1862,7 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID #endif } -void RenderingServerScene::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { +void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { // render for AR/VR interface Camera *camera = camera_owner.getornull(p_camera); @@ -1932,7 +1946,7 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<XRInterface> _render_scene(p_render_buffers, cam_transform, camera_matrix, false, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1); }; -void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { +void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { // Note, in stereo rendering: // - p_cam_transform will be a transform in the middle of our two eyes // - p_cam_projection is a wider frustrum that encompasses both eyes @@ -1942,10 +1956,10 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const render_pass++; uint32_t camera_layer_mask = p_visible_layers; - RSG::scene_render->set_scene_pass(render_pass); + scene_render->set_scene_pass(render_pass); if (p_render_buffers.is_valid()) { - RSG::scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not) + scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not) } RENDER_TIMESTAMP("Frustum Culling"); @@ -1998,7 +2012,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const light_cull_result[light_cull_count] = ins; light_instance_cull_result[light_cull_count] = light->instance; if (p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(ins->base)) { - RSG::scene_render->light_instance_mark_visible(light->instance); //mark it visible for shadow allocation later + scene_render->light_instance_mark_visible(light->instance); //mark it visible for shadow allocation later } light_cull_count++; @@ -2014,7 +2028,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const if (!reflection_probe->geometries.empty()) { //do not add this light if no geometry is affected by it.. - if (reflection_probe->reflection_dirty || RSG::scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) { + if (reflection_probe->reflection_dirty || scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) { if (!reflection_probe->update_list.in_list()) { reflection_probe->render_step = 0; reflection_probe_render_list.add_last(&reflection_probe->update_list); @@ -2023,7 +2037,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const reflection_probe->reflection_dirty = false; } - if (RSG::scene_render->reflection_probe_instance_has_reflection(reflection_probe->instance)) { + if (scene_render->reflection_probe_instance_has_reflection(reflection_probe->instance)) { reflection_probe_instance_cull_result[reflection_probe_cull_count] = reflection_probe->instance; reflection_probe_cull_count++; } @@ -2063,7 +2077,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data); if (ins->redraw_if_visible) { - RenderingServerRaster::redraw_request(); + RenderingServerDefault::redraw_request(); } if (ins->base_type == RS::INSTANCE_PARTICLES) { @@ -2075,7 +2089,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const RSG::storage->particles_request_process(ins->base); RSG::storage->particles_set_view_axis(ins->base, -p_cam_transform.basis.get_axis(2).normalized()); //particles visible? request redraw - RenderingServerRaster::redraw_request(); + RenderingServerDefault::redraw_request(); } } @@ -2177,7 +2191,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } - RSG::scene_render->set_directional_shadow_count(directional_shadow_count); + scene_render->set_directional_shadow_count(directional_shadow_count); for (int i = 0; i < directional_shadow_count; i++) { RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i)); @@ -2276,7 +2290,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const light->shadow_dirty = false; } - bool redraw = RSG::scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version); + bool redraw = scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version); if (redraw) { //must redraw! @@ -2297,9 +2311,9 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const uint32_t sdfgi_light_cull_count = 0; uint32_t prev_cascade = 0xFFFFFFFF; - for (int i = 0; i < RSG::scene_render->sdfgi_get_pending_region_count(p_render_buffers); i++) { - AABB region = RSG::scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i); - uint32_t region_cascade = RSG::scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i); + for (int i = 0; i < scene_render->sdfgi_get_pending_region_count(p_render_buffers); i++) { + AABB region = scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i); + uint32_t region_cascade = scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i); if (region_cascade != prev_cascade) { cascade_sizes[cascade_count] = 0; @@ -2341,21 +2355,21 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } - RSG::scene_render->render_sdfgi(p_render_buffers, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, sdfgi_cull_count); + scene_render->render_sdfgi(p_render_buffers, i, (RendererSceneRender::InstanceBase **)instance_shadow_cull_result, sdfgi_cull_count); //have to save updated cascades, then update static lights. } if (sdfgi_light_cull_count) { - RSG::scene_render->render_sdfgi_static_lights(p_render_buffers, cascade_count, cascade_index, cascade_ptrs, cascade_sizes); + scene_render->render_sdfgi_static_lights(p_render_buffers, cascade_count, cascade_index, cascade_ptrs, cascade_sizes); } - RSG::scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_light_ptr, directional_light_count, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size()); + scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_light_ptr, directional_light_count, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size()); } } -RID RenderingServerScene::_render_get_environment(RID p_camera, RID p_scenario) { +RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { Camera *camera = camera_owner.getornull(p_camera); - if (camera && RSG::scene_render->is_environment(camera->env)) { + if (camera && scene_render->is_environment(camera->env)) { return camera->env; } @@ -2363,18 +2377,18 @@ RID RenderingServerScene::_render_get_environment(RID p_camera, RID p_scenario) if (!scenario) { return RID(); } - if (RSG::scene_render->is_environment(scenario->environment)) { + if (scene_render->is_environment(scenario->environment)) { return scenario->environment; } - if (RSG::scene_render->is_environment(scenario->fallback_environment)) { + if (scene_render->is_environment(scenario->fallback_environment)) { return scenario->fallback_environment; } return RID(); } -void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { +void RendererSceneCull::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { Scenario *scenario = scenario_owner.getornull(p_scenario); RID camera_effects; @@ -2386,10 +2400,10 @@ void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p /* PROCESS GEOMETRY AND DRAW SCENE */ RENDER_TIMESTAMP("Render Scene "); - RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, (RasterizerScene::InstanceBase **)lightmap_cull_result, lightmap_cull_count, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); + scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RendererSceneRender::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, (RendererSceneRender::InstanceBase **)lightmap_cull_result, lightmap_cull_count, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); } -void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { +void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { #ifndef _3D_DISABLED Scenario *scenario = scenario_owner.getornull(p_scenario); @@ -2401,19 +2415,19 @@ void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenar environment = scenario->fallback_environment; } RENDER_TIMESTAMP("Render Empty Scene "); - RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); + scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); #endif } -bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) { +bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int p_step) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); Scenario *scenario = p_instance->scenario; ERR_FAIL_COND_V(!scenario, true); - RenderingServerRaster::redraw_request(); //update, so it updates in editor + RenderingServerDefault::redraw_request(); //update, so it updates in editor if (p_step == 0) { - if (!RSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) { + if (!scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) { return true; //all full } } @@ -2468,13 +2482,13 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i } else { //do roughness postprocess step until it believes it's done RENDER_TIMESTAMP("Post-Process Reflection Probe, Step " + itos(p_step)); - return RSG::scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance); + return scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance); } return false; } -void RenderingServerScene::render_probes() { +void RendererSceneCull::render_probes() { /* REFLECTION PROBES */ SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first(); @@ -2611,7 +2625,7 @@ void RenderingServerScene::render_probes() { cache_count = idx; } - bool update_lights = RSG::scene_render->gi_probe_needs_update(probe->probe_instance); + bool update_lights = scene_render->gi_probe_needs_update(probe->probe_instance); if (cache_dirty) { probe->light_cache.resize(cache_count); @@ -2702,7 +2716,7 @@ void RenderingServerScene::render_probes() { } } - RSG::scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, instance_cull_count, (RasterizerScene::InstanceBase **)instance_cull_result); + scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, instance_cull_count, (RendererSceneRender::InstanceBase **)instance_cull_result); gi_probe_update_list.remove(gi_probe); @@ -2710,7 +2724,7 @@ void RenderingServerScene::render_probes() { } } -void RenderingServerScene::render_particle_colliders() { +void RendererSceneCull::render_particle_colliders() { while (heightfield_particle_colliders_update_list.front()) { Instance *hfpc = heightfield_particle_colliders_update_list.front()->get(); @@ -2725,16 +2739,16 @@ void RenderingServerScene::render_particle_colliders() { } } - RSG::scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, (RasterizerScene::InstanceBase **)instance_cull_result, cull_count); + scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, (RendererSceneRender::InstanceBase **)instance_cull_result, cull_count); } heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front()); } } -void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) { - List<RasterizerStorage::InstanceShaderParam> plist; +void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) { + List<RendererStorage::InstanceShaderParam> plist; RSG::storage->material_get_instance_shader_parameters(p_material, &plist); - for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { + for (List<RendererStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { StringName name = E->get().info.name; if (isparams.has(name)) { if (isparams[name].info.type != E->get().info.type) { @@ -2746,7 +2760,7 @@ void RenderingServerScene::_update_instance_shader_parameters_from_material(Map< continue; //first one found always has priority } - RasterizerScene::InstanceBase::InstanceShaderParameter isp; + RendererSceneRender::InstanceBase::InstanceShaderParameter isp; isp.index = E->get().index; isp.info = E->get().info; isp.default_value = E->get().default_value; @@ -2759,7 +2773,7 @@ void RenderingServerScene::_update_instance_shader_parameters_from_material(Map< } } -void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { +void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if (p_instance->update_aabb) { _update_instance_aabb(p_instance); } @@ -2795,7 +2809,7 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { bool can_cast_shadows = true; bool is_animated = false; - Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> isparams; + Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> isparams; if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { can_cast_shadows = false; @@ -2946,7 +2960,7 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0); if (p_instance->instance_allocated_shader_parameters) { p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self); - for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) { + for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) { if (E->get().value.get_type() != Variant::NIL) { RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value); } @@ -2973,7 +2987,7 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { p_instance->update_dependencies = false; } -void RenderingServerScene::update_dirty_instances() { +void RendererSceneCull::update_dirty_instances() { RSG::storage->update_dirty_resources(); while (_instance_update_list.first()) { @@ -2981,7 +2995,17 @@ void RenderingServerScene::update_dirty_instances() { } } -bool RenderingServerScene::free(RID p_rid) { +void RendererSceneCull::update() { + scene_render->update(); + update_dirty_instances(); + render_particle_colliders(); +} + +bool RendererSceneCull::free(RID p_rid) { + if (scene_render->free(p_rid)) { + return true; + } + if (camera_owner.owns(p_rid)) { Camera *camera = camera_owner.getornull(p_rid); @@ -2994,8 +3018,8 @@ bool RenderingServerScene::free(RID p_rid) { while (scenario->instances.first()) { instance_set_scenario(scenario->instances.first()->self()->self, RID()); } - RSG::scene_render->free(scenario->reflection_probe_shadow_atlas); - RSG::scene_render->free(scenario->reflection_atlas); + scene_render->free(scenario->reflection_probe_shadow_atlas); + scene_render->free(scenario->reflection_atlas); scenario_owner.free(p_rid); memdelete(scenario); @@ -3027,16 +3051,22 @@ bool RenderingServerScene::free(RID p_rid) { return true; } -TypedArray<Image> RenderingServerScene::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { - return RSG::scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size); +TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { + return scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size); } -RenderingServerScene *RenderingServerScene::singleton = nullptr; +/*******************************/ +/* Passthrough to Scene Render */ +/*******************************/ + +/* ENVIRONMENT API */ + +RendererSceneCull *RendererSceneCull::singleton = nullptr; -RenderingServerScene::RenderingServerScene() { +RendererSceneCull::RendererSceneCull() { render_pass = 1; singleton = this; } -RenderingServerScene::~RenderingServerScene() { +RendererSceneCull::~RendererSceneCull() { } diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/renderer_scene_cull.h index eb438be273..46ca983986 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/renderer_scene_cull.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_scene.h */ +/* renderer_scene_cull.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,10 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUALSERVERSCENE_H -#define VISUALSERVERSCENE_H +#ifndef RENDERING_SERVER_SCENE_CULL_H +#define RENDERING_SERVER_SCENE_CULL_H -#include "servers/rendering/rasterizer.h" +#include "core/templates/pass_func.h" +#include "servers/rendering/renderer_compositor.h" #include "core/math/geometry_3d.h" #include "core/math/octree.h" @@ -40,10 +41,14 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" +#include "servers/rendering/renderer_scene.h" +#include "servers/rendering/renderer_scene_render.h" #include "servers/xr/xr_interface.h" -class RenderingServerScene { +class RendererSceneCull : public RendererScene { public: + RendererSceneRender *scene_render; + enum { MAX_INSTANCE_CULL = 65536, MAX_LIGHTS_CULLED = 4096, @@ -57,7 +62,7 @@ public: uint64_t render_pass; - static RenderingServerScene *singleton; + static RendererSceneCull *singleton; /* CAMERA API */ @@ -102,6 +107,7 @@ public: virtual void camera_set_environment(RID p_camera, RID p_env); virtual void camera_set_camera_effects(RID p_camera, RID p_fx); virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable); + virtual bool is_camera(RID p_camera) const; /* SCENARIO API */ @@ -139,6 +145,8 @@ public: virtual void scenario_set_camera_effects(RID p_scenario, RID p_fx); virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment); virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count); + virtual bool is_scenario(RID p_scenario) const; + virtual RID scenario_get_environment(RID p_scenario); /* INSTANCING API */ @@ -146,7 +154,7 @@ public: virtual ~InstanceBaseData() {} }; - struct Instance : RasterizerScene::InstanceBase { + struct Instance : RendererSceneRender::InstanceBase { RID self; //scenario stuff OctreeElementID octree_id; @@ -438,7 +446,7 @@ public: virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance); virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); - void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material); + void _update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material); virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; @@ -464,14 +472,112 @@ public: void update_dirty_instances(); void render_particle_colliders(); - void render_probes(); + virtual void render_probes(); TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size); + //pass to scene render + + /* ENVIRONMENT API */ + +#ifdef PASSBASE +#undef PASSBASE +#endif + +#define PASSBASE scene_render + + PASS1(directional_shadow_atlas_set_size, int) + PASS1(gi_probe_set_quality, RS::GIProbeQuality) + + /* SKY API */ + + PASS0R(RID, sky_create) + PASS2(sky_set_radiance_size, RID, int) + PASS2(sky_set_mode, RID, RS::SkyMode) + PASS2(sky_set_material, RID, RID) + PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) + + PASS0R(RID, environment_create) + + PASS1RC(bool, is_environment, RID) + + PASS2(environment_set_background, RID, RS::EnvironmentBG) + PASS2(environment_set_sky, RID, RID) + PASS2(environment_set_sky_custom_fov, RID, float) + PASS2(environment_set_sky_orientation, RID, const Basis &) + PASS2(environment_set_bg_color, RID, const Color &) + PASS2(environment_set_bg_energy, RID, float) + PASS2(environment_set_canvas_max_layer, RID, int) + PASS7(environment_set_ambient_light, RID, const Color &, RS::EnvironmentAmbientSource, float, float, RS::EnvironmentReflectionSource, const Color &) + + PASS6(environment_set_ssr, RID, bool, int, float, float, float) + PASS1(environment_set_ssr_roughness_quality, RS::EnvironmentSSRRoughnessQuality) + + PASS9(environment_set_ssao, RID, bool, float, float, float, float, float, RS::EnvironmentSSAOBlur, float) + PASS2(environment_set_ssao_quality, RS::EnvironmentSSAOQuality, bool) + + PASS11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float) + PASS1(environment_glow_set_use_bicubic_upscale, bool) + PASS1(environment_glow_set_use_high_quality, bool) + + PASS9(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float, bool, float, float, float, float) + + PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + + PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) + PASS9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter) + + PASS2(environment_set_volumetric_fog_volume_size, int, int) + PASS1(environment_set_volumetric_fog_filter_active, bool) + PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) + PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) + + PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) + PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount) + PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge) + + PASS1RC(RS::EnvironmentBG, environment_get_background, RID) + PASS1RC(int, environment_get_canvas_max_layer, RID) + + PASS3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + + PASS3(screen_space_roughness_limiter_set_active, bool, float, float) + PASS1(sub_surface_scattering_set_quality, RS::SubSurfaceScatteringQuality) + PASS2(sub_surface_scattering_set_scale, float, float) + + /* CAMERA EFFECTS */ + + PASS0R(RID, camera_effects_create) + + PASS2(camera_effects_set_dof_blur_quality, RS::DOFBlurQuality, bool) + PASS1(camera_effects_set_dof_blur_bokeh_shape, RS::DOFBokehShape) + + PASS8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) + PASS3(camera_effects_set_custom_exposure, RID, bool, float) + + PASS1(shadows_quality_set, RS::ShadowQuality) + PASS1(directional_shadow_quality_set, RS::ShadowQuality) + + PASS2(sdfgi_set_debug_probe_select, const Vector3 &, const Vector3 &) + + /* Render Buffers */ + + PASS0R(RID, render_buffers_create) + PASS7(render_buffers_configure, RID, RID, int, int, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool) + + /* Shadow Atlas */ + PASS0R(RID, shadow_atlas_create) + PASS2(shadow_atlas_set_size, RID, int) + PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int) + + PASS1(set_debug_draw_mode, RS::ViewportDebugDraw) + + virtual void update(); + bool free(RID p_rid); - RenderingServerScene(); - virtual ~RenderingServerScene(); + RendererSceneCull(); + virtual ~RendererSceneCull(); }; #endif // VISUALSERVERSCENE_H diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp new file mode 100644 index 0000000000..2c36c5c59d --- /dev/null +++ b/servers/rendering/renderer_scene_render.cpp @@ -0,0 +1,31 @@ +/*************************************************************************/ +/* renderer_scene_render.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "renderer_scene_render.h" diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h new file mode 100644 index 0000000000..cc543a7599 --- /dev/null +++ b/servers/rendering/renderer_scene_render.h @@ -0,0 +1,267 @@ +/*************************************************************************/ +/* renderer_scene_render.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef RENDERINGSERVERSCENERENDER_H +#define RENDERINGSERVERSCENERENDER_H + +#include "core/math/camera_matrix.h" +#include "servers/rendering/renderer_storage.h" + +class RendererSceneRender { +public: + /* SHADOW ATLAS API */ + + virtual RID shadow_atlas_create() = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; + virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; + virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0; + + virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual int get_directional_light_shadow_size(RID p_light_intance) = 0; + virtual void set_directional_shadow_count(int p_count) = 0; + + /* SDFGI UPDATE */ + + struct InstanceBase; + + virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0; + virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0; + virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0; + virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0; + virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0; + + /* SKY API */ + + virtual RID sky_create() = 0; + virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; + virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; + virtual void sky_set_material(RID p_sky, RID p_material) = 0; + virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0; + + /* ENVIRONMENT API */ + + virtual RID environment_create() = 0; + + virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; + virtual void environment_set_sky(RID p_env, RID p_sky) = 0; + virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; + virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0; + virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0; + virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0; + virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; + virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) = 0; +// FIXME: Disabled during Vulkan refactoring, should be ported. +#if 0 + virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; +#endif + + virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; + virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; + virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + + virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; + virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; + virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; + virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; + + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; + + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0; + + virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0; + + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + + virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; + virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; + + virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; + + virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0; + + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + + virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; + + virtual bool is_environment(RID p_env) const = 0; + virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; + virtual int environment_get_canvas_max_layer(RID p_env) const = 0; + + virtual RID camera_effects_create() = 0; + + virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; + virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; + + virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; + virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + + virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0; + virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; + + struct InstanceBase : public RendererStorage::InstanceBaseDependency { + RS::InstanceType base_type; + RID base; + + RID skeleton; + RID material_override; + + RID instance_data; + + Transform transform; + + int depth_layer; + uint32_t layer_mask; + + //RID sampled_light; + + Vector<RID> materials; + Vector<RID> light_instances; + Vector<RID> reflection_probe_instances; + Vector<RID> gi_probe_instances; + + Vector<float> blend_values; + + RS::ShadowCastingSetting cast_shadows; + + //fit in 32 bits + bool mirror : 8; + bool receive_shadows : 8; + bool visible : 8; + bool baked_light : 2; //this flag is only to know if it actually did use baked light + bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light + bool redraw_if_visible : 4; + + float depth; //used for sorting + + InstanceBase *lightmap; + Rect2 lightmap_uv_scale; + int lightmap_slice_index; + uint32_t lightmap_cull_index; + Vector<Color> lightmap_sh; //spherical harmonic + + AABB aabb; + AABB transformed_aabb; + + struct InstanceShaderParameter { + int32_t index = -1; + Variant value; + Variant default_value; + PropertyInfo info; + }; + + Map<StringName, InstanceShaderParameter> instance_shader_parameters; + bool instance_allocated_shader_parameters = false; + int32_t instance_allocated_shader_parameters_offset = -1; + + InstanceBase() { + base_type = RS::INSTANCE_NONE; + cast_shadows = RS::SHADOW_CASTING_SETTING_ON; + receive_shadows = true; + visible = true; + depth_layer = 0; + layer_mask = 1; + instance_version = 0; + baked_light = false; + dynamic_gi = false; + redraw_if_visible = false; + lightmap_slice_index = 0; + lightmap = nullptr; + lightmap_cull_index = 0; + } + + virtual ~InstanceBase() { + } + }; + + virtual RID light_instance_create(RID p_light) = 0; + virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; + virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; + virtual void light_instance_mark_visible(RID p_light_instance) = 0; + virtual bool light_instances_can_render_shadow_cube() const { + return true; + } + + virtual RID reflection_atlas_create() = 0; + virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0; + + virtual RID reflection_probe_instance_create(RID p_probe) = 0; + virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) = 0; + virtual void reflection_probe_release_atlas_index(RID p_instance) = 0; + virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0; + virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0; + virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0; + virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0; + + virtual RID decal_instance_create(RID p_decal) = 0; + virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0; + + virtual RID gi_probe_instance_create(RID p_gi_probe) = 0; + virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0; + virtual bool gi_probe_needs_update(RID p_probe) const = 0; + virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0; + + virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; + + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; + + virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0; + virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) = 0; + virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) = 0; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) = 0; + + virtual void set_scene_pass(uint64_t p_pass) = 0; + virtual void set_time(double p_time, double p_step) = 0; + virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; + + virtual RID render_buffers_create() = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; + + virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; + virtual bool screen_space_roughness_limiter_is_active() const = 0; + + virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; + virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; + + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + + virtual bool free(RID p_rid) = 0; + + virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0; + + virtual void update() = 0; + virtual ~RendererSceneRender() {} +}; + +#endif // RENDERINGSERVERSCENERENDER_H diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/renderer_storage.cpp index 32084c8a3e..1b2773e404 100644 --- a/servers/rendering/rasterizer.cpp +++ b/servers/rendering/renderer_storage.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer.cpp */ +/* renderer_storage.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,49 +28,38 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rasterizer.h" +#include "renderer_storage.h" -#include "core/os/os.h" -#include "core/string/print_string.h" +RendererStorage *RendererStorage::base_singleton = nullptr; -Rasterizer *(*Rasterizer::_create_func)() = nullptr; - -void RasterizerScene::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) { - for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { +void RendererStorage::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) { + for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependency_changed(p_aabb, p_dependencies); } } -void RasterizerScene::InstanceDependency::instance_notify_deleted(RID p_deleted) { - for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { +void RendererStorage::InstanceDependency::instance_notify_deleted(RID p_deleted) { + for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependency_deleted(p_deleted); } - for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { + for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependencies.erase(this); } instances.clear(); } -RasterizerScene::InstanceDependency::~InstanceDependency() { +RendererStorage::InstanceDependency::~InstanceDependency() { #ifdef DEBUG_ENABLED if (instances.size()) { WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing."); - for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { + for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependencies.erase(this); } } #endif } -Rasterizer *Rasterizer::create() { - return _create_func(); -} - -RasterizerCanvas *RasterizerCanvas::singleton = nullptr; - -RasterizerStorage *RasterizerStorage::base_singleton = nullptr; - -RasterizerStorage::RasterizerStorage() { +RendererStorage::RendererStorage() { base_singleton = this; } diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h new file mode 100644 index 0000000000..03d4397d77 --- /dev/null +++ b/servers/rendering/renderer_storage.h @@ -0,0 +1,581 @@ +/*************************************************************************/ +/* renderer_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef RENDERINGSERVERSTORAGE_H +#define RENDERINGSERVERSTORAGE_H + +#include "servers/rendering_server.h" + +class RendererStorage { + Color default_clear_color; + +public: + struct InstanceBaseDependency; + + struct InstanceDependency { + void instance_notify_changed(bool p_aabb, bool p_dependencies); + void instance_notify_deleted(RID p_deleted); + + ~InstanceDependency(); + + private: + friend struct InstanceBaseDependency; + Map<InstanceBaseDependency *, uint32_t> instances; + }; + + struct InstanceBaseDependency { + uint32_t instance_version; + Set<InstanceDependency *> dependencies; + + virtual void dependency_deleted(RID p_dependency) {} + virtual void dependency_changed(bool p_aabb, bool p_dependencies) {} + + void instance_increase_version() { + instance_version++; + } + + void update_dependency(InstanceDependency *p_dependency) { + dependencies.insert(p_dependency); + p_dependency->instances[this] = instance_version; + } + + void clean_up_dependencies() { + List<Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *>> to_clean_up; + for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { + InstanceDependency *dep = E->get(); + Map<InstanceBaseDependency *, uint32_t>::Element *F = dep->instances.find(this); + ERR_CONTINUE(!F); + if (F->get() != instance_version) { + Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *> p; + p.first = dep; + p.second = F; + to_clean_up.push_back(p); + } + } + + while (to_clean_up.size()) { + to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second); + to_clean_up.pop_front(); + } + } + + void clear_dependencies() { + for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { + InstanceDependency *dep = E->get(); + dep->instances.erase(this); + } + dependencies.clear(); + } + + virtual ~InstanceBaseDependency() { clear_dependencies(); } + }; + + /* TEXTURE API */ + + virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; + virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; + virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; + virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent + + virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming + virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0; + virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; + + //these two APIs can be used together or in combination with the others. + virtual RID texture_2d_placeholder_create() = 0; + virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0; + virtual RID texture_3d_placeholder_create() = 0; + + virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; + virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0; + + virtual void texture_replace(RID p_texture, RID p_by_texture) = 0; + virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0; + + virtual void texture_set_path(RID p_texture, const String &p_path) = 0; + virtual String texture_get_path(RID p_texture) const = 0; + + virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; + virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; + virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) = 0; + + virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) = 0; + + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; + + virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; + + virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; + virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; + + /* CANVAS TEXTURE API */ + + virtual RID canvas_texture_create() = 0; + virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0; + virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0; + + virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0; + virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0; + + /* SHADER API */ + + virtual RID shader_create() = 0; + + virtual void shader_set_code(RID p_shader, const String &p_code) = 0; + virtual String shader_get_code(RID p_shader) const = 0; + virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; + + virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0; + virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0; + virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0; + + /* COMMON MATERIAL API */ + + virtual RID material_create() = 0; + + virtual void material_set_render_priority(RID p_material, int priority) = 0; + virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; + + virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0; + virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0; + + virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0; + + virtual bool material_is_animated(RID p_material) = 0; + virtual bool material_casts_shadows(RID p_material) = 0; + + struct InstanceShaderParam { + PropertyInfo info; + int index; + Variant default_value; + }; + + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; + + virtual void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) = 0; + + /* MESH API */ + + virtual RID mesh_create() = 0; + + /// Returns stride + virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) = 0; + + virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; + + virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) = 0; + virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; + + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0; + + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; + virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; + + virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const = 0; + + virtual int mesh_get_surface_count(RID p_mesh) const = 0; + + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; + virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; + + virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0; + + virtual void mesh_clear(RID p_mesh) = 0; + + /* MULTIMESH API */ + + virtual RID multimesh_create() = 0; + + virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; + + virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; + + virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; + virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0; + virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0; + virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0; + virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0; + + virtual RID multimesh_get_mesh(RID p_multimesh) const = 0; + + virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; + virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0; + virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0; + virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0; + + virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) = 0; + virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const = 0; + + virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0; + virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0; + + virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; + + /* IMMEDIATE API */ + + virtual RID immediate_create() = 0; + virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0; + virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0; + virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0; + virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) = 0; + virtual void immediate_color(RID p_immediate, const Color &p_color) = 0; + virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) = 0; + virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) = 0; + virtual void immediate_end(RID p_immediate) = 0; + virtual void immediate_clear(RID p_immediate) = 0; + virtual void immediate_set_material(RID p_immediate, RID p_material) = 0; + virtual RID immediate_get_material(RID p_immediate) const = 0; + virtual AABB immediate_get_aabb(RID p_immediate) const = 0; + + /* SKELETON API */ + + virtual RID skeleton_create() = 0; + virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; + virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; + virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; + virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; + virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0; + virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0; + virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0; + + /* Light API */ + + virtual RID light_create(RS::LightType p_type) = 0; + + RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); } + RID omni_light_create() { return light_create(RS::LIGHT_OMNI); } + RID spot_light_create() { return light_create(RS::LIGHT_SPOT); } + + virtual void light_set_color(RID p_light, const Color &p_color) = 0; + virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; + virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; + virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; + virtual void light_set_projector(RID p_light, RID p_texture) = 0; + virtual void light_set_negative(RID p_light, bool p_enable) = 0; + virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; + virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; + virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0; + virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0; + + virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) = 0; + + virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0; + virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; + virtual bool light_directional_get_blend_splits(RID p_light) const = 0; + virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0; + virtual bool light_directional_is_sky_only(RID p_light) const = 0; + virtual void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0; + virtual RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0; + + virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0; + virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0; + + virtual bool light_has_shadow(RID p_light) const = 0; + + virtual RS::LightType light_get_type(RID p_light) const = 0; + virtual AABB light_get_aabb(RID p_light) const = 0; + virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0; + virtual Color light_get_color(RID p_light) = 0; + virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0; + virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0; + virtual uint64_t light_get_version(RID p_light) const = 0; + + /* PROBE API */ + + virtual RID reflection_probe_create() = 0; + + virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0; + virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0; + virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0; + virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) = 0; + virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) = 0; + virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) = 0; + virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) = 0; + virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) = 0; + virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) = 0; + virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) = 0; + virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0; + virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0; + virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0; + + virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0; + virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0; + virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0; + virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0; + virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const = 0; + virtual float reflection_probe_get_origin_max_distance(RID p_probe) const = 0; + virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0; + + virtual void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0; + virtual void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0; + + /* DECAL API */ + + virtual RID decal_create() = 0; + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0; + virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0; + virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0; + virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0; + virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0; + virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0; + virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0; + virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0; + virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0; + + virtual AABB decal_get_aabb(RID p_decal) const = 0; + + /* GI PROBE API */ + + virtual RID gi_probe_create() = 0; + + virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + + virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; + virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; + virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const = 0; + virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const = 0; + virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const = 0; + + virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const = 0; + virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) = 0; + virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) = 0; + virtual float gi_probe_get_propagation(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_energy(RID p_gi_probe, float p_energy) = 0; + virtual float gi_probe_get_energy(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) = 0; + virtual float gi_probe_get_ao(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) = 0; + virtual float gi_probe_get_ao_size(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_bias(RID p_gi_probe, float p_bias) = 0; + virtual float gi_probe_get_bias(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) = 0; + virtual float gi_probe_get_normal_bias(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_interior(RID p_gi_probe, bool p_enable) = 0; + virtual bool gi_probe_is_interior(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) = 0; + virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const = 0; + + virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0; + virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0; + + virtual uint32_t gi_probe_get_version(RID p_probe) = 0; + + /* LIGHTMAP CAPTURE */ + + virtual RID lightmap_create() = 0; + + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0; + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0; + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0; + virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0; + virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0; + virtual bool lightmap_is_interior(RID p_lightmap) const = 0; + virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0; + virtual float lightmap_get_probe_capture_update_speed() const = 0; + + /* PARTICLES */ + + virtual RID particles_create() = 0; + + virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; + virtual bool particles_get_emitting(RID p_particles) = 0; + + virtual void particles_set_amount(RID p_particles, int p_amount) = 0; + virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0; + virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0; + virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; + virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; + virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0; + virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0; + virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; + virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; + virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0; + virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0; + virtual void particles_set_collision_base_size(RID p_particles, float p_size) = 0; + virtual void particles_restart(RID p_particles) = 0; + virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0; + virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0; + + virtual bool particles_is_inactive(RID p_particles) const = 0; + + virtual void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) = 0; + + virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0; + virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0; + + virtual void particles_request_process(RID p_particles) = 0; + virtual AABB particles_get_current_aabb(RID p_particles) = 0; + virtual AABB particles_get_aabb(RID p_particles) const = 0; + + virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; + + virtual int particles_get_draw_passes(RID p_particles) const = 0; + virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0; + + virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0; + + virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0; + virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0; + + virtual void update_particles() = 0; + + /* PARTICLES COLLISION */ + + virtual RID particles_collision_create() = 0; + virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0; + virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0; + virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres + virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres + virtual void particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) = 0; + virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) = 0; + virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) = 0; + virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic + virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field + virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field + virtual AABB particles_collision_get_aabb(RID p_particles_collision) const = 0; + virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0; + virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0; + + /* GLOBAL VARIABLES */ + + virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0; + virtual void global_variable_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_variable_get_list() const = 0; + + virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual Variant global_variable_get(const StringName &p_name) const = 0; + virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + + virtual void global_variables_load_settings(bool p_load_textures = true) = 0; + virtual void global_variables_clear() = 0; + + virtual int32_t global_variables_instance_allocate(RID p_instance) = 0; + virtual void global_variables_instance_free(RID p_instance) = 0; + virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; + + /* RENDER TARGET */ + + enum RenderTargetFlags { + RENDER_TARGET_TRANSPARENT, + RENDER_TARGET_DIRECT_TO_SCREEN, + RENDER_TARGET_FLAG_MAX + }; + + virtual RID render_target_create() = 0; + virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0; + virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0; + virtual RID render_target_get_texture(RID p_render_target) = 0; + virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0; + virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0; + virtual bool render_target_was_used(RID p_render_target) = 0; + virtual void render_target_set_as_unused(RID p_render_target) = 0; + + virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0; + virtual bool render_target_is_clear_requested(RID p_render_target) = 0; + virtual Color render_target_get_clear_request_color(RID p_render_target) = 0; + virtual void render_target_disable_clear_request(RID p_render_target) = 0; + virtual void render_target_do_clear_request(RID p_render_target) = 0; + + virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0; + virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0; + + virtual RS::InstanceType get_base_type(RID p_rid) const = 0; + virtual bool free(RID p_rid) = 0; + + virtual bool has_os_feature(const String &p_feature) const = 0; + + virtual void update_dirty_resources() = 0; + + virtual void set_debug_generate_wireframes(bool p_generate) = 0; + + virtual void render_info_begin_capture() = 0; + virtual void render_info_end_capture() = 0; + virtual int get_captured_render_info(RS::RenderInfo p_info) = 0; + + virtual int get_render_info(RS::RenderInfo p_info) = 0; + virtual String get_video_adapter_name() const = 0; + virtual String get_video_adapter_vendor() const = 0; + + static RendererStorage *base_singleton; + + void set_default_clear_color(const Color &p_color) { + default_clear_color = p_color; + } + + Color get_default_clear_color() const { + return default_clear_color; + } +#define TIMESTAMP_BEGIN() \ + { \ + if (RSG::storage->capturing_timestamps) \ + RSG::storage->capture_timestamps_begin(); \ + } + +#define RENDER_TIMESTAMP(m_text) \ + { \ + if (RSG::storage->capturing_timestamps) \ + RSG::storage->capture_timestamp(m_text); \ + } + + bool capturing_timestamps = false; + + virtual void capture_timestamps_begin() = 0; + virtual void capture_timestamp(const String &p_name) = 0; + virtual uint32_t get_captured_timestamps_count() const = 0; + virtual uint64_t get_captured_timestamps_frame() const = 0; + virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0; + virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0; + virtual String get_captured_timestamp_name(uint32_t p_index) const = 0; + + RendererStorage(); + virtual ~RendererStorage() {} +}; + +#endif // RENDERINGSERVERSTORAGE_H diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/renderer_viewport.cpp index c048aa381f..86bfda056b 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_viewport.cpp */ +/* renderer_viewport.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rendering_server_viewport.h" +#include "renderer_viewport.h" #include "core/config/project_settings.h" -#include "rendering_server_canvas.h" +#include "renderer_canvas_cull.h" +#include "renderer_scene_cull.h" #include "rendering_server_globals.h" -#include "rendering_server_scene.h" -static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_viewport, RenderingServerCanvas::Canvas *p_canvas, RenderingServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { +static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, RendererCanvasCull::Canvas *p_canvas, RendererViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { Transform2D xf = p_viewport->global_transform; float scale = 1.0; @@ -71,7 +71,7 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi return xf; } -void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) { +void RendererViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) { RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); Ref<XRInterface> xr_interface; @@ -87,7 +87,7 @@ void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p RENDER_TIMESTAMP("<End Rendering 3D Scene"); } -void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) { +void RendererViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) { if (p_viewport->measure_render_time) { String rt_id = "vp_begin_" + itos(p_viewport->self.get_id()); RSG::storage->capture_timestamp(rt_id); @@ -101,17 +101,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Color bgcolor = RSG::storage->get_default_clear_color(); - if (!p_viewport->hide_canvas && !p_viewport->disable_environment && RSG::scene->scenario_owner.owns(p_viewport->scenario)) { - RenderingServerScene::Scenario *scenario = RSG::scene->scenario_owner.getornull(p_viewport->scenario); - ERR_FAIL_COND(!scenario); - if (RSG::scene_render->is_environment(scenario->environment)) { - scenario_draw_canvas_bg = RSG::scene_render->environment_get_background(scenario->environment) == RS::ENV_BG_CANVAS; - - scenario_canvas_max_layer = RSG::scene_render->environment_get_canvas_max_layer(scenario->environment); + if (!p_viewport->hide_canvas && !p_viewport->disable_environment && RSG::scene->is_scenario(p_viewport->scenario)) { + RID environment = RSG::scene->scenario_get_environment(p_viewport->scenario); + if (RSG::scene->is_environment(environment)) { + scenario_draw_canvas_bg = RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS; + scenario_canvas_max_layer = RSG::scene->environment_get_canvas_max_layer(environment); } } - bool can_draw_3d = RSG::scene->camera_owner.owns(p_viewport->camera); + bool can_draw_3d = RSG::scene->is_camera(p_viewport->camera); if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) { if (p_viewport->transparent_bg) { @@ -124,8 +122,8 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) { //wants to draw 3D but there is no render buffer, create - p_viewport->render_buffers = RSG::scene_render->render_buffers_create(); - RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding); + p_viewport->render_buffers = RSG::scene->render_buffers_create(); + RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding); } RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor); @@ -140,25 +138,25 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map; Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); - RasterizerCanvas::Light *lights = nullptr; - RasterizerCanvas::Light *lights_with_shadow = nullptr; + RendererCanvasRender::Light *lights = nullptr; + RendererCanvasRender::Light *lights_with_shadow = nullptr; - RasterizerCanvas::Light *directional_lights = nullptr; - RasterizerCanvas::Light *directional_lights_with_shadow = nullptr; + RendererCanvasRender::Light *directional_lights = nullptr; + RendererCanvasRender::Light *directional_lights_with_shadow = nullptr; if (p_viewport->sdf_active) { //process SDF Rect2 sdf_rect = RSG::storage->render_target_get_sdf_rect(p_viewport->render_target); - RasterizerCanvas::LightOccluderInstance *occluders = nullptr; + RendererCanvasRender::LightOccluderInstance *occluders = nullptr; //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); - for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { + for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) { continue; } @@ -184,14 +182,14 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RENDER_TIMESTAMP("Cull Canvas Lights"); for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); //find lights in canvas - for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { - RasterizerCanvas::Light *cl = F->get(); + for (Set<RendererCanvasRender::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { + RendererCanvasRender::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. Size2 tsize = RSG::storage->texture_size_with_proxy(cl->texture); @@ -228,8 +226,8 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } } - for (Set<RasterizerCanvas::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) { - RasterizerCanvas::Light *cl = F->get(); + for (Set<RendererCanvasRender::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) { + RendererCanvasRender::Light *cl = F->get(); if (cl->enabled) { cl->filter_next_ptr = directional_lights; directional_lights = cl; @@ -254,17 +252,17 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: if (lights_with_shadow) { //update shadows if any - RasterizerCanvas::LightOccluderInstance *occluders = nullptr; + RendererCanvasRender::LightOccluderInstance *occluders = nullptr; RENDER_TIMESTAMP(">Render 2D Shadows"); RENDER_TIMESTAMP("Cull Occluders"); //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); - for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { + for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) { continue; } @@ -277,7 +275,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } //update the light shadowmaps with them - RasterizerCanvas::Light *light = lights_with_shadow; + RendererCanvasRender::Light *light = lights_with_shadow; while (light) { RENDER_TIMESTAMP("Render Shadow"); @@ -290,7 +288,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: if (directional_lights_with_shadow) { //update shadows if any - RasterizerCanvas::Light *light = directional_lights_with_shadow; + RendererCanvasRender::Light *light = directional_lights_with_shadow; while (light) { Vector2 light_dir = -light->xform_cache.elements[1].normalized(); // Y is light direction float cull_distance = light->directional_distance; @@ -335,17 +333,17 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Vector2 xf_points[6]; - RasterizerCanvas::LightOccluderInstance *occluders = nullptr; + RendererCanvasRender::LightOccluderInstance *occluders = nullptr; RENDER_TIMESTAMP(">Render Directional 2D Shadows"); //make list of occluders int occ_cullded = 0; for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); - for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { + for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) { continue; } @@ -381,14 +379,14 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get()->canvas); + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get()->canvas); Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); - RasterizerCanvas::Light *canvas_lights = nullptr; - RasterizerCanvas::Light *canvas_directional_lights = nullptr; + RendererCanvasRender::Light *canvas_lights = nullptr; + RendererCanvasRender::Light *canvas_directional_lights = nullptr; - RasterizerCanvas::Light *ptr = lights; + RendererCanvasRender::Light *ptr = lights; while (ptr) { if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { ptr->next_ptr = canvas_lights; @@ -444,7 +442,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } } -void RenderingServerViewport::draw_viewports() { +void RendererViewport::draw_viewports() { timestamp_vp_map.clear(); // get our xr interface in case we need it @@ -464,7 +462,7 @@ void RenderingServerViewport::draw_viewports() { //sort viewports active_viewports.sort_custom<ViewportSort>(); - Map<DisplayServer::WindowID, Vector<Rasterizer::BlitToScreen>> blit_to_screen_list; + Map<DisplayServer::WindowID, Vector<RendererCompositor::BlitToScreen>> blit_to_screen_list; //draw viewports RENDER_TIMESTAMP(">Render Viewports"); @@ -559,7 +557,7 @@ void RenderingServerViewport::draw_viewports() { { RSG::storage->render_target_set_external_texture(vp->render_target, 0); - RSG::scene_render->set_debug_draw_mode(vp->debug_draw); + RSG::scene->set_debug_draw_mode(vp->debug_draw); RSG::storage->render_info_begin_capture(); // render standard mono camera @@ -575,7 +573,7 @@ void RenderingServerViewport::draw_viewports() { if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !RSG::rasterizer->is_low_end())) { //copy to screen if set as such - Rasterizer::BlitToScreen blit; + RendererCompositor::BlitToScreen blit; blit.render_target = vp->render_target; if (vp->viewport_to_screen_rect != Rect2()) { blit.rect = vp->viewport_to_screen_rect; @@ -585,7 +583,7 @@ void RenderingServerViewport::draw_viewports() { } if (!blit_to_screen_list.has(vp->viewport_to_screen)) { - blit_to_screen_list[vp->viewport_to_screen] = Vector<Rasterizer::BlitToScreen>(); + blit_to_screen_list[vp->viewport_to_screen] = Vector<RendererCompositor::BlitToScreen>(); } blit_to_screen_list[vp->viewport_to_screen].push_back(blit); @@ -598,18 +596,18 @@ void RenderingServerViewport::draw_viewports() { RENDER_TIMESTAMP("<Rendering Viewport " + itos(i)); } - RSG::scene_render->set_debug_draw_mode(RS::VIEWPORT_DEBUG_DRAW_DISABLED); + RSG::scene->set_debug_draw_mode(RS::VIEWPORT_DEBUG_DRAW_DISABLED); RENDER_TIMESTAMP("<Render Viewports"); //this needs to be called to make screen swapping more efficient RSG::rasterizer->prepare_for_blitting_render_targets(); - for (Map<int, Vector<Rasterizer::BlitToScreen>>::Element *E = blit_to_screen_list.front(); E; E = E->next()) { + for (Map<int, Vector<RendererCompositor::BlitToScreen>>::Element *E = blit_to_screen_list.front(); E; E = E->next()) { RSG::rasterizer->blit_render_targets_to_screen(E->key(), E->get().ptr(), E->get().size()); } } -RID RenderingServerViewport::viewport_create() { +RID RendererViewport::viewport_create() { Viewport *viewport = memnew(Viewport); RID rid = viewport_owner.make_rid(viewport); @@ -618,20 +616,20 @@ RID RenderingServerViewport::viewport_create() { viewport->hide_scenario = false; viewport->hide_canvas = false; viewport->render_target = RSG::storage->render_target_create(); - viewport->shadow_atlas = RSG::scene_render->shadow_atlas_create(); + viewport->shadow_atlas = RSG::scene->shadow_atlas_create(); viewport->viewport_render_direct_to_screen = false; return rid; } -void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { +void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->use_xr = p_use_xr; } -void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { +void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { ERR_FAIL_COND(p_width < 0 && p_height < 0); Viewport *viewport = viewport_owner.getornull(p_viewport); @@ -641,15 +639,15 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height); if (viewport->render_buffers.is_valid()) { if (p_width == 0 || p_height == 0) { - RSG::scene_render->free(viewport->render_buffers); + RSG::scene->free(viewport->render_buffers); viewport->render_buffers = RID(); } else { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding); + RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding); } } } -void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) { +void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -661,21 +659,21 @@ void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) } } -void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) { +void RendererViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->parent = p_parent_viewport; } -void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) { +void RendererViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->clear_mode = p_clear_mode; } -void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) { +void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -701,7 +699,7 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re } } -void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) { +void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -715,7 +713,7 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); } - RSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable); + RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable); viewport->viewport_render_direct_to_screen = p_enable; // if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation @@ -725,61 +723,61 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor } } -void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) { +void RendererViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->update_mode = p_mode; } -RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const { +RID RendererViewport::viewport_get_texture(RID p_viewport) const { const Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, RID()); return RSG::storage->render_target_get_texture(viewport->render_target); } -void RenderingServerViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) { +void RendererViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->hide_scenario = p_hide; } -void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) { +void RendererViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->hide_canvas = p_hide; } -void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { +void RendererViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->disable_environment = p_disable; } -void RenderingServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) { +void RendererViewport::viewport_attach_camera(RID p_viewport, RID p_camera) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->camera = p_camera; } -void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { +void RendererViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->scenario = p_scenario; } -void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { +void RendererViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); ERR_FAIL_COND(viewport->canvas_map.has(p_canvas)); - RenderingServerCanvas::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas); + RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); canvas->viewports.insert(p_viewport); @@ -789,18 +787,18 @@ void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canva viewport->canvas_map[p_canvas].canvas = canvas; } -void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) { +void RendererViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - RenderingServerCanvas::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas); + RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); viewport->canvas_map.erase(p_canvas); canvas->viewports.erase(p_viewport); } -void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { +void RendererViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -808,22 +806,22 @@ void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID viewport->canvas_map[p_canvas].transform = p_offset; } -void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { +void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - RSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_TRANSPARENT, p_enabled); + RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_TRANSPARENT, p_enabled); viewport->transparent_bg = p_enabled; } -void RenderingServerViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) { +void RendererViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->global_transform = p_transform; } -void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) { +void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -832,23 +830,23 @@ void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p viewport->canvas_map[p_canvas].sublayer = p_sublayer; } -void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) { +void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->shadow_atlas_size = p_size; - RSG::scene_render->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size); + RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size); } -void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { +void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - RSG::scene_render->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv); + RSG::scene->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv); } -void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) { +void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -857,11 +855,11 @@ void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA } viewport->msaa = p_msaa; if (viewport->render_buffers.is_valid()) { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding); + RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding); } } -void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) { +void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -870,11 +868,11 @@ void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::V } viewport->screen_space_aa = p_mode; if (viewport->render_buffers.is_valid()) { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding); + RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding); } } -void RenderingServerViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) { +void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -883,11 +881,11 @@ void RenderingServerViewport::viewport_set_use_debanding(RID p_viewport, bool p_ } viewport->use_debanding = p_use_debanding; if (viewport->render_buffers.is_valid()) { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding); + RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding); } } -int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) { +int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) { ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1); Viewport *viewport = viewport_owner.getornull(p_viewport); @@ -898,54 +896,54 @@ int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::Viewpo return viewport->render_info[p_info]; } -void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) { +void RendererViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->debug_draw = p_draw; } -void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) { +void RendererViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->measure_render_time = p_enable; } -float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const { +float RendererViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, 0); return double(viewport->time_cpu_end - viewport->time_cpu_begin) / 1000.0; } -float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const { +float RendererViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, 0); return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0; } -void RenderingServerViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) { +void RendererViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->snap_2d_transforms_to_pixel = p_enabled; } -void RenderingServerViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) { +void RendererViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->snap_2d_vertices_to_pixel = p_enabled; } -void RenderingServerViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) { +void RendererViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) { ERR_FAIL_COND_MSG(p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, "Viewport does not accept DEFAULT as texture filter (it's the topmost choice already).)"); Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->texture_filter = p_filter; } -void RenderingServerViewport::viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat) { +void RendererViewport::viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat) { ERR_FAIL_COND_MSG(p_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, "Viewport does not accept DEFAULT as texture repeat (it's the topmost choice already).)"); Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -953,21 +951,21 @@ void RenderingServerViewport::viewport_set_default_canvas_item_texture_repeat(RI viewport->texture_repeat = p_repeat; } -void RenderingServerViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { +void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); RSG::storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale); } -bool RenderingServerViewport::free(RID p_rid) { +bool RendererViewport::free(RID p_rid) { if (viewport_owner.owns(p_rid)) { Viewport *viewport = viewport_owner.getornull(p_rid); RSG::storage->free(viewport->render_target); - RSG::scene_render->free(viewport->shadow_atlas); + RSG::scene->free(viewport->shadow_atlas); if (viewport->render_buffers.is_valid()) { - RSG::scene_render->free(viewport->render_buffers); + RSG::scene->free(viewport->render_buffers); } while (viewport->canvas_map.front()) { @@ -986,7 +984,7 @@ bool RenderingServerViewport::free(RID p_rid) { return false; } -void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) { +void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) { RID *vp = timestamp_vp_map.getptr(p_timestamp); if (!vp) { return; @@ -1008,9 +1006,9 @@ void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cp } } -void RenderingServerViewport::set_default_clear_color(const Color &p_color) { +void RendererViewport::set_default_clear_color(const Color &p_color) { RSG::storage->set_default_clear_color(p_color); } -RenderingServerViewport::RenderingServerViewport() { +RendererViewport::RendererViewport() { } diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/renderer_viewport.h index ba55b2e66e..6634ef66e2 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_viewport.h */ +/* renderer_viewport.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -33,11 +33,11 @@ #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" -#include "rasterizer.h" +#include "renderer_compositor.h" #include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" -class RenderingServerViewport { +class RendererViewport { public: struct CanvasBase { }; @@ -244,8 +244,8 @@ public: bool free(RID p_rid); - RenderingServerViewport(); - virtual ~RenderingServerViewport() {} + RendererViewport(); + virtual ~RendererViewport() {} }; #endif // VISUALSERVERVIEWPORT_H diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index f1f8b3cda0..5fa37c2ce4 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -392,7 +392,7 @@ public: uint32_t depth; uint32_t array_layers; uint32_t mipmaps; - TextureType type; + TextureType texture_type; TextureSamples samples; uint32_t usage_bits; Vector<DataFormat> shareable_formats; @@ -404,7 +404,7 @@ public: depth = 1; array_layers = 1; mipmaps = 1; - type = TEXTURE_TYPE_2D; + texture_type = TEXTURE_TYPE_2D; samples = TEXTURE_SAMPLES_1; usage_bits = 0; } @@ -629,7 +629,7 @@ public: virtual RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>()) = 0; struct Uniform { - UniformType type; + UniformType uniform_type; int binding; //binding index as specified in shader //for single items, provide one ID, for @@ -640,7 +640,7 @@ public: Vector<RID> ids; Uniform() { - type = UNIFORM_TYPE_IMAGE; + uniform_type = UNIFORM_TYPE_IMAGE; binding = 0; } }; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index 66c6a1c3a9..5deeec3ffe 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -64,7 +64,7 @@ public: RD_SETGET(uint32_t, depth) RD_SETGET(uint32_t, array_layers) RD_SETGET(uint32_t, mipmaps) - RD_SETGET(RD::TextureType, type) + RD_SETGET(RD::TextureType, texture_type) RD_SETGET(RD::TextureSamples, samples) RD_SETGET(uint32_t, usage_bits) @@ -79,7 +79,7 @@ protected: RD_BIND(Variant::INT, RDTextureFormat, depth); RD_BIND(Variant::INT, RDTextureFormat, array_layers); RD_BIND(Variant::INT, RDTextureFormat, mipmaps); - RD_BIND(Variant::INT, RDTextureFormat, type); + RD_BIND(Variant::INT, RDTextureFormat, texture_type); RD_BIND(Variant::INT, RDTextureFormat, samples); RD_BIND(Variant::INT, RDTextureFormat, usage_bits); ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format); @@ -392,7 +392,7 @@ class RDUniform : public Reference { RD::Uniform base; public: - RD_SETGET(RD::UniformType, type) + RD_SETGET(RD::UniformType, uniform_type) RD_SETGET(int32_t, binding) void add_id(const RID &p_id) { base.ids.push_back(p_id); } @@ -415,7 +415,7 @@ protected: } } static void _bind_methods() { - RD_BIND(Variant::INT, RDUniform, type); + RD_BIND(Variant::INT, RDUniform, uniform_type); RD_BIND(Variant::INT, RDUniform, binding); ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id); ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids); diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_default.cpp index 94cfb6b752..47f7fa07d5 100644 --- a/servers/rendering/rendering_server_raster.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_raster.cpp */ +/* rendering_server_default.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,43 +28,43 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rendering_server_raster.h" +#include "rendering_server_default.h" #include "core/config/project_settings.h" #include "core/io/marshalls.h" #include "core/os/os.h" #include "core/templates/sort_array.h" -#include "rendering_server_canvas.h" +#include "renderer_canvas_cull.h" +#include "renderer_scene_cull.h" #include "rendering_server_globals.h" -#include "rendering_server_scene.h" // careful, these may run in different threads than the visual server -int RenderingServerRaster::changes = 0; +int RenderingServerDefault::changes = 0; /* BLACK BARS */ -void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) { +void RenderingServerDefault::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) { black_margin[MARGIN_LEFT] = p_left; black_margin[MARGIN_TOP] = p_top; black_margin[MARGIN_RIGHT] = p_right; black_margin[MARGIN_BOTTOM] = p_bottom; } -void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) { +void RenderingServerDefault::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) { black_image[MARGIN_LEFT] = p_left; black_image[MARGIN_TOP] = p_top; black_image[MARGIN_RIGHT] = p_right; black_image[MARGIN_BOTTOM] = p_bottom; } -void RenderingServerRaster::_draw_margins() { +void RenderingServerDefault::_draw_margins() { RSG::canvas_render->draw_window_margins(black_margin, black_image); }; /* FREE */ -void RenderingServerRaster::free(RID p_rid) { +void RenderingServerDefault::free(RID p_rid) { if (RSG::storage->free(p_rid)) { return; } @@ -77,14 +77,11 @@ void RenderingServerRaster::free(RID p_rid) { if (RSG::scene->free(p_rid)) { return; } - if (RSG::scene_render->free(p_rid)) { - return; - } } /* EVENT QUEUING */ -void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) { +void RenderingServerDefault::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) { ERR_FAIL_NULL(p_where); FrameDrawnCallbacks fdc; fdc.object = p_where->get_instance_id(); @@ -94,7 +91,7 @@ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const frame_drawn_callbacks.push_back(fdc); } -void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { +void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) { //needs to be done before changes is reset to 0, to not force the editor to redraw RS::get_singleton()->emit_signal("frame_pre_draw"); @@ -104,11 +101,8 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { TIMESTAMP_BEGIN() - RSG::scene_render->update(); //update scenes stuff before updating instances - - RSG::scene->update_dirty_instances(); //update scene stuff + RSG::scene->update(); //update scenes stuff before updating instances - RSG::scene->render_particle_colliders(); RSG::storage->update_particles(); //need to be done after instances are updated (colliders and particle transforms), and colliders are rendered RSG::scene->render_probes(); @@ -165,18 +159,18 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { frame_profile_frame = RSG::storage->get_captured_timestamps_frame(); } -void RenderingServerRaster::sync() { +void RenderingServerDefault::sync() { } -bool RenderingServerRaster::has_changed() const { +bool RenderingServerDefault::has_changed() const { return changes > 0; } -void RenderingServerRaster::init() { +void RenderingServerDefault::init() { RSG::rasterizer->initialize(); } -void RenderingServerRaster::finish() { +void RenderingServerDefault::finish() { if (test_cube.is_valid()) { free(test_cube); } @@ -186,69 +180,69 @@ void RenderingServerRaster::finish() { /* STATUS INFORMATION */ -int RenderingServerRaster::get_render_info(RenderInfo p_info) { +int RenderingServerDefault::get_render_info(RenderInfo p_info) { return RSG::storage->get_render_info(p_info); } -String RenderingServerRaster::get_video_adapter_name() const { +String RenderingServerDefault::get_video_adapter_name() const { return RSG::storage->get_video_adapter_name(); } -String RenderingServerRaster::get_video_adapter_vendor() const { +String RenderingServerDefault::get_video_adapter_vendor() const { return RSG::storage->get_video_adapter_vendor(); } -void RenderingServerRaster::set_frame_profiling_enabled(bool p_enable) { +void RenderingServerDefault::set_frame_profiling_enabled(bool p_enable) { RSG::storage->capturing_timestamps = p_enable; } -uint64_t RenderingServerRaster::get_frame_profile_frame() { +uint64_t RenderingServerDefault::get_frame_profile_frame() { return frame_profile_frame; } -Vector<RenderingServer::FrameProfileArea> RenderingServerRaster::get_frame_profile() { +Vector<RenderingServer::FrameProfileArea> RenderingServerDefault::get_frame_profile() { return frame_profile; } /* TESTING */ -void RenderingServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { +void RenderingServerDefault::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { redraw_request(); RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter); } -void RenderingServerRaster::set_default_clear_color(const Color &p_color) { +void RenderingServerDefault::set_default_clear_color(const Color &p_color) { RSG::viewport->set_default_clear_color(p_color); } -bool RenderingServerRaster::has_feature(Features p_feature) const { +bool RenderingServerDefault::has_feature(Features p_feature) const { return false; } -void RenderingServerRaster::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { - RSG::scene_render->sdfgi_set_debug_probe_select(p_position, p_dir); +void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { + RSG::scene->sdfgi_set_debug_probe_select(p_position, p_dir); } -RID RenderingServerRaster::get_test_cube() { +RID RenderingServerDefault::get_test_cube() { if (!test_cube.is_valid()) { test_cube = _make_test_cube(); } return test_cube; } -bool RenderingServerRaster::has_os_feature(const String &p_feature) const { +bool RenderingServerDefault::has_os_feature(const String &p_feature) const { return RSG::storage->has_os_feature(p_feature); } -void RenderingServerRaster::set_debug_generate_wireframes(bool p_generate) { +void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) { RSG::storage->set_debug_generate_wireframes(p_generate); } -void RenderingServerRaster::call_set_use_vsync(bool p_enable) { +void RenderingServerDefault::call_set_use_vsync(bool p_enable) { DisplayServer::get_singleton()->_set_use_vsync(p_enable); } -bool RenderingServerRaster::is_low_end() const { +bool RenderingServerDefault::is_low_end() const { // FIXME: Commented out when rebasing vulkan branch on master, // causes a crash, it seems rasterizer is not initialized yet the // first time it's called. @@ -256,14 +250,15 @@ bool RenderingServerRaster::is_low_end() const { return false; } -RenderingServerRaster::RenderingServerRaster() { - RSG::canvas = memnew(RenderingServerCanvas); - RSG::viewport = memnew(RenderingServerViewport); - RSG::scene = memnew(RenderingServerScene); - RSG::rasterizer = Rasterizer::create(); +RenderingServerDefault::RenderingServerDefault() { + RSG::canvas = memnew(RendererCanvasCull); + RSG::viewport = memnew(RendererViewport); + RendererSceneCull *sr = memnew(RendererSceneCull); + RSG::scene = sr; + RSG::rasterizer = RendererCompositor::create(); RSG::storage = RSG::rasterizer->get_storage(); RSG::canvas_render = RSG::rasterizer->get_canvas(); - RSG::scene_render = RSG::rasterizer->get_scene(); + sr->scene_render = RSG::rasterizer->get_scene(); frame_profile_frame = 0; @@ -273,7 +268,7 @@ RenderingServerRaster::RenderingServerRaster() { } } -RenderingServerRaster::~RenderingServerRaster() { +RenderingServerDefault::~RenderingServerDefault() { memdelete(RSG::canvas); memdelete(RSG::viewport); memdelete(RSG::rasterizer); diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_default.h index 76ceccb3c5..e75fd0ee53 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_default.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rendering_server_raster.h */ +/* rendering_server_default.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_RASTER_H -#define RENDERING_SERVER_RASTER_H +#ifndef RENDERING_SERVER_DEFAULT_H +#define RENDERING_SERVER_DEFAULT_H #include "core/math/octree.h" -#include "rendering_server_canvas.h" +#include "renderer_canvas_cull.h" +#include "renderer_scene_cull.h" +#include "renderer_viewport.h" #include "rendering_server_globals.h" -#include "rendering_server_scene.h" -#include "rendering_server_viewport.h" -#include "servers/rendering/rasterizer.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" -class RenderingServerRaster : public RenderingServer { +class RenderingServerDefault : public RenderingServer { enum { MAX_INSTANCE_CULL = 8192, MAX_INSTANCE_LIGHTS = 4, @@ -554,7 +554,7 @@ public: #undef BINDBASE //from now on, calls forwarded to this singleton -#define BINDBASE RSG::scene_render +#define BINDBASE RSG::scene BIND1(directional_shadow_atlas_set_size, int) BIND1(gi_probe_set_quality, GIProbeQuality) @@ -853,8 +853,8 @@ public: virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir); - RenderingServerRaster(); - ~RenderingServerRaster(); + RenderingServerDefault(); + ~RenderingServerDefault(); #undef DISPLAY_CHANGED diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp index 5a270520a9..b9df36e93a 100644 --- a/servers/rendering/rendering_server_globals.cpp +++ b/servers/rendering/rendering_server_globals.cpp @@ -30,11 +30,10 @@ #include "rendering_server_globals.h" -RasterizerStorage *RenderingServerGlobals::storage = nullptr; -RasterizerCanvas *RenderingServerGlobals::canvas_render = nullptr; -RasterizerScene *RenderingServerGlobals::scene_render = nullptr; -Rasterizer *RenderingServerGlobals::rasterizer = nullptr; +RendererStorage *RenderingServerGlobals::storage = nullptr; +RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr; +RendererCompositor *RenderingServerGlobals::rasterizer = nullptr; -RenderingServerCanvas *RenderingServerGlobals::canvas = nullptr; -RenderingServerViewport *RenderingServerGlobals::viewport = nullptr; -RenderingServerScene *RenderingServerGlobals::scene = nullptr; +RendererCanvasCull *RenderingServerGlobals::canvas = nullptr; +RendererViewport *RenderingServerGlobals::viewport = nullptr; +RendererScene *RenderingServerGlobals::scene = nullptr; diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h index b33f328b69..580526f7e0 100644 --- a/servers/rendering/rendering_server_globals.h +++ b/servers/rendering/rendering_server_globals.h @@ -31,22 +31,23 @@ #ifndef RENDERING_SERVER_GLOBALS_H #define RENDERING_SERVER_GLOBALS_H -#include "rasterizer.h" +#include "servers/rendering/renderer_canvas_cull.h" +#include "servers/rendering/renderer_canvas_render.h" +#include "servers/rendering/renderer_scene.h" -class RenderingServerCanvas; -class RenderingServerViewport; -class RenderingServerScene; +class RendererCanvasCull; +class RendererViewport; +class RendererScene; class RenderingServerGlobals { public: - static RasterizerStorage *storage; - static RasterizerCanvas *canvas_render; - static RasterizerScene *scene_render; - static Rasterizer *rasterizer; + static RendererStorage *storage; + static RendererCanvasRender *canvas_render; + static RendererCompositor *rasterizer; - static RenderingServerCanvas *canvas; - static RenderingServerViewport *viewport; - static RenderingServerScene *scene; + static RendererCanvasCull *canvas; + static RendererViewport *viewport; + static RendererScene *scene; }; #define RSG RenderingServerGlobals diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 1ab353c9d0..2f7e950841 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -223,7 +223,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { String ShaderLanguage::get_token_text(Token p_token) { String name = token_names[p_token.type]; - if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_REAL_CONSTANT) { + if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_FLOAT_CONSTANT) { name += "(" + rtos(p_token.constant) + ")"; } else if (p_token.type == TK_IDENTIFIER) { name += "(" + String(p_token.text) + ")"; @@ -637,7 +637,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { char_idx += str.length(); Token tk; if (period_found || exponent_found || float_suffix_found) { - tk.type = TK_REAL_CONSTANT; + tk.type = TK_FLOAT_CONSTANT; } else { tk.type = TK_INT_CONSTANT; } @@ -3269,7 +3269,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons return nullptr; } - } else if (tk.type == TK_REAL_CONSTANT) { + } else if (tk.type == TK_FLOAT_CONSTANT) { ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; v.real = tk.constant; @@ -6260,7 +6260,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); } - if (tk.type != TK_REAL_CONSTANT && tk.type != TK_INT_CONSTANT) { + if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) { _set_error("Expected integer constant"); return ERR_PARSE_ERROR; } @@ -6284,7 +6284,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); } - if (tk.type != TK_REAL_CONSTANT && tk.type != TK_INT_CONSTANT) { + if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) { _set_error("Expected integer constant after ','"); return ERR_PARSE_ERROR; } @@ -6297,7 +6297,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct if (tk.type == TK_COMMA) { tk = _get_token(); - if (tk.type != TK_REAL_CONSTANT && tk.type != TK_INT_CONSTANT) { + if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) { _set_error("Expected integer constant after ','"); return ERR_PARSE_ERROR; } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 3a9f408dc0..cb77324489 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -46,7 +46,7 @@ public: TK_IDENTIFIER, TK_TRUE, TK_FALSE, - TK_REAL_CONSTANT, + TK_FLOAT_CONSTANT, TK_INT_CONSTANT, TK_TYPE_VOID, TK_TYPE_BOOL, diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index bd61f2a549..0c9b2ddf2f 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -67,6 +67,12 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_INDICES"] = ShaderLanguage::TYPE_UVEC4; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_WEIGHTS"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM0"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM1"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM2"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM3"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].can_discard = false; //builtins diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 9c8342b34d..433b56ab41 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -315,8 +315,10 @@ RID RenderingServer::get_white_texture() { #define SMALL_VEC2 Vector2(0.00001, 0.00001) #define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001) -Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, Vector<uint8_t> &r_vertex_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) { +Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) { uint8_t *vw = r_vertex_array.ptrw(); + uint8_t *aw = r_attrib_array.ptrw(); + uint8_t *sw = r_skin_array.ptrw(); uint8_t *iw = nullptr; if (r_index_array.size()) { @@ -345,7 +347,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint for (int i = 0; i < p_vertex_array_len; i++) { float vector[2] = { src[i].x, src[i].y }; - copymem(&vw[p_offsets[ai] + i * p_stride], vector, sizeof(float) * 2); + copymem(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(float) * 2); if (i == 0) { aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size @@ -370,7 +372,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint for (int i = 0; i < p_vertex_array_len; i++) { float vector[3] = { src[i].x, src[i].y, src[i].z }; - copymem(&vw[p_offsets[ai] + i * p_stride], vector, sizeof(float) * 3); + copymem(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(float) * 3); if (i == 0) { aabb = AABB(src[i], SMALL_VEC3); @@ -391,26 +393,15 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint ERR_FAIL_COND_V(array.size() != p_vertex_array_len, ERR_INVALID_PARAMETER); const Vector3 *src = array.ptr(); + for (int i = 0; i < p_vertex_array_len; i++) { + Vector3 n = src[i] * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - // setting vertices means regenerating the AABB + uint32_t value = 0; + value |= CLAMP(int(n.x * 1023.0), 0, 1023); + value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; + value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; - if (p_format & ARRAY_COMPRESS_NORMAL) { - for (int i = 0; i < p_vertex_array_len; i++) { - int8_t vector[4] = { - (int8_t)CLAMP(src[i].x * 127, -128, 127), - (int8_t)CLAMP(src[i].y * 127, -128, 127), - (int8_t)CLAMP(src[i].z * 127, -128, 127), - 0, - }; - - copymem(&vw[p_offsets[ai] + i * p_stride], vector, 4); - } - - } else { - for (int i = 0; i < p_vertex_array_len; i++) { - float vector[3] = { src[i].x, src[i].y, src[i].z }; - copymem(&vw[p_offsets[ai] + i * p_stride], vector, 3 * 4); - } + copymem(&vw[p_offsets[ai] + i * p_vertex_stride], &value, 4); } } break; @@ -424,29 +415,14 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const real_t *src = array.ptr(); - if (p_format & ARRAY_COMPRESS_TANGENT) { - for (int i = 0; i < p_vertex_array_len; i++) { - int8_t xyzw[4] = { - (int8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127), - (int8_t)CLAMP(src[i * 4 + 1] * 127, -128, 127), - (int8_t)CLAMP(src[i * 4 + 2] * 127, -128, 127), - (int8_t)CLAMP(src[i * 4 + 3] * 127, -128, 127) - }; - - copymem(&vw[p_offsets[ai] + i * p_stride], xyzw, 4); - } + for (int i = 0; i < p_vertex_array_len; i++) { + uint32_t value = 0; + value |= CLAMP(int((src[i * 4 + 0] * 0.5 + 0.5) * 1023.0), 0, 1023); + value |= CLAMP(int((src[i * 4 + 1] * 0.5 + 0.5) * 1023.0), 0, 1023) << 10; + value |= CLAMP(int((src[i * 4 + 2] * 0.5 + 0.5) * 1023.0), 0, 1023) << 20; + value |= CLAMP(int((src[i * 4 + 3] * 0.5 + 0.5) * 3.0), 0, 3) << 30; - } else { - for (int i = 0; i < p_vertex_array_len; i++) { - float xyzw[4] = { - src[i * 4 + 0], - src[i * 4 + 1], - src[i * 4 + 2], - src[i * 4 + 3] - }; - - copymem(&vw[p_offsets[ai] + i * p_stride], xyzw, 4 * 4); - } + copymem(&vw[p_offsets[ai] + i * p_vertex_stride], &value, 4); } } break; @@ -458,23 +434,14 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint ERR_FAIL_COND_V(array.size() != p_vertex_array_len, ERR_INVALID_PARAMETER); const Color *src = array.ptr(); - - if (p_format & ARRAY_COMPRESS_COLOR) { - for (int i = 0; i < p_vertex_array_len; i++) { - uint8_t colors[4]; - - for (int j = 0; j < 4; j++) { - colors[j] = CLAMP(int((src[i][j]) * 255.0), 0, 255); - } - - copymem(&vw[p_offsets[ai] + i * p_stride], colors, 4); - } - } else { - for (int i = 0; i < p_vertex_array_len; i++) { - copymem(&vw[p_offsets[ai] + i * p_stride], &src[i], 4 * 4); - } + uint16_t color16[4]; + for (int i = 0; i < p_vertex_array_len; i++) { + color16[0] = Math::make_half_float(src[i].r); + color16[1] = Math::make_half_float(src[i].g); + color16[2] = Math::make_half_float(src[i].b); + color16[3] = Math::make_half_float(src[i].a); + copymem(&aw[p_offsets[ai] + i * p_attrib_stride], color16, 8); } - } break; case RS::ARRAY_TEX_UV: { ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_VECTOR2_ARRAY, ERR_INVALID_PARAMETER); @@ -485,18 +452,10 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const Vector2 *src = array.ptr(); - if (p_format & ARRAY_COMPRESS_TEX_UV) { - for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) }; - copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 2); - } - - } else { - for (int i = 0; i < p_vertex_array_len; i++) { - float uv[2] = { src[i].x, src[i].y }; + for (int i = 0; i < p_vertex_array_len; i++) { + float uv[2] = { src[i].x, src[i].y }; - copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 4); - } + copymem(&aw[p_offsets[ai] + i * p_attrib_stride], uv, 2 * 4); } } break; @@ -510,37 +469,90 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const Vector2 *src = array.ptr(); - if (p_format & ARRAY_COMPRESS_TEX_UV2) { - for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) }; - copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 2); - } + for (int i = 0; i < p_vertex_array_len; i++) { + uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) }; + copymem(&aw[p_offsets[ai] + i * p_attrib_stride], uv, 2 * 2); + } + } break; + case RS::ARRAY_CUSTOM0: + case RS::ARRAY_CUSTOM1: + case RS::ARRAY_CUSTOM2: + case RS::ARRAY_CUSTOM3: { + uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (RS::ARRAY_CUSTOM0 - ai))) & ARRAY_FORMAT_CUSTOM_MASK; + switch (type) { + case ARRAY_CUSTOM_RGBA8_UNORM: + case ARRAY_CUSTOM_RGBA8_SNORM: + case ARRAY_CUSTOM_RG_HALF: { + //size 4 + ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER); - } else { - for (int i = 0; i < p_vertex_array_len; i++) { - float uv[2] = { src[i].x, src[i].y }; + Vector<uint8_t> array = p_arrays[ai]; + + ERR_FAIL_COND_V(array.size() != p_vertex_array_len * 4, ERR_INVALID_PARAMETER); + + const uint8_t *src = array.ptr(); + + for (int i = 0; i < p_vertex_array_len; i++) { + copymem(&aw[p_offsets[ai] + i * p_attrib_stride], &src[i * 4], 4); + } + + } break; + case ARRAY_CUSTOM_RGBA_HALF: { + //size 8 + ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER); + + Vector<uint8_t> array = p_arrays[ai]; + + ERR_FAIL_COND_V(array.size() != p_vertex_array_len * 8, ERR_INVALID_PARAMETER); + + const uint8_t *src = array.ptr(); - copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 4); + for (int i = 0; i < p_vertex_array_len; i++) { + copymem(&aw[p_offsets[ai] + i * p_attrib_stride], &src[i * 8], 8); + } + } break; + case ARRAY_CUSTOM_R_FLOAT: + case ARRAY_CUSTOM_RG_FLOAT: + case ARRAY_CUSTOM_RGB_FLOAT: + case ARRAY_CUSTOM_RGBA_FLOAT: { + //RF + ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER); + + Vector<float> array = p_arrays[ai]; + int32_t s = ARRAY_CUSTOM_R_FLOAT - ai + 1; + + ERR_FAIL_COND_V(array.size() != p_vertex_array_len * s, ERR_INVALID_PARAMETER); + + const float *src = array.ptr(); + + for (int i = 0; i < p_vertex_array_len; i++) { + copymem(&aw[p_offsets[ai] + i * p_attrib_stride], &src[i * s], 4 * s); + } + } break; + default: { } } + } break; case RS::ARRAY_WEIGHTS: { ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER); + uint32_t bone_count = (p_format & ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4; + Vector<real_t> array = p_arrays[ai]; - ERR_FAIL_COND_V(array.size() != p_vertex_array_len * RS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(array.size() != (int32_t)(p_vertex_array_len * bone_count), ERR_INVALID_PARAMETER); const real_t *src = array.ptr(); { + uint16_t data[8]; for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t data[RS::ARRAY_WEIGHTS_SIZE]; - for (int j = 0; j < RS::ARRAY_WEIGHTS_SIZE; j++) { - data[j] = CLAMP(src[i * RS::ARRAY_WEIGHTS_SIZE + j] * 65535, 0, 65535); + for (uint32_t j = 0; j < bone_count; j++) { + data[j] = CLAMP(src[i * bone_count + j] * 65535, 0, 65535); } - copymem(&vw[p_offsets[ai] + i * p_stride], data, 2 * 4); + copymem(&sw[p_offsets[ai] + i * p_skin_stride], data, 2 * bone_count); } } @@ -550,21 +562,25 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint Vector<int> array = p_arrays[ai]; - ERR_FAIL_COND_V(array.size() != p_vertex_array_len * RS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER); + uint32_t bone_count = (p_format & ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4; + + ERR_FAIL_COND_V(array.size() != (int32_t)(p_vertex_array_len * bone_count), ERR_INVALID_PARAMETER); const int *src = array.ptr(); + uint16_t data[8]; + for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t data[RS::ARRAY_WEIGHTS_SIZE]; - for (int j = 0; j < RS::ARRAY_WEIGHTS_SIZE; j++) { - data[j] = src[i * RS::ARRAY_WEIGHTS_SIZE + j]; + for (uint32_t j = 0; j < bone_count; j++) { + data[j] = src[i * bone_count + j]; max_bone = MAX(data[j], max_bone); } - copymem(&vw[p_offsets[ai] + i * p_stride], data, 2 * 4); + copymem(&sw[p_offsets[ai] + i * p_skin_stride], data, 2 * bone_count); } } break; + case RS::ARRAY_INDEX: { ERR_FAIL_NULL_V(iw, ERR_INVALID_DATA); ERR_FAIL_COND_V(p_index_array_len <= 0, ERR_INVALID_DATA); @@ -652,23 +668,62 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint return OK; } -uint32_t RenderingServer::mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const { +uint32_t RenderingServer::mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_array_index) const { + p_format &= ~ARRAY_FORMAT_INDEX; uint32_t offsets[ARRAY_MAX]; - mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets); + uint32_t vstr; + uint32_t astr; + uint32_t sstr; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, 0, offsets, vstr, astr, sstr); return offsets[p_array_index]; } -uint32_t RenderingServer::mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const { +uint32_t RenderingServer::mesh_surface_get_format_vertex_stride(uint32_t p_format, int p_vertex_len) const { + p_format &= ~ARRAY_FORMAT_INDEX; uint32_t offsets[ARRAY_MAX]; - return mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets); + uint32_t vstr; + uint32_t astr; + uint32_t sstr; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, 0, offsets, vstr, astr, sstr); + return vstr; } +uint32_t RenderingServer::mesh_surface_get_format_attribute_stride(uint32_t p_format, int p_vertex_len) const { + p_format &= ~ARRAY_FORMAT_INDEX; + uint32_t offsets[ARRAY_MAX]; + uint32_t vstr; + uint32_t astr; + uint32_t sstr; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, 0, offsets, vstr, astr, sstr); + return astr; +} +uint32_t RenderingServer::mesh_surface_get_format_skin_stride(uint32_t p_format, int p_vertex_len) const { + p_format &= ~ARRAY_FORMAT_INDEX; + uint32_t offsets[ARRAY_MAX]; + uint32_t vstr; + uint32_t astr; + uint32_t sstr; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, 0, offsets, vstr, astr, sstr); + return sstr; +} + +void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const { + r_vertex_element_size = 0; + r_attrib_element_size = 0; + r_skin_element_size = 0; -uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const { - int total_elem_size = 0; + uint32_t *size_accum; for (int i = 0; i < RS::ARRAY_MAX; i++) { r_offsets[i] = 0; //reset + if (i == RS::ARRAY_VERTEX) { + size_accum = &r_vertex_element_size; + } else if (i == RS::ARRAY_COLOR) { + size_accum = &r_attrib_element_size; + } else if (i == RS::ARRAY_BONES) { + size_accum = &r_skin_element_size; + } + if (!(p_format & (1 << i))) { // no array continue; } @@ -693,53 +748,64 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma } break; case RS::ARRAY_NORMAL: { - if (p_format & ARRAY_COMPRESS_NORMAL) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 3; - } - + elem_size = 4; } break; case RS::ARRAY_TANGENT: { - if (p_format & ARRAY_COMPRESS_TANGENT) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 4; - } - + elem_size = 4; } break; case RS::ARRAY_COLOR: { - if (p_format & ARRAY_COMPRESS_COLOR) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 4; - } + elem_size = 8; } break; case RS::ARRAY_TEX_UV: { - if (p_format & ARRAY_COMPRESS_TEX_UV) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 2; - } + elem_size = 8; } break; case RS::ARRAY_TEX_UV2: { - if (p_format & ARRAY_COMPRESS_TEX_UV2) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 2; - } + elem_size = 8; } break; + case RS::ARRAY_CUSTOM0: + case RS::ARRAY_CUSTOM1: + case RS::ARRAY_CUSTOM2: + case RS::ARRAY_CUSTOM3: { + uint32_t format = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + (ARRAY_FORMAT_CUSTOM_BITS * (i - ARRAY_CUSTOM0)))) & ARRAY_FORMAT_CUSTOM_MASK; + switch (format) { + case ARRAY_CUSTOM_RGBA8_UNORM: { + elem_size = 4; + } break; + case ARRAY_CUSTOM_RGBA8_SNORM: { + elem_size = 4; + } break; + case ARRAY_CUSTOM_RG_HALF: { + elem_size = 4; + } break; + case ARRAY_CUSTOM_RGBA_HALF: { + elem_size = 8; + } break; + case ARRAY_CUSTOM_R_FLOAT: { + elem_size = 4; + } break; + case ARRAY_CUSTOM_RG_FLOAT: { + elem_size = 8; + } break; + case ARRAY_CUSTOM_RGB_FLOAT: { + elem_size = 12; + } break; + case ARRAY_CUSTOM_RGBA_FLOAT: { + elem_size = 16; + } break; + } + } break; case RS::ARRAY_WEIGHTS: { - elem_size = sizeof(uint16_t) * 4; + uint32_t bone_count = (p_format & ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4; + elem_size = sizeof(uint16_t) * bone_count; } break; case RS::ARRAY_BONES: { - elem_size = sizeof(uint16_t) * 4; - + uint32_t bone_count = (p_format & ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4; + elem_size = sizeof(uint16_t) * bone_count; } break; case RS::ARRAY_INDEX: { if (p_index_len <= 0) { @@ -757,14 +823,13 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma continue; } default: { - ERR_FAIL_V(0); + ERR_FAIL(); } } - r_offsets[i] = total_elem_size; - total_elem_size += elem_size; + r_offsets[i] = (*size_accum); + (*size_accum) += elem_size; } - return total_elem_size; } Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_compress_format) { @@ -785,20 +850,20 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa format |= (1 << i); if (i == RS::ARRAY_VERTEX) { - Variant var = p_arrays[i]; - switch (var.get_type()) { + switch (p_arrays[i].get_type()) { case Variant::PACKED_VECTOR2_ARRAY: { - Vector<Vector2> v2 = var; + Vector<Vector2> v2 = p_arrays[i]; + array_len = v2.size(); } break; case Variant::PACKED_VECTOR3_ARRAY: { - Vector<Vector3> v3 = var; + Vector<Vector3> v3 = p_arrays[i]; + array_len = v3.size(); } break; default: { - Array v = var; + ERR_FAIL_V(ERR_INVALID_DATA); } break; } - array_len = PackedVector3Array(p_arrays[i]).size(); ERR_FAIL_COND_V(array_len == 0, ERR_INVALID_DATA); } else if (i == RS::ARRAY_INDEX) { index_array_len = PackedInt32Array(p_arrays[i]).size(); @@ -824,117 +889,28 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa uint32_t offsets[RS::ARRAY_MAX]; - int total_elem_size = 0; - - for (int i = 0; i < RS::ARRAY_MAX; i++) { - offsets[i] = 0; //reset - - if (!(format & (1 << i))) { // no array - continue; - } - - int elem_size = 0; - - switch (i) { - case RS::ARRAY_VERTEX: { - Variant arr = p_arrays[0]; - if (arr.get_type() == Variant::PACKED_VECTOR2_ARRAY) { - elem_size = 2; - p_compress_format |= ARRAY_FLAG_USE_2D_VERTICES; - } else if (arr.get_type() == Variant::PACKED_VECTOR3_ARRAY) { - p_compress_format &= ~ARRAY_FLAG_USE_2D_VERTICES; - elem_size = 3; - } else { - elem_size = (p_compress_format & ARRAY_FLAG_USE_2D_VERTICES) ? 2 : 3; - } - - { - elem_size *= sizeof(float); - } - - } break; - case RS::ARRAY_NORMAL: { - if (p_compress_format & ARRAY_COMPRESS_NORMAL) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 3; - } - - } break; - - case RS::ARRAY_TANGENT: { - if (p_compress_format & ARRAY_COMPRESS_TANGENT) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 4; - } - - } break; - case RS::ARRAY_COLOR: { - if (p_compress_format & ARRAY_COMPRESS_COLOR) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 4; - } - } break; - case RS::ARRAY_TEX_UV: { - if (p_compress_format & ARRAY_COMPRESS_TEX_UV) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 2; - } - - } break; - - case RS::ARRAY_TEX_UV2: { - if (p_compress_format & ARRAY_COMPRESS_TEX_UV2) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 2; - } - - } break; - case RS::ARRAY_WEIGHTS: { - elem_size = sizeof(uint16_t) * 4; - - } break; - case RS::ARRAY_BONES: { - elem_size = sizeof(uint16_t) * 4; - - } break; - case RS::ARRAY_INDEX: { - if (index_array_len <= 0) { - ERR_PRINT("index_array_len==NO_INDEX_ARRAY"); - break; - } - /* determine whether using 16 or 32 bits indices */ - if (array_len >= (1 << 16)) { - elem_size = 4; - - } else { - elem_size = 2; - } - offsets[i] = elem_size; - continue; - } - default: { - ERR_FAIL_V(ERR_BUG); - } - } + uint32_t vertex_element_size; + uint32_t attrib_element_size; + uint32_t skin_element_size; - offsets[i] = total_elem_size; - total_elem_size += elem_size; - } + mesh_surface_make_offsets_from_format(format, array_len, index_array_len, offsets, vertex_element_size, attrib_element_size, skin_element_size); uint32_t mask = (1 << ARRAY_MAX) - 1; format |= (~mask) & p_compress_format; //make the full format - int array_size = total_elem_size * array_len; + int vertex_array_size = vertex_element_size * array_len; + int attrib_array_size = attrib_element_size * array_len; + int skin_array_size = skin_element_size * array_len; + int index_array_size = offsets[RS::ARRAY_INDEX] * index_array_len; Vector<uint8_t> vertex_array; - vertex_array.resize(array_size); + vertex_array.resize(vertex_array_size); - int index_array_size = offsets[RS::ARRAY_INDEX] * index_array_len; + Vector<uint8_t> attrib_array; + attrib_array.resize(attrib_array_size); + + Vector<uint8_t> skin_array; + skin_array.resize(skin_array_size); Vector<uint8_t> index_array; index_array.resize(index_array_size); @@ -942,22 +918,29 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa AABB aabb; Vector<AABB> bone_aabb; - Error err = _surface_set_data(p_arrays, format, offsets, total_elem_size, vertex_array, array_len, index_array, index_array_len, aabb, bone_aabb); + Error err = _surface_set_data(p_arrays, format, offsets, vertex_element_size, attrib_element_size, skin_element_size, vertex_array, attrib_array, skin_array, array_len, index_array, index_array_len, aabb, bone_aabb); ERR_FAIL_COND_V_MSG(err != OK, ERR_INVALID_DATA, "Invalid array format for surface."); - Vector<Vector<uint8_t>> blend_shape_data; - - for (int i = 0; i < p_blend_shapes.size(); i++) { - Vector<uint8_t> vertex_array_shape; - vertex_array_shape.resize(array_size); - Vector<uint8_t> noindex; + Vector<uint8_t> blend_shape_data; + uint32_t blend_shape_count = 0; - AABB laabb; - Error err2 = _surface_set_data(p_blend_shapes[i], format & ~ARRAY_FORMAT_INDEX, offsets, total_elem_size, vertex_array_shape, array_len, noindex, 0, laabb, bone_aabb); - aabb.merge_with(laabb); - ERR_FAIL_COND_V_MSG(err2 != OK, ERR_INVALID_DATA, "Invalid blend shape array format for surface."); - - blend_shape_data.push_back(vertex_array_shape); + if (p_blend_shapes.size()) { + uint32_t bs_format = format & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK; + for (int i = 0; i < p_blend_shapes.size(); i++) { + Vector<uint8_t> vertex_array_shape; + vertex_array_shape.resize(vertex_array_size); + Vector<uint8_t> noindex; + Vector<uint8_t> noattrib; + Vector<uint8_t> noskin; + + AABB laabb; + Error err2 = _surface_set_data(p_blend_shapes[i], bs_format, offsets, vertex_element_size, 0, 0, vertex_array_shape, noattrib, noskin, array_len, noindex, 0, laabb, bone_aabb); + aabb.merge_with(laabb); + ERR_FAIL_COND_V_MSG(err2 != OK, ERR_INVALID_DATA, "Invalid blend shape array format for surface."); + + blend_shape_data.append_array(vertex_array_shape); + blend_shape_count++; + } } Vector<SurfaceData::LOD> lods; if (index_array_len) { @@ -1004,10 +987,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa surface_data.primitive = p_primitive; surface_data.aabb = aabb; surface_data.vertex_data = vertex_array; + surface_data.attribute_data = attrib_array; + surface_data.skin_data = skin_array; surface_data.vertex_count = array_len; surface_data.index_data = index_array; surface_data.index_count = index_array_len; - surface_data.blend_shapes = blend_shape_data; + surface_data.blend_shape_count = blend_shape_count; + surface_data.blend_shape_data = blend_shape_data; surface_data.bone_aabbs = bone_aabb; surface_data.lods = lods; @@ -1023,110 +1009,20 @@ void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_p mesh_add_surface(p_mesh, sd); } -Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const { - uint32_t offsets[ARRAY_MAX]; - - int total_elem_size = 0; - - for (int i = 0; i < RS::ARRAY_MAX; i++) { - offsets[i] = 0; //reset - - if (!(p_format & (1 << i))) { // no array - continue; - } - - int elem_size = 0; - - switch (i) { - case RS::ARRAY_VERTEX: { - if (p_format & ARRAY_FLAG_USE_2D_VERTICES) { - elem_size = 2; - } else { - elem_size = 3; - } - - { - elem_size *= sizeof(float); - } - - } break; - case RS::ARRAY_NORMAL: { - if (p_format & ARRAY_COMPRESS_NORMAL) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 3; - } - - } break; - - case RS::ARRAY_TANGENT: { - if (p_format & ARRAY_COMPRESS_TANGENT) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 4; - } - - } break; - case RS::ARRAY_COLOR: { - if (p_format & ARRAY_COMPRESS_COLOR) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 4; - } - } break; - case RS::ARRAY_TEX_UV: { - if (p_format & ARRAY_COMPRESS_TEX_UV) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 2; - } - - } break; - - case RS::ARRAY_TEX_UV2: { - if (p_format & ARRAY_COMPRESS_TEX_UV2) { - elem_size = sizeof(uint32_t); - } else { - elem_size = sizeof(float) * 2; - } - - } break; - case RS::ARRAY_WEIGHTS: { - elem_size = sizeof(uint16_t) * 4; - - } break; - case RS::ARRAY_BONES: { - elem_size = sizeof(uint16_t) * 4; - - } break; - case RS::ARRAY_INDEX: { - if (p_index_len <= 0) { - ERR_PRINT("index_array_len==NO_INDEX_ARRAY"); - break; - } - /* determine whether using 16 or 32 bits indices */ - if (p_vertex_len >= (1 << 16)) { - elem_size = 4; - - } else { - elem_size = 2; - } - offsets[i] = elem_size; - continue; - } - default: { - ERR_FAIL_V(Array()); - } - } +Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const { + uint32_t offsets[RS::ARRAY_MAX]; - offsets[i] = total_elem_size; - total_elem_size += elem_size; - } + uint32_t vertex_elem_size; + uint32_t attrib_elem_size; + uint32_t skin_elem_size; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets, vertex_elem_size, attrib_elem_size, skin_elem_size); Array ret; ret.resize(RS::ARRAY_MAX); const uint8_t *r = p_vertex_data.ptr(); + const uint8_t *ar = p_attrib_data.ptr(); + const uint8_t *sr = p_skin_data.ptr(); for (int i = 0; i < RS::ARRAY_MAX; i++) { if (!(p_format & (1 << i))) { @@ -1143,7 +1039,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector2 *w = arr_2d.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * vertex_elem_size + offsets[i]]; w[j] = Vector2(v[0], v[1]); } } @@ -1157,7 +1053,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector3 *w = arr_3d.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * vertex_elem_size + offsets[i]]; w[j] = Vector3(v[0], v[1], v[2]); } } @@ -1170,21 +1066,11 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector<Vector3> arr; arr.resize(p_vertex_len); - if (p_format & ARRAY_COMPRESS_NORMAL) { - Vector3 *w = arr.ptrw(); - const float multiplier = 1.f / 127.f; + Vector3 *w = arr.ptrw(); - for (int j = 0; j < p_vertex_len; j++) { - const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]]; - w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier); - } - } else { - Vector3 *w = arr.ptrw(); - - for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; - w[j] = Vector3(v[0], v[1], v[2]); - } + for (int j = 0; j < p_vertex_len; j++) { + const uint32_t v = *(const uint32_t *)&r[j * vertex_elem_size + offsets[i]]; + w[j] = Vector3((v & 0x3FF) / 1023.0, ((v >> 10) & 0x3FF) / 1023.0, ((v >> 20) & 0x3FF) / 1023.0) * Vector3(2, 2, 2) - Vector3(1, 1, 1); } ret[i] = arr; @@ -1194,24 +1080,16 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t case RS::ARRAY_TANGENT: { Vector<float> arr; arr.resize(p_vertex_len * 4); - if (p_format & ARRAY_COMPRESS_TANGENT) { - float *w = arr.ptrw(); - for (int j = 0; j < p_vertex_len; j++) { - const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]]; - for (int k = 0; k < 4; k++) { - w[j * 4 + k] = float(v[k] / 127.0); - } - } - } else { - float *w = arr.ptrw(); + float *w = arr.ptrw(); - for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; - for (int k = 0; k < 4; k++) { - w[j * 4 + k] = v[k]; - } - } + for (int j = 0; j < p_vertex_len; j++) { + const uint32_t v = *(const uint32_t *)&r[j * vertex_elem_size + offsets[i]]; + + w[j * 4 + 0] = ((v & 0x3FF) / 1023.0) * 2.0 - 1.0; + w[j * 4 + 1] = (((v >> 10) & 0x3FF) / 1023.0) * 2.0 - 1.0; + w[j * 4 + 2] = (((v >> 20) & 0x3FF) / 1023.0) * 2.0 - 1.0; + w[j * 4 + 3] = ((v >> 30) / 3.0) * 2.0 - 1.0; } ret[i] = arr; @@ -1221,20 +1099,11 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector<Color> arr; arr.resize(p_vertex_len); - if (p_format & ARRAY_COMPRESS_COLOR) { - Color *w = arr.ptrw(); + Color *w = arr.ptrw(); - for (int j = 0; j < p_vertex_len; j++) { - const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]]; - w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0)); - } - } else { - Color *w = arr.ptrw(); - - for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; - w[j] = Color(v[0], v[1], v[2], v[3]); - } + for (int32_t j = 0; j < p_vertex_len; j++) { + const uint16_t *v = (const uint16_t *)&ar[j * attrib_elem_size + offsets[i]]; + w[j] = Color(Math::half_to_float(v[0]), Math::half_to_float(v[1]), Math::half_to_float(v[2]), Math::half_to_float(v[3])); } ret[i] = arr; @@ -1243,20 +1112,11 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector<Vector2> arr; arr.resize(p_vertex_len); - if (p_format & ARRAY_COMPRESS_TEX_UV) { - Vector2 *w = arr.ptrw(); + Vector2 *w = arr.ptrw(); - for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; - w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); - } - } else { - Vector2 *w = arr.ptrw(); - - for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; - w[j] = Vector2(v[0], v[1]); - } + for (int j = 0; j < p_vertex_len; j++) { + const float *v = (const float *)&ar[j * attrib_elem_size + offsets[i]]; + w[j] = Vector2(v[0], v[1]); } ret[i] = arr; @@ -1266,35 +1126,74 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector<Vector2> arr; arr.resize(p_vertex_len); - if (p_format & ARRAY_COMPRESS_TEX_UV2) { - Vector2 *w = arr.ptrw(); - - for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; - w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); - } - } else { - Vector2 *w = arr.ptrw(); + Vector2 *w = arr.ptrw(); - for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; - w[j] = Vector2(v[0], v[1]); - } + for (int j = 0; j < p_vertex_len; j++) { + const float *v = (const float *)&ar[j * attrib_elem_size + offsets[i]]; + w[j] = Vector2(v[0], v[1]); } ret[i] = arr; } break; + case RS::ARRAY_CUSTOM0: + case RS::ARRAY_CUSTOM1: + case RS::ARRAY_CUSTOM2: + case RS::ARRAY_CUSTOM3: { + uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (RS::ARRAY_CUSTOM0 - i))) & ARRAY_FORMAT_CUSTOM_MASK; + switch (type) { + case ARRAY_CUSTOM_RGBA8_UNORM: + case ARRAY_CUSTOM_RGBA8_SNORM: + case ARRAY_CUSTOM_RG_HALF: + case ARRAY_CUSTOM_RGBA_HALF: { + //size 4 + int s = type == ARRAY_CUSTOM_RGBA_HALF ? 8 : 4; + Vector<uint8_t> arr; + arr.resize(p_vertex_len * s); + + uint8_t *w = arr.ptrw(); + + for (int j = 0; j < p_vertex_len; j++) { + const uint8_t *v = (const uint8_t *)&ar[j * attrib_elem_size + offsets[i]]; + copymem(&w[j * s], v, s); + } + + ret[i] = arr; + + } break; + case ARRAY_CUSTOM_R_FLOAT: + case ARRAY_CUSTOM_RG_FLOAT: + case ARRAY_CUSTOM_RGB_FLOAT: + case ARRAY_CUSTOM_RGBA_FLOAT: { + uint32_t s = type - ARRAY_CUSTOM_R_FLOAT + 1; + + Vector<float> arr; + float *w = arr.ptrw(); + + for (int j = 0; j < p_vertex_len; j++) { + const float *v = (const float *)&ar[j * attrib_elem_size + offsets[i]]; + copymem(&w[j * s], v, s * sizeof(float)); + } + ret[i] = arr; + + } break; + default: { + } + } + + } break; case RS::ARRAY_WEIGHTS: { + uint32_t bone_count = (p_format & ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4; + Vector<float> arr; - arr.resize(p_vertex_len * 4); + arr.resize(p_vertex_len * bone_count); { float *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; - for (int k = 0; k < 4; k++) { - w[j * 4 + k] = float(v[k] / 65535.0); + const uint16_t *v = (const uint16_t *)&sr[j * skin_elem_size + offsets[i]]; + for (uint32_t k = 0; k < bone_count; k++) { + w[j * bone_count + k] = float(v[k] / 65535.0); } } } @@ -1303,15 +1202,17 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_BONES: { + uint32_t bone_count = (p_format & ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4; + Vector<int> arr; - arr.resize(p_vertex_len * 4); + arr.resize(p_vertex_len * bone_count); int *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; - for (int k = 0; k < 4; k++) { - w[j * 4 + k] = v[k]; + const uint16_t *v = (const uint16_t *)&sr[j * skin_elem_size + offsets[i]]; + for (uint32_t k = 0; k < bone_count; k++) { + w[j * bone_count + k] = v[k]; } } @@ -1394,20 +1295,30 @@ Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_sur SurfaceData sd = mesh_get_surface(p_mesh, p_surface); ERR_FAIL_COND_V(sd.vertex_count == 0, Array()); - Vector<Vector<uint8_t>> blend_shape_data = sd.blend_shapes; + Vector<uint8_t> blend_shape_data = sd.blend_shape_data; if (blend_shape_data.size() > 0) { - int vertex_len = sd.vertex_count; + uint32_t bs_offsets[RS::ARRAY_MAX]; + uint32_t bs_format = (sd.format & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK); + uint32_t vertex_elem_size; + uint32_t attrib_elem_size; + uint32_t skin_elem_size; - Vector<uint8_t> index_data = sd.index_data; - int index_len = sd.index_count; + mesh_surface_make_offsets_from_format(bs_format, sd.vertex_count, 0, bs_offsets, vertex_elem_size, attrib_elem_size, skin_elem_size); - uint32_t format = sd.format; + int divisor = vertex_elem_size * sd.vertex_count; + ERR_FAIL_COND_V((blend_shape_data.size() % divisor) != 0, Array()); + + uint32_t blend_shape_count = blend_shape_data.size() / divisor; + + ERR_FAIL_COND_V(blend_shape_count != sd.blend_shape_count, Array()); Array blend_shape_array; - blend_shape_array.resize(blend_shape_data.size()); - for (int i = 0; i < blend_shape_data.size(); i++) { - blend_shape_array.set(i, _get_array_from_surface(format, blend_shape_data[i], vertex_len, index_data, index_len)); + blend_shape_array.resize(blend_shape_count); + for (uint32_t i = 0; i < blend_shape_count; i++) { + Vector<uint8_t> bs_data = blend_shape_data.subarray(i * divisor, (i + 1) * divisor - 1); + Vector<uint8_t> unused; + blend_shape_array.set(i, _get_array_from_surface(bs_format, bs_data, unused, unused, sd.vertex_count, unused, 0)); } return blend_shape_array; @@ -1418,6 +1329,8 @@ Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_sur Array RenderingServer::mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const { Vector<uint8_t> vertex_data = p_data.vertex_data; + Vector<uint8_t> attrib_data = p_data.attribute_data; + Vector<uint8_t> skin_data = p_data.skin_data; ERR_FAIL_COND_V(vertex_data.size() == 0, Array()); int vertex_len = p_data.vertex_count; @@ -1427,7 +1340,7 @@ Array RenderingServer::mesh_create_arrays_from_surface_data(const SurfaceData &p uint32_t format = p_data.format; - return _get_array_from_surface(format, vertex_data, vertex_len, index_data, index_len); + return _get_array_from_surface(format, vertex_data, attrib_data, skin_data, vertex_len, index_data, index_len); } #if 0 Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const { @@ -1540,9 +1453,11 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("material_set_next_pass", "material", "next_material"), &RenderingServer::material_set_next_pass); ClassDB::bind_method(D_METHOD("mesh_create"), &RenderingServer::mesh_create); - ClassDB::bind_method(D_METHOD("mesh_surface_get_format_offset", "format", "vertex_len", "index_len", "array_index"), &RenderingServer::mesh_surface_get_format_offset); - ClassDB::bind_method(D_METHOD("mesh_surface_get_format_stride", "format", "vertex_len", "index_len"), &RenderingServer::mesh_surface_get_format_stride); - ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primitive", "arrays", "blend_shapes", "lods", "compress_format"), &RenderingServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("mesh_surface_get_format_offset", "format", "vertex_count", "array_index"), &RenderingServer::mesh_surface_get_format_offset); + ClassDB::bind_method(D_METHOD("mesh_surface_get_format_vertex_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_vertex_stride); + ClassDB::bind_method(D_METHOD("mesh_surface_get_format_attribute_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_attribute_stride); + ClassDB::bind_method(D_METHOD("mesh_surface_get_format_skin_stride", "format", "vertex_count"), &RenderingServer::mesh_surface_get_format_skin_stride); + //ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primitive", "arrays", "blend_shapes", "lods", "compress_format"), &RenderingServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &RenderingServer::mesh_get_blend_shape_count); ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_mode", "mesh", "mode"), &RenderingServer::mesh_set_blend_shape_mode); ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_mode", "mesh"), &RenderingServer::mesh_get_blend_shape_mode); @@ -1932,6 +1847,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_COLOR); BIND_ENUM_CONSTANT(ARRAY_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM3); BIND_ENUM_CONSTANT(ARRAY_BONES); BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_INDEX); @@ -1943,20 +1862,28 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3); BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK); + + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT); + + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE); BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS); BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 6102958aaa..abe3cc6975 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -52,7 +52,7 @@ class RenderingServer : public Object { void _camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); void _canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate = Color(1, 1, 1)); - Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const; + Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const; protected: RID _make_test_cube(); @@ -61,7 +61,7 @@ protected: RID white_texture; RID test_material; - Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, Vector<uint8_t> &r_vertex_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb); + Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb); static RenderingServer *(*create_func)(); static void _bind_methods(); @@ -199,16 +199,36 @@ public: /* MESH API */ enum ArrayType { - ARRAY_VERTEX = 0, - ARRAY_NORMAL = 1, - ARRAY_TANGENT = 2, - ARRAY_COLOR = 3, - ARRAY_TEX_UV = 4, - ARRAY_TEX_UV2 = 5, - ARRAY_BONES = 6, - ARRAY_WEIGHTS = 7, - ARRAY_INDEX = 8, - ARRAY_MAX = 9 + ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit) + ARRAY_NORMAL = 1, // A2B10G10R10 + ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal + ARRAY_COLOR = 3, // RGBA16F + ARRAY_TEX_UV = 4, // RG32F + ARRAY_TEX_UV2 = 5, // RG32F + ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat + ARRAY_CUSTOM1 = 7, + ARRAY_CUSTOM2 = 8, + ARRAY_CUSTOM3 = 9, + ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights) + ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights) + ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF + ARRAY_MAX = 13 + }; + + enum { + ARRAY_CUSTOM_COUNT = ARRAY_BONES - ARRAY_CUSTOM0 + }; + + enum ArrayCustomFormat { + ARRAY_CUSTOM_RGBA8_UNORM, + ARRAY_CUSTOM_RGBA8_SNORM, + ARRAY_CUSTOM_RG_HALF, + ARRAY_CUSTOM_RGBA_HALF, + ARRAY_CUSTOM_R_FLOAT, + ARRAY_CUSTOM_RG_FLOAT, + ARRAY_CUSTOM_RGB_FLOAT, + ARRAY_CUSTOM_RGBA_FLOAT, + ARRAY_CUSTOM_MAX }; enum ArrayFormat { @@ -219,21 +239,29 @@ public: ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR, ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV, ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2, + ARRAY_FORMAT_CUSTOM0 = 1 << ARRAY_CUSTOM0, + ARRAY_FORMAT_CUSTOM1 = 1 << ARRAY_CUSTOM1, + ARRAY_FORMAT_CUSTOM2 = 1 << ARRAY_CUSTOM2, + ARRAY_FORMAT_CUSTOM3 = 1 << ARRAY_CUSTOM3, ARRAY_FORMAT_BONES = 1 << ARRAY_BONES, ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS, ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX, - ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1), - ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2, + ARRAY_FORMAT_BLEND_SHAPE_MASK = (~(ARRAY_FORMAT_COLOR | ARRAY_FORMAT_TEX_UV | ARRAY_FORMAT_TEX_UV2 | ARRAY_FORMAT_BONES | ARRAY_FORMAT_WEIGHTS | ARRAY_FORMAT_CUSTOM0 | ARRAY_FORMAT_CUSTOM1 | ARRAY_FORMAT_CUSTOM2 | ARRAY_FORMAT_CUSTOM3 | ARRAY_FORMAT_INDEX)) & 0x7FFFFFFF, - ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, - ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, + ARRAY_FORMAT_CUSTOM_BASE = (ARRAY_INDEX + 1), + ARRAY_FORMAT_CUSTOM_BITS = 3, + ARRAY_FORMAT_CUSTOM0_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + 0), + ARRAY_FORMAT_CUSTOM1_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS), + ARRAY_FORMAT_CUSTOM2_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * 2), + ARRAY_FORMAT_CUSTOM3_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * 3), + + ARRAY_FORMAT_CUSTOM_MASK = 0x7, + ARRAY_COMPRESS_FLAGS_BASE = (ARRAY_INDEX + 1 + 12), + + ARRAY_FLAG_USE_2D_VERTICES = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 0), + ARRAY_FLAG_USE_DYNAMIC_UPDATE = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 1), + ARRAY_FLAG_USE_8_BONE_WEIGHTS = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 2), }; enum PrimitiveType { @@ -249,11 +277,15 @@ public: PrimitiveType primitive = PRIMITIVE_MAX; uint32_t format = 0; - Vector<uint8_t> vertex_data; + Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape) + Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3 + Vector<uint8_t> skin_data; // bone index, bone weight uint32_t vertex_count = 0; Vector<uint8_t> index_data; uint32_t index_count = 0; + uint32_t blend_shape_count = 0; + AABB aabb; struct LOD { float edge_length; @@ -262,7 +294,7 @@ public: Vector<LOD> lods; Vector<AABB> bone_aabbs; - Vector<Vector<uint8_t>> blend_shapes; + Vector<uint8_t> blend_shape_data; RID material; }; @@ -270,17 +302,20 @@ public: virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces) = 0; virtual RID mesh_create() = 0; - virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const; - virtual uint32_t mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const; + virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_array_index) const; + virtual uint32_t mesh_surface_get_format_vertex_stride(uint32_t p_format, int p_vertex_len) const; + virtual uint32_t mesh_surface_get_format_attribute_stride(uint32_t p_format, int p_vertex_len) const; + virtual uint32_t mesh_surface_get_format_skin_stride(uint32_t p_format, int p_vertex_len) const; + /// Returns stride - virtual uint32_t mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const; - virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT); + virtual void mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const; + virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = 0); Array mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const; Array mesh_surface_get_arrays(RID p_mesh, int p_surface) const; Array mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const; Dictionary mesh_surface_get_lods(RID p_mesh, int p_surface) const; - virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT); + virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = 0); virtual void mesh_add_surface(RID p_mesh, const SurfaceData &p_surface) = 0; virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 99fcef7925..8afcf115d2 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -33,7 +33,6 @@ #include "core/math/camera_matrix.h" #include "core/os/thread_safe.h" -#include "scene/main/window.h" #include "servers/xr_server.h" /** diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index ad5cee92ea..a59565fe0d 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -38,9 +38,9 @@ void XRPositionalTracker::_bind_methods() { BIND_ENUM_CONSTANT(TRACKER_RIGHT_HAND); // this class is read only from GDScript, so we only have access to getters.. - ClassDB::bind_method(D_METHOD("get_type"), &XRPositionalTracker::get_type); + ClassDB::bind_method(D_METHOD("get_tracker_type"), &XRPositionalTracker::get_tracker_type); ClassDB::bind_method(D_METHOD("get_tracker_id"), &XRPositionalTracker::get_tracker_id); - ClassDB::bind_method(D_METHOD("get_name"), &XRPositionalTracker::get_name); + ClassDB::bind_method(D_METHOD("get_tracker_name"), &XRPositionalTracker::get_tracker_name); ClassDB::bind_method(D_METHOD("get_joy_id"), &XRPositionalTracker::get_joy_id); ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &XRPositionalTracker::get_tracks_orientation); ClassDB::bind_method(D_METHOD("get_orientation"), &XRPositionalTracker::get_orientation); @@ -77,7 +77,7 @@ void XRPositionalTracker::set_type(XRServer::TrackerType p_type) { }; }; -XRServer::TrackerType XRPositionalTracker::get_type() const { +XRServer::TrackerType XRPositionalTracker::get_tracker_type() const { return type; }; @@ -85,7 +85,7 @@ void XRPositionalTracker::set_name(const String &p_name) { name = p_name; }; -StringName XRPositionalTracker::get_name() const { +StringName XRPositionalTracker::get_tracker_name() const { return name; }; diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 515359e9b1..8834b64464 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -72,9 +72,9 @@ protected: public: void set_type(XRServer::TrackerType p_type); - XRServer::TrackerType get_type() const; + XRServer::TrackerType get_tracker_type() const; void set_name(const String &p_name); - StringName get_name() const; + StringName get_tracker_name() const; int get_tracker_id() const; void set_joy_id(int p_joy_id); int get_joy_id() const; diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index 45199edd24..9d35825ae9 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -235,7 +235,7 @@ Array XRServer::get_interfaces() const { bool XRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const { for (int i = 0; i < trackers.size(); i++) { - if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { + if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { return true; }; }; @@ -264,7 +264,7 @@ void XRServer::add_tracker(XRPositionalTracker *p_tracker) { ERR_FAIL_NULL(p_tracker); trackers.push_back(p_tracker); - emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id()); + emit_signal("tracker_added", p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id()); }; void XRServer::remove_tracker(XRPositionalTracker *p_tracker) { @@ -280,7 +280,7 @@ void XRServer::remove_tracker(XRPositionalTracker *p_tracker) { ERR_FAIL_COND(idx == -1); - emit_signal("tracker_removed", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id()); + emit_signal("tracker_removed", p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id()); trackers.remove(idx); }; @@ -298,7 +298,7 @@ XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, i ERR_FAIL_COND_V(p_tracker_id == 0, nullptr); for (int i = 0; i < trackers.size(); i++) { - if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { + if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { return trackers[i]; }; }; @@ -336,7 +336,7 @@ uint64_t XRServer::get_last_frame_usec() { }; void XRServer::_process() { - /* called from rendering_server_viewport.draw_viewports right before we start drawing our viewports */ + /* called from renderer_viewport.draw_viewports right before we start drawing our viewports */ /* mark for our frame timing */ last_process_usec = OS::get_singleton()->get_ticks_usec(); diff --git a/tests/test_crypto.h b/tests/test_crypto.h new file mode 100644 index 0000000000..9e219ceec9 --- /dev/null +++ b/tests/test_crypto.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* test_crypto.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef TEST_CRYPTO_H +#define TEST_CRYPTO_H + +#include "core/crypto/crypto.h" +#include "tests/test_macros.h" +#include <stdio.h> + +namespace TestCrypto { + +class _MockCrypto : public Crypto { + virtual PackedByteArray generate_random_bytes(int p_bytes) { return PackedByteArray(); } + virtual Ref<CryptoKey> generate_rsa(int p_bytes) { return nullptr; } + virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) { return nullptr; } + + virtual Vector<uint8_t> sign(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Ref<CryptoKey> p_key) { return Vector<uint8_t>(); } + virtual bool verify(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Vector<uint8_t> p_signature, Ref<CryptoKey> p_key) { return false; } + virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_plaintext) { return Vector<uint8_t>(); } + virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_ciphertext) { return Vector<uint8_t>(); } + virtual PackedByteArray hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg) { return PackedByteArray(); } +}; + +PackedByteArray raw_to_pba(const uint8_t *arr, size_t len) { + PackedByteArray pba; + pba.resize(len); + for (size_t i = 0; i < len; i++) { + pba.set(i, arr[i]); + } + return pba; +} + +TEST_CASE("[Crypto] PackedByteArray constant time compare") { + const uint8_t hm1[] = { 144, 140, 176, 38, 88, 113, 101, 45, 71, 105, 10, 91, 248, 16, 117, 244, 189, 30, 238, 29, 219, 134, 82, 130, 212, 114, 161, 166, 188, 169, 200, 106 }; + const uint8_t hm2[] = { 80, 30, 144, 228, 108, 38, 188, 125, 150, 64, 165, 127, 221, 118, 144, 232, 45, 100, 15, 248, 193, 244, 245, 34, 116, 147, 132, 200, 110, 27, 38, 75 }; + PackedByteArray p1 = raw_to_pba(hm1, sizeof(hm1) / sizeof(hm1[0])); + PackedByteArray p2 = raw_to_pba(hm2, sizeof(hm2) / sizeof(hm2[0])); + _MockCrypto crypto; + bool equal = crypto.constant_time_compare(p1, p1); + CHECK(equal); + equal = crypto.constant_time_compare(p1, p2); + CHECK(!equal); +} +} // namespace TestCrypto + +#endif // TEST_CRYPTO_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 9d1e7da6f7..dd8c36e737 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -39,6 +39,7 @@ #include "test_color.h" #include "test_command_queue.h" #include "test_config_file.h" +#include "test_crypto.h" #include "test_curve.h" #include "test_expression.h" #include "test_gradient.h" diff --git a/thirdparty/README.md b/thirdparty/README.md index d011832210..b2707e7f7c 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -413,7 +413,7 @@ Collection of single-file libraries used in Godot components. * License: Apache 2.0 - `open-simplex-noise.{c,h}` * Upstream: https://github.com/smcameron/open-simplex-noise-in-c - * Version: git (0fef0dbedd76f767da7e3c894822729d0f07e54d, 2020) + custom changes + * Version: git (826f1dd1724e6fb3ff45f58e48c0fbae864c3403, 2020) + custom changes * License: Unlicense - `pcg.{cpp,h}` * Upstream: http://www.pcg-random.org @@ -671,7 +671,7 @@ File extracted from upstream release tarball: ## xatlas - Upstream: https://github.com/jpcy/xatlas -- Version: git (470576d3516f7e6d8b4554e7c941194a935969fd, 2020) +- Version: git (5571fc7ef0d06832947c0a935ccdcf083f7a9264, 2020) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/misc/open-simplex-noise.c b/thirdparty/misc/open-simplex-noise.c index 88fbd3e51d..44a072cad1 100644 --- a/thirdparty/misc/open-simplex-noise.c +++ b/thirdparty/misc/open-simplex-noise.c @@ -100,27 +100,27 @@ static const signed char gradients4D[] = { -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, }; -static double extrapolate2(struct osn_context *ctx, int xsb, int ysb, double dx, double dy) +static double extrapolate2(const struct osn_context *ctx, int xsb, int ysb, double dx, double dy) { - int16_t *perm = ctx->perm; + const int16_t *perm = ctx->perm; int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E; return gradients2D[index] * dx + gradients2D[index + 1] * dy; } -static double extrapolate3(struct osn_context *ctx, int xsb, int ysb, int zsb, double dx, double dy, double dz) +static double extrapolate3(const struct osn_context *ctx, int xsb, int ysb, int zsb, double dx, double dy, double dz) { - int16_t *perm = ctx->perm; - int16_t *permGradIndex3D = ctx->permGradIndex3D; + const int16_t *perm = ctx->perm; + const int16_t *permGradIndex3D = ctx->permGradIndex3D; int index = permGradIndex3D[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF]; return gradients3D[index] * dx + gradients3D[index + 1] * dy + gradients3D[index + 2] * dz; } -static double extrapolate4(struct osn_context *ctx, int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw) +static double extrapolate4(const struct osn_context *ctx, int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw) { - int16_t *perm = ctx->perm; + const int16_t *perm = ctx->perm; int index = perm[(perm[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF] + wsb) & 0xFF] & 0xFC; return gradients4D[index] * dx + gradients4D[index + 1] * dy @@ -227,7 +227,7 @@ void open_simplex_noise_free(struct osn_context *ctx) // -- GODOT end -- /* 2D OpenSimplex (Simplectic) Noise. */ -double open_simplex_noise2(struct osn_context *ctx, double x, double y) +double open_simplex_noise2(const struct osn_context *ctx, double x, double y) { /* Place input coordinates onto grid. */ @@ -355,7 +355,7 @@ double open_simplex_noise2(struct osn_context *ctx, double x, double y) /* * 3D OpenSimplex (Simplectic) Noise */ -double open_simplex_noise3(struct osn_context *ctx, double x, double y, double z) +double open_simplex_noise3(const struct osn_context *ctx, double x, double y, double z) { /* Place input coordinates on simplectic honeycomb. */ @@ -928,7 +928,7 @@ double open_simplex_noise3(struct osn_context *ctx, double x, double y, double z /* * 4D OpenSimplex (Simplectic) Noise. */ -double open_simplex_noise4(struct osn_context *ctx, double x, double y, double z, double w) +double open_simplex_noise4(const struct osn_context *ctx, double x, double y, double z, double w) { double uins; double dx1, dy1, dz1, dw1; diff --git a/thirdparty/misc/open-simplex-noise.h b/thirdparty/misc/open-simplex-noise.h index 89e0df8218..fd9248c3a1 100644 --- a/thirdparty/misc/open-simplex-noise.h +++ b/thirdparty/misc/open-simplex-noise.h @@ -47,9 +47,9 @@ int open_simplex_noise(int64_t seed, struct osn_context *ctx); //int open_simplex_noise_init_perm(struct osn_context *ctx, int16_t p[], int nelements); // -- GODOT end -- void open_simplex_noise_free(struct osn_context *ctx); -double open_simplex_noise2(struct osn_context *ctx, double x, double y); -double open_simplex_noise3(struct osn_context *ctx, double x, double y, double z); -double open_simplex_noise4(struct osn_context *ctx, double x, double y, double z, double w); +double open_simplex_noise2(const struct osn_context *ctx, double x, double y); +double open_simplex_noise3(const struct osn_context *ctx, double x, double y, double z); +double open_simplex_noise4(const struct osn_context *ctx, double x, double y, double z, double w); #ifdef __cplusplus } diff --git a/thirdparty/xatlas/xatlas.cpp b/thirdparty/xatlas/xatlas.cpp index 43aec33a9f..9f66ae0067 100644 --- a/thirdparty/xatlas/xatlas.cpp +++ b/thirdparty/xatlas/xatlas.cpp @@ -33,19 +33,25 @@ https://github.com/brandonpelfrey/Fast-BVH MIT License Copyright (c) 2012 Brandon Pelfrey */ -#include <atomic> -#include <condition_variable> -#include <mutex> -#include <thread> +#include "xatlas.h" +#ifndef XATLAS_C_API +#define XATLAS_C_API 0 +#endif +#if XATLAS_C_API +#include "xatlas_c.h" +#endif #include <assert.h> #include <float.h> // FLT_MAX #include <limits.h> #include <math.h> +#include <atomic> +#include <condition_variable> +#include <mutex> +#include <thread> #define __STDC_LIMIT_MACROS #include <stdint.h> #include <stdio.h> #include <string.h> -#include "xatlas.h" #ifndef XA_DEBUG #ifdef NDEBUG @@ -59,7 +65,7 @@ Copyright (c) 2012 Brandon Pelfrey #define XA_PROFILE 0 #endif #if XA_PROFILE -#include <time.h> +#include <chrono> #endif #ifndef XA_MULTITHREADED @@ -70,7 +76,10 @@ Copyright (c) 2012 Brandon Pelfrey #define XA_XSTR(x) XA_STR(x) #ifndef XA_ASSERT -#define XA_ASSERT(exp) if (!(exp)) { XA_PRINT_WARNING("\rASSERT: %s %s %d\n", XA_XSTR(exp), __FILE__, __LINE__); } +#define XA_ASSERT(exp) \ + if (!(exp)) { \ + XA_PRINT_WARNING("\rASSERT: %s %s %d\n", XA_XSTR(exp), __FILE__, __LINE__); \ + } #endif #ifndef XA_DEBUG_ASSERT @@ -78,13 +87,13 @@ Copyright (c) 2012 Brandon Pelfrey #endif #ifndef XA_PRINT -#define XA_PRINT(...) \ +#define XA_PRINT(...) \ if (xatlas::internal::s_print && xatlas::internal::s_printVerbose) \ xatlas::internal::s_print(__VA_ARGS__); #endif #ifndef XA_PRINT_WARNING -#define XA_PRINT_WARNING(...) \ +#define XA_PRINT_WARNING(...) \ if (xatlas::internal::s_print) \ xatlas::internal::s_print(__VA_ARGS__); #endif @@ -116,9 +125,9 @@ Copyright (c) 2012 Brandon Pelfrey #define XA_MERGE_CHARTS 1 #define XA_MERGE_CHARTS_MIN_NORMAL_DEVIATION 0.5f #define XA_RECOMPUTE_CHARTS 1 -#define XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION 0 -#define XA_FIX_INTERNAL_BOUNDARY_LOOPS 1 -#define XA_PRINT_CHART_WARNINGS 0 +#define XA_CHECK_PARAM_WINDING 0 +#define XA_CHECK_PIECEWISE_CHART_QUALITY 0 +#define XA_CHECK_T_JUNCTIONS 0 #define XA_DEBUG_HEAP 0 #define XA_DEBUG_SINGLE_CHART 0 @@ -131,25 +140,19 @@ Copyright (c) 2012 Brandon Pelfrey #define XA_DEBUG_EXPORT_OBJ_CHART_GROUPS 0 #define XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS 0 #define XA_DEBUG_EXPORT_OBJ_CHARTS 0 -#define XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION 0 -#define XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR 0 +#define XA_DEBUG_EXPORT_OBJ_TJUNCTION 0 // XA_CHECK_T_JUNCTIONS must also be set #define XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION 0 #define XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION 0 #define XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS 0 -#define XA_DEBUG_EXPORT_OBJ (0 \ - || XA_DEBUG_EXPORT_OBJ_FACE_GROUPS \ - || XA_DEBUG_EXPORT_OBJ_CHART_GROUPS \ - || XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS \ - || XA_DEBUG_EXPORT_OBJ_CHARTS \ - || XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION \ - || XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR \ - || XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION \ - || XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION \ - || XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS) +#define XA_DEBUG_EXPORT_OBJ (0 || XA_DEBUG_EXPORT_OBJ_FACE_GROUPS || XA_DEBUG_EXPORT_OBJ_CHART_GROUPS || XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS || XA_DEBUG_EXPORT_OBJ_CHARTS || XA_DEBUG_EXPORT_OBJ_TJUNCTION || XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION || XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION || XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS) #ifdef _MSC_VER -#define XA_FOPEN(_file, _filename, _mode) { if (fopen_s(&_file, _filename, _mode) != 0) _file = NULL; } +#define XA_FOPEN(_file, _filename, _mode) \ + { \ + if (fopen_s(&_file, _filename, _mode) != 0) \ + _file = NULL; \ + } #define XA_SPRINTF(_buffer, _size, _format, ...) sprintf_s(_buffer, _size, _format, __VA_ARGS__) #else #define XA_FOPEN(_file, _filename, _mode) _file = fopen(_filename, _mode) @@ -165,74 +168,76 @@ static PrintFunc s_print = printf; static bool s_printVerbose = false; #if XA_PROFILE -#define XA_PROFILE_START(var) const clock_t var##Start = clock(); -#define XA_PROFILE_END(var) internal::s_profile.var += clock() - var##Start; -#define XA_PROFILE_PRINT_AND_RESET(label, var) XA_PRINT("%s%.2f seconds (%g ms)\n", label, internal::clockToSeconds(internal::s_profile.var), internal::clockToMs(internal::s_profile.var)); internal::s_profile.var = 0; +typedef uint64_t Duration; + +#define XA_PROFILE_START(var) const std::chrono::time_point<std::chrono::high_resolution_clock> var##Start = std::chrono::high_resolution_clock::now(); +#define XA_PROFILE_END(var) internal::s_profile.var += uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - var##Start).count()); +#define XA_PROFILE_PRINT_AND_RESET(label, var) \ + XA_PRINT("%s%.2f seconds (%g ms)\n", label, internal::durationToSeconds(internal::s_profile.var), internal::durationToMs(internal::s_profile.var)); \ + internal::s_profile.var = 0u; #define XA_PROFILE_ALLOC 0 -struct ProfileData -{ +struct ProfileData { #if XA_PROFILE_ALLOC - std::atomic<clock_t> alloc; + std::atomic<Duration> alloc; #endif - clock_t addMeshReal; - clock_t addMeshCopyData; - std::atomic<clock_t> addMeshThread; - std::atomic<clock_t> addMeshCreateColocals; - clock_t computeChartsReal; - std::atomic<clock_t> computeChartsThread; - std::atomic<clock_t> createFaceGroups; - std::atomic<clock_t> extractInvalidMeshGeometry; - std::atomic<clock_t> chartGroupComputeChartsReal; - std::atomic<clock_t> chartGroupComputeChartsThread; - std::atomic<clock_t> createChartGroupMesh; - std::atomic<clock_t> createChartGroupMeshColocals; - std::atomic<clock_t> createChartGroupMeshBoundaries; - std::atomic<clock_t> buildAtlas; - std::atomic<clock_t> buildAtlasInit; - std::atomic<clock_t> planarCharts; - std::atomic<clock_t> clusteredCharts; - std::atomic<clock_t> clusteredChartsPlaceSeeds; - std::atomic<clock_t> clusteredChartsPlaceSeedsBoundaryIntersection; - std::atomic<clock_t> clusteredChartsRelocateSeeds; - std::atomic<clock_t> clusteredChartsReset; - std::atomic<clock_t> clusteredChartsGrow; - std::atomic<clock_t> clusteredChartsGrowBoundaryIntersection; - std::atomic<clock_t> clusteredChartsMerge; - std::atomic<clock_t> clusteredChartsFillHoles; - std::atomic<clock_t> copyChartFaces; - clock_t parameterizeChartsReal; - std::atomic<clock_t> parameterizeChartsThread; - std::atomic<clock_t> createChartMesh; - std::atomic<clock_t> fixChartMeshTJunctions; - std::atomic<clock_t> closeChartMeshHoles; - std::atomic<clock_t> parameterizeChartsOrthogonal; - std::atomic<clock_t> parameterizeChartsLSCM; - std::atomic<clock_t> parameterizeChartsRecompute; - std::atomic<clock_t> parameterizeChartsPiecewise; - std::atomic<clock_t> parameterizeChartsPiecewiseBoundaryIntersection; - std::atomic<clock_t> parameterizeChartsEvaluateQuality; - clock_t packCharts; - clock_t packChartsAddCharts; - std::atomic<clock_t> packChartsAddChartsThread; - std::atomic<clock_t> packChartsAddChartsRestoreTexcoords; - clock_t packChartsRasterize; - clock_t packChartsDilate; - clock_t packChartsFindLocation; - clock_t packChartsBlit; - clock_t buildOutputMeshes; + std::chrono::time_point<std::chrono::high_resolution_clock> addMeshRealStart; + Duration addMeshReal; + Duration addMeshCopyData; + std::atomic<Duration> addMeshThread; + std::atomic<Duration> addMeshCreateColocals; + Duration computeChartsReal; + std::atomic<Duration> computeChartsThread; + std::atomic<Duration> createFaceGroups; + std::atomic<Duration> extractInvalidMeshGeometry; + std::atomic<Duration> chartGroupComputeChartsReal; + std::atomic<Duration> chartGroupComputeChartsThread; + std::atomic<Duration> createChartGroupMesh; + std::atomic<Duration> createChartGroupMeshColocals; + std::atomic<Duration> createChartGroupMeshBoundaries; + std::atomic<Duration> buildAtlas; + std::atomic<Duration> buildAtlasInit; + std::atomic<Duration> planarCharts; + std::atomic<Duration> originalUvCharts; + std::atomic<Duration> clusteredCharts; + std::atomic<Duration> clusteredChartsPlaceSeeds; + std::atomic<Duration> clusteredChartsPlaceSeedsBoundaryIntersection; + std::atomic<Duration> clusteredChartsRelocateSeeds; + std::atomic<Duration> clusteredChartsReset; + std::atomic<Duration> clusteredChartsGrow; + std::atomic<Duration> clusteredChartsGrowBoundaryIntersection; + std::atomic<Duration> clusteredChartsMerge; + std::atomic<Duration> clusteredChartsFillHoles; + std::atomic<Duration> copyChartFaces; + std::atomic<Duration> createChartMeshAndParameterizeReal; + std::atomic<Duration> createChartMeshAndParameterizeThread; + std::atomic<Duration> createChartMesh; + std::atomic<Duration> parameterizeCharts; + std::atomic<Duration> parameterizeChartsOrthogonal; + std::atomic<Duration> parameterizeChartsLSCM; + std::atomic<Duration> parameterizeChartsRecompute; + std::atomic<Duration> parameterizeChartsPiecewise; + std::atomic<Duration> parameterizeChartsPiecewiseBoundaryIntersection; + std::atomic<Duration> parameterizeChartsEvaluateQuality; + Duration packCharts; + Duration packChartsAddCharts; + std::atomic<Duration> packChartsAddChartsThread; + std::atomic<Duration> packChartsAddChartsRestoreTexcoords; + Duration packChartsRasterize; + Duration packChartsDilate; + Duration packChartsFindLocation; + Duration packChartsBlit; + Duration buildOutputMeshes; }; static ProfileData s_profile; -static double clockToMs(clock_t c) -{ - return c * 1000.0 / CLOCKS_PER_SEC; +static double durationToMs(Duration c) { + return (double)c * 0.001; } -static double clockToSeconds(clock_t c) -{ - return c / (double)CLOCKS_PER_SEC; +static double durationToSeconds(Duration c) { + return (double)c * 0.000001; } #else #define XA_PROFILE_START(var) @@ -241,10 +246,8 @@ static double clockToSeconds(clock_t c) #define XA_PROFILE_ALLOC 0 #endif -struct MemTag -{ - enum - { +struct MemTag { + enum { Default, BitImage, BVH, @@ -267,8 +270,7 @@ struct MemTag }; #if XA_DEBUG_HEAP -struct AllocHeader -{ +struct AllocHeader { size_t size; const char *file; int line; @@ -281,11 +283,10 @@ struct AllocHeader static std::mutex s_allocMutex; static AllocHeader *s_allocRoot = nullptr; static size_t s_allocTotalCount = 0, s_allocTotalSize = 0, s_allocPeakSize = 0, s_allocCount[MemTag::Count] = { 0 }, s_allocTotalTagSize[MemTag::Count] = { 0 }, s_allocPeakTagSize[MemTag::Count] = { 0 }; -static uint32_t s_allocId =0 ; +static uint32_t s_allocId = 0; static constexpr uint32_t kAllocRedzone = 0x12345678; -static void *Realloc(void *ptr, size_t size, int tag, const char *file, int line) -{ +static void *Realloc(void *ptr, size_t size, int tag, const char *file, int line) { std::unique_lock<std::mutex> lock(s_allocMutex); if (!size && !ptr) return nullptr; @@ -346,8 +347,7 @@ static void *Realloc(void *ptr, size_t size, int tag, const char *file, int line return newPtr + sizeof(AllocHeader); } -static void ReportLeaks() -{ +static void ReportLeaks() { printf("Checking for memory leaks...\n"); bool anyLeaks = false; AllocHeader *header = s_allocRoot; @@ -375,8 +375,7 @@ static void ReportLeaks() s_allocTotalTagSize[i] = s_allocPeakTagSize[i] = 0; } -static void PrintMemoryUsage() -{ +static void PrintMemoryUsage() { XA_PRINT("Total allocations: %zu\n", s_allocTotalCount); XA_PRINT("Memory usage: %0.2fMB current, %0.2fMB peak\n", internal::s_allocTotalSize / 1024.0f / 1024.0f, internal::s_allocPeakSize / 1024.0f / 1024.0f); static const char *labels[] = { // Sync with MemTag @@ -405,8 +404,7 @@ static void PrintMemoryUsage() #define XA_PRINT_MEM_USAGE internal::PrintMemoryUsage(); #else -static void *Realloc(void *ptr, size_t size, int /*tag*/, const char * /*file*/, int /*line*/) -{ +static void *Realloc(void *ptr, size_t size, int /*tag*/, const char * /*file*/, int /*line*/) { if (size == 0 && !ptr) return nullptr; if (size == 0 && s_free) { @@ -432,89 +430,75 @@ static constexpr float kEpsilon = 0.0001f; static constexpr float kAreaEpsilon = FLT_EPSILON; static constexpr float kNormalEpsilon = 0.001f; -static int align(int x, int a) -{ +static int align(int x, int a) { return (x + a - 1) & ~(a - 1); } template <typename T> -static T max(const T &a, const T &b) -{ +static T max(const T &a, const T &b) { return a > b ? a : b; } template <typename T> -static T min(const T &a, const T &b) -{ +static T min(const T &a, const T &b) { return a < b ? a : b; } template <typename T> -static T max3(const T &a, const T &b, const T &c) -{ +static T max3(const T &a, const T &b, const T &c) { return max(a, max(b, c)); } /// Return the maximum of the three arguments. template <typename T> -static T min3(const T &a, const T &b, const T &c) -{ +static T min3(const T &a, const T &b, const T &c) { return min(a, min(b, c)); } /// Clamp between two values. template <typename T> -static T clamp(const T &x, const T &a, const T &b) -{ +static T clamp(const T &x, const T &a, const T &b) { return min(max(x, a), b); } template <typename T> -static void swap(T &a, T &b) -{ +static void swap(T &a, T &b) { T temp = a; a = b; b = temp; } -union FloatUint32 -{ +union FloatUint32 { float f; uint32_t u; }; -static bool isFinite(float f) -{ +static bool isFinite(float f) { FloatUint32 fu; fu.f = f; return fu.u != 0x7F800000u && fu.u != 0x7F800001u; } -static bool isNan(float f) -{ +static bool isNan(float f) { return f != f; } // Robust floating point comparisons: // http://realtimecollisiondetection.net/blog/?p=89 -static bool equal(const float f0, const float f1, const float epsilon) -{ +static bool equal(const float f0, const float f1, const float epsilon) { //return fabs(f0-f1) <= epsilon; return fabs(f0 - f1) <= epsilon * max3(1.0f, fabsf(f0), fabsf(f1)); } -static int ftoi_ceil(float val) -{ +static int ftoi_ceil(float val) { return (int)ceilf(val); } -static bool isZero(const float f, const float epsilon) -{ +static bool isZero(const float f, const float epsilon) { return fabs(f) <= epsilon; } -static float square(float f) -{ +static float square(float f) { return f * f; } @@ -524,9 +508,8 @@ static float square(float f) * @note isPowerOfTwo(x) == true -> nextPowerOfTwo(x) == x * @note nextPowerOfTwo(x) = 2 << log2(x-1) */ -static uint32_t nextPowerOfTwo(uint32_t x) -{ - XA_DEBUG_ASSERT( x != 0 ); +static uint32_t nextPowerOfTwo(uint32_t x) { + XA_DEBUG_ASSERT(x != 0); // On modern CPUs this is supposed to be as fast as using the bsr instruction. x--; x |= x >> 1; @@ -537,38 +520,34 @@ static uint32_t nextPowerOfTwo(uint32_t x) return x + 1; } -class Vector2 -{ +class Vector2 { public: Vector2() {} - explicit Vector2(float f) : x(f), y(f) {} - Vector2(float x, float y): x(x), y(y) {} + explicit Vector2(float f) : + x(f), y(f) {} + Vector2(float _x, float _y) : + x(_x), y(_y) {} - Vector2 operator-() const - { + Vector2 operator-() const { return Vector2(-x, -y); } - void operator+=(const Vector2 &v) - { + void operator+=(const Vector2 &v) { x += v.x; y += v.y; } - void operator-=(const Vector2 &v) - { + void operator-=(const Vector2 &v) { x -= v.x; y -= v.y; } - void operator*=(float s) - { + void operator*=(float s) { x *= s; y *= s; } - void operator*=(const Vector2 &v) - { + void operator*=(const Vector2 &v) { x *= v.x; y *= v.y; } @@ -576,13 +555,11 @@ public: float x, y; }; -static bool operator==(const Vector2 &a, const Vector2 &b) -{ +static bool operator==(const Vector2 &a, const Vector2 &b) { return a.x == b.x && a.y == b.y; } -static bool operator!=(const Vector2 &a, const Vector2 &b) -{ +static bool operator!=(const Vector2 &a, const Vector2 &b) { return a.x != b.x || a.y != b.y; } @@ -591,78 +568,64 @@ static bool operator!=(const Vector2 &a, const Vector2 &b) return Vector2(a.x + b.x, a.y + b.y); }*/ -static Vector2 operator-(const Vector2 &a, const Vector2 &b) -{ +static Vector2 operator-(const Vector2 &a, const Vector2 &b) { return Vector2(a.x - b.x, a.y - b.y); } -static Vector2 operator*(const Vector2 &v, float s) -{ +static Vector2 operator*(const Vector2 &v, float s) { return Vector2(v.x * s, v.y * s); } -static float dot(const Vector2 &a, const Vector2 &b) -{ +static float dot(const Vector2 &a, const Vector2 &b) { return a.x * b.x + a.y * b.y; } -static float lengthSquared(const Vector2 &v) -{ +static float lengthSquared(const Vector2 &v) { return v.x * v.x + v.y * v.y; } -static float length(const Vector2 &v) -{ +static float length(const Vector2 &v) { return sqrtf(lengthSquared(v)); } #if XA_DEBUG -static bool isNormalized(const Vector2 &v, float epsilon = kNormalEpsilon) -{ +static bool isNormalized(const Vector2 &v, float epsilon = kNormalEpsilon) { return equal(length(v), 1, epsilon); } #endif -static Vector2 normalize(const Vector2 &v, float epsilon) -{ - float l = length(v); - XA_DEBUG_ASSERT(!isZero(l, epsilon)); - XA_UNUSED(epsilon); - Vector2 n = v * (1.0f / l); +static Vector2 normalize(const Vector2 &v) { + const float l = length(v); + XA_DEBUG_ASSERT(l > 0.0f); // Never negative. + const Vector2 n = v * (1.0f / l); XA_DEBUG_ASSERT(isNormalized(n)); return n; } -static Vector2 normalizeSafe(const Vector2 &v, const Vector2 &fallback, float epsilon) -{ - float l = length(v); - if (isZero(l, epsilon)) - return fallback; - return v * (1.0f / l); +static Vector2 normalizeSafe(const Vector2 &v, const Vector2 &fallback) { + const float l = length(v); + if (l > 0.0f) // Never negative. + return v * (1.0f / l); + return fallback; } -static bool equal(const Vector2 &v1, const Vector2 &v2, float epsilon) -{ +static bool equal(const Vector2 &v1, const Vector2 &v2, float epsilon) { return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon); } -static Vector2 min(const Vector2 &a, const Vector2 &b) -{ +static Vector2 min(const Vector2 &a, const Vector2 &b) { return Vector2(min(a.x, b.x), min(a.y, b.y)); } -static Vector2 max(const Vector2 &a, const Vector2 &b) -{ +static Vector2 max(const Vector2 &a, const Vector2 &b) { return Vector2(max(a.x, b.x), max(a.y, b.y)); } -static bool isFinite(const Vector2 &v) -{ +static bool isFinite(const Vector2 &v) { return isFinite(v.x) && isFinite(v.y); } -static float triangleArea(const Vector2 &a, const Vector2 &b, const Vector2 &c) -{ +static float triangleArea(const Vector2 &a, const Vector2 &b, const Vector2 &c) { // IC: While it may be appealing to use the following expression: //return (c.x * a.y + a.x * b.y + b.x * c.y - b.x * a.y - c.x * b.y - a.x * c.y) * 0.5f; // That's actually a terrible idea. Small triangles far from the origin can end up producing fairly large floating point @@ -676,8 +639,7 @@ static float triangleArea(const Vector2 &a, const Vector2 &b, const Vector2 &c) return (v0.x * v1.y - v0.y * v1.x) * 0.5f; } -static bool linesIntersect(const Vector2 &a1, const Vector2 &a2, const Vector2 &b1, const Vector2 &b2, float epsilon) -{ +static bool linesIntersect(const Vector2 &a1, const Vector2 &a2, const Vector2 &b1, const Vector2 &b2, float epsilon) { const Vector2 v0 = a2 - a1; const Vector2 v1 = b2 - b1; const float denom = -v1.x * v0.y + v0.x * v1.y; @@ -685,76 +647,70 @@ static bool linesIntersect(const Vector2 &a1, const Vector2 &a2, const Vector2 & return false; const float s = (-v0.y * (a1.x - b1.x) + v0.x * (a1.y - b1.y)) / denom; if (s > epsilon && s < 1.0f - epsilon) { - const float t = ( v1.x * (a1.y - b1.y) - v1.y * (a1.x - b1.x)) / denom; + const float t = (v1.x * (a1.y - b1.y) - v1.y * (a1.x - b1.x)) / denom; return t > epsilon && t < 1.0f - epsilon; } return false; } -struct Vector2i -{ +struct Vector2i { Vector2i() {} - Vector2i(int32_t x, int32_t y) : x(x), y(y) {} + Vector2i(int32_t _x, int32_t _y) : + x(_x), y(_y) {} int32_t x, y; }; -class Vector3 -{ +class Vector3 { public: Vector3() {} - explicit Vector3(float f) : x(f), y(f), z(f) {} - Vector3(float x, float y, float z) : x(x), y(y), z(z) {} - Vector3(const Vector2 &v, float z) : x(v.x), y(v.y), z(z) {} - - Vector2 xy() const - { + explicit Vector3(float f) : + x(f), y(f), z(f) {} + Vector3(float _x, float _y, float _z) : + x(_x), y(_y), z(_z) {} + Vector3(const Vector2 &v, float _z) : + x(v.x), y(v.y), z(_z) {} + + Vector2 xy() const { return Vector2(x, y); } - Vector3 operator-() const - { + Vector3 operator-() const { return Vector3(-x, -y, -z); } - void operator+=(const Vector3 &v) - { + void operator+=(const Vector3 &v) { x += v.x; y += v.y; z += v.z; } - void operator-=(const Vector3 &v) - { + void operator-=(const Vector3 &v) { x -= v.x; y -= v.y; z -= v.z; } - void operator*=(float s) - { + void operator*=(float s) { x *= s; y *= s; z *= s; } - void operator/=(float s) - { + void operator/=(float s) { float is = 1.0f / s; x *= is; y *= is; z *= is; } - void operator*=(const Vector3 &v) - { + void operator*=(const Vector3 &v) { x *= v.x; y *= v.y; z *= v.z; } - void operator/=(const Vector3 &v) - { + void operator/=(const Vector3 &v) { x /= v.x; y /= v.y; z /= v.z; @@ -763,260 +719,151 @@ public: float x, y, z; }; -static Vector3 operator+(const Vector3 &a, const Vector3 &b) -{ +static Vector3 operator+(const Vector3 &a, const Vector3 &b) { return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); } -static Vector3 operator-(const Vector3 &a, const Vector3 &b) -{ +static Vector3 operator-(const Vector3 &a, const Vector3 &b) { return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); } -static Vector3 cross(const Vector3 &a, const Vector3 &b) -{ +static bool operator==(const Vector3 &a, const Vector3 &b) { + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +static Vector3 cross(const Vector3 &a, const Vector3 &b) { return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } -static Vector3 operator*(const Vector3 &v, float s) -{ +static Vector3 operator*(const Vector3 &v, float s) { return Vector3(v.x * s, v.y * s, v.z * s); } -static Vector3 operator/(const Vector3 &v, float s) -{ +static Vector3 operator/(const Vector3 &v, float s) { return v * (1.0f / s); } -static float dot(const Vector3 &a, const Vector3 &b) -{ +static float dot(const Vector3 &a, const Vector3 &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } -static float lengthSquared(const Vector3 &v) -{ +static float lengthSquared(const Vector3 &v) { return v.x * v.x + v.y * v.y + v.z * v.z; } -static float length(const Vector3 &v) -{ +static float length(const Vector3 &v) { return sqrtf(lengthSquared(v)); } -static bool isNormalized(const Vector3 &v, float epsilon = kNormalEpsilon) -{ - return equal(length(v), 1, epsilon); +static bool isNormalized(const Vector3 &v, float epsilon = kNormalEpsilon) { + return equal(length(v), 1.0f, epsilon); } -static Vector3 normalize(const Vector3 &v, float epsilon) -{ - float l = length(v); - XA_DEBUG_ASSERT(!isZero(l, epsilon)); - XA_UNUSED(epsilon); - Vector3 n = v * (1.0f / l); +static Vector3 normalize(const Vector3 &v) { + const float l = length(v); + XA_DEBUG_ASSERT(l > 0.0f); // Never negative. + const Vector3 n = v * (1.0f / l); XA_DEBUG_ASSERT(isNormalized(n)); return n; } -static Vector3 normalizeSafe(const Vector3 &v, const Vector3 &fallback, float epsilon) -{ - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return v * (1.0f / l); +static Vector3 normalizeSafe(const Vector3 &v, const Vector3 &fallback) { + const float l = length(v); + if (l > 0.0f) // Never negative. + return v * (1.0f / l); + return fallback; } -static bool equal(const Vector3 &v0, const Vector3 &v1, float epsilon) -{ +static bool equal(const Vector3 &v0, const Vector3 &v1, float epsilon) { return fabs(v0.x - v1.x) <= epsilon && fabs(v0.y - v1.y) <= epsilon && fabs(v0.z - v1.z) <= epsilon; } -static Vector3 min(const Vector3 &a, const Vector3 &b) -{ +static Vector3 min(const Vector3 &a, const Vector3 &b) { return Vector3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)); } -static Vector3 max(const Vector3 &a, const Vector3 &b) -{ +static Vector3 max(const Vector3 &a, const Vector3 &b) { return Vector3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); } #if XA_DEBUG -bool isFinite(const Vector3 &v) -{ +bool isFinite(const Vector3 &v) { return isFinite(v.x) && isFinite(v.y) && isFinite(v.z); } #endif -struct Extents2 -{ +struct Extents2 { Vector2 min, max; Extents2() {} - - Extents2(Vector2 p1, Vector2 p2) - { + + Extents2(Vector2 p1, Vector2 p2) { min = xatlas::internal::min(p1, p2); max = xatlas::internal::max(p1, p2); } - void reset() - { + void reset() { min.x = min.y = FLT_MAX; max.x = max.y = -FLT_MAX; } - void add(Vector2 p) - { + void add(Vector2 p) { min = xatlas::internal::min(min, p); max = xatlas::internal::max(max, p); } - Vector2 midpoint() const - { + Vector2 midpoint() const { return Vector2(min.x + (max.x - min.x) * 0.5f, min.y + (max.y - min.y) * 0.5f); } - static bool intersect(const Extents2 &e1, const Extents2 &e2) - { + static bool intersect(const Extents2 &e1, const Extents2 &e2) { return e1.min.x <= e2.max.x && e1.max.x >= e2.min.x && e1.min.y <= e2.max.y && e1.max.y >= e2.min.y; } }; -struct Plane -{ - Plane() = default; - - Plane(const Vector3 &p1, const Vector3 &p2, const Vector3 &p3) - { - normal = cross(p2 - p1, p3 - p1); - dist = dot(normal, p1); - } - - float distance(const Vector3 &p) const - { - return dot(normal, p) - dist; - } - - void normalize() - { - const float len = length(normal); - if (len > 0.0f) { - const float il = 1.0f / len; - normal *= il; - dist *= il; - } - } - - Vector3 normal; - float dist; -}; - -static bool lineIntersectsPoint(const Vector3 &point, const Vector3 &lineStart, const Vector3 &lineEnd, float *t, float epsilon) -{ - float tt; - if (!t) - t = &tt; - *t = 0.0f; - if (equal(lineStart, point, epsilon) || equal(lineEnd, point, epsilon)) - return false; // Vertex lies on either line vertices. - const Vector3 v01 = point - lineStart; - const Vector3 v21 = lineEnd - lineStart; - const float l = length(v21); - const float d = length(cross(v01, v21)) / l; - if (!isZero(d, epsilon)) - return false; - *t = dot(v01, v21) / (l * l); - return *t > kEpsilon && *t < 1.0f - kEpsilon; -} - -static bool sameSide(const Vector3 &p1, const Vector3 &p2, const Vector3 &a, const Vector3 &b) -{ - const Vector3 &ab = b - a; - return dot(cross(ab, p1 - a), cross(ab, p2 - a)) >= 0.0f; -} - -// http://blackpawn.com/texts/pointinpoly/default.html -static bool pointInTriangle(const Vector3 &p, const Vector3 &a, const Vector3 &b, const Vector3 &c) -{ - return sameSide(p, a, b, c) && sameSide(p, b, a, c) && sameSide(p, c, a, b); -} - -#if XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION -// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm -static bool rayIntersectsTriangle(const Vector3 &rayOrigin, const Vector3 &rayDir, const Vector3 *tri, float *t) -{ - *t = 0.0f; - const Vector3 &edge1 = tri[1] - tri[0]; - const Vector3 &edge2 = tri[2] - tri[0]; - const Vector3 h = cross(rayDir, edge2); - const float a = dot(edge1, h); - if (a > -kEpsilon && a < kEpsilon) - return false; // This ray is parallel to this triangle. - const float f = 1.0f / a; - const Vector3 s = rayOrigin - tri[0]; - const float u = f * dot(s, h); - if (u < 0.0f || u > 1.0f) - return false; - const Vector3 q = cross(s, edge1); - const float v = f * dot(rayDir, q); - if (v < 0.0f || u + v > 1.0f) - return false; - // At this stage we can compute t to find out where the intersection point is on the line. - *t = f * dot(edge2, q); - if (*t > kEpsilon && *t < 1.0f - kEpsilon) - return true; - // This means that there is a line intersection but not a ray intersection. - return false; -} -#endif - // From Fast-BVH -struct AABB -{ - AABB() : min(FLT_MAX, FLT_MAX, FLT_MAX), max(-FLT_MAX, -FLT_MAX, -FLT_MAX) {} - AABB(const Vector3 &min, const Vector3 &max) : min(min), max(max) { } - AABB(const Vector3 &p, float radius = 0.0f) : min(p), max(p) { if (radius > 0.0f) expand(radius); } - - bool intersect(const AABB &other) const - { +struct AABB { + AABB() : + min(FLT_MAX, FLT_MAX, FLT_MAX), max(-FLT_MAX, -FLT_MAX, -FLT_MAX) {} + AABB(const Vector3 &_min, const Vector3 &_max) : + min(_min), max(_max) {} + AABB(const Vector3 &p, float radius = 0.0f) : + min(p), max(p) { + if (radius > 0.0f) + expand(radius); + } + + bool intersect(const AABB &other) const { return min.x <= other.max.x && max.x >= other.min.x && min.y <= other.max.y && max.y >= other.min.y && min.z <= other.max.z && max.z >= other.min.z; } - void expandToInclude(const Vector3 &p) - { + void expandToInclude(const Vector3 &p) { min = internal::min(min, p); max = internal::max(max, p); } - void expandToInclude(const AABB &aabb) - { + void expandToInclude(const AABB &aabb) { min = internal::min(min, aabb.min); max = internal::max(max, aabb.max); } - void expand(float amount) - { + void expand(float amount) { min -= Vector3(amount); max += Vector3(amount); } - Vector3 centroid() const - { + Vector3 centroid() const { return min + (max - min) * 0.5f; } - uint32_t maxDimension() const - { + uint32_t maxDimension() const { const Vector3 extent = max - min; uint32_t result = 0; if (extent.y > extent.x) { result = 1; if (extent.z > extent.y) result = 2; - } - else if(extent.z > extent.x) + } else if (extent.z > extent.x) result = 2; return result; } @@ -1024,10 +871,9 @@ struct AABB Vector3 min, max; }; -struct ArrayBase -{ - ArrayBase(uint32_t elementSize, int memTag = MemTag::Default) : buffer(nullptr), elementSize(elementSize), size(0), capacity(0) - { +struct ArrayBase { + ArrayBase(uint32_t _elementSize, int memTag = MemTag::Default) : + buffer(nullptr), elementSize(_elementSize), size(0), capacity(0) { #if XA_DEBUG_HEAP this->memTag = memTag; #else @@ -1035,31 +881,31 @@ struct ArrayBase #endif } - ~ArrayBase() - { + ~ArrayBase() { XA_FREE(buffer); } - XA_INLINE void clear() - { + XA_INLINE void clear() { size = 0; } - void copyFrom(const uint8_t *data, uint32_t length) - { + void copyFrom(const uint8_t *data, uint32_t length) { + XA_DEBUG_ASSERT(data); + XA_DEBUG_ASSERT(length > 0); resize(length, true); - memcpy(buffer, data, length * elementSize); + if (buffer && data && length > 0) + memcpy(buffer, data, length * elementSize); } - void copyTo(ArrayBase &other) const - { + void copyTo(ArrayBase &other) const { XA_DEBUG_ASSERT(elementSize == other.elementSize); + XA_DEBUG_ASSERT(size > 0); other.resize(size, true); - memcpy(other.buffer, buffer, size * elementSize); + if (other.buffer && buffer && size > 0) + memcpy(other.buffer, buffer, size * elementSize); } - void destroy() - { + void destroy() { size = 0; XA_FREE(buffer); buffer = nullptr; @@ -1068,17 +914,18 @@ struct ArrayBase } // Insert the given element at the given index shifting all the elements up. - void insertAt(uint32_t index, const uint8_t *value) - { + void insertAt(uint32_t index, const uint8_t *value) { XA_DEBUG_ASSERT(index >= 0 && index <= size); + XA_DEBUG_ASSERT(value); resize(size + 1, false); - if (index < size - 1) + XA_DEBUG_ASSERT(buffer); + if (buffer && index < size - 1) memmove(buffer + elementSize * (index + 1), buffer + elementSize * index, elementSize * (size - 1 - index)); - memcpy(&buffer[index * elementSize], value, elementSize); + if (buffer && value) + memcpy(&buffer[index * elementSize], value, elementSize); } - void moveTo(ArrayBase &other) - { + void moveTo(ArrayBase &other) { XA_DEBUG_ASSERT(elementSize == other.elementSize); other.destroy(); other.buffer = buffer; @@ -1092,55 +939,61 @@ struct ArrayBase elementSize = size = capacity = 0; } - void pop_back() - { + void pop_back() { XA_DEBUG_ASSERT(size > 0); resize(size - 1, false); } - void push_back(const uint8_t *value) - { + void push_back(const uint8_t *value) { XA_DEBUG_ASSERT(value < buffer || value >= buffer + size); + XA_DEBUG_ASSERT(value); resize(size + 1, false); - memcpy(&buffer[(size - 1) * elementSize], value, elementSize); + XA_DEBUG_ASSERT(buffer); + if (buffer && value) + memcpy(&buffer[(size - 1) * elementSize], value, elementSize); } - void push_back(const ArrayBase &other) - { + void push_back(const ArrayBase &other) { XA_DEBUG_ASSERT(elementSize == other.elementSize); - if (other.size == 0) - return; - const uint32_t oldSize = size; - resize(size + other.size, false); - memcpy(buffer + oldSize * elementSize, other.buffer, other.size * other.elementSize); + if (other.size > 0) { + const uint32_t oldSize = size; + resize(size + other.size, false); + XA_DEBUG_ASSERT(buffer); + if (buffer) + memcpy(buffer + oldSize * elementSize, other.buffer, other.size * other.elementSize); + } } // Remove the element at the given index. This is an expensive operation! - void removeAt(uint32_t index) - { + void removeAt(uint32_t index) { XA_DEBUG_ASSERT(index >= 0 && index < size); - if (size != 1) - memmove(buffer + elementSize * index, buffer + elementSize * (index + 1), elementSize * (size - 1 - index)); - size--; + XA_DEBUG_ASSERT(buffer); + if (buffer) { + if (size > 1) + memmove(buffer + elementSize * index, buffer + elementSize * (index + 1), elementSize * (size - 1 - index)); + if (size > 0) + size--; + } } // Element at index is swapped with the last element, then the array length is decremented. - void removeAtFast(uint32_t index) - { + void removeAtFast(uint32_t index) { XA_DEBUG_ASSERT(index >= 0 && index < size); - if (size != 1 && index != size - 1) - memcpy(buffer + elementSize * index, buffer + elementSize * (size - 1), elementSize); - size--; + XA_DEBUG_ASSERT(buffer); + if (buffer) { + if (size > 1 && index != size - 1) + memcpy(buffer + elementSize * index, buffer + elementSize * (size - 1), elementSize); + if (size > 0) + size--; + } } - void reserve(uint32_t desiredSize) - { + void reserve(uint32_t desiredSize) { if (desiredSize > capacity) setArrayCapacity(desiredSize); } - void resize(uint32_t newSize, bool exact) - { + void resize(uint32_t newSize, bool exact) { size = newSize; if (size > capacity) { // First allocation is always exact. Otherwise, following allocations grow array to 150% of desired size. @@ -1153,8 +1006,7 @@ struct ArrayBase } } - void setArrayCapacity(uint32_t newCapacity) - { + void setArrayCapacity(uint32_t newCapacity) { XA_DEBUG_ASSERT(newCapacity >= size); if (newCapacity == 0) { // free the buffer. @@ -1174,8 +1026,7 @@ struct ArrayBase } #if XA_DEBUG_HEAP - void setMemTag(int _memTag) - { + void setMemTag(int _memTag) { this->memTag = _memTag; } #endif @@ -1189,28 +1040,27 @@ struct ArrayBase #endif }; -template<typename T> -class Array -{ +template <typename T> +class Array { public: - Array(int memTag = MemTag::Default) : m_base(sizeof(T), memTag) {} - Array(const Array&) = delete; + Array(int memTag = MemTag::Default) : + m_base(sizeof(T), memTag) {} + Array(const Array &) = delete; Array &operator=(const Array &) = delete; - XA_INLINE const T &operator[](uint32_t index) const - { + XA_INLINE const T &operator[](uint32_t index) const { XA_DEBUG_ASSERT(index < m_base.size); + XA_DEBUG_ASSERT(m_base.buffer); return ((const T *)m_base.buffer)[index]; } - XA_INLINE T &operator[](uint32_t index) - { + XA_INLINE T &operator[](uint32_t index) { XA_DEBUG_ASSERT(index < m_base.size); + XA_DEBUG_ASSERT(m_base.buffer); return ((T *)m_base.buffer)[index]; } - XA_INLINE const T &back() const - { + XA_INLINE const T &back() const { XA_DEBUG_ASSERT(!isEmpty()); return ((const T *)m_base.buffer)[m_base.size - 1]; } @@ -1218,8 +1068,7 @@ public: XA_INLINE T *begin() { return (T *)m_base.buffer; } XA_INLINE void clear() { m_base.clear(); } - bool contains(const T &value) const - { + bool contains(const T &value) const { for (uint32_t i = 0; i < m_base.size; i++) { if (((const T *)m_base.buffer)[i] == value) return true; @@ -1244,28 +1093,25 @@ public: void reserve(uint32_t desiredSize) { m_base.reserve(desiredSize); } void resize(uint32_t newSize) { m_base.resize(newSize, true); } - void runCtors() - { + void runCtors() { for (uint32_t i = 0; i < m_base.size; i++) new (&((T *)m_base.buffer)[i]) T; } - void runDtors() - { + void runDtors() { for (uint32_t i = 0; i < m_base.size; i++) ((T *)m_base.buffer)[i].~T(); } - void fill(const T &value) - { + void fill(const T &value) { auto buffer = (T *)m_base.buffer; for (uint32_t i = 0; i < m_base.size; i++) buffer[i] = value; } - void fillBytes(uint8_t value) - { - memset(m_base.buffer, (int)value, m_base.size * m_base.elementSize); + void fillBytes(uint8_t value) { + if (m_base.buffer && m_base.size > 0) + memset(m_base.buffer, (int)value, m_base.size * m_base.elementSize); } #if XA_DEBUG_HEAP @@ -1273,41 +1119,67 @@ public: #endif XA_INLINE uint32_t size() const { return m_base.size; } - XA_INLINE void zeroOutMemory() { memset(m_base.buffer, 0, m_base.elementSize * m_base.size); } + + XA_INLINE void zeroOutMemory() { + if (m_base.buffer && m_base.size > 0) + memset(m_base.buffer, 0, m_base.elementSize * m_base.size); + } private: ArrayBase m_base; }; -template<typename T> -struct ArrayView -{ - ArrayView() : data(nullptr), length(0) {} - ArrayView(Array<T> &a) : data(a.data()), length(a.size()) {} - ArrayView(T *data, uint32_t length) : data(data), length(length) {} - ArrayView &operator=(Array<T> &a) { data = a.data(); length = a.size(); return *this; } - XA_INLINE const T &operator[](uint32_t index) const { XA_DEBUG_ASSERT(index < length); return data[index]; } +template <typename T> +struct ArrayView { + ArrayView() : + data(nullptr), length(0) {} + ArrayView(Array<T> &a) : + data(a.data()), length(a.size()) {} + ArrayView(T *_data, uint32_t _length) : + data(_data), length(_length) {} + ArrayView &operator=(Array<T> &a) { + data = a.data(); + length = a.size(); + return *this; + } + XA_INLINE const T &operator[](uint32_t index) const { + XA_DEBUG_ASSERT(index < length); + return data[index]; + } + XA_INLINE T &operator[](uint32_t index) { + XA_DEBUG_ASSERT(index < length); + return data[index]; + } T *data; uint32_t length; }; -template<typename T> -struct ConstArrayView -{ - ConstArrayView() : data(nullptr), length(0) {} - ConstArrayView(const Array<T> &a) : data(a.data()), length(a.size()) {} - ConstArrayView(const T *data, uint32_t length) : data(data), length(length) {} - ConstArrayView &operator=(const Array<T> &a) { data = a.data(); length = a.size(); return *this; } - XA_INLINE const T &operator[](uint32_t index) const { XA_DEBUG_ASSERT(index < length); return data[index]; } +template <typename T> +struct ConstArrayView { + ConstArrayView() : + data(nullptr), length(0) {} + ConstArrayView(const Array<T> &a) : + data(a.data()), length(a.size()) {} + ConstArrayView(ArrayView<T> av) : + data(av.data), length(av.length) {} + ConstArrayView(const T *_data, uint32_t _length) : + data(_data), length(_length) {} + ConstArrayView &operator=(const Array<T> &a) { + data = a.data(); + length = a.size(); + return *this; + } + XA_INLINE const T &operator[](uint32_t index) const { + XA_DEBUG_ASSERT(index < length); + return data[index]; + } const T *data; uint32_t length; }; /// Basis class to compute tangent space basis, ortogonalizations and to transform vectors from one space to another. -struct Basis -{ - XA_NODISCARD static Vector3 computeTangent(const Vector3 &normal) - { +struct Basis { + XA_NODISCARD static Vector3 computeTangent(const Vector3 &normal) { XA_ASSERT(isNormalized(normal)); // Choose minimum axis. Vector3 tangent; @@ -1319,12 +1191,11 @@ struct Basis tangent = Vector3(0, 0, 1); // Ortogonalize tangent -= normal * dot(normal, tangent); - tangent = normalize(tangent, kEpsilon); + tangent = normalize(tangent); return tangent; } - XA_NODISCARD static Vector3 computeBitangent(const Vector3 &normal, const Vector3 &tangent) - { + XA_NODISCARD static Vector3 computeBitangent(const Vector3 &normal, const Vector3 &tangent) { return cross(normal, tangent); } @@ -1334,42 +1205,36 @@ struct Basis }; // Simple bit array. -class BitArray -{ +class BitArray { public: - BitArray() : m_size(0) {} + BitArray() : + m_size(0) {} - BitArray(uint32_t sz) - { + BitArray(uint32_t sz) { resize(sz); } - void resize(uint32_t new_size) - { + void resize(uint32_t new_size) { m_size = new_size; m_wordArray.resize((m_size + 31) >> 5); } - bool get(uint32_t index) const - { + bool get(uint32_t index) const { XA_DEBUG_ASSERT(index < m_size); return (m_wordArray[index >> 5] & (1 << (index & 31))) != 0; } - void set(uint32_t index) - { + void set(uint32_t index) { XA_DEBUG_ASSERT(index < m_size); m_wordArray[index >> 5] |= (1 << (index & 31)); } - void unset(uint32_t index) - { + void unset(uint32_t index) { XA_DEBUG_ASSERT(index < m_size); m_wordArray[index >> 5] &= ~(1 << (index & 31)); } - void zeroOutMemory() - { + void zeroOutMemory() { m_wordArray.zeroOutMemory(); } @@ -1378,13 +1243,13 @@ private: Array<uint32_t> m_wordArray; }; -class BitImage -{ +class BitImage { public: - BitImage() : m_width(0), m_height(0), m_rowStride(0), m_data(MemTag::BitImage) {} + BitImage() : + m_width(0), m_height(0), m_rowStride(0), m_data(MemTag::BitImage) {} - BitImage(uint32_t w, uint32_t h) : m_width(w), m_height(h), m_data(MemTag::BitImage) - { + BitImage(uint32_t w, uint32_t h) : + m_width(w), m_height(h), m_data(MemTag::BitImage) { m_rowStride = (m_width + 63) >> 6; m_data.resize(m_rowStride * m_height); m_data.zeroOutMemory(); @@ -1395,16 +1260,14 @@ public: uint32_t width() const { return m_width; } uint32_t height() const { return m_height; } - void copyTo(BitImage &other) - { + void copyTo(BitImage &other) { other.m_width = m_width; other.m_height = m_height; other.m_rowStride = m_rowStride; m_data.copyTo(other.m_data); } - void resize(uint32_t w, uint32_t h, bool discard) - { + void resize(uint32_t w, uint32_t h, bool discard) { const uint32_t rowStride = (w + 63) >> 6; if (discard) { m_data.resize(rowStride * h); @@ -1428,28 +1291,24 @@ public: m_rowStride = rowStride; } - bool get(uint32_t x, uint32_t y) const - { + bool get(uint32_t x, uint32_t y) const { XA_DEBUG_ASSERT(x < m_width && y < m_height); const uint32_t index = (x >> 6) + y * m_rowStride; return (m_data[index] & (UINT64_C(1) << (uint64_t(x) & UINT64_C(63)))) != 0; } - void set(uint32_t x, uint32_t y) - { + void set(uint32_t x, uint32_t y) { XA_DEBUG_ASSERT(x < m_width && y < m_height); const uint32_t index = (x >> 6) + y * m_rowStride; m_data[index] |= UINT64_C(1) << (uint64_t(x) & UINT64_C(63)); XA_DEBUG_ASSERT(get(x, y)); } - void zeroOutMemory() - { + void zeroOutMemory() { m_data.zeroOutMemory(); } - bool canBlit(const BitImage &image, uint32_t offsetX, uint32_t offsetY) const - { + bool canBlit(const BitImage &image, uint32_t offsetX, uint32_t offsetY) const { for (uint32_t y = 0; y < image.m_height; y++) { const uint32_t thisY = y + offsetY; if (thisY >= m_height) @@ -1473,8 +1332,7 @@ public: return true; } - void dilate(uint32_t padding) - { + void dilate(uint32_t padding) { BitImage tmp(m_width, m_height); for (uint32_t p = 0; p < padding; p++) { tmp.zeroOutMemory(); @@ -1484,15 +1342,21 @@ public: if (!b) { if (x > 0) { b |= get(x - 1, y); - if (y > 0) b |= get(x - 1, y - 1); - if (y < m_height - 1) b |= get(x - 1, y + 1); + if (y > 0) + b |= get(x - 1, y - 1); + if (y < m_height - 1) + b |= get(x - 1, y + 1); } - if (y > 0) b |= get(x, y - 1); - if (y < m_height - 1) b |= get(x, y + 1); + if (y > 0) + b |= get(x, y - 1); + if (y < m_height - 1) + b |= get(x, y + 1); if (x < m_width - 1) { b |= get(x + 1, y); - if (y > 0) b |= get(x + 1, y - 1); - if (y < m_height - 1) b |= get(x + 1, y + 1); + if (y > 0) + b |= get(x + 1, y - 1); + if (y < m_height - 1) + b |= get(x + 1, y + 1); } } if (b) @@ -1511,11 +1375,10 @@ private: }; // From Fast-BVH -class BVH -{ +class BVH { public: - BVH(const Array<AABB> &objectAabbs, uint32_t leafSize = 4) : m_objectIds(MemTag::BVH), m_nodes(MemTag::BVH) - { + BVH(const Array<AABB> &objectAabbs, uint32_t leafSize = 4) : + m_objectIds(MemTag::BVH), m_nodes(MemTag::BVH) { m_objectAabbs = &objectAabbs; if (m_objectAabbs->isEmpty()) return; @@ -1535,7 +1398,7 @@ public: Node node; m_nodes.reserve(objectAabbs.size() * 2); uint32_t nNodes = 0; - while(stackptr > 0) { + while (stackptr > 0) { // Pop the next item off of the stack const BuildEntry &bnode = todo[--stackptr]; const uint32_t start = bnode.start; @@ -1548,7 +1411,7 @@ public: // Calculate the bounding box for this node AABB bb(objectAabbs[m_objectIds[start]]); AABB bc(objectAabbs[m_objectIds[start]].centroid()); - for(uint32_t p = start + 1; p < end; ++p) { + for (uint32_t p = start + 1; p < end; ++p) { bb.expandToInclude(objectAabbs[m_objectIds[p]]); bc.expandToInclude(objectAabbs[m_objectIds[p]].centroid()); } @@ -1564,7 +1427,7 @@ public: m_nodes[bnode.parent].rightOffset--; // When this is the second touch, this is the right child. // The right child sets up the offset for the flat tree. - if (m_nodes[bnode.parent].rightOffset == kTouchedTwice ) + if (m_nodes[bnode.parent].rightOffset == kTouchedTwice) m_nodes[bnode.parent].rightOffset = nNodes - 1 - bnode.parent; } // If this is a leaf, no need to subdivide. @@ -1599,21 +1462,20 @@ public: } } - void query(const AABB &queryAabb, Array<uint32_t> &result) const - { + void query(const AABB &queryAabb, Array<uint32_t> &result) const { result.clear(); // Working set uint32_t todo[64]; int32_t stackptr = 0; // "Push" on the root node to the working set todo[stackptr] = 0; - while(stackptr >= 0) { + while (stackptr >= 0) { // Pop off the next node to work on. const int ni = todo[stackptr--]; const Node &node = m_nodes[ni]; // Is leaf -> Intersect if (node.rightOffset == 0) { - for(uint32_t o = 0; o < node.nPrims; ++o) { + for (uint32_t o = 0; o < node.nPrims; ++o) { const uint32_t obj = node.start + o; if (queryAabb.intersect((*m_objectAabbs)[m_objectIds[obj]])) result.push_back(m_objectIds[obj]); @@ -1630,14 +1492,12 @@ public: } private: - struct BuildEntry - { + struct BuildEntry { uint32_t parent; // If non-zero then this is the index of the parent. (used in offsets) uint32_t start, end; // The range of objects in the object list covered by this node. }; - struct Node - { + struct Node { AABB aabb; uint32_t start, nPrims, rightOffset; }; @@ -1647,16 +1507,14 @@ private: Array<Node> m_nodes; }; -struct Fit -{ - static bool computeBasis(const Vector3 *points, uint32_t pointsCount, Basis *basis) - { - if (computeLeastSquaresNormal(points, pointsCount, &basis->normal)) { +struct Fit { + static bool computeBasis(ConstArrayView<Vector3> points, Basis *basis) { + if (computeLeastSquaresNormal(points, &basis->normal)) { basis->tangent = Basis::computeTangent(basis->normal); basis->bitangent = Basis::computeBitangent(basis->normal, basis->tangent); return true; } - return computeEigen(points, pointsCount, basis); + return computeEigen(points, basis); } private: @@ -1664,21 +1522,20 @@ private: // Fast, and accurate to within a few degrees. // Returns None if the points do not span a plane. // https://www.ilikebigbits.com/2015_03_04_plane_from_points.html - static bool computeLeastSquaresNormal(const Vector3 *points, uint32_t pointsCount, Vector3 *normal) - { - XA_DEBUG_ASSERT(pointsCount >= 3); - if (pointsCount == 3) { - *normal = normalize(cross(points[2] - points[0], points[1] - points[0]), kEpsilon); + static bool computeLeastSquaresNormal(ConstArrayView<Vector3> points, Vector3 *normal) { + XA_DEBUG_ASSERT(points.length >= 3); + if (points.length == 3) { + *normal = normalize(cross(points[2] - points[0], points[1] - points[0])); return true; } - const float invN = 1.0f / float(pointsCount); + const float invN = 1.0f / float(points.length); Vector3 centroid(0.0f); - for (uint32_t i = 0; i < pointsCount; i++) + for (uint32_t i = 0; i < points.length; i++) centroid += points[i]; centroid *= invN; // Calculate full 3x3 covariance matrix, excluding symmetries: float xx = 0.0f, xy = 0.0f, xz = 0.0f, yy = 0.0f, yz = 0.0f, zz = 0.0f; - for (uint32_t i = 0; i < pointsCount; i++) { + for (uint32_t i = 0; i < points.length; i++) { Vector3 r = points[i] - centroid; xx += r.x * r.x; xy += r.x * r.y; @@ -1730,7 +1587,7 @@ private: // Pick path with best conditioning: Vector3 dir(0.0f); if (det_max == det_x) - dir = Vector3(det_x,xz * yz - xy * zz,xy * yz - xz * yy); + dir = Vector3(det_x, xz * yz - xy * zz, xy * yz - xz * yy); else if (det_max == det_y) dir = Vector3(xz * yz - xy * zz, det_y, xy * xz - yz * xx); else if (det_max == det_z) @@ -1743,41 +1600,37 @@ private: return isNormalized(*normal); } - static bool computeEigen(const Vector3 *points, uint32_t pointsCount, Basis *basis) - { + static bool computeEigen(ConstArrayView<Vector3> points, Basis *basis) { float matrix[6]; - computeCovariance(pointsCount, points, matrix); + computeCovariance(points, matrix); if (matrix[0] == 0 && matrix[3] == 0 && matrix[5] == 0) return false; float eigenValues[3]; Vector3 eigenVectors[3]; if (!eigenSolveSymmetric3(matrix, eigenValues, eigenVectors)) return false; - basis->normal = normalize(eigenVectors[2], kEpsilon); - basis->tangent = normalize(eigenVectors[0], kEpsilon); - basis->bitangent = normalize(eigenVectors[1], kEpsilon); + basis->normal = normalize(eigenVectors[2]); + basis->tangent = normalize(eigenVectors[0]); + basis->bitangent = normalize(eigenVectors[1]); return true; } - static Vector3 computeCentroid(int n, const Vector3 * points) - { + static Vector3 computeCentroid(ConstArrayView<Vector3> points) { Vector3 centroid(0.0f); - for (int i = 0; i < n; i++) { + for (uint32_t i = 0; i < points.length; i++) centroid += points[i]; - } - centroid /= float(n); + centroid /= float(points.length); return centroid; } - static Vector3 computeCovariance(int n, const Vector3 * points, float * covariance) - { + static Vector3 computeCovariance(ConstArrayView<Vector3> points, float *covariance) { // compute the centroid - Vector3 centroid = computeCentroid(n, points); + Vector3 centroid = computeCentroid(points); // compute covariance matrix for (int i = 0; i < 6; i++) { covariance[i] = 0.0f; } - for (int i = 0; i < n; i++) { + for (uint32_t i = 0; i < points.length; i++) { Vector3 v = points[i] - centroid; covariance[0] += v.x * v.x; covariance[1] += v.x * v.y; @@ -1792,8 +1645,7 @@ private: // Tridiagonal solver from Charles Bloom. // Householder transforms followed by QL decomposition. // Seems to be based on the code from Numerical Recipes in C. - static bool eigenSolveSymmetric3(const float matrix[6], float eigenValues[3], Vector3 eigenVectors[3]) - { + static bool eigenSolveSymmetric3(const float matrix[6], float eigenValues[3], Vector3 eigenVectors[3]) { XA_DEBUG_ASSERT(matrix != nullptr && eigenValues != nullptr && eigenVectors != nullptr); float subd[3]; float diag[3]; @@ -1818,7 +1670,7 @@ private: // eigenvectors are the columns; make them the rows : for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - (&eigenVectors[j].x)[i] = (float) work[i][j]; + (&eigenVectors[j].x)[i] = (float)work[i][j]; } } // shuffle to sort by singular value : @@ -1840,8 +1692,7 @@ private: } private: - static void EigenSolver3_Tridiagonal(float mat[3][3], float *diag, float *subd) - { + static void EigenSolver3_Tridiagonal(float mat[3][3], float *diag, float *subd) { // Householder reduction T = Q^t M Q // Input: // mat, symmetric 3x3 matrix M @@ -1893,8 +1744,7 @@ private: } } - static bool EigenSolver3_QLAlgorithm(float mat[3][3], float *diag, float *subd) - { + static bool EigenSolver3_QLAlgorithm(float mat[3][3], float *diag, float *subd) { // QL iteration with implicit shifting to reduce matrix from tridiagonal // to diagonal const int maxiter = 32; @@ -1904,21 +1754,21 @@ private: int m; for (m = ell; m <= 1; m++) { float dd = fabsf(diag[m]) + fabsf(diag[m + 1]); - if ( fabsf(subd[m]) + dd == dd ) + if (fabsf(subd[m]) + dd == dd) break; } - if ( m == ell ) + if (m == ell) break; float g = (diag[ell + 1] - diag[ell]) / (2 * subd[ell]); float r = sqrtf(g * g + 1); - if ( g < 0 ) + if (g < 0) g = diag[m] - diag[ell] + subd[ell] / (g - r); else g = diag[m] - diag[ell] + subd[ell] / (g + r); float s = 1, c = 1, p = 0; for (int i = m - 1; i >= ell; i--) { float f = s * subd[i], b = c * subd[i]; - if ( fabsf(f) >= fabsf(g) ) { + if (fabsf(f) >= fabsf(g)) { c = g / f; r = sqrtf(c * c + 1); subd[i + 1] = f * r; @@ -1944,7 +1794,7 @@ private: subd[ell] = g; subd[m] = 0; } - if ( iter == maxiter ) + if (iter == maxiter) // should not get here under normal circumstances return false; } @@ -1952,56 +1802,48 @@ private: } }; -static uint32_t sdbmHash(const void *data_in, uint32_t size, uint32_t h = 5381) -{ - const uint8_t *data = (const uint8_t *) data_in; +static uint32_t sdbmHash(const void *data_in, uint32_t size, uint32_t h = 5381) { + const uint8_t *data = (const uint8_t *)data_in; uint32_t i = 0; while (i < size) { - h = (h << 16) + (h << 6) - h + (uint32_t ) data[i++]; + h = (h << 16) + (h << 6) - h + (uint32_t)data[i++]; } return h; } template <typename T> -static uint32_t hash(const T &t, uint32_t h = 5381) -{ +static uint32_t hash(const T &t, uint32_t h = 5381) { return sdbmHash(&t, sizeof(T), h); } template <typename Key> -struct Hash -{ +struct Hash { uint32_t operator()(const Key &k) const { return hash(k); } }; template <typename Key> -struct PassthroughHash -{ +struct PassthroughHash { uint32_t operator()(const Key &k) const { return (uint32_t)k; } }; template <typename Key> -struct Equal -{ +struct Equal { bool operator()(const Key &k0, const Key &k1) const { return k0 == k1; } }; -template<typename Key, typename H = Hash<Key>, typename E = Equal<Key> > -class HashMap -{ +template <typename Key, typename H = Hash<Key>, typename E = Equal<Key>> +class HashMap { public: - HashMap(int memTag, uint32_t size) : m_memTag(memTag), m_size(size), m_numSlots(0), m_slots(nullptr), m_keys(memTag), m_next(memTag) - { + HashMap(int memTag, uint32_t size) : + m_memTag(memTag), m_size(size), m_numSlots(0), m_slots(nullptr), m_keys(memTag), m_next(memTag) { } - ~HashMap() - { + ~HashMap() { if (m_slots) XA_FREE(m_slots); } - void destroy() - { + void destroy() { if (m_slots) { XA_FREE(m_slots); m_slots = nullptr; @@ -2010,8 +1852,7 @@ public: m_next.destroy(); } - uint32_t add(const Key &key) - { + uint32_t add(const Key &key) { if (!m_slots) alloc(); const uint32_t hash = computeHash(key); @@ -2021,36 +1862,18 @@ public: return m_keys.size() - 1; } - uint32_t get(const Key &key) const - { + uint32_t get(const Key &key) const { if (!m_slots) return UINT32_MAX; - const uint32_t hash = computeHash(key); - uint32_t i = m_slots[hash]; - E equal; - while (i != UINT32_MAX) { - if (equal(m_keys[i], key)) - return i; - i = m_next[i]; - } - return UINT32_MAX; + return find(key, m_slots[computeHash(key)]); } - uint32_t getNext(uint32_t current) const - { - uint32_t i = m_next[current]; - E equal; - while (i != UINT32_MAX) { - if (equal(m_keys[i], m_keys[current])) - return i; - i = m_next[i]; - } - return UINT32_MAX; + uint32_t getNext(const Key &key, uint32_t current) const { + return find(key, m_next[current]); } private: - void alloc() - { + void alloc() { XA_DEBUG_ASSERT(m_size > 0); m_numSlots = nextPowerOfTwo(m_size); auto minNumSlots = uint32_t(m_size * 1.3); @@ -2063,12 +1886,21 @@ private: m_next.reserve(m_size); } - uint32_t computeHash(const Key &key) const - { + uint32_t computeHash(const Key &key) const { H hash; return hash(key) & (m_numSlots - 1); } + uint32_t find(const Key &key, uint32_t current) const { + E equal; + while (current != UINT32_MAX) { + if (equal(m_keys[current], key)) + return current; + current = m_next[current]; + } + return current; + } + int m_memTag; uint32_t m_size; uint32_t m_numSlots; @@ -2077,9 +1909,8 @@ private: Array<uint32_t> m_next; }; -template<typename T> -static void insertionSort(T *data, uint32_t length) -{ +template <typename T> +static void insertionSort(T *data, uint32_t length) { for (int32_t i = 1; i < (int32_t)length; i++) { T x = data[i]; int32_t j = i - 1; @@ -2091,21 +1922,18 @@ static void insertionSort(T *data, uint32_t length) } } -class KISSRng -{ +class KISSRng { public: KISSRng() { reset(); } - void reset() - { + void reset() { x = 123456789; y = 362436000; z = 521288629; c = 7654321; } - uint32_t getRange(uint32_t range) - { + uint32_t getRange(uint32_t range) { if (range == 0) return 0; x = 69069 * x + 12345; @@ -2124,12 +1952,10 @@ private: // Based on Pierre Terdiman's and Michael Herf's source code. // http://www.codercorner.com/RadixSortRevisited.htm // http://www.stereopsis.com/radix.html -class RadixSort -{ +class RadixSort { public: - void sort(const float *input, uint32_t count) - { - if (input == nullptr || count == 0) { + void sort(ConstArrayView<float> input) { + if (input.length == 0) { m_buffer1.clear(); m_buffer2.clear(); m_ranks = m_buffer1.data(); @@ -2137,33 +1963,27 @@ public: return; } // Resize lists if needed - m_buffer1.resize(count); - m_buffer2.resize(count); + m_buffer1.resize(input.length); + m_buffer2.resize(input.length); m_ranks = m_buffer1.data(); m_ranks2 = m_buffer2.data(); m_validRanks = false; - if (count < 32) - insertionSort(input, count); + if (input.length < 32) + insertionSort(input); else { // @@ Avoid touching the input multiple times. - for (uint32_t i = 0; i < count; i++) { + for (uint32_t i = 0; i < input.length; i++) { floatFlip((uint32_t &)input[i]); } - radixSort<uint32_t>((const uint32_t *)input, count); - for (uint32_t i = 0; i < count; i++) { + radixSort(ConstArrayView<uint32_t>((const uint32_t *)input.data, input.length)); + for (uint32_t i = 0; i < input.length; i++) { ifloatFlip((uint32_t &)input[i]); } } } - void sort(const Array<float> &input) - { - sort(input.data(), input.size()); - } - // Access to results. m_ranks is a list of indices in sorted order, i.e. in the order you may further process your data - const uint32_t *ranks() const - { + const uint32_t *ranks() const { XA_DEBUG_ASSERT(m_validRanks); return m_ranks; } @@ -2171,54 +1991,40 @@ public: private: uint32_t *m_ranks, *m_ranks2; Array<uint32_t> m_buffer1, m_buffer2; - bool m_validRanks; + bool m_validRanks = false; - void floatFlip(uint32_t &f) - { + void floatFlip(uint32_t &f) { int32_t mask = (int32_t(f) >> 31) | 0x80000000; // Warren Hunt, Manchor Ko. f ^= mask; } - void ifloatFlip(uint32_t &f) - { + void ifloatFlip(uint32_t &f) { uint32_t mask = ((f >> 31) - 1) | 0x80000000; // Michael Herf. f ^= mask; } - template<typename T> - void createHistograms(const T *buffer, uint32_t count, uint32_t *histogram) - { - const uint32_t bucketCount = sizeof(T); // (8 * sizeof(T)) / log2(radix) + void createHistograms(ConstArrayView<uint32_t> input, uint32_t *histogram) { + const uint32_t bucketCount = sizeof(uint32_t); // Init bucket pointers. uint32_t *h[bucketCount]; for (uint32_t i = 0; i < bucketCount; i++) { h[i] = histogram + 256 * i; } // Clear histograms. - memset(histogram, 0, 256 * bucketCount * sizeof(uint32_t )); + memset(histogram, 0, 256 * bucketCount * sizeof(uint32_t)); // @@ Add support for signed integers. // Build histograms. - const uint8_t *p = (const uint8_t *)buffer; // @@ Does this break aliasing rules? - const uint8_t *pe = p + count * sizeof(T); + const uint8_t *p = (const uint8_t *)input.data; // @@ Does this break aliasing rules? + const uint8_t *pe = p + input.length * sizeof(uint32_t); while (p != pe) { h[0][*p++]++, h[1][*p++]++, h[2][*p++]++, h[3][*p++]++; -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4127) -#endif - if (bucketCount == 8) h[4][*p++]++, h[5][*p++]++, h[6][*p++]++, h[7][*p++]++; -#ifdef _MSC_VER -#pragma warning(pop) -#endif } } - template <typename T> - void insertionSort(const T *input, uint32_t count) - { + void insertionSort(ConstArrayView<float> input) { if (!m_validRanks) { m_ranks[0] = 0; - for (uint32_t i = 1; i != count; ++i) { + for (uint32_t i = 1; i != input.length; ++i) { int rank = m_ranks[i] = i; uint32_t j = i; while (j != 0 && input[rank] < input[m_ranks[j - 1]]) { @@ -2231,7 +2037,7 @@ private: } m_validRanks = true; } else { - for (uint32_t i = 1; i != count; ++i) { + for (uint32_t i = 1; i != input.length; ++i) { int rank = m_ranks[i]; uint32_t j = i; while (j != 0 && input[rank] < input[m_ranks[j - 1]]) { @@ -2245,35 +2051,34 @@ private: } } - template <typename T> - void radixSort(const T *input, uint32_t count) - { - const uint32_t P = sizeof(T); // pass count + void radixSort(ConstArrayView<uint32_t> input) { + const uint32_t P = sizeof(uint32_t); // pass count // Allocate histograms & offsets on the stack uint32_t histogram[256 * P]; uint32_t *link[256]; - createHistograms(input, count, histogram); + createHistograms(input, histogram); // Radix sort, j is the pass number (0=LSB, P=MSB) for (uint32_t j = 0; j < P; j++) { // Pointer to this bucket. const uint32_t *h = &histogram[j * 256]; - const uint8_t *inputBytes = (const uint8_t *)input; // @@ Is this aliasing legal? + auto inputBytes = (const uint8_t *)input.data; // @@ Is this aliasing legal? inputBytes += j; - if (h[inputBytes[0]] == count) { + if (h[inputBytes[0]] == input.length) { // Skip this pass, all values are the same. continue; } // Create offsets link[0] = m_ranks2; - for (uint32_t i = 1; i < 256; i++) link[i] = link[i - 1] + h[i - 1]; + for (uint32_t i = 1; i < 256; i++) + link[i] = link[i - 1] + h[i - 1]; // Perform Radix Sort if (!m_validRanks) { - for (uint32_t i = 0; i < count; i++) { + for (uint32_t i = 0; i < input.length; i++) { *link[inputBytes[i * P]]++ = i; } m_validRanks = true; } else { - for (uint32_t i = 0; i < count; i++) { + for (uint32_t i = 0; i < input.length; i++) { const uint32_t idx = m_ranks[i]; *link[inputBytes[idx * P]]++ = idx; } @@ -2283,7 +2088,7 @@ private: } // All values were equal, generate linear ranks. if (!m_validRanks) { - for (uint32_t i = 0; i < count; i++) + for (uint32_t i = 0; i < input.length; i++) m_ranks[i] = i; m_validRanks = true; } @@ -2291,30 +2096,25 @@ private: }; // Wrapping this in a class allows temporary arrays to be re-used. -class BoundingBox2D -{ +class BoundingBox2D { public: Vector2 majorAxis, minorAxis, minCorner, maxCorner; - void clear() - { + void clear() { m_boundaryVertices.clear(); } - void appendBoundaryVertex(Vector2 v) - { + void appendBoundaryVertex(Vector2 v) { m_boundaryVertices.push_back(v); } // This should compute convex hull and use rotating calipers to find the best box. Currently it uses a brute force method. - // If vertices is null or vertexCount is 0, the boundary vertices are used. - void compute(const Vector2 *vertices = nullptr, uint32_t vertexCount = 0) - { - if (!vertices || vertexCount == 0) { - vertices = m_boundaryVertices.data(); - vertexCount = m_boundaryVertices.size(); - } - convexHull(m_boundaryVertices.data(), m_boundaryVertices.size(), m_hull, 0.00001f); + // If vertices are empty, the boundary vertices are used. + void compute(ConstArrayView<Vector2> vertices = ConstArrayView<Vector2>()) { + XA_DEBUG_ASSERT(!m_boundaryVertices.isEmpty()); + if (vertices.length == 0) + vertices = m_boundaryVertices; + convexHull(m_boundaryVertices, m_hull, 0.00001f); // @@ Ideally I should use rotating calipers to find the best box. Using brute force for now. float best_area = FLT_MAX; Vector2 best_min(0); @@ -2324,13 +2124,13 @@ public: for (uint32_t i = 0, j = hullCount - 1; i < hullCount; j = i, i++) { if (equal(m_hull[i], m_hull[j], kEpsilon)) continue; - Vector2 axis = normalize(m_hull[i] - m_hull[j], 0.0f); + Vector2 axis = normalize(m_hull[i] - m_hull[j]); XA_DEBUG_ASSERT(isFinite(axis)); // Compute bounding box. Vector2 box_min(FLT_MAX, FLT_MAX); Vector2 box_max(-FLT_MAX, -FLT_MAX); // Consider all points, not only boundary points, in case the input chart is malformed. - for (uint32_t v = 0; v < vertexCount; v++) { + for (uint32_t v = 0; v < vertices.length; v++) { const Vector2 &point = vertices[v]; const float x = dot(axis, point); const float y = dot(Vector2(-axis.y, axis.x), point); @@ -2357,28 +2157,27 @@ public: private: // Compute the convex hull using Graham Scan. - void convexHull(const Vector2 *input, uint32_t inputCount, Array<Vector2> &output, float epsilon) - { - m_coords.resize(inputCount); - for (uint32_t i = 0; i < inputCount; i++) + void convexHull(ConstArrayView<Vector2> input, Array<Vector2> &output, float epsilon) { + m_coords.resize(input.length); + for (uint32_t i = 0; i < input.length; i++) m_coords[i] = input[i].x; m_radix.sort(m_coords); const uint32_t *ranks = m_radix.ranks(); m_top.clear(); m_bottom.clear(); - m_top.reserve(inputCount); - m_bottom.reserve(inputCount); + m_top.reserve(input.length); + m_bottom.reserve(input.length); Vector2 P = input[ranks[0]]; - Vector2 Q = input[ranks[inputCount - 1]]; + Vector2 Q = input[ranks[input.length - 1]]; float topy = max(P.y, Q.y); float boty = min(P.y, Q.y); - for (uint32_t i = 0; i < inputCount; i++) { + for (uint32_t i = 0; i < input.length; i++) { Vector2 p = input[ranks[i]]; if (p.y >= boty) m_top.push_back(p); } - for (uint32_t i = 0; i < inputCount; i++) { - Vector2 p = input[ranks[inputCount - 1 - i]]; + for (uint32_t i = 0; i < input.length; i++) { + Vector2 p = input[ranks[input.length - 1 - i]]; if (p.y <= topy) m_bottom.push_back(p); } @@ -2387,7 +2186,7 @@ private: XA_DEBUG_ASSERT(m_top.size() >= 2); output.push_back(m_top[0]); output.push_back(m_top[1]); - for (uint32_t i = 2; i < m_top.size(); ) { + for (uint32_t i = 2; i < m_top.size();) { Vector2 a = output[output.size() - 2]; Vector2 b = output[output.size() - 1]; Vector2 c = m_top[i]; @@ -2403,7 +2202,7 @@ private: XA_DEBUG_ASSERT(m_bottom.size() >= 2); output.push_back(m_bottom[1]); // Filter bottom list. - for (uint32_t i = 2; i < m_bottom.size(); ) { + for (uint32_t i = 2; i < m_bottom.size();) { Vector2 a = output[output.size() - 2]; Vector2 b = output[output.size() - 1]; Vector2 c = m_bottom[i]; @@ -2426,32 +2225,45 @@ private: RadixSort m_radix; }; -static uint32_t meshEdgeFace(uint32_t edge) { return edge / 3; } -static uint32_t meshEdgeIndex0(uint32_t edge) { return edge; } +struct EdgeKey { + EdgeKey(const EdgeKey &k) : + v0(k.v0), v1(k.v1) {} + EdgeKey(uint32_t _v0, uint32_t _v1) : + v0(_v0), v1(_v1) {} + bool operator==(const EdgeKey &k) const { return v0 == k.v0 && v1 == k.v1; } -static uint32_t meshEdgeIndex1(uint32_t edge) -{ + uint32_t v0; + uint32_t v1; +}; + +struct EdgeHash { + uint32_t operator()(const EdgeKey &k) const { return k.v0 * 32768u + k.v1; } +}; + +static uint32_t meshEdgeFace(uint32_t edge) { + return edge / 3; +} +static uint32_t meshEdgeIndex0(uint32_t edge) { + return edge; +} + +static uint32_t meshEdgeIndex1(uint32_t edge) { const uint32_t faceFirstEdge = edge / 3 * 3; return faceFirstEdge + (edge - faceFirstEdge + 1) % 3; } -struct MeshFlags -{ - enum - { - HasIgnoredFaces = 1<<0, - HasNormals = 1<<1 +struct MeshFlags { + enum { + HasIgnoredFaces = 1 << 0, + HasNormals = 1 << 1, + HasMaterials = 1 << 2 }; }; -class Mesh; -static void meshGetBoundaryLoops(const Mesh &mesh, Array<uint32_t> &boundaryLoops); - -class Mesh -{ +class Mesh { public: - Mesh(float epsilon, uint32_t approxVertexCount, uint32_t approxFaceCount, uint32_t flags = 0, uint32_t id = UINT32_MAX) : m_epsilon(epsilon), m_flags(flags), m_id(id), m_faceIgnore(MemTag::Mesh), m_indices(MemTag::MeshIndices), m_positions(MemTag::MeshPositions), m_normals(MemTag::MeshNormals), m_texcoords(MemTag::MeshTexcoords), m_nextColocalVertex(MemTag::MeshColocals), m_boundaryEdges(MemTag::MeshBoundaries), m_oppositeEdges(MemTag::MeshBoundaries), m_nextBoundaryEdges(MemTag::MeshBoundaries), m_edgeMap(MemTag::MeshEdgeMap, approxFaceCount * 3) - { + Mesh(float epsilon, uint32_t approxVertexCount, uint32_t approxFaceCount, uint32_t flags = 0, uint32_t id = UINT32_MAX) : + m_epsilon(epsilon), m_flags(flags), m_id(id), m_faceIgnore(MemTag::Mesh), m_faceMaterials(MemTag::Mesh), m_indices(MemTag::MeshIndices), m_positions(MemTag::MeshPositions), m_normals(MemTag::MeshNormals), m_texcoords(MemTag::MeshTexcoords), m_nextColocalVertex(MemTag::MeshColocals), m_firstColocalVertex(MemTag::MeshColocals), m_boundaryEdges(MemTag::MeshBoundaries), m_oppositeEdges(MemTag::MeshBoundaries), m_edgeMap(MemTag::MeshEdgeMap, approxFaceCount * 3) { m_indices.reserve(approxFaceCount * 3); m_positions.reserve(approxVertexCount); m_texcoords.reserve(approxVertexCount); @@ -2459,13 +2271,14 @@ public: m_faceIgnore.reserve(approxFaceCount); if (m_flags & MeshFlags::HasNormals) m_normals.reserve(approxVertexCount); + if (m_flags & MeshFlags::HasMaterials) + m_faceMaterials.reserve(approxFaceCount); } uint32_t flags() const { return m_flags; } uint32_t id() const { return m_id; } - void addVertex(const Vector3 &pos, const Vector3 &normal = Vector3(0.0f), const Vector2 &texcoord = Vector2(0.0f)) - { + void addVertex(const Vector3 &pos, const Vector3 &normal = Vector3(0.0f), const Vector2 &texcoord = Vector2(0.0f)) { XA_DEBUG_ASSERT(isFinite(pos)); m_positions.push_back(pos); if (m_flags & MeshFlags::HasNormals) @@ -2473,45 +2286,22 @@ public: m_texcoords.push_back(texcoord); } - struct AddFaceResult - { - enum Enum - { - OK, - DuplicateEdge = 1 - }; - }; - - AddFaceResult::Enum addFace(uint32_t v0, uint32_t v1, uint32_t v2, bool ignore = false) - { - uint32_t indexArray[3]; - indexArray[0] = v0; - indexArray[1] = v1; - indexArray[2] = v2; - return addFace(indexArray, ignore); - } - - AddFaceResult::Enum addFace(const uint32_t *indices, bool ignore = false) - { - AddFaceResult::Enum result = AddFaceResult::OK; + void addFace(const uint32_t *indices, bool ignore = false, uint32_t material = UINT32_MAX) { if (m_flags & MeshFlags::HasIgnoredFaces) m_faceIgnore.push_back(ignore); + if (m_flags & MeshFlags::HasMaterials) + m_faceMaterials.push_back(material); const uint32_t firstIndex = m_indices.size(); for (uint32_t i = 0; i < 3; i++) m_indices.push_back(indices[i]); for (uint32_t i = 0; i < 3; i++) { const uint32_t vertex0 = m_indices[firstIndex + i]; const uint32_t vertex1 = m_indices[firstIndex + (i + 1) % 3]; - const EdgeKey key(vertex0, vertex1); - if (m_edgeMap.get(key) != UINT32_MAX) - result = AddFaceResult::DuplicateEdge; - m_edgeMap.add(key); + m_edgeMap.add(EdgeKey(vertex0, vertex1)); } - return result; } - void createColocals() - { + void createColocalsBVH() { const uint32_t vertexCount = m_positions.size(); Array<AABB> aabbs(MemTag::BVH); aabbs.resize(vertexCount); @@ -2522,6 +2312,8 @@ public: Array<uint32_t> potential(MemTag::MeshColocals); m_nextColocalVertex.resize(vertexCount); m_nextColocalVertex.fillBytes(0xff); + m_firstColocalVertex.resize(vertexCount); + m_firstColocalVertex.fillBytes(0xff); for (uint32_t i = 0; i < vertexCount; i++) { if (m_nextColocalVertex[i] != UINT32_MAX) continue; // Already linked. @@ -2537,18 +2329,65 @@ public: if (colocals.size() == 1) { // No colocals for this vertex. m_nextColocalVertex[i] = i; - continue; + m_firstColocalVertex[i] = i; + continue; } // Link in ascending order. insertionSort(colocals.data(), colocals.size()); - for (uint32_t j = 0; j < colocals.size(); j++) + for (uint32_t j = 0; j < colocals.size(); j++) { m_nextColocalVertex[colocals[j]] = colocals[(j + 1) % colocals.size()]; + m_firstColocalVertex[colocals[j]] = colocals[0]; + } XA_DEBUG_ASSERT(m_nextColocalVertex[i] != UINT32_MAX); } } - void createBoundaries() - { + void createColocalsHash() { + const uint32_t vertexCount = m_positions.size(); + HashMap<Vector3> positionToVertexMap(MemTag::Default, vertexCount); + for (uint32_t i = 0; i < vertexCount; i++) + positionToVertexMap.add(m_positions[i]); + Array<uint32_t> colocals(MemTag::MeshColocals); + m_nextColocalVertex.resize(vertexCount); + m_nextColocalVertex.fillBytes(0xff); + m_firstColocalVertex.resize(vertexCount); + m_firstColocalVertex.fillBytes(0xff); + for (uint32_t i = 0; i < vertexCount; i++) { + if (m_nextColocalVertex[i] != UINT32_MAX) + continue; // Already linked. + // Find other vertices colocal to this one. + colocals.clear(); + colocals.push_back(i); // Always add this vertex. + uint32_t otherVertex = positionToVertexMap.get(m_positions[i]); + while (otherVertex != UINT32_MAX) { + if (otherVertex != i && equal(m_positions[i], m_positions[otherVertex], m_epsilon) && m_nextColocalVertex[otherVertex] == UINT32_MAX) + colocals.push_back(otherVertex); + otherVertex = positionToVertexMap.getNext(m_positions[i], otherVertex); + } + if (colocals.size() == 1) { + // No colocals for this vertex. + m_nextColocalVertex[i] = i; + m_firstColocalVertex[i] = i; + continue; + } + // Link in ascending order. + insertionSort(colocals.data(), colocals.size()); + for (uint32_t j = 0; j < colocals.size(); j++) { + m_nextColocalVertex[colocals[j]] = colocals[(j + 1) % colocals.size()]; + m_firstColocalVertex[colocals[j]] = colocals[0]; + } + XA_DEBUG_ASSERT(m_nextColocalVertex[i] != UINT32_MAX); + } + } + + void createColocals() { + if (m_epsilon <= FLT_EPSILON) + createColocalsHash(); + else + createColocalsBVH(); + } + + void createBoundaries() { const uint32_t edgeCount = m_indices.size(); const uint32_t vertexCount = m_positions.size(); m_oppositeEdges.resize(edgeCount); @@ -2578,151 +2417,54 @@ public: } } - void linkBoundaries() - { - const uint32_t edgeCount = m_indices.size(); - HashMap<uint32_t> vertexToEdgeMap(MemTag::Mesh, edgeCount); // Edge is index / 2 - for (uint32_t i = 0; i < edgeCount; i++) { - vertexToEdgeMap.add(m_indices[meshEdgeIndex0(i)]); - vertexToEdgeMap.add(m_indices[meshEdgeIndex1(i)]); - } - m_nextBoundaryEdges.resize(edgeCount); - for (uint32_t i = 0; i < edgeCount; i++) - m_nextBoundaryEdges[i] = UINT32_MAX; - uint32_t numBoundaryLoops = 0, numUnclosedBoundaries = 0; - BitArray linkedEdges(edgeCount); - linkedEdges.zeroOutMemory(); - for (;;) { - // Find the first boundary edge that hasn't been linked yet. - uint32_t firstEdge = UINT32_MAX; - for (uint32_t i = 0; i < edgeCount; i++) { - if (m_oppositeEdges[i] == UINT32_MAX && !linkedEdges.get(i)) { - firstEdge = i; - break; - } - } - if (firstEdge == UINT32_MAX) - break; - uint32_t currentEdge = firstEdge; - for (;;) { - // Find the next boundary edge. The first vertex will be the same as (or colocal to) the current edge second vertex. - const uint32_t startVertex = m_indices[meshEdgeIndex1(currentEdge)]; - uint32_t bestNextEdge = UINT32_MAX; - for (ColocalVertexIterator it(this, startVertex); !it.isDone(); it.advance()) { - uint32_t mapIndex = vertexToEdgeMap.get(it.vertex()); - while (mapIndex != UINT32_MAX) { - const uint32_t otherEdge = mapIndex / 2; // Two vertices added per edge. - if (m_oppositeEdges[otherEdge] != UINT32_MAX) - goto next; // Not a boundary edge. - if (linkedEdges.get(otherEdge)) - goto next; // Already linked. - if (m_indices[meshEdgeIndex0(otherEdge)] != it.vertex()) - goto next; // Edge contains the vertex, but it's the wrong one. - // First edge (closing the boundary loop) has the highest priority. - // Non-colocal vertex has the next highest. - if (bestNextEdge != firstEdge && (bestNextEdge == UINT32_MAX || it.vertex() == startVertex)) - bestNextEdge = otherEdge; - next: - mapIndex = vertexToEdgeMap.getNext(mapIndex); - } - } - if (bestNextEdge == UINT32_MAX) { - numUnclosedBoundaries++; - if (currentEdge == firstEdge) - linkedEdges.set(firstEdge); // Only 1 edge in this boundary "loop". - break; // Can't find a next edge. - } - m_nextBoundaryEdges[currentEdge] = bestNextEdge; - linkedEdges.set(bestNextEdge); - currentEdge = bestNextEdge; - if (currentEdge == firstEdge) { - numBoundaryLoops++; - break; // Closed the boundary loop. - } - } - } -#if XA_FIX_INTERNAL_BOUNDARY_LOOPS - // Find internal boundary loops and separate them. - // Detect by finding two edges in a boundary loop that have a colocal end vertex. - // Fix by swapping their next boundary edge. - // Need to start over after every fix since known boundary loops have changed. - Array<uint32_t> boundaryLoops; - fixInternalBoundary: - meshGetBoundaryLoops(*this, boundaryLoops); - for (uint32_t loop = 0; loop < boundaryLoops.size(); loop++) { - linkedEdges.zeroOutMemory(); - for (Mesh::BoundaryLoopEdgeIterator it1(this, boundaryLoops[loop]); !it1.isDone(); it1.advance()) { - const uint32_t e1 = it1.edge(); - if (linkedEdges.get(e1)) - continue; - for (Mesh::BoundaryLoopEdgeIterator it2(this, boundaryLoops[loop]); !it2.isDone(); it2.advance()) { - const uint32_t e2 = it2.edge(); - if (e1 == e2 || !isBoundaryEdge(e2) || linkedEdges.get(e2)) - continue; - if (!areColocal(m_indices[meshEdgeIndex1(e1)], m_indices[meshEdgeIndex1(e2)])) - continue; - swap(m_nextBoundaryEdges[e1], m_nextBoundaryEdges[e2]); - linkedEdges.set(e1); - linkedEdges.set(e2); - goto fixInternalBoundary; // start over - } - } - } -#endif - } - /// Find edge, test all colocals. - uint32_t findEdge(uint32_t vertex0, uint32_t vertex1) const - { - uint32_t result = UINT32_MAX; - if (m_nextColocalVertex.isEmpty()) { + uint32_t findEdge(uint32_t vertex0, uint32_t vertex1) const { + // Try to find exact vertex match first. + { EdgeKey key(vertex0, vertex1); uint32_t edge = m_edgeMap.get(key); while (edge != UINT32_MAX) { // Don't find edges of ignored faces. - if (!isFaceIgnored(meshEdgeFace(edge))) { - //XA_DEBUG_ASSERT(m_id != UINT32_MAX || (m_id == UINT32_MAX && result == UINT32_MAX)); // duplicate edge - ignore on initial meshes - result = edge; -#if !XA_DEBUG - return result; -#endif - } - edge = m_edgeMap.getNext(edge); + if (!isFaceIgnored(meshEdgeFace(edge))) + return edge; + edge = m_edgeMap.getNext(key, edge); } - } else { - for (ColocalVertexIterator it0(this, vertex0); !it0.isDone(); it0.advance()) { - for (ColocalVertexIterator it1(this, vertex1); !it1.isDone(); it1.advance()) { - EdgeKey key(it0.vertex(), it1.vertex()); + } + // If colocals were created, try every permutation. + if (!m_nextColocalVertex.isEmpty()) { + uint32_t colocalVertex0 = vertex0; + for (;;) { + uint32_t colocalVertex1 = vertex1; + for (;;) { + EdgeKey key(colocalVertex0, colocalVertex1); uint32_t edge = m_edgeMap.get(key); while (edge != UINT32_MAX) { // Don't find edges of ignored faces. - if (!isFaceIgnored(meshEdgeFace(edge))) { - XA_DEBUG_ASSERT(m_id != UINT32_MAX || (m_id == UINT32_MAX && result == UINT32_MAX)); // duplicate edge - ignore on initial meshes - result = edge; -#if !XA_DEBUG - return result; -#endif - } - edge = m_edgeMap.getNext(edge); + if (!isFaceIgnored(meshEdgeFace(edge))) + return edge; + edge = m_edgeMap.getNext(key, edge); } + colocalVertex1 = m_nextColocalVertex[colocalVertex1]; + if (colocalVertex1 == vertex1) + break; // Back to start. } + colocalVertex0 = m_nextColocalVertex[colocalVertex0]; + if (colocalVertex0 == vertex0) + break; // Back to start. } } - return result; + return UINT32_MAX; } // Edge map can be destroyed when no longer used to reduce memory usage. It's used by: // * Mesh::createBoundaries() - // * Mesh::ColocalEdgeIterator (used by MeshFaceGroups) - // * meshCloseHole() - void destroyEdgeMap() - { + // * Mesh::edgeMap() (used by MeshFaceGroups) + void destroyEdgeMap() { m_edgeMap.destroy(); } #if XA_DEBUG_EXPORT_OBJ - void writeObjVertices(FILE *file) const - { + void writeObjVertices(FILE *file) const { for (uint32_t i = 0; i < m_positions.size(); i++) fprintf(file, "v %g %g %g\n", m_positions[i].x, m_positions[i].y, m_positions[i].z); if (m_flags & MeshFlags::HasNormals) { @@ -2733,8 +2475,7 @@ public: fprintf(file, "vt %g %g\n", m_texcoords[i].x, m_texcoords[i].y); } - void writeObjFace(FILE *file, uint32_t face, uint32_t offset = 0) const - { + void writeObjFace(FILE *file, uint32_t face, uint32_t offset = 0) const { fprintf(file, "f "); for (uint32_t j = 0; j < 3; j++) { const uint32_t index = m_indices[face * 3 + j] + 1 + offset; // 1-indexed @@ -2742,8 +2483,7 @@ public: } } - void writeObjBoundaryEges(FILE *file) const - { + void writeObjBoundaryEges(FILE *file) const { if (m_oppositeEdges.isEmpty()) return; // Boundaries haven't been created. fprintf(file, "o boundary_edges\n"); @@ -2754,31 +2494,7 @@ public: } } - void writeObjLinkedBoundaries(FILE *file) const - { - if (m_oppositeEdges.isEmpty() || m_nextBoundaryEdges.isEmpty()) - return; // Boundaries haven't been created and/or linked. - Array<uint32_t> boundaryLoops; - meshGetBoundaryLoops(*this, boundaryLoops); - for (uint32_t i = 0; i < boundaryLoops.size(); i++) { - uint32_t edge = boundaryLoops[i]; - fprintf(file, "o boundary_%04d\n", i); - fprintf(file, "l"); - for (;;) { - const uint32_t vertex0 = m_indices[meshEdgeIndex0(edge)]; - const uint32_t vertex1 = m_indices[meshEdgeIndex1(edge)]; - fprintf(file, " %d", vertex0 + 1); // 1-indexed - edge = m_nextBoundaryEdges[edge]; - if (edge == boundaryLoops[i] || edge == UINT32_MAX) { - fprintf(file, " %d\n", vertex1 + 1); // 1-indexed - break; - } - } - } - } - - void writeObjFile(const char *filename) const - { + void writeObjFile(const char *filename) const { FILE *file; XA_FOPEN(file, filename, "w"); if (!file) @@ -2789,13 +2505,11 @@ public: for (uint32_t i = 0; i < faceCount(); i++) writeObjFace(file, i); writeObjBoundaryEges(file); - writeObjLinkedBoundaries(file); fclose(file); } #endif - float computeSurfaceArea() const - { + float computeSurfaceArea() const { float area = 0; for (uint32_t f = 0; f < faceCount(); f++) area += computeFaceArea(f); @@ -2804,24 +2518,21 @@ public: } // Returned value is always positive, even if some triangles are flipped. - float computeParametricArea() const - { + float computeParametricArea() const { float area = 0; for (uint32_t f = 0; f < faceCount(); f++) area += fabsf(computeFaceParametricArea(f)); // May be negative, depends on texcoord winding. - return area; + return area; } - float computeFaceArea(uint32_t face) const - { + float computeFaceArea(uint32_t face) const { const Vector3 &p0 = m_positions[m_indices[face * 3 + 0]]; const Vector3 &p1 = m_positions[m_indices[face * 3 + 1]]; const Vector3 &p2 = m_positions[m_indices[face * 3 + 2]]; return length(cross(p1 - p0, p2 - p0)) * 0.5f; } - Vector3 computeFaceCentroid(uint32_t face) const - { + Vector3 computeFaceCentroid(uint32_t face) const { Vector3 sum(0.0f); for (uint32_t i = 0; i < 3; i++) sum += m_positions[m_indices[face * 3 + i]]; @@ -2830,8 +2541,7 @@ public: // Average of the edge midpoints weighted by the edge length. // I want a point inside the triangle, but closer to the cirumcenter. - Vector3 computeFaceCenter(uint32_t face) const - { + Vector3 computeFaceCenter(uint32_t face) const { const Vector3 &p0 = m_positions[m_indices[face * 3 + 0]]; const Vector3 &p1 = m_positions[m_indices[face * 3 + 1]]; const Vector3 &p2 = m_positions[m_indices[face * 3 + 2]]; @@ -2844,28 +2554,25 @@ public: return m0 + m1 + m2; } - Vector3 computeFaceNormal(uint32_t face) const - { + Vector3 computeFaceNormal(uint32_t face) const { const Vector3 &p0 = m_positions[m_indices[face * 3 + 0]]; const Vector3 &p1 = m_positions[m_indices[face * 3 + 1]]; const Vector3 &p2 = m_positions[m_indices[face * 3 + 2]]; const Vector3 e0 = p2 - p0; const Vector3 e1 = p1 - p0; const Vector3 normalAreaScaled = cross(e0, e1); - return normalizeSafe(normalAreaScaled, Vector3(0, 0, 1), 0.0f); + return normalizeSafe(normalAreaScaled, Vector3(0, 0, 1)); } - float computeFaceParametricArea(uint32_t face) const - { + float computeFaceParametricArea(uint32_t face) const { const Vector2 &t0 = m_texcoords[m_indices[face * 3 + 0]]; const Vector2 &t1 = m_texcoords[m_indices[face * 3 + 1]]; const Vector2 &t2 = m_texcoords[m_indices[face * 3 + 2]]; return triangleArea(t0, t1, t2); } - + // @@ This is not exactly accurate, we should compare the texture coordinates... - bool isSeam(uint32_t edge) const - { + bool isSeam(uint32_t edge) const { const uint32_t oppositeEdge = m_oppositeEdges[edge]; if (oppositeEdge == UINT32_MAX) return false; // boundary edge @@ -2876,8 +2583,7 @@ public: return m_indices[e0] != m_indices[oe1] || m_indices[e1] != m_indices[oe0]; } - bool isTextureSeam(uint32_t edge) const - { + bool isTextureSeam(uint32_t edge) const { const uint32_t oppositeEdge = m_oppositeEdges[edge]; if (oppositeEdge == UINT32_MAX) return false; // boundary edge @@ -2888,26 +2594,9 @@ public: return m_texcoords[m_indices[e0]] != m_texcoords[m_indices[oe1]] || m_texcoords[m_indices[e1]] != m_texcoords[m_indices[oe0]]; } - uint32_t firstColocal(uint32_t vertex) const - { - for (ColocalVertexIterator it(this, vertex); !it.isDone(); it.advance()) { - if (it.vertex() < vertex) - vertex = it.vertex(); - } - return vertex; - } - - bool areColocal(uint32_t vertex0, uint32_t vertex1) const - { - if (vertex0 == vertex1) - return true; - if (m_nextColocalVertex.isEmpty()) - return false; - for (ColocalVertexIterator it(this, vertex0); !it.isDone(); it.advance()) { - if (it.vertex() == vertex1) - return true; - } - return false; + uint32_t firstColocalVertex(uint32_t vertex) const { + XA_DEBUG_ASSERT(m_firstColocalVertex.size() == m_positions.size()); + return m_firstColocalVertex[vertex]; } XA_INLINE float epsilon() const { return m_epsilon; } @@ -2919,23 +2608,28 @@ public: XA_INLINE uint32_t vertexCount() const { return m_positions.size(); } XA_INLINE uint32_t vertexAt(uint32_t i) const { return m_indices[i]; } XA_INLINE const Vector3 &position(uint32_t vertex) const { return m_positions[vertex]; } - XA_INLINE const Vector3 *positions() const { return m_positions.data(); } - XA_INLINE const Vector3 &normal(uint32_t vertex) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasNormals); return m_normals[vertex]; } + XA_INLINE ConstArrayView<Vector3> positions() const { return m_positions; } + XA_INLINE const Vector3 &normal(uint32_t vertex) const { + XA_DEBUG_ASSERT(m_flags & MeshFlags::HasNormals); + return m_normals[vertex]; + } XA_INLINE const Vector2 &texcoord(uint32_t vertex) const { return m_texcoords[vertex]; } XA_INLINE Vector2 &texcoord(uint32_t vertex) { return m_texcoords[vertex]; } - XA_INLINE const Vector2 *texcoords() const { return m_texcoords.data(); } - XA_INLINE Vector2 *texcoords() { return m_texcoords.data(); } + XA_INLINE const ConstArrayView<Vector2> texcoords() const { return m_texcoords; } + XA_INLINE ArrayView<Vector2> texcoords() { return m_texcoords; } XA_INLINE uint32_t faceCount() const { return m_indices.size() / 3; } - XA_INLINE const uint32_t *indices() const { return m_indices.data(); } + XA_INLINE ConstArrayView<uint32_t> indices() const { return m_indices; } XA_INLINE uint32_t indexCount() const { return m_indices.size(); } XA_INLINE bool isFaceIgnored(uint32_t face) const { return (m_flags & MeshFlags::HasIgnoredFaces) && m_faceIgnore[face]; } + XA_INLINE uint32_t faceMaterial(uint32_t face) const { return (m_flags & MeshFlags::HasMaterials) ? m_faceMaterials[face] : UINT32_MAX; } + XA_INLINE const HashMap<EdgeKey, EdgeHash> &edgeMap() const { return m_edgeMap; } private: - float m_epsilon; uint32_t m_flags; uint32_t m_id; Array<bool> m_faceIgnore; + Array<uint32_t> m_faceMaterials; Array<uint32_t> m_indices; Array<Vector3> m_positions; Array<Vector3> m_normals; @@ -2943,205 +2637,31 @@ private: // Populated by createColocals Array<uint32_t> m_nextColocalVertex; // In: vertex index. Out: the vertex index of the next colocal position. + Array<uint32_t> m_firstColocalVertex; // Populated by createBoundaries BitArray m_isBoundaryVertex; Array<uint32_t> m_boundaryEdges; Array<uint32_t> m_oppositeEdges; // In: edge index. Out: the index of the opposite edge (i.e. wound the opposite direction). UINT32_MAX if the input edge is a boundary edge. - // Populated by linkBoundaries - Array<uint32_t> m_nextBoundaryEdges; // The index of the next boundary edge. UINT32_MAX if the edge is not a boundary edge. - - struct EdgeKey - { - EdgeKey(const EdgeKey &k) : v0(k.v0), v1(k.v1) {} - EdgeKey(uint32_t v0, uint32_t v1) : v0(v0), v1(v1) {} - bool operator==(const EdgeKey &k) const { return v0 == k.v0 && v1 == k.v1; } - - uint32_t v0; - uint32_t v1; - }; - - struct EdgeHash - { - uint32_t operator()(const EdgeKey &k) const { return k.v0 * 32768u + k.v1; } - }; - HashMap<EdgeKey, EdgeHash> m_edgeMap; public: - class BoundaryLoopEdgeIterator - { + class FaceEdgeIterator { public: - BoundaryLoopEdgeIterator(const Mesh *mesh, uint32_t edge) : m_mesh(mesh), m_first(UINT32_MAX), m_current(edge) {} - - void advance() - { - if (m_first == UINT32_MAX) - m_first = m_current; - m_current = m_mesh->m_nextBoundaryEdges[m_current]; - } - - bool isDone() const - { - return m_first == m_current || m_current == UINT32_MAX; - } - - uint32_t edge() const - { - return m_current; - } - - uint32_t nextEdge() const - { - return m_mesh->m_nextBoundaryEdges[m_current]; - } - - private: - const Mesh *m_mesh; - uint32_t m_first; - uint32_t m_current; - }; - - class ColocalVertexIterator - { - public: - ColocalVertexIterator(const Mesh *mesh, uint32_t v) : m_mesh(mesh), m_first(UINT32_MAX), m_current(v) {} - - void advance() - { - if (m_first == UINT32_MAX) - m_first = m_current; - if (!m_mesh->m_nextColocalVertex.isEmpty()) - m_current = m_mesh->m_nextColocalVertex[m_current]; - } - - bool isDone() const - { - return m_first == m_current; - } - - uint32_t vertex() const - { - return m_current; - } - - const Vector3 *pos() const - { - return &m_mesh->m_positions[m_current]; - } - - private: - const Mesh *m_mesh; - uint32_t m_first; - uint32_t m_current; - }; - - class ColocalEdgeIterator - { - public: - ColocalEdgeIterator(const Mesh *mesh, uint32_t vertex0, uint32_t vertex1) : m_mesh(mesh), m_vertex0It(mesh, vertex0), m_vertex1It(mesh, vertex1), m_vertex1(vertex1) - { - do { - if (!resetElement()) { - advanceVertex1(); - } - else { - break; - } - } while (!isDone()); - } - - void advance() - { - advanceElement(); - } - - bool isDone() const - { - return m_vertex0It.isDone() && m_vertex1It.isDone() && m_edge == UINT32_MAX; - } - - uint32_t edge() const - { - return m_edge; - } - - private: - bool resetElement() - { - m_edge = m_mesh->m_edgeMap.get(Mesh::EdgeKey(m_vertex0It.vertex(), m_vertex1It.vertex())); - while (m_edge != UINT32_MAX) { - if (!isIgnoredFace()) - break; - m_edge = m_mesh->m_edgeMap.getNext(m_edge); - } - if (m_edge == UINT32_MAX) { - return false; - } - return true; - } - - void advanceElement() - { - for (;;) { - m_edge = m_mesh->m_edgeMap.getNext(m_edge); - if (m_edge == UINT32_MAX) - break; - if (!isIgnoredFace()) - break; - } - if (m_edge == UINT32_MAX) - advanceVertex1(); - } - - void advanceVertex1() - { - auto successful = false; - while (!successful) { - m_vertex1It.advance(); - if (m_vertex1It.isDone()) { - if (!m_vertex0It.isDone()) { - m_vertex0It.advance(); - m_vertex1It = ColocalVertexIterator(m_mesh, m_vertex1); - } - else { - return; - } - } - successful = resetElement(); - } - } - - bool isIgnoredFace() const - { - return m_mesh->m_faceIgnore[meshEdgeFace(m_edge)]; - } - - const Mesh *m_mesh; - ColocalVertexIterator m_vertex0It, m_vertex1It; - const uint32_t m_vertex1; - uint32_t m_edge; - }; - - class FaceEdgeIterator - { - public: - FaceEdgeIterator (const Mesh *mesh, uint32_t face) : m_mesh(mesh), m_face(face), m_relativeEdge(0) - { + FaceEdgeIterator(const Mesh *mesh, uint32_t face) : + m_mesh(mesh), m_face(face), m_relativeEdge(0) { m_edge = m_face * 3; } - void advance() - { + void advance() { if (m_relativeEdge < 3) { m_edge++; m_relativeEdge++; } } - bool isDone() const - { + bool isDone() const { return m_relativeEdge == 3; } @@ -3152,9 +2672,8 @@ public: uint32_t relativeEdge() const { return m_relativeEdge; } uint32_t face() const { return m_face; } uint32_t oppositeEdge() const { return m_mesh->m_oppositeEdges[m_edge]; } - - uint32_t oppositeFace() const - { + + uint32_t oppositeFace() const { const uint32_t oedge = m_mesh->m_oppositeEdges[m_edge]; if (oedge == UINT32_MAX) return UINT32_MAX; @@ -3178,19 +2697,18 @@ public: }; }; -struct MeshFaceGroups -{ +struct MeshFaceGroups { typedef uint32_t Handle; static constexpr Handle kInvalid = UINT32_MAX; - MeshFaceGroups(const Mesh *mesh) : m_mesh(mesh), m_groups(MemTag::Mesh), m_firstFace(MemTag::Mesh), m_nextFace(MemTag::Mesh), m_faceCount(MemTag::Mesh) {} + MeshFaceGroups(const Mesh *mesh) : + m_mesh(mesh), m_groups(MemTag::Mesh), m_firstFace(MemTag::Mesh), m_nextFace(MemTag::Mesh), m_faceCount(MemTag::Mesh) {} XA_INLINE Handle groupAt(uint32_t face) const { return m_groups[face]; } XA_INLINE uint32_t groupCount() const { return m_faceCount.size(); } XA_INLINE uint32_t nextFace(uint32_t face) const { return m_nextFace[face]; } XA_INLINE uint32_t faceCount(uint32_t group) const { return m_faceCount[group]; } - void compute() - { + void compute() { m_groups.resize(m_mesh->faceCount()); m_groups.fillBytes(0xff); // Set all faces to kInvalid uint32_t firstUnassignedFace = 0; @@ -3222,57 +2740,25 @@ struct MeshFaceGroups break; const uint32_t f = growFaces.back(); growFaces.pop_back(); + const uint32_t material = m_mesh->faceMaterial(f); for (Mesh::FaceEdgeIterator edgeIt(m_mesh, f); !edgeIt.isDone(); edgeIt.advance()) { - // Iterate opposite edges. There may be more than one - non-manifold geometry can have duplicate edges. - // Prioritize the one with exact vertex match, not just colocal. - // If *any* of the opposite edges are already assigned to this group, don't do anything. - bool alreadyAssignedToThisGroup = false; - uint32_t bestConnectedFace = UINT32_MAX; - for (Mesh::ColocalEdgeIterator oppositeEdgeIt(m_mesh, edgeIt.vertex1(), edgeIt.vertex0()); !oppositeEdgeIt.isDone(); oppositeEdgeIt.advance()) { - const uint32_t oppositeEdge = oppositeEdgeIt.edge(); - const uint32_t oppositeFace = meshEdgeFace(oppositeEdge); -#if 0 - // Reject opposite face if dihedral angle >= 90 degrees. - { - Vector3 a = m_mesh->computeFaceNormal(f); - Vector3 b = m_mesh->computeFaceNormal(oppositeFace); - if (dot(a, b) <= 0.0f) - continue; - } -#endif - if (m_mesh->isFaceIgnored(oppositeFace)) - continue; // Don't add ignored faces to group. - if (m_groups[oppositeFace] == group) { - alreadyAssignedToThisGroup = true; - break; - } - if (m_groups[oppositeFace] != kInvalid) - continue; // Connected face is already assigned to another group. - if (faceDuplicatesGroupEdge(group, oppositeFace)) - continue; // Don't want duplicate edges in a group. - const uint32_t oppositeVertex0 = m_mesh->vertexAt(meshEdgeIndex0(oppositeEdge)); - const uint32_t oppositeVertex1 = m_mesh->vertexAt(meshEdgeIndex1(oppositeEdge)); - if (bestConnectedFace == UINT32_MAX || (oppositeVertex0 == edgeIt.vertex1() && oppositeVertex1 == edgeIt.vertex0())) - bestConnectedFace = oppositeFace; -#if 0 - else { - // Choose the opposite face with the smallest dihedral angle. - const float d1 = 1.0f - dot(computeFaceNormal(f), computeFaceNormal(bestConnectedFace)); - const float d2 = 1.0f - dot(computeFaceNormal(f), computeFaceNormal(oppositeFace)); - if (d2 < d1) - bestConnectedFace = oppositeFace; - } -#endif - } - if (!alreadyAssignedToThisGroup && bestConnectedFace != UINT32_MAX) { - m_groups[bestConnectedFace] = group; - m_nextFace[bestConnectedFace] = UINT32_MAX; - if (prevFace != UINT32_MAX) - m_nextFace[prevFace] = bestConnectedFace; - prevFace = bestConnectedFace; - groupFaceCount++; - growFaces.push_back(bestConnectedFace); - } + const uint32_t oppositeEdge = m_mesh->findEdge(edgeIt.vertex1(), edgeIt.vertex0()); + if (oppositeEdge == UINT32_MAX) + continue; // Boundary edge. + const uint32_t oppositeFace = meshEdgeFace(oppositeEdge); + if (m_mesh->isFaceIgnored(oppositeFace)) + continue; // Don't add ignored faces to group. + if (m_mesh->faceMaterial(oppositeFace) != material) + continue; // Different material. + if (m_groups[oppositeFace] != kInvalid) + continue; // Connected face is already assigned to another group. + m_groups[oppositeFace] = group; + m_nextFace[oppositeFace] = UINT32_MAX; + if (prevFace != UINT32_MAX) + m_nextFace[prevFace] = oppositeFace; + prevFace = oppositeFace; + groupFaceCount++; + growFaces.push_back(oppositeFace); } } m_faceCount.push_back(groupFaceCount); @@ -3281,27 +2767,23 @@ struct MeshFaceGroups } } - class Iterator - { + class Iterator { public: - Iterator(const MeshFaceGroups *meshFaceGroups, Handle group) : m_meshFaceGroups(meshFaceGroups) - { + Iterator(const MeshFaceGroups *meshFaceGroups, Handle group) : + m_meshFaceGroups(meshFaceGroups) { XA_DEBUG_ASSERT(group != kInvalid); m_current = m_meshFaceGroups->m_firstFace[group]; } - void advance() - { + void advance() { m_current = m_meshFaceGroups->m_nextFace[m_current]; } - bool isDone() const - { + bool isDone() const { return m_current == UINT32_MAX; } - uint32_t face() const - { + uint32_t face() const { return m_current; } @@ -3311,18 +2793,6 @@ struct MeshFaceGroups }; private: - // Check if the face duplicates any edges of any face already in the group. - bool faceDuplicatesGroupEdge(Handle group, uint32_t face) const - { - for (Mesh::FaceEdgeIterator edgeIt(m_mesh, face); !edgeIt.isDone(); edgeIt.advance()) { - for (Mesh::ColocalEdgeIterator colocalEdgeIt(m_mesh, edgeIt.vertex0(), edgeIt.vertex1()); !colocalEdgeIt.isDone(); colocalEdgeIt.advance()) { - if (m_groups[meshEdgeFace(colocalEdgeIt.edge())] == group) - return true; - } - } - return false; - } - const Mesh *m_mesh; Array<Handle> m_groups; Array<uint32_t> m_firstFace; @@ -3332,243 +2802,27 @@ private: constexpr MeshFaceGroups::Handle MeshFaceGroups::kInvalid; -static bool meshCloseHole(Mesh *mesh, const Array<uint32_t> &holeVertices, const Vector3 &normal) -{ -#if XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION - const uint32_t faceCount = mesh->faceCount(); -#endif - const bool compareNormal = equal(normal, Vector3(0.0f), FLT_EPSILON); - uint32_t frontCount = holeVertices.size(); - Array<uint32_t> frontVertices; - Array<Vector3> frontPoints; - Array<float> frontAngles; - frontVertices.resize(frontCount); - frontPoints.resize(frontCount); - for (uint32_t i = 0; i < frontCount; i++) { - frontVertices[i] = holeVertices[i]; - frontPoints[i] = mesh->position(frontVertices[i]); - } - while (frontCount >= 3) { - frontAngles.resize(frontCount); - float smallestAngle = kPi2, smallestAngleIgnoringNormal = kPi2; - uint32_t smallestAngleIndex = UINT32_MAX, smallestAngleIndexIgnoringNormal = UINT32_MAX; - for (uint32_t i = 0; i < frontCount; i++) { - const uint32_t i1 = i == 0 ? frontCount - 1 : i - 1; - const uint32_t i2 = i; - const uint32_t i3 = (i + 1) % frontCount; - const Vector3 edge1 = frontPoints[i1] - frontPoints[i2]; - const Vector3 edge2 = frontPoints[i3] - frontPoints[i2]; - frontAngles[i] = atan2f(length(cross(edge1, edge2)), dot(edge1, edge2)); - if (frontAngles[i] >= smallestAngle || isNan(frontAngles[i])) - continue; - // Don't duplicate edges. - if (mesh->findEdge(frontVertices[i1], frontVertices[i2]) != UINT32_MAX) - continue; - if (mesh->findEdge(frontVertices[i2], frontVertices[i3]) != UINT32_MAX) - continue; - if (mesh->findEdge(frontVertices[i3], frontVertices[i1]) != UINT32_MAX) - continue; - /* - Make sure he new edge that would be formed by (i3, i1) doesn't intersect any vertices. This often happens when fixing t-junctions. - - i2 - * - / \ - / \ - i1 *--*--* i3 - \ | / - \|/ - * - */ - bool intersection = false; - for (uint32_t j = 0; j < frontCount; j++) { - if (j == i1 || j == i2 || j == i3) - continue; - if (lineIntersectsPoint(frontPoints[j], frontPoints[i3], frontPoints[i1], nullptr, mesh->epsilon())) { - intersection = true; - break; - } - } - if (intersection) - continue; - // Don't add the triangle if a boundary point lies on the same plane as the triangle, and is inside it. - intersection = false; - const Plane plane(frontPoints[i1], frontPoints[i2], frontPoints[i3]); - for (uint32_t j = 0; j < frontCount; j++) { - if (j == i1 || j == i2 || j == i3) - continue; - if (!isZero(plane.distance(frontPoints[j]), mesh->epsilon())) - continue; - if (pointInTriangle(frontPoints[j], frontPoints[i1], frontPoints[i2], frontPoints[i3])) { - intersection = true; - break; - } - } - if (intersection) - continue; -#if XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION - // Don't add the triangle if the new edge (i3, i1), intersects any other triangle that isn't part of the filled hole. - intersection = false; - const Vector3 newEdgeVector = frontPoints[i1] - frontPoints[i3]; - for (uint32_t f = 0; f < faceCount; f++) { - Vector3 tri[3]; - for (uint32_t j = 0; j < 3; j++) - tri[j] = mesh->position(mesh->vertexAt(f * 3 + j)); - float t; - if (rayIntersectsTriangle(frontPoints[i3], newEdgeVector, tri, &t)) { - intersection = true; - break; - } - } - if (intersection) - continue; -#endif - // Skip backwards facing triangles. - if (compareNormal) { - if (frontAngles[i] < smallestAngleIgnoringNormal) { - smallestAngleIgnoringNormal = frontAngles[i]; - smallestAngleIndexIgnoringNormal = i; - } - const Vector3 e0 = frontPoints[i3] - frontPoints[i1]; - const Vector3 e1 = frontPoints[i2] - frontPoints[i1]; - const Vector3 triNormal = normalizeSafe(cross(e0, e1), Vector3(0.0f), mesh->epsilon()); - if (dot(normal, triNormal) <= 0.0f) - continue; - } - smallestAngle = smallestAngleIgnoringNormal = frontAngles[i]; - smallestAngleIndex = smallestAngleIndexIgnoringNormal = i; - } - // Closing holes failed if we don't have a smallest angle. - // Fallback to ignoring the backwards facing normal test if possible. - if (smallestAngleIndex == UINT32_MAX || smallestAngle <= 0.0f || smallestAngle >= kPi) { - if (smallestAngleIgnoringNormal == UINT32_MAX || smallestAngleIgnoringNormal <= 0.0f || smallestAngleIgnoringNormal >= kPi) - return false; - else - smallestAngleIndex = smallestAngleIndexIgnoringNormal; - } - const uint32_t i1 = smallestAngleIndex == 0 ? frontCount - 1 : smallestAngleIndex - 1; - const uint32_t i2 = smallestAngleIndex; - const uint32_t i3 = (smallestAngleIndex + 1) % frontCount; - const Mesh::AddFaceResult::Enum result = mesh->addFace(frontVertices[i1], frontVertices[i2], frontVertices[i3]); - XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); // Shouldn't happen due to the findEdge calls above. - XA_UNUSED(result); - frontVertices.removeAt(i2); - frontPoints.removeAt(i2); - frontCount = frontVertices.size(); - } - return true; -} - -static bool meshCloseHoles(Mesh *mesh, const Array<uint32_t> &boundaryLoops, const Vector3 &normal, uint32_t *holeCount, Array<uint32_t> *holeFaceCounts) -{ - if (holeFaceCounts) - holeFaceCounts->clear(); - // Compute lengths. - const uint32_t boundaryCount = boundaryLoops.size(); - Array<float> boundaryLengths; - Array<uint32_t> boundaryEdgeCounts; - boundaryEdgeCounts.resize(boundaryCount); - for (uint32_t i = 0; i < boundaryCount; i++) { - float boundaryLength = 0.0f; - boundaryEdgeCounts[i] = 0; - for (Mesh::BoundaryLoopEdgeIterator it(mesh, boundaryLoops[i]); !it.isDone(); it.advance()) { - const Vector3 &t0 = mesh->position(mesh->vertexAt(meshEdgeIndex0(it.edge()))); - const Vector3 &t1 = mesh->position(mesh->vertexAt(meshEdgeIndex1(it.edge()))); - boundaryLength += length(t1 - t0); - boundaryEdgeCounts[i]++; - } - boundaryLengths.push_back(boundaryLength); - } - // Find disk boundary. - uint32_t diskBoundary = 0; - float maxLength = boundaryLengths[0]; - for (uint32_t i = 1; i < boundaryCount; i++) { - if (boundaryLengths[i] > maxLength) { - maxLength = boundaryLengths[i]; - diskBoundary = i; - } - } - // Close holes. - Array<uint32_t> holeVertices; - Array<Vector3> holePoints; - bool result = true; - for (uint32_t i = 0; i < boundaryCount; i++) { - if (diskBoundary == i) - continue; // Skip disk boundary. - holeVertices.resize(boundaryEdgeCounts[i]); - holePoints.resize(boundaryEdgeCounts[i]); - // Winding is backwards for internal boundaries. - uint32_t e = 0; - for (Mesh::BoundaryLoopEdgeIterator it(mesh, boundaryLoops[i]); !it.isDone(); it.advance()) { - const uint32_t vertex = mesh->vertexAt(meshEdgeIndex0(it.edge())); - holeVertices[boundaryEdgeCounts[i] - 1 - e] = vertex; - holePoints[boundaryEdgeCounts[i] - 1 - e] = mesh->position(vertex); - e++; - } - const uint32_t oldFaceCount = mesh->faceCount(); - if (!meshCloseHole(mesh, holeVertices, normal)) - result = false; // Return false if any hole failed to close, but keep trying to close other holes. - if (holeCount) - (*holeCount)++; - if (holeFaceCounts) - holeFaceCounts->push_back(mesh->faceCount() - oldFaceCount); - } - return result; -} - -static bool meshIsPlanar(const Mesh &mesh) -{ - const Vector3 p1 = mesh.position(mesh.vertexAt(0)); - const Vector3 p2 = mesh.position(mesh.vertexAt(1)); - const Vector3 p3 = mesh.position(mesh.vertexAt(2)); - const Plane plane(p1, p2, p3); - const uint32_t vertexCount = mesh.vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) { - const float d = plane.distance(mesh.position(v)); - if (!isZero(d, mesh.epsilon())) - return false; - } - return true; -} - -/* -Fixing T-junctions. - -- Find T-junctions. Find vertices that are on an edge. -- This test is approximate. -- Insert edges on a spatial index to speedup queries. -- Consider only open edges, that is edges that have no pairs. -- Consider only vertices on boundaries. -- Close T-junction. -- Split edge. - -*/ -struct SplitEdge -{ - uint32_t edge; - float t; - uint32_t vertex; - - bool operator<(const SplitEdge &other) const - { - if (edge < other.edge) - return true; - else if (edge == other.edge) { - if (t < other.t) - return true; - } +#if XA_CHECK_T_JUNCTIONS +static bool lineIntersectsPoint(const Vector3 &point, const Vector3 &lineStart, const Vector3 &lineEnd, float *t, float epsilon) { + float tt; + if (!t) + t = &tt; + *t = 0.0f; + if (equal(lineStart, point, epsilon) || equal(lineEnd, point, epsilon)) + return false; // Vertex lies on either line vertices. + const Vector3 v01 = point - lineStart; + const Vector3 v21 = lineEnd - lineStart; + const float l = length(v21); + const float d = length(cross(v01, v21)) / l; + if (!isZero(d, epsilon)) return false; - } -}; + *t = dot(v01, v21) / (l * l); + return *t > kEpsilon && *t < 1.0f - kEpsilon; +} -// Returns nullptr if there were no t-junctions to fix. -static Mesh *meshFixTJunctions(const Mesh &inputMesh, bool *duplicatedEdge, bool *failed, uint32_t *fixedTJunctionsCount) -{ - if (duplicatedEdge) - *duplicatedEdge = false; - if (failed) - *failed = false; - Array<SplitEdge> splitEdges; +// Returns the number of T-junctions found. +static int meshCheckTJunctions(const Mesh &inputMesh) { + int count = 0; const uint32_t vertexCount = inputMesh.vertexCount(); const uint32_t edgeCount = inputMesh.edgeCount(); for (uint32_t v = 0; v < vertexCount; v++) { @@ -3582,155 +2836,130 @@ static Mesh *meshFixTJunctions(const Mesh &inputMesh, bool *duplicatedEdge, bool const Vector3 &edgePos1 = inputMesh.position(inputMesh.vertexAt(meshEdgeIndex0(e))); const Vector3 &edgePos2 = inputMesh.position(inputMesh.vertexAt(meshEdgeIndex1(e))); float t; - if (!lineIntersectsPoint(pos, edgePos1, edgePos2, &t, inputMesh.epsilon())) - continue; - SplitEdge splitEdge; - splitEdge.edge = e; - splitEdge.t = t; - splitEdge.vertex = v; - splitEdges.push_back(splitEdge); + if (lineIntersectsPoint(pos, edgePos1, edgePos2, &t, inputMesh.epsilon())) + count++; } } - if (splitEdges.isEmpty()) - return nullptr; - const uint32_t faceCount = inputMesh.faceCount(); - Mesh *mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, inputMesh.epsilon(), vertexCount + splitEdges.size(), faceCount); - for (uint32_t v = 0; v < vertexCount; v++) - mesh->addVertex(inputMesh.position(v)); - Array<uint32_t> indexArray; - indexArray.reserve(4); - Array<SplitEdge> faceSplitEdges; - faceSplitEdges.reserve(4); - for (uint32_t f = 0; f < faceCount; f++) { - // Find t-junctions in this face. - faceSplitEdges.clear(); - for (uint32_t i = 0; i < splitEdges.size(); i++) { - if (meshEdgeFace(splitEdges[i].edge) == f) - faceSplitEdges.push_back(splitEdges[i]); - } - if (!faceSplitEdges.isEmpty()) { - // Need to split edges in winding order when a single edge has multiple t-junctions. - insertionSort(faceSplitEdges.data(), faceSplitEdges.size()); - indexArray.clear(); - for (Mesh::FaceEdgeIterator it(&inputMesh, f); !it.isDone(); it.advance()) { - indexArray.push_back(it.vertex0()); - for (uint32_t se = 0; se < faceSplitEdges.size(); se++) { - const SplitEdge &splitEdge = faceSplitEdges[se]; - if (splitEdge.edge == it.edge()) - indexArray.push_back(splitEdge.vertex); + return count; +} +#endif + +// References invalid faces and vertices in a mesh. +struct InvalidMeshGeometry { + // If meshFaceGroups is not null, invalid faces have the face group MeshFaceGroups::kInvalid. + // If meshFaceGroups is null, invalid faces are Mesh::isFaceIgnored. + void extract(const Mesh *mesh, const MeshFaceGroups *meshFaceGroups) { + // Copy invalid faces. + m_faces.clear(); + const uint32_t meshFaceCount = mesh->faceCount(); + for (uint32_t f = 0; f < meshFaceCount; f++) { + if ((meshFaceGroups && meshFaceGroups->groupAt(f) == MeshFaceGroups::kInvalid) || (!meshFaceGroups && mesh->isFaceIgnored(f))) + m_faces.push_back(f); + } + // Create *unique* list of vertices of invalid faces. + const uint32_t faceCount = m_faces.size(); + m_indices.resize(faceCount * 3); + const uint32_t approxVertexCount = min(faceCount * 3, mesh->vertexCount()); + m_vertexToSourceVertexMap.clear(); + m_vertexToSourceVertexMap.reserve(approxVertexCount); + HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToVertexMap(MemTag::Mesh, approxVertexCount); + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t face = m_faces[f]; + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = mesh->vertexAt(face * 3 + i); + uint32_t newVertex = sourceVertexToVertexMap.get(vertex); + if (newVertex == UINT32_MAX) { + newVertex = sourceVertexToVertexMap.add(vertex); + m_vertexToSourceVertexMap.push_back(vertex); } - } - if (!meshCloseHole(mesh, indexArray, Vector3(0.0f))) { - if (failed) - *failed = true; - } - } else { - // No t-junctions in this face. Copy from input mesh. - if (mesh->addFace(&inputMesh.indices()[f * 3]) == Mesh::AddFaceResult::DuplicateEdge) { - if (duplicatedEdge) - *duplicatedEdge = true; + m_indices[f * 3 + i] = newVertex; } } } - if (fixedTJunctionsCount) - *fixedTJunctionsCount = splitEdges.size(); - return mesh; -} -// boundaryLoops are the first edges for each boundary loop. -static void meshGetBoundaryLoops(const Mesh &mesh, Array<uint32_t> &boundaryLoops) -{ - const uint32_t edgeCount = mesh.edgeCount(); - BitArray bitFlags(edgeCount); - bitFlags.zeroOutMemory(); - boundaryLoops.clear(); - // Search for boundary edges. Mark all the edges that belong to the same boundary. - for (uint32_t e = 0; e < edgeCount; e++) { - if (bitFlags.get(e) || !mesh.isBoundaryEdge(e)) - continue; - for (Mesh::BoundaryLoopEdgeIterator it(&mesh, e); !it.isDone(); it.advance()) - bitFlags.set(it.edge()); - boundaryLoops.push_back(e); - } -} + ConstArrayView<uint32_t> faces() const { return m_faces; } + ConstArrayView<uint32_t> indices() const { return m_indices; } + ConstArrayView<uint32_t> vertices() const { return m_vertexToSourceVertexMap; } -struct Progress -{ - Progress(ProgressCategory::Enum category, ProgressFunc func, void *userData, uint32_t maxValue) : value(0), cancel(false), m_category(category), m_func(func), m_userData(userData), m_maxValue(maxValue), m_progress(0) - { +private: + Array<uint32_t> m_faces, m_indices; + Array<uint32_t> m_vertexToSourceVertexMap; // Map face vertices to vertices of the source mesh. +}; + +struct Progress { + Progress(ProgressCategory category, ProgressFunc func, void *userData, uint32_t maxValue) : + cancel(false), m_category(category), m_func(func), m_userData(userData), m_value(0), m_maxValue(maxValue), m_percent(0) { if (m_func) { if (!m_func(category, 0, userData)) cancel = true; } } - ~Progress() - { + ~Progress() { if (m_func) { if (!m_func(m_category, 100, m_userData)) cancel = true; } } - void update() - { - if (!m_func) - return; - m_mutex.lock(); - const uint32_t newProgress = uint32_t(ceilf(value.load() / (float)m_maxValue * 100.0f)); - if (newProgress != m_progress && newProgress < 100) { - m_progress = newProgress; - if (!m_func(m_category, m_progress, m_userData)) - cancel = true; - } - m_mutex.unlock(); + void increment(uint32_t value) { + m_value += value; + update(); } - void setMaxValue(uint32_t maxValue) - { - m_mutex.lock(); + void setMaxValue(uint32_t maxValue) { m_maxValue = maxValue; - m_mutex.unlock(); + update(); } - std::atomic<uint32_t> value; std::atomic<bool> cancel; private: - ProgressCategory::Enum m_category; + void update() { + if (!m_func) + return; + const uint32_t newPercent = uint32_t(ceilf(m_value.load() / (float)m_maxValue.load() * 100.0f)); + if (newPercent != m_percent) { + // Atomic max. + uint32_t oldPercent = m_percent; + while (oldPercent < newPercent && !m_percent.compare_exchange_weak(oldPercent, newPercent)) { + } + if (!m_func(m_category, m_percent, m_userData)) + cancel = true; + } + } + + ProgressCategory m_category; ProgressFunc m_func; void *m_userData; - uint32_t m_maxValue; - uint32_t m_progress; - std::mutex m_mutex; + std::atomic<uint32_t> m_value, m_maxValue, m_percent; }; -struct Spinlock -{ - void lock() { while(m_lock.test_and_set(std::memory_order_acquire)) {} } +struct Spinlock { + void lock() { + while (m_lock.test_and_set(std::memory_order_acquire)) { + } + } void unlock() { m_lock.clear(std::memory_order_release); } private: std::atomic_flag m_lock = ATOMIC_FLAG_INIT; }; -struct TaskGroupHandle -{ +struct TaskGroupHandle { uint32_t value = UINT32_MAX; }; -struct Task -{ - void (*func)(void *userData); - void *userData; +struct Task { + void (*func)(void *groupUserData, void *taskUserData); + void *userData; // Passed to func as taskUserData. }; #if XA_MULTITHREADED -class TaskScheduler -{ +class TaskScheduler { public: - TaskScheduler() : m_shutdown(false) - { + TaskScheduler() : + m_shutdown(false) { m_threadIndex = 0; // Max with current task scheduler usage is 1 per thread + 1 deep nesting, but allow for some slop. m_maxGroups = std::thread::hardware_concurrency() * 4; @@ -3739,6 +2968,7 @@ public: new (&m_groups[i]) TaskGroup(); m_groups[i].free = true; m_groups[i].ref = 0; + m_groups[i].userData = nullptr; } m_workers.resize(std::thread::hardware_concurrency() <= 1 ? 1 : std::thread::hardware_concurrency() - 1); for (uint32_t i = 0; i < m_workers.size(); i++) { @@ -3748,8 +2978,7 @@ public: } } - ~TaskScheduler() - { + ~TaskScheduler() { m_shutdown = true; for (uint32_t i = 0; i < m_workers.size(); i++) { Worker &worker = m_workers[i]; @@ -3767,13 +2996,12 @@ public: XA_FREE(m_groups); } - uint32_t threadCount() const - { + uint32_t threadCount() const { return max(1u, std::thread::hardware_concurrency()); // Including the main thread. } - TaskGroupHandle createTaskGroup(uint32_t reserveSize = 0) - { + // userData is passed to Task::func as groupUserData. + TaskGroupHandle createTaskGroup(void *userData = nullptr, uint32_t reserveSize = 0) { // Claim the first free group. for (uint32_t i = 0; i < m_maxGroups; i++) { TaskGroup &group = m_groups[i]; @@ -3785,6 +3013,8 @@ public: group.queue.clear(); group.queue.reserve(reserveSize); group.queueLock.unlock(); + group.userData = userData; + group.ref = 0; TaskGroupHandle handle; handle.value = i; return handle; @@ -3795,8 +3025,7 @@ public: return handle; } - void run(TaskGroupHandle handle, const Task &task) - { + void run(TaskGroupHandle handle, const Task &task) { XA_DEBUG_ASSERT(handle.value != UINT32_MAX); TaskGroup &group = m_groups[handle.value]; group.queueLock.lock(); @@ -3810,8 +3039,7 @@ public: } } - void wait(TaskGroupHandle *handle) - { + void wait(TaskGroupHandle *handle) { if (handle->value == UINT32_MAX) { XA_DEBUG_ASSERT(false); return; @@ -3826,7 +3054,7 @@ public: group.queueLock.unlock(); if (!task) break; - task->func(task->userData); + task->func(group.userData, task->userData); group.ref--; } // Even though the task queue is empty, workers can still be running tasks. @@ -3839,17 +3067,16 @@ public: static uint32_t currentThreadIndex() { return m_threadIndex; } private: - struct TaskGroup - { + struct TaskGroup { std::atomic<bool> free; Array<Task> queue; // Items are never removed. queueHead is incremented to pop items. uint32_t queueHead = 0; Spinlock queueLock; std::atomic<uint32_t> ref; // Increment when a task is enqueued, decrement when a task finishes. + void *userData; }; - struct Worker - { + struct Worker { std::thread *thread = nullptr; std::mutex mutex; std::condition_variable cv; @@ -3862,12 +3089,11 @@ private: uint32_t m_maxGroups; static thread_local uint32_t m_threadIndex; - static void workerThread(TaskScheduler *scheduler, Worker *worker, uint32_t threadIndex) - { + static void workerThread(TaskScheduler *scheduler, Worker *worker, uint32_t threadIndex) { m_threadIndex = threadIndex; std::unique_lock<std::mutex> lock(worker->mutex); for (;;) { - worker->cv.wait(lock, [=]{ return worker->wakeup.load(); }); + worker->cv.wait(lock, [=] { return worker->wakeup.load(); }); worker->wakeup = false; for (;;) { if (scheduler->m_shutdown) @@ -3889,7 +3115,7 @@ private: } if (!task) break; - task->func(task->userData); + task->func(group->userData, task->userData); group->ref--; } } @@ -3898,44 +3124,39 @@ private: thread_local uint32_t TaskScheduler::m_threadIndex; #else -class TaskScheduler -{ +class TaskScheduler { public: - ~TaskScheduler() - { + ~TaskScheduler() { for (uint32_t i = 0; i < m_groups.size(); i++) destroyGroup({ i }); } - uint32_t threadCount() const - { + uint32_t threadCount() const { return 1; } - TaskGroupHandle createTaskGroup(uint32_t reserveSize = 0) - { + TaskGroupHandle createTaskGroup(void *userData = nullptr, uint32_t reserveSize = 0) { TaskGroup *group = XA_NEW(MemTag::Default, TaskGroup); group->queue.reserve(reserveSize); + group->userData = userData; m_groups.push_back(group); TaskGroupHandle handle; handle.value = m_groups.size() - 1; return handle; } - void run(TaskGroupHandle handle, Task task) - { + void run(TaskGroupHandle handle, Task task) { m_groups[handle.value]->queue.push_back(task); } - void wait(TaskGroupHandle *handle) - { + void wait(TaskGroupHandle *handle) { if (handle->value == UINT32_MAX) { XA_DEBUG_ASSERT(false); return; } TaskGroup *group = m_groups[handle->value]; for (uint32_t i = 0; i < group->queue.size(); i++) - group->queue[i].func(group->queue[i].userData); + group->queue[i].func(group->userData, group->queue[i].userData); group->queue.clear(); destroyGroup(*handle); handle->value = UINT32_MAX; @@ -3944,8 +3165,7 @@ public: static uint32_t currentThreadIndex() { return 0; } private: - void destroyGroup(TaskGroupHandle handle) - { + void destroyGroup(TaskGroupHandle handle) { TaskGroup *group = m_groups[handle.value]; if (group) { group->~TaskGroup(); @@ -3954,9 +3174,9 @@ private: } } - struct TaskGroup - { + struct TaskGroup { Array<Task> queue; + void *userData; }; Array<TaskGroup *> m_groups; @@ -3968,8 +3188,7 @@ const uint8_t TGA_TYPE_RGB = 2; const uint8_t TGA_ORIGIN_UPPER = 0x20; #pragma pack(push, 1) -struct TgaHeader -{ +struct TgaHeader { uint8_t id_length; uint8_t colormap_type; uint8_t image_type; @@ -3986,8 +3205,7 @@ struct TgaHeader }; #pragma pack(pop) -static void WriteTga(const char *filename, const uint8_t *data, uint32_t width, uint32_t height) -{ +static void WriteTga(const char *filename, const uint8_t *data, uint32_t width, uint32_t height) { XA_DEBUG_ASSERT(sizeof(TgaHeader) == TgaHeader::Size); FILE *f; XA_FOPEN(f, filename, "wb"); @@ -4012,12 +3230,10 @@ static void WriteTga(const char *filename, const uint8_t *data, uint32_t width, } #endif -template<typename T> -class ThreadLocal -{ +template <typename T> +class ThreadLocal { public: - ThreadLocal() - { + ThreadLocal() { #if XA_MULTITHREADED const uint32_t n = std::thread::hardware_concurrency(); #else @@ -4028,8 +3244,7 @@ public: new (&m_array[i]) T; } - ~ThreadLocal() - { + ~ThreadLocal() { #if XA_MULTITHREADED const uint32_t n = std::thread::hardware_concurrency(); #else @@ -4040,8 +3255,7 @@ public: XA_FREE(m_array); } - T &get() const - { + T &get() const { return m_array[TaskScheduler::currentThreadIndex()]; } @@ -4049,11 +3263,104 @@ private: T *m_array; }; -class UniformGrid2 -{ +// Implemented as a struct so the temporary arrays can be reused. +struct Triangulator { + // This is doing a simple ear-clipping algorithm that skips invalid triangles. Ideally, we should + // also sort the ears by angle, start with the ones that have the smallest angle and proceed in order. + void triangulatePolygon(ConstArrayView<Vector3> vertices, ConstArrayView<uint32_t> inputIndices, Array<uint32_t> &outputIndices) { + m_polygonVertices.clear(); + m_polygonVertices.reserve(inputIndices.length); + outputIndices.clear(); + if (inputIndices.length == 3) { + // Simple case for triangles. + outputIndices.push_back(inputIndices[0]); + outputIndices.push_back(inputIndices[1]); + outputIndices.push_back(inputIndices[2]); + } else { + // Build 2D polygon projecting vertices onto normal plane. + // Faces are not necesarily planar, this is for example the case, when the face comes from filling a hole. In such cases + // it's much better to use the best fit plane. + Basis basis; + basis.normal = normalize(cross(vertices[inputIndices[1]] - vertices[inputIndices[0]], vertices[inputIndices[2]] - vertices[inputIndices[1]])); + basis.tangent = basis.computeTangent(basis.normal); + basis.bitangent = basis.computeBitangent(basis.normal, basis.tangent); + const uint32_t edgeCount = inputIndices.length; + m_polygonPoints.clear(); + m_polygonPoints.reserve(edgeCount); + m_polygonAngles.clear(); + m_polygonAngles.reserve(edgeCount); + for (uint32_t i = 0; i < inputIndices.length; i++) { + m_polygonVertices.push_back(inputIndices[i]); + const Vector3 &pos = vertices[inputIndices[i]]; + m_polygonPoints.push_back(Vector2(dot(basis.tangent, pos), dot(basis.bitangent, pos))); + } + m_polygonAngles.resize(edgeCount); + while (m_polygonVertices.size() > 2) { + const uint32_t size = m_polygonVertices.size(); + // Update polygon angles. @@ Update only those that have changed. + float minAngle = kPi2; + uint32_t bestEar = 0; // Use first one if none of them is valid. + bool bestIsValid = false; + for (uint32_t i = 0; i < size; i++) { + uint32_t i0 = i; + uint32_t i1 = (i + 1) % size; // Use Sean's polygon interation trick. + uint32_t i2 = (i + 2) % size; + Vector2 p0 = m_polygonPoints[i0]; + Vector2 p1 = m_polygonPoints[i1]; + Vector2 p2 = m_polygonPoints[i2]; + float d = clamp(dot(p0 - p1, p2 - p1) / (length(p0 - p1) * length(p2 - p1)), -1.0f, 1.0f); + float angle = acosf(d); + float area = triangleArea(p0, p1, p2); + if (area < 0.0f) + angle = kPi2 - angle; + m_polygonAngles[i1] = angle; + if (angle < minAngle || !bestIsValid) { + // Make sure this is a valid ear, if not, skip this point. + bool valid = true; + for (uint32_t j = 0; j < size; j++) { + if (j == i0 || j == i1 || j == i2) + continue; + Vector2 p = m_polygonPoints[j]; + if (pointInTriangle(p, p0, p1, p2)) { + valid = false; + break; + } + } + if (valid || !bestIsValid) { + minAngle = angle; + bestEar = i1; + bestIsValid = valid; + } + } + } + // Clip best ear: + const uint32_t i0 = (bestEar + size - 1) % size; + const uint32_t i1 = (bestEar + 0) % size; + const uint32_t i2 = (bestEar + 1) % size; + outputIndices.push_back(m_polygonVertices[i0]); + outputIndices.push_back(m_polygonVertices[i1]); + outputIndices.push_back(m_polygonVertices[i2]); + m_polygonVertices.removeAt(i1); + m_polygonPoints.removeAt(i1); + m_polygonAngles.removeAt(i1); + } + } + } + +private: + static bool pointInTriangle(const Vector2 &p, const Vector2 &a, const Vector2 &b, const Vector2 &c) { + return triangleArea(a, b, p) >= kAreaEpsilon && triangleArea(b, c, p) >= kAreaEpsilon && triangleArea(c, a, p) >= kAreaEpsilon; + } + + Array<int> m_polygonVertices; + Array<float> m_polygonAngles; + Array<Vector2> m_polygonPoints; +}; + +class UniformGrid2 { public: - void reset(const Vector2 *positions, const uint32_t *indices = nullptr, uint32_t reserveEdgeCount = 0) - { + // indices are optional. + void reset(ConstArrayView<Vector2> positions, ConstArrayView<uint32_t> indices = ConstArrayView<uint32_t>(), uint32_t reserveEdgeCount = 0) { m_edges.clear(); if (reserveEdgeCount > 0) m_edges.reserve(reserveEdgeCount); @@ -4062,14 +3369,12 @@ public: m_cellDataOffsets.clear(); } - void append(uint32_t edge) - { + void append(uint32_t edge) { XA_DEBUG_ASSERT(m_cellDataOffsets.isEmpty()); m_edges.push_back(edge); } - bool intersect(Vector2 v1, Vector2 v2, float epsilon) - { + bool intersect(Vector2 v1, Vector2 v2, float epsilon) { const uint32_t edgeCount = m_edges.size(); bool bruteForce = edgeCount <= 20; if (!bruteForce && m_cellDataOffsets.isEmpty()) @@ -4096,8 +3401,7 @@ public: } // If edges is empty, checks for intersection with all edges in the grid. - bool intersect(float epsilon, ConstArrayView<uint32_t> edges = ConstArrayView<uint32_t>(), ConstArrayView<uint32_t> ignoreEdges = ConstArrayView<uint32_t>()) - { + bool intersect(float epsilon, ConstArrayView<uint32_t> edges = ConstArrayView<uint32_t>(), ConstArrayView<uint32_t> ignoreEdges = ConstArrayView<uint32_t>()) { bool bruteForce = m_edges.size() <= 20; if (!bruteForce && m_cellDataOffsets.isEmpty()) bruteForce = !createGrid(); @@ -4167,8 +3471,7 @@ public: } #if XA_DEBUG_EXPORT_BOUNDARY_GRID - void debugExport(const char *filename) - { + void debugExport(const char *filename) { Array<uint8_t> image; image.resize(m_gridWidth * m_gridHeight * 3); for (uint32_t y = 0; y < m_gridHeight; y++) { @@ -4190,8 +3493,7 @@ public: #endif private: - bool createGrid() - { + bool createGrid() { // Compute edge extents. Min will be the grid origin. const uint32_t edgeCount = m_edges.size(); Extents2 edgeExtents; @@ -4202,14 +3504,14 @@ private: edgeExtents.add(edgePosition1(edge)); } m_gridOrigin = edgeExtents.min; - // Size grid to approximately one edge per cell. + // Size grid to approximately one edge per cell in the largest dimension. const Vector2 extentsSize(edgeExtents.max - edgeExtents.min); - m_cellSize = min(extentsSize.x, extentsSize.y) / sqrtf((float)edgeCount); + m_cellSize = max(extentsSize.x, extentsSize.y) / (float)clamp(edgeCount, 32u, 512u); if (m_cellSize <= 0.0f) return false; m_gridWidth = uint32_t(ceilf(extentsSize.x / m_cellSize)); m_gridHeight = uint32_t(ceilf(extentsSize.y / m_cellSize)); - if (m_gridWidth == 0 || m_gridHeight == 0) + if (m_gridWidth <= 1 || m_gridHeight <= 1) return false; // Insert edges into cells. m_cellDataOffsets.resize(m_gridWidth * m_gridHeight); @@ -4243,8 +3545,7 @@ private: return true; } - void computePotentialEdges(Vector2 p1, Vector2 p2) - { + void computePotentialEdges(Vector2 p1, Vector2 p2) { m_potentialEdges.clear(); traverse(p1, p2); for (uint32_t j = 0; j < m_traversedCellOffsets.size(); j++) { @@ -4262,10 +3563,9 @@ private: } // "A Fast Voxel Traversal Algorithm for Ray Tracing" - void traverse(Vector2 p1, Vector2 p2) - { + void traverse(Vector2 p1, Vector2 p2) { const Vector2 dir = p2 - p1; - const Vector2 normal = normalizeSafe(dir, Vector2(0.0f), kEpsilon); + const Vector2 normal = normalizeSafe(dir, Vector2(0.0f)); const int stepX = dir.x >= 0 ? 1 : -1; const int stepY = dir.y >= 0 ? 1 : -1; const uint32_t firstCell[2] = { cellX(p1.x), cellY(p1.y) }; @@ -4284,14 +3584,12 @@ private: if (normal.x > kEpsilon || normal.x < -kEpsilon) { tMaxX = (distToNextCellX * stepX) / normal.x; tDeltaX = (m_cellSize * stepX) / normal.x; - } - else + } else tMaxX = tDeltaX = FLT_MAX; if (normal.y > kEpsilon || normal.y < -kEpsilon) { tMaxY = (distToNextCellY * stepY) / normal.y; tDeltaY = (m_cellSize * stepY) / normal.y; - } - else + } else tMaxY = tDeltaY = FLT_MAX; m_traversedCellOffsets.clear(); m_traversedCellOffsets.push_back(firstCell[0] + firstCell[1] * m_gridWidth); @@ -4318,34 +3616,29 @@ private: } } - uint32_t cellX(float x) const - { + uint32_t cellX(float x) const { return min((uint32_t)max(0.0f, (x - m_gridOrigin.x) / m_cellSize), m_gridWidth - 1u); } - uint32_t cellY(float y) const - { + uint32_t cellY(float y) const { return min((uint32_t)max(0.0f, (y - m_gridOrigin.y) / m_cellSize), m_gridHeight - 1u); } - Vector2 edgePosition0(uint32_t edge) const - { + Vector2 edgePosition0(uint32_t edge) const { return m_positions[vertexAt(meshEdgeIndex0(edge))]; } - Vector2 edgePosition1(uint32_t edge) const - { + Vector2 edgePosition1(uint32_t edge) const { return m_positions[vertexAt(meshEdgeIndex1(edge))]; } - uint32_t vertexAt(uint32_t index) const - { - return m_indices ? m_indices[index] : index; + uint32_t vertexAt(uint32_t index) const { + return m_indices.length > 0 ? m_indices[index] : index; } Array<uint32_t> m_edges; - const Vector2 *m_positions; - const uint32_t *m_indices; // Optional + ConstArrayView<Vector2> m_positions; + ConstArrayView<uint32_t> m_indices; // Optional. Empty if unused. float m_cellSize; Vector2 m_gridOrigin; uint32_t m_gridWidth, m_gridHeight; // in cells @@ -4355,26 +3648,25 @@ private: Array<uint32_t> m_traversedCellOffsets; }; -struct UvMeshChart -{ +struct UvMeshChart { Array<uint32_t> faces; Array<uint32_t> indices; uint32_t material; }; -struct UvMesh -{ +struct UvMesh { UvMeshDecl decl; + BitArray faceIgnore; + Array<uint32_t> faceMaterials; Array<uint32_t> indices; + Array<Vector2> texcoords; // Copied from input and never modified, UvMeshInstance::texcoords are. Used to restore UvMeshInstance::texcoords so packing can be run multiple times. Array<UvMeshChart *> charts; Array<uint32_t> vertexToChartMap; }; -struct UvMeshInstance -{ +struct UvMeshInstance { UvMesh *mesh; Array<Vector2> texcoords; - bool rotateCharts; }; /* @@ -4420,27 +3712,30 @@ struct UvMeshInstance * FRANCE */ namespace opennl { -#define NL_NEW(T) XA_ALLOC(MemTag::OpenNL, T) -#define NL_NEW_ARRAY(T,NB) XA_ALLOC_ARRAY(MemTag::OpenNL, T, NB) -#define NL_RENEW_ARRAY(T,x,NB) XA_REALLOC(MemTag::OpenNL, x, T, NB) -#define NL_DELETE(x) XA_FREE(x); x = nullptr -#define NL_DELETE_ARRAY(x) XA_FREE(x); x = nullptr -#define NL_CLEAR(x, T) memset(x, 0, sizeof(T)); -#define NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (size_t)(NB)*sizeof(T)) -#define NL_NEW_VECTOR(dim) XA_ALLOC_ARRAY(MemTag::OpenNL, double, dim) -#define NL_DELETE_VECTOR(ptr) XA_FREE(ptr) +#define NL_NEW(T) XA_ALLOC(MemTag::OpenNL, T) +#define NL_NEW_ARRAY(T, NB) XA_ALLOC_ARRAY(MemTag::OpenNL, T, NB) +#define NL_RENEW_ARRAY(T, x, NB) XA_REALLOC(MemTag::OpenNL, x, T, NB) +#define NL_DELETE(x) \ + XA_FREE(x); \ + x = nullptr +#define NL_DELETE_ARRAY(x) \ + XA_FREE(x); \ + x = nullptr +#define NL_CLEAR(x, T) memset(x, 0, sizeof(T)); +#define NL_CLEAR_ARRAY(T, x, NB) memset(x, 0, (size_t)(NB) * sizeof(T)) +#define NL_NEW_VECTOR(dim) XA_ALLOC_ARRAY(MemTag::OpenNL, double, dim) +#define NL_DELETE_VECTOR(ptr) XA_FREE(ptr) struct NLMatrixStruct; -typedef NLMatrixStruct * NLMatrix; +typedef NLMatrixStruct *NLMatrix; typedef void (*NLDestroyMatrixFunc)(NLMatrix M); -typedef void (*NLMultMatrixVectorFunc)(NLMatrix M, const double* x, double* y); +typedef void (*NLMultMatrixVectorFunc)(NLMatrix M, const double *x, double *y); #define NL_MATRIX_SPARSE_DYNAMIC 0x1001 -#define NL_MATRIX_CRS 0x1002 -#define NL_MATRIX_OTHER 0x1006 +#define NL_MATRIX_CRS 0x1002 +#define NL_MATRIX_OTHER 0x1006 -struct NLMatrixStruct -{ +struct NLMatrixStruct { uint32_t m; uint32_t n; uint32_t type; @@ -4450,39 +3745,35 @@ struct NLMatrixStruct /* Dynamic arrays for sparse row/columns */ -struct NLCoeff -{ +struct NLCoeff { uint32_t index; double value; }; -struct NLRowColumn -{ +struct NLRowColumn { uint32_t size; uint32_t capacity; - NLCoeff* coeff; + NLCoeff *coeff; }; /* Compressed Row Storage */ -struct NLCRSMatrix -{ +struct NLCRSMatrix { uint32_t m; uint32_t n; uint32_t type; NLDestroyMatrixFunc destroy_func; NLMultMatrixVectorFunc mult_func; - double* val; - uint32_t* rowptr; - uint32_t* colind; + double *val; + uint32_t *rowptr; + uint32_t *colind; uint32_t nslices; - uint32_t* sliceptr; + uint32_t *sliceptr; }; /* SparseMatrix data structure */ -struct NLSparseMatrix -{ +struct NLSparseMatrix { uint32_t m; uint32_t n; uint32_t type; @@ -4490,25 +3781,23 @@ struct NLSparseMatrix NLMultMatrixVectorFunc mult_func; uint32_t diag_size; uint32_t diag_capacity; - NLRowColumn* row; - NLRowColumn* column; - double* diag; + NLRowColumn *row; + NLRowColumn *column; + double *diag; uint32_t row_capacity; uint32_t column_capacity; }; /* NLContext data structure */ -struct NLBufferBinding -{ - void* base_address; +struct NLBufferBinding { + void *base_address; uint32_t stride; }; -#define NL_BUFFER_ITEM(B,i) *(double*)((void*)((char*)((B).base_address)+((i)*(B).stride))) +#define NL_BUFFER_ITEM(B, i) *(double *)((void *)((char *)((B).base_address) + ((i) * (B).stride))) -struct NLContext -{ +struct NLContext { NLBufferBinding *variable_buffer; double *variable_value; bool *variable_is_locked; @@ -4532,35 +3821,30 @@ struct NLContext double error; }; -static void nlDeleteMatrix(NLMatrix M) -{ +static void nlDeleteMatrix(NLMatrix M) { if (!M) return; M->destroy_func(M); NL_DELETE(M); } -static void nlMultMatrixVector(NLMatrix M, const double* x, double* y) -{ +static void nlMultMatrixVector(NLMatrix M, const double *x, double *y) { M->mult_func(M, x, y); } -static void nlRowColumnConstruct(NLRowColumn* c) -{ +static void nlRowColumnConstruct(NLRowColumn *c) { c->size = 0; c->capacity = 0; c->coeff = nullptr; } -static void nlRowColumnDestroy(NLRowColumn* c) -{ +static void nlRowColumnDestroy(NLRowColumn *c) { NL_DELETE_ARRAY(c->coeff); c->size = 0; c->capacity = 0; } -static void nlRowColumnGrow(NLRowColumn* c) -{ +static void nlRowColumnGrow(NLRowColumn *c) { if (c->capacity != 0) { c->capacity = 2 * c->capacity; c->coeff = NL_RENEW_ARRAY(NLCoeff, c->coeff, c->capacity); @@ -4571,8 +3855,7 @@ static void nlRowColumnGrow(NLRowColumn* c) } } -static void nlRowColumnAdd(NLRowColumn* c, uint32_t index, double value) -{ +static void nlRowColumnAdd(NLRowColumn *c, uint32_t index, double value) { for (uint32_t i = 0; i < c->size; i++) { if (c->coeff[i].index == index) { c->coeff[i].value += value; @@ -4587,8 +3870,7 @@ static void nlRowColumnAdd(NLRowColumn* c, uint32_t index, double value) } /* Does not check whether the index already exists */ -static void nlRowColumnAppend(NLRowColumn* c, uint32_t index, double value) -{ +static void nlRowColumnAppend(NLRowColumn *c, uint32_t index, double value) { if (c->size == c->capacity) nlRowColumnGrow(c); c->coeff[c->size].index = index; @@ -4596,32 +3878,27 @@ static void nlRowColumnAppend(NLRowColumn* c, uint32_t index, double value) c->size++; } -static void nlRowColumnZero(NLRowColumn* c) -{ +static void nlRowColumnZero(NLRowColumn *c) { c->size = 0; } -static void nlRowColumnClear(NLRowColumn* c) -{ +static void nlRowColumnClear(NLRowColumn *c) { c->size = 0; c->capacity = 0; NL_DELETE_ARRAY(c->coeff); } -static int nlCoeffCompare(const void* p1, const void* p2) -{ - return (((NLCoeff*)(p2))->index < ((NLCoeff*)(p1))->index); +static int nlCoeffCompare(const void *p1, const void *p2) { + return (((NLCoeff *)(p2))->index < ((NLCoeff *)(p1))->index); } -static void nlRowColumnSort(NLRowColumn* c) -{ +static void nlRowColumnSort(NLRowColumn *c) { qsort(c->coeff, c->size, sizeof(NLCoeff), nlCoeffCompare); } /* CRSMatrix data structure */ -static void nlCRSMatrixDestroy(NLCRSMatrix* M) -{ +static void nlCRSMatrixDestroy(NLCRSMatrix *M) { NL_DELETE_ARRAY(M->val); NL_DELETE_ARRAY(M->rowptr); NL_DELETE_ARRAY(M->colind); @@ -4631,8 +3908,7 @@ static void nlCRSMatrixDestroy(NLCRSMatrix* M) M->nslices = 0; } -static void nlCRSMatrixMultSlice(NLCRSMatrix* M, const double* x, double* y, uint32_t Ibegin, uint32_t Iend) -{ +static void nlCRSMatrixMultSlice(NLCRSMatrix *M, const double *x, double *y, uint32_t Ibegin, uint32_t Iend) { for (uint32_t i = Ibegin; i < Iend; ++i) { double sum = 0.0; for (uint32_t j = M->rowptr[i]; j < M->rowptr[i + 1]; ++j) @@ -4641,15 +3917,13 @@ static void nlCRSMatrixMultSlice(NLCRSMatrix* M, const double* x, double* y, uin } } -static void nlCRSMatrixMult(NLCRSMatrix* M, const double* x, double* y) -{ +static void nlCRSMatrixMult(NLCRSMatrix *M, const double *x, double *y) { int nslices = (int)(M->nslices); for (int slice = 0; slice < nslices; ++slice) nlCRSMatrixMultSlice(M, x, y, M->sliceptr[slice], M->sliceptr[slice + 1]); } -static void nlCRSMatrixConstruct(NLCRSMatrix* M, uint32_t m, uint32_t n, uint32_t nnz, uint32_t nslices) -{ +static void nlCRSMatrixConstruct(NLCRSMatrix *M, uint32_t m, uint32_t n, uint32_t nnz, uint32_t nslices) { M->m = m; M->n = n; M->type = NL_MATRIX_CRS; @@ -4668,22 +3942,19 @@ static void nlCRSMatrixConstruct(NLCRSMatrix* M, uint32_t m, uint32_t n, uint32_ /* SparseMatrix data structure */ -static void nlSparseMatrixDestroyRowColumns(NLSparseMatrix* M) -{ +static void nlSparseMatrixDestroyRowColumns(NLSparseMatrix *M) { for (uint32_t i = 0; i < M->m; i++) nlRowColumnDestroy(&(M->row[i])); NL_DELETE_ARRAY(M->row); } -static void nlSparseMatrixDestroy(NLSparseMatrix* M) -{ +static void nlSparseMatrixDestroy(NLSparseMatrix *M) { XA_DEBUG_ASSERT(M->type == NL_MATRIX_SPARSE_DYNAMIC); nlSparseMatrixDestroyRowColumns(M); NL_DELETE_ARRAY(M->diag); } -static void nlSparseMatrixAdd(NLSparseMatrix* M, uint32_t i, uint32_t j, double value) -{ +static void nlSparseMatrixAdd(NLSparseMatrix *M, uint32_t i, uint32_t j, double value) { XA_DEBUG_ASSERT(i >= 0 && i <= M->m - 1); XA_DEBUG_ASSERT(j >= 0 && j <= M->n - 1); if (i == j) @@ -4692,24 +3963,21 @@ static void nlSparseMatrixAdd(NLSparseMatrix* M, uint32_t i, uint32_t j, double } /* Returns the number of non-zero coefficients */ -static uint32_t nlSparseMatrixNNZ(NLSparseMatrix* M) -{ +static uint32_t nlSparseMatrixNNZ(NLSparseMatrix *M) { uint32_t nnz = 0; for (uint32_t i = 0; i < M->m; i++) nnz += M->row[i].size; return nnz; } -static void nlSparseMatrixSort(NLSparseMatrix* M) -{ +static void nlSparseMatrixSort(NLSparseMatrix *M) { for (uint32_t i = 0; i < M->m; i++) nlRowColumnSort(&(M->row[i])); } /* SparseMatrix x Vector routines, internal helper routines */ -static void nlSparseMatrix_mult_rows(NLSparseMatrix* A, const double* x, double* y) -{ +static void nlSparseMatrix_mult_rows(NLSparseMatrix *A, const double *x, double *y) { /* * Note: OpenMP does not like unsigned ints * (causes some floating point exceptions), @@ -4717,8 +3985,8 @@ static void nlSparseMatrix_mult_rows(NLSparseMatrix* A, const double* x, double* * indices. */ int m = (int)(A->m); - NLCoeff* c = nullptr; - NLRowColumn* Ri = nullptr; + NLCoeff *c = nullptr; + NLRowColumn *Ri = nullptr; for (int i = 0; i < m; i++) { Ri = &(A->row[i]); y[i] = 0; @@ -4729,14 +3997,12 @@ static void nlSparseMatrix_mult_rows(NLSparseMatrix* A, const double* x, double* } } -static void nlSparseMatrixMult(NLSparseMatrix* A, const double* x, double* y) -{ +static void nlSparseMatrixMult(NLSparseMatrix *A, const double *x, double *y) { XA_DEBUG_ASSERT(A->type == NL_MATRIX_SPARSE_DYNAMIC); nlSparseMatrix_mult_rows(A, x, y); } -static void nlSparseMatrixConstruct(NLSparseMatrix* M, uint32_t m, uint32_t n) -{ +static void nlSparseMatrixConstruct(NLSparseMatrix *M, uint32_t m, uint32_t n) { M->m = m; M->n = n; M->type = NL_MATRIX_SPARSE_DYNAMIC; @@ -4756,24 +4022,23 @@ static void nlSparseMatrixConstruct(NLSparseMatrix* M, uint32_t m, uint32_t n) NL_CLEAR_ARRAY(double, M->diag, M->diag_size); } -static NLMatrix nlCRSMatrixNewFromSparseMatrix(NLSparseMatrix* M) -{ +static NLMatrix nlCRSMatrixNewFromSparseMatrix(NLSparseMatrix *M) { uint32_t nnz = nlSparseMatrixNNZ(M); uint32_t nslices = 8; /* TODO: get number of cores */ uint32_t slice, cur_bound, cur_NNZ, cur_row; uint32_t k; uint32_t slice_size = nnz / nslices; - NLCRSMatrix* CRS = NL_NEW(NLCRSMatrix); + NLCRSMatrix *CRS = NL_NEW(NLCRSMatrix); NL_CLEAR(CRS, NLCRSMatrix); nlCRSMatrixConstruct(CRS, M->m, M->n, nnz, nslices); nlSparseMatrixSort(M); /* Convert matrix to CRS format */ k = 0; for (uint32_t i = 0; i < M->m; ++i) { - NLRowColumn* Ri = &(M->row[i]); + NLRowColumn *Ri = &(M->row[i]); CRS->rowptr[i] = k; for (uint32_t ij = 0; ij < Ri->size; ij++) { - NLCoeff* c = &(Ri->coeff[ij]); + NLCoeff *c = &(Ri->coeff[ij]); CRS->val[k] = c->value; CRS->colind[k] = c->index; ++k; @@ -4799,19 +4064,17 @@ static NLMatrix nlCRSMatrixNewFromSparseMatrix(NLSparseMatrix* M) return (NLMatrix)CRS; } -static void nlMatrixCompress(NLMatrix* M) -{ +static void nlMatrixCompress(NLMatrix *M) { NLMatrix CRS = nullptr; if ((*M)->type != NL_MATRIX_SPARSE_DYNAMIC) return; - CRS = nlCRSMatrixNewFromSparseMatrix((NLSparseMatrix*)*M); + CRS = nlCRSMatrixNewFromSparseMatrix((NLSparseMatrix *)*M); nlDeleteMatrix(*M); *M = CRS; } -static NLContext *nlNewContext() -{ - NLContext* result = NL_NEW(NLContext); +static NLContext *nlNewContext() { + NLContext *result = NL_NEW(NLContext); NL_CLEAR(result, NLContext); result->max_iterations = 100; result->threshold = 1e-6; @@ -4820,8 +4083,7 @@ static NLContext *nlNewContext() return result; } -static void nlDeleteContext(NLContext *context) -{ +static void nlDeleteContext(NLContext *context) { nlDeleteMatrix(context->M); context->M = nullptr; nlDeleteMatrix(context->P); @@ -4839,22 +4101,19 @@ static void nlDeleteContext(NLContext *context) NL_DELETE(context); } -static double ddot(int n, const double *x, const double *y) -{ +static double ddot(int n, const double *x, const double *y) { double sum = 0.0; for (int i = 0; i < n; i++) sum += x[i] * y[i]; return sum; } -static void daxpy(int n, double a, const double *x, double *y) -{ +static void daxpy(int n, double a, const double *x, double *y) { for (int i = 0; i < n; i++) y[i] = a * x[i] + y[i]; } -static void dscal(int n, double a, double *x) -{ +static void dscal(int n, double a, double *x) { for (int i = 0; i < n; i++) x[i] *= a; } @@ -4877,17 +4136,16 @@ static void dscal(int n, double a, double *x) * versions of matrix x vector product (CPU/GPU, sparse/dense ...) */ -static uint32_t nlSolveSystem_PRE_CG(NLMatrix M, NLMatrix P, double* b, double* x, double eps, uint32_t max_iter, double *sq_bnorm, double *sq_rnorm) -{ - int N = (int)M->n; - double* r = NL_NEW_VECTOR(N); - double* d = NL_NEW_VECTOR(N); - double* h = NL_NEW_VECTOR(N); +static uint32_t nlSolveSystem_PRE_CG(NLMatrix M, NLMatrix P, double *b, double *x, double eps, uint32_t max_iter, double *sq_bnorm, double *sq_rnorm) { + int N = (int)M->n; + double *r = NL_NEW_VECTOR(N); + double *d = NL_NEW_VECTOR(N); + double *h = NL_NEW_VECTOR(N); double *Ad = h; uint32_t its = 0; double rh, alpha, beta; double b_square = ddot(N, b, b); - double err = eps * eps*b_square; + double err = eps * eps * b_square; double curr_err; nlMultMatrixVector(M, x, r); daxpy(N, -1., b, r); @@ -4917,13 +4175,12 @@ static uint32_t nlSolveSystem_PRE_CG(NLMatrix M, NLMatrix P, double* b, double* return its; } -static uint32_t nlSolveSystemIterative(NLContext *context, NLMatrix M, NLMatrix P, double* b_in, double* x_in, double eps, uint32_t max_iter) -{ +static uint32_t nlSolveSystemIterative(NLContext *context, NLMatrix M, NLMatrix P, double *b_in, double *x_in, double eps, uint32_t max_iter) { uint32_t result = 0; double rnorm = 0.0; double bnorm = 0.0; - double* b = b_in; - double* x = x_in; + double *b = b_in; + double *x = x_in; XA_DEBUG_ASSERT(M->m == M->n); double sq_bnorm, sq_rnorm; result = nlSolveSystem_PRE_CG(M, P, b, x, eps, max_iter, &sq_bnorm, &sq_rnorm); @@ -4938,10 +4195,9 @@ static uint32_t nlSolveSystemIterative(NLContext *context, NLMatrix M, NLMatrix return result; } -static bool nlSolveIterative(NLContext *context) -{ - double* b = context->b; - double* x = context->x; +static bool nlSolveIterative(NLContext *context) { + double *b = context->b; + double *x = context->x; uint32_t n = context->n; NLMatrix M = context->M; NLMatrix P = context->P; @@ -4953,34 +4209,30 @@ static bool nlSolveIterative(NLContext *context) return true; } -struct NLJacobiPreconditioner -{ +struct NLJacobiPreconditioner { uint32_t m; uint32_t n; uint32_t type; NLDestroyMatrixFunc destroy_func; NLMultMatrixVectorFunc mult_func; - double* diag_inv; + double *diag_inv; }; -static void nlJacobiPreconditionerDestroy(NLJacobiPreconditioner* M) -{ +static void nlJacobiPreconditionerDestroy(NLJacobiPreconditioner *M) { NL_DELETE_ARRAY(M->diag_inv); } -static void nlJacobiPreconditionerMult(NLJacobiPreconditioner* M, const double* x, double* y) -{ +static void nlJacobiPreconditionerMult(NLJacobiPreconditioner *M, const double *x, double *y) { for (uint32_t i = 0; i < M->n; ++i) y[i] = x[i] * M->diag_inv[i]; } -static NLMatrix nlNewJacobiPreconditioner(NLMatrix M_in) -{ - NLSparseMatrix* M = nullptr; - NLJacobiPreconditioner* result = nullptr; +static NLMatrix nlNewJacobiPreconditioner(NLMatrix M_in) { + NLSparseMatrix *M = nullptr; + NLJacobiPreconditioner *result = nullptr; XA_DEBUG_ASSERT(M_in->type == NL_MATRIX_SPARSE_DYNAMIC); XA_DEBUG_ASSERT(M_in->m == M_in->n); - M = (NLSparseMatrix*)M_in; + M = (NLSparseMatrix *)M_in; result = NL_NEW(NLJacobiPreconditioner); NL_CLEAR(result, NLJacobiPreconditioner); result->m = M->m; @@ -4998,8 +4250,7 @@ static NLMatrix nlNewJacobiPreconditioner(NLMatrix M_in) #define NL_NB_VARIABLES 0x101 #define NL_MAX_ITERATIONS 0x103 -static void nlSolverParameteri(NLContext *context, uint32_t pname, int param) -{ +static void nlSolverParameteri(NLContext *context, uint32_t pname, int param) { if (pname == NL_NB_VARIABLES) { XA_DEBUG_ASSERT(param > 0); context->nb_variables = (uint32_t)param; @@ -5010,26 +4261,22 @@ static void nlSolverParameteri(NLContext *context, uint32_t pname, int param) } } -static void nlSetVariable(NLContext *context, uint32_t index, double value) -{ +static void nlSetVariable(NLContext *context, uint32_t index, double value) { XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1); NL_BUFFER_ITEM(context->variable_buffer[0], index) = value; } -static double nlGetVariable(NLContext *context, uint32_t index) -{ +static double nlGetVariable(NLContext *context, uint32_t index) { XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1); return NL_BUFFER_ITEM(context->variable_buffer[0], index); } -static void nlLockVariable(NLContext *context, uint32_t index) -{ +static void nlLockVariable(NLContext *context, uint32_t index) { XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1); context->variable_is_locked[index] = true; } -static void nlVariablesToVector(NLContext *context) -{ +static void nlVariablesToVector(NLContext *context) { uint32_t n = context->n; XA_DEBUG_ASSERT(context->x); for (uint32_t k = 0; k < context->nb_systems; ++k) { @@ -5044,8 +4291,7 @@ static void nlVariablesToVector(NLContext *context) } } -static void nlVectorToVariables(NLContext *context) -{ +static void nlVectorToVariables(NLContext *context) { uint32_t n = context->n; XA_DEBUG_ASSERT(context->x); for (uint32_t k = 0; k < context->nb_systems; ++k) { @@ -5060,8 +4306,7 @@ static void nlVectorToVariables(NLContext *context) } } -static void nlCoefficient(NLContext *context, uint32_t index, double value) -{ +static void nlCoefficient(NLContext *context, uint32_t index, double value) { XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1); if (context->variable_is_locked[index]) { /* @@ -5078,12 +4323,11 @@ static void nlCoefficient(NLContext *context, uint32_t index, double value) } } -#define NL_SYSTEM 0x0 -#define NL_MATRIX 0x1 -#define NL_ROW 0x2 +#define NL_SYSTEM 0x0 +#define NL_MATRIX 0x1 +#define NL_ROW 0x2 -static void nlBegin(NLContext *context, uint32_t prim) -{ +static void nlBegin(NLContext *context, uint32_t prim) { if (prim == NL_SYSTEM) { XA_DEBUG_ASSERT(context->nb_variables > 0); context->variable_buffer = NL_NEW_ARRAY(NLBufferBinding, context->nb_systems); @@ -5092,8 +4336,8 @@ static void nlBegin(NLContext *context, uint32_t prim) NL_CLEAR_ARRAY(double, context->variable_value, context->nb_variables * context->nb_systems); for (uint32_t k = 0; k < context->nb_systems; ++k) { context->variable_buffer[k].base_address = - context->variable_value + - k * context->nb_variables; + context->variable_value + + k * context->nb_variables; context->variable_buffer[k].stride = sizeof(double); } context->variable_is_locked = NL_NEW_ARRAY(bool, context->nb_variables); @@ -5116,11 +4360,11 @@ static void nlBegin(NLContext *context, uint32_t prim) context->max_iterations = n * 5; context->M = (NLMatrix)(NL_NEW(NLSparseMatrix)); NL_CLEAR(context->M, NLSparseMatrix); - nlSparseMatrixConstruct((NLSparseMatrix*)(context->M), n, n); - context->x = NL_NEW_ARRAY(double, n*context->nb_systems); - NL_CLEAR_ARRAY(double, context->x, n*context->nb_systems); - context->b = NL_NEW_ARRAY(double, n*context->nb_systems); - NL_CLEAR_ARRAY(double, context->b, n*context->nb_systems); + nlSparseMatrixConstruct((NLSparseMatrix *)(context->M), n, n); + context->x = NL_NEW_ARRAY(double, n * context->nb_systems); + NL_CLEAR_ARRAY(double, context->x, n * context->nb_systems); + context->b = NL_NEW_ARRAY(double, n * context->nb_systems); + NL_CLEAR_ARRAY(double, context->b, n * context->nb_systems); nlVariablesToVector(context); nlRowColumnConstruct(&context->af); nlRowColumnConstruct(&context->al); @@ -5131,16 +4375,15 @@ static void nlBegin(NLContext *context, uint32_t prim) } } -static void nlEnd(NLContext *context, uint32_t prim) -{ +static void nlEnd(NLContext *context, uint32_t prim) { if (prim == NL_MATRIX) { nlRowColumnClear(&context->af); nlRowColumnClear(&context->al); } else if (prim == NL_ROW) { - NLRowColumn* af = &context->af; - NLRowColumn* al = &context->al; - NLSparseMatrix* M = (NLSparseMatrix*)context->M; - double* b = context->b; + NLRowColumn *af = &context->af; + NLRowColumn *al = &context->al; + NLSparseMatrix *M = (NLSparseMatrix *)context->M; + double *b = context->b; uint32_t nf = af->size; uint32_t nl = al->size; uint32_t n = context->n; @@ -5161,14 +4404,13 @@ static void nlEnd(NLContext *context, uint32_t prim) S += al->coeff[jj].value * NL_BUFFER_ITEM(context->variable_buffer[k], j); } for (uint32_t jj = 0; jj < nf; jj++) - b[k*n + af->coeff[jj].index] -= af->coeff[jj].value * S; + b[k * n + af->coeff[jj].index] -= af->coeff[jj].value * S; } context->current_row++; } } -static bool nlSolve(NLContext *context) -{ +static bool nlSolve(NLContext *context) { nlDeleteMatrix(context->P); context->P = nlNewJacobiPreconditioner(context->M); nlMatrixCompress(&context->M); @@ -5179,11 +4421,9 @@ static bool nlSolve(NLContext *context) } // namespace opennl namespace raster { -class ClippedTriangle -{ +class ClippedTriangle { public: - ClippedTriangle(const Vector2 &a, const Vector2 &b, const Vector2 &c) - { + ClippedTriangle(const Vector2 &a, const Vector2 &b, const Vector2 &c) { m_numVertices = 3; m_activeVertexBuffer = 0; m_verticesA[0] = a; @@ -5194,20 +4434,20 @@ public: m_area = 0; } - void clipHorizontalPlane(float offset, float clipdirection) - { - Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; + void clipHorizontalPlane(float offset, float clipdirection) { + Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; m_activeVertexBuffer ^= 1; Vector2 *v2 = m_vertexBuffers[m_activeVertexBuffer]; v[m_numVertices] = v[0]; - float dy2, dy1 = offset - v[0].y; - int dy2in, dy1in = clipdirection * dy1 >= 0; - uint32_t p = 0; + float dy2, dy1 = offset - v[0].y; + int dy2in, dy1in = clipdirection * dy1 >= 0; + uint32_t p = 0; for (uint32_t k = 0; k < m_numVertices; k++) { - dy2 = offset - v[k + 1].y; + dy2 = offset - v[k + 1].y; dy2in = clipdirection * dy2 >= 0; - if (dy1in) v2[p++] = v[k]; - if ( dy1in + dy2in == 1 ) { // not both in/out + if (dy1in) + v2[p++] = v[k]; + if (dy1in + dy2in == 1) { // not both in/out float dx = v[k + 1].x - v[k].x; float dy = v[k + 1].y - v[k].y; v2[p++] = Vector2(v[k].x + dy1 * (dx / dy), offset); @@ -5218,20 +4458,20 @@ public: m_numVertices = p; } - void clipVerticalPlane(float offset, float clipdirection) - { - Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; + void clipVerticalPlane(float offset, float clipdirection) { + Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; m_activeVertexBuffer ^= 1; Vector2 *v2 = m_vertexBuffers[m_activeVertexBuffer]; v[m_numVertices] = v[0]; - float dx2, dx1 = offset - v[0].x; - int dx2in, dx1in = clipdirection * dx1 >= 0; - uint32_t p = 0; + float dx2, dx1 = offset - v[0].x; + int dx2in, dx1in = clipdirection * dx1 >= 0; + uint32_t p = 0; for (uint32_t k = 0; k < m_numVertices; k++) { dx2 = offset - v[k + 1].x; dx2in = clipdirection * dx2 >= 0; - if (dx1in) v2[p++] = v[k]; - if ( dx1in + dx2in == 1 ) { // not both in/out + if (dx1in) + v2[p++] = v[k]; + if (dx1in + dx2in == 1) { // not both in/out float dx = v[k + 1].x - v[k].x; float dy = v[k + 1].y - v[k].y; v2[p++] = Vector2(offset, v[k].y + dx1 * (dy / dx)); @@ -5242,9 +4482,8 @@ public: m_numVertices = p; } - void computeArea() - { - Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; + void computeArea() { + Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; v[m_numVertices] = v[0]; m_area = 0; float centroidx = 0, centroidy = 0; @@ -5258,8 +4497,7 @@ public: m_area = 0.5f * fabsf(m_area); } - void clipAABox(float x0, float y0, float x1, float y1) - { + void clipAABox(float x0, float y0, float x1, float y1) { clipVerticalPlane(x0, -1); clipHorizontalPlane(y0, -1); clipVerticalPlane(x1, 1); @@ -5267,8 +4505,7 @@ public: computeArea(); } - float area() const - { + float area() const { return m_area; } @@ -5285,10 +4522,9 @@ private: typedef bool (*SamplingCallback)(void *param, int x, int y); /// A triangle for rasterization. -struct Triangle -{ - Triangle(const Vector2 &_v0, const Vector2 &_v1, const Vector2 &_v2) : v1(_v0), v2(_v2), v3(_v1) - { +struct Triangle { + Triangle(const Vector2 &_v0, const Vector2 &_v1, const Vector2 &_v2) : + v1(_v0), v2(_v2), v3(_v1), n1(0.0f), n2(0.0f), n3(0.0f) { // make sure every triangle is front facing. flipBackface(); // Compute deltas. @@ -5296,8 +4532,7 @@ struct Triangle computeUnitInwardNormals(); } - bool isValid() - { + bool isValid() { const Vector2 e0 = v3 - v1; const Vector2 e1 = v2 - v1; const float area = e0.y * e1.x - e1.y * e0.x; @@ -5305,18 +4540,17 @@ struct Triangle } // extents has to be multiple of BK_SIZE!! - bool drawAA(const Vector2 &extents, SamplingCallback cb, void *param) - { - const float PX_INSIDE = 1.0f/sqrtf(2.0f); - const float PX_OUTSIDE = -1.0f/sqrtf(2.0f); + bool drawAA(const Vector2 &extents, SamplingCallback cb, void *param) { + const float PX_INSIDE = 1.0f / sqrtf(2.0f); + const float PX_OUTSIDE = -1.0f / sqrtf(2.0f); const float BK_SIZE = 8; - const float BK_INSIDE = sqrtf(BK_SIZE*BK_SIZE/2.0f); - const float BK_OUTSIDE = -sqrtf(BK_SIZE*BK_SIZE/2.0f); + const float BK_INSIDE = sqrtf(BK_SIZE * BK_SIZE / 2.0f); + const float BK_OUTSIDE = -sqrtf(BK_SIZE * BK_SIZE / 2.0f); // Bounding rectangle float minx = floorf(max(min3(v1.x, v2.x, v3.x), 0.0f)); float miny = floorf(max(min3(v1.y, v2.y, v3.y), 0.0f)); - float maxx = ceilf( min(max3(v1.x, v2.x, v3.x), extents.x - 1.0f)); - float maxy = ceilf( min(max3(v1.y, v2.y, v3.y), extents.y - 1.0f)); + float maxx = ceilf(min(max3(v1.x, v2.x, v3.x), extents.x - 1.0f)); + float maxy = ceilf(min(max3(v1.y, v2.y, v3.y), extents.y - 1.0f)); // There's no reason to align the blocks to the viewport, instead we align them to the origin of the triangle bounds. minx = floorf(minx); miny = floorf(miny); @@ -5341,9 +4575,10 @@ struct Triangle float bC = C2 + n2.x * xc + n2.y * yc; float cC = C3 + n3.x * xc + n3.y * yc; // Skip block when outside an edge - if ( (aC <= BK_OUTSIDE) || (bC <= BK_OUTSIDE) || (cC <= BK_OUTSIDE) ) continue; + if ((aC <= BK_OUTSIDE) || (bC <= BK_OUTSIDE) || (cC <= BK_OUTSIDE)) + continue; // Accept whole block when totally covered - if ( (aC >= BK_INSIDE) && (bC >= BK_INSIDE) && (cC >= BK_INSIDE) ) { + if ((aC >= BK_INSIDE) && (bC >= BK_INSIDE) && (cC >= BK_INSIDE)) { for (float y = y0; y < y0 + BK_SIZE; y++) { for (float x = x0; x < x0 + BK_SIZE; x++) { if (!cb(param, (int)x, (int)y)) @@ -5386,10 +4621,9 @@ struct Triangle } private: - void flipBackface() - { + void flipBackface() { // check if triangle is backfacing, if so, swap two vertices - if ( ((v3.x - v1.x) * (v2.y - v1.y) - (v3.y - v1.y) * (v2.x - v1.x)) < 0 ) { + if (((v3.x - v1.x) * (v2.y - v1.y) - (v3.y - v1.y) * (v2.x - v1.x)) < 0) { Vector2 hv = v1; v1 = v2; v2 = hv; // swap pos @@ -5397,8 +4631,7 @@ private: } // compute unit inward normals for each edge. - void computeUnitInwardNormals() - { + void computeUnitInwardNormals() { n1 = v1 - v2; n1 = Vector2(-n1.y, n1.x); n1 = n1 * (1.0f / sqrtf(dot(n1, n1))); @@ -5416,8 +4649,7 @@ private: }; // Process the given triangle. Returns false if rasterization was interrupted by the callback. -static bool drawTriangle(const Vector2 &extents, const Vector2 v[3], SamplingCallback cb, void *param) -{ +static bool drawTriangle(const Vector2 &extents, const Vector2 v[3], SamplingCallback cb, void *param) { Triangle tri(v[0], v[1], v[2]); // @@ It would be nice to have a conservative drawing mode that enlarges the triangle extents by one texel and is able to handle degenerate triangles. // @@ Maybe the simplest thing to do would be raster triangle edges. @@ -5432,22 +4664,19 @@ namespace segment { // - Insertion is o(n) // - Smallest element goes at the end, so that popping it is o(1). -struct CostQueue -{ - CostQueue(uint32_t size = UINT32_MAX) : m_maxSize(size), m_pairs(MemTag::SegmentAtlasChartCandidates) {} +struct CostQueue { + CostQueue(uint32_t size = UINT32_MAX) : + m_maxSize(size), m_pairs(MemTag::SegmentAtlasChartCandidates) {} - float peekCost() const - { + float peekCost() const { return m_pairs.back().cost; } - uint32_t peekFace() const - { + uint32_t peekFace() const { return m_pairs.back().face; } - void push(float cost, uint32_t face) - { + void push(float cost, uint32_t face) { const Pair p = { cost, face }; if (m_pairs.isEmpty() || cost < peekCost()) m_pairs.push_back(p); @@ -5464,29 +4693,25 @@ struct CostQueue } } - uint32_t pop() - { + uint32_t pop() { XA_DEBUG_ASSERT(!m_pairs.isEmpty()); uint32_t f = m_pairs.back().face; m_pairs.pop_back(); return f; } - XA_INLINE void clear() - { + XA_INLINE void clear() { m_pairs.clear(); } - XA_INLINE uint32_t count() const - { + XA_INLINE uint32_t count() const { return m_pairs.size(); } private: const uint32_t m_maxSize; - struct Pair - { + struct Pair { float cost; uint32_t face; }; @@ -5494,25 +4719,27 @@ private: Array<Pair> m_pairs; }; -struct AtlasData -{ +struct AtlasData { ChartOptions options; const Mesh *mesh = nullptr; Array<float> edgeDihedralAngles; Array<float> edgeLengths; Array<float> faceAreas; + Array<float> faceUvAreas; // Can be negative. Array<Vector3> faceNormals; BitArray isFaceInChart; - AtlasData() : edgeDihedralAngles(MemTag::SegmentAtlasMeshData), edgeLengths(MemTag::SegmentAtlasMeshData), faceAreas(MemTag::SegmentAtlasMeshData), faceNormals(MemTag::SegmentAtlasMeshData) {} + AtlasData() : + edgeDihedralAngles(MemTag::SegmentAtlasMeshData), edgeLengths(MemTag::SegmentAtlasMeshData), faceAreas(MemTag::SegmentAtlasMeshData), faceNormals(MemTag::SegmentAtlasMeshData) {} - void compute() - { + void compute() { const uint32_t faceCount = mesh->faceCount(); const uint32_t edgeCount = mesh->edgeCount(); edgeDihedralAngles.resize(edgeCount); edgeLengths.resize(edgeCount); faceAreas.resize(faceCount); + if (options.useInputMeshUvs) + faceUvAreas.resize(faceCount); faceNormals.resize(faceCount); isFaceInChart.resize(faceCount); isFaceInChart.zeroOutMemory(); @@ -5526,6 +4753,8 @@ struct AtlasData } faceAreas[f] = mesh->computeFaceArea(f); XA_DEBUG_ASSERT(faceAreas[f] > 0.0f); + if (options.useInputMeshUvs) + faceUvAreas[f] = mesh->computeFaceParametricArea(f); faceNormals[f] = mesh->computeFaceNormal(f); } for (uint32_t face = 0; face < faceCount; face++) { @@ -5543,19 +4772,109 @@ struct AtlasData } }; +// If MeshDecl::vertexUvData is set on input meshes, find charts by floodfilling faces in world/model space without crossing UV seams. +struct OriginalUvCharts { + OriginalUvCharts(AtlasData &data) : + m_data(data) {} + uint32_t chartCount() const { return m_charts.size(); } + const Basis &chartBasis(uint32_t chartIndex) const { return m_chartBasis[chartIndex]; } + + ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const { + const Chart &chart = m_charts[chartIndex]; + return ConstArrayView<uint32_t>(&m_chartFaces[chart.firstFace], chart.faceCount); + } + + void compute() { + m_charts.clear(); + m_chartFaces.clear(); + const Mesh *mesh = m_data.mesh; + const uint32_t faceCount = mesh->faceCount(); + for (uint32_t f = 0; f < faceCount; f++) { + if (m_data.isFaceInChart.get(f)) + continue; + if (isZero(m_data.faceUvAreas[f], kAreaEpsilon)) + continue; // Face must have valid UVs. + // Found an unassigned face, create a new chart. + Chart chart; + chart.firstFace = m_chartFaces.size(); + chart.faceCount = 1; + m_chartFaces.push_back(f); + m_data.isFaceInChart.set(f); + floodfillFaces(chart); + m_charts.push_back(chart); + } + // Compute basis for each chart. + m_chartBasis.resize(m_charts.size()); + for (uint32_t c = 0; c < m_charts.size(); c++) { + const Chart &chart = m_charts[c]; + m_tempPoints.resize(chart.faceCount * 3); + for (uint32_t f = 0; f < chart.faceCount; f++) { + const uint32_t face = m_chartFaces[chart.firstFace + f]; + for (uint32_t i = 0; i < 3; i++) + m_tempPoints[f * 3 + i] = m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + i)); + } + Fit::computeBasis(m_tempPoints, &m_chartBasis[c]); + } + } + +private: + struct Chart { + uint32_t firstFace, faceCount; + }; + + void floodfillFaces(Chart &chart) { + const bool isFaceAreaNegative = m_data.faceUvAreas[m_chartFaces[chart.firstFace]] < 0.0f; + for (;;) { + bool newFaceAdded = false; + const uint32_t faceCount = chart.faceCount; + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t sourceFace = m_chartFaces[chart.firstFace + f]; + for (Mesh::FaceEdgeIterator edgeIt(m_data.mesh, sourceFace); !edgeIt.isDone(); edgeIt.advance()) { + const uint32_t face = edgeIt.oppositeFace(); + if (face == UINT32_MAX) + continue; // Boundary edge. + if (m_data.isFaceInChart.get(face)) + continue; // Already assigned to a chart. + if (isZero(m_data.faceUvAreas[face], kAreaEpsilon)) + continue; // Face must have valid UVs. + if ((m_data.faceUvAreas[face] < 0.0f) != isFaceAreaNegative) + continue; // Face winding is opposite of the first chart face. + const Vector2 &uv0 = m_data.mesh->texcoord(edgeIt.vertex0()); + const Vector2 &uv1 = m_data.mesh->texcoord(edgeIt.vertex1()); + const Vector2 &ouv0 = m_data.mesh->texcoord(m_data.mesh->vertexAt(meshEdgeIndex0(edgeIt.oppositeEdge()))); + const Vector2 &ouv1 = m_data.mesh->texcoord(m_data.mesh->vertexAt(meshEdgeIndex1(edgeIt.oppositeEdge()))); + if (!equal(uv0, ouv1, m_data.mesh->epsilon()) || !equal(uv1, ouv0, m_data.mesh->epsilon())) + continue; // UVs must match exactly. + m_chartFaces.push_back(face); + chart.faceCount++; + m_data.isFaceInChart.set(face); + newFaceAdded = true; + } + } + if (!newFaceAdded) + break; + } + } + + AtlasData &m_data; + Array<Chart> m_charts; + Array<Basis> m_chartBasis; + Array<uint32_t> m_chartFaces; + Array<Vector3> m_tempPoints; +}; + #if XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS static uint32_t s_planarRegionsCurrentRegion; static uint32_t s_planarRegionsCurrentVertex; #endif -struct PlanarCharts -{ - PlanarCharts(AtlasData &data) : m_data(data), m_nextRegionFace(MemTag::SegmentAtlasPlanarRegions), m_faceToRegionId(MemTag::SegmentAtlasPlanarRegions) {} +struct PlanarCharts { + PlanarCharts(AtlasData &data) : + m_data(data), m_nextRegionFace(MemTag::SegmentAtlasPlanarRegions), m_faceToRegionId(MemTag::SegmentAtlasPlanarRegions) {} const Basis &chartBasis(uint32_t chartIndex) const { return m_chartBasis[chartIndex]; } uint32_t chartCount() const { return m_charts.size(); } - - ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const - { + + ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const { const Chart &chart = m_charts[chartIndex]; return ConstArrayView<uint32_t>(&m_chartFaces[chart.firstFace], chart.faceCount); } @@ -5564,8 +4883,7 @@ struct PlanarCharts uint32_t nextRegionFace(uint32_t face) const { return m_nextRegionFace[face]; } float regionArea(uint32_t region) const { return m_regionAreas[region]; } - void compute() - { + void compute() { const uint32_t faceCount = m_data.mesh->faceCount(); // Precompute regions of coplanar incident faces. m_regionFirstFace.clear(); @@ -5581,6 +4899,8 @@ struct PlanarCharts for (uint32_t f = 0; f < faceCount; f++) { if (m_nextRegionFace[f] != f) continue; // Already assigned. + if (m_data.isFaceInChart.get(f)) + continue; // Already in a chart. faceStack.clear(); faceStack.push_back(f); for (;;) { @@ -5595,6 +4915,8 @@ struct PlanarCharts continue; if (m_nextRegionFace[oface] != oface) continue; // Already assigned. + if (m_data.isFaceInChart.get(oface)) + continue; // Already in a chart. if (!equal(dot(m_data.faceNormals[face], m_data.faceNormals[oface]), 1.0f, kEpsilon)) continue; // Not coplanar. const uint32_t next = m_nextRegionFace[face]; @@ -5632,8 +4954,11 @@ struct PlanarCharts // Precompute planar region areas. m_regionAreas.resize(regionCount); m_regionAreas.zeroOutMemory(); - for (uint32_t f = 0; f < faceCount; f++) + for (uint32_t f = 0; f < faceCount; f++) { + if (m_faceToRegionId[f] == UINT32_MAX) + continue; m_regionAreas[m_faceToRegionId[f]] += m_data.faceAreas[f]; + } // Create charts from suitable planar regions. // The dihedral angle of all boundary edges must be >= 90 degrees. m_charts.clear(); @@ -5658,8 +4983,7 @@ struct PlanarCharts if (!createChart) break; face = m_nextRegionFace[face]; - } - while (face != firstRegionFace); + } while (face != firstRegionFace); // Create a chart. if (createChart) { Chart chart; @@ -5671,15 +4995,13 @@ struct PlanarCharts m_chartFaces.push_back(face); chart.faceCount++; face = m_nextRegionFace[face]; - } - while (face != firstRegionFace); + } while (face != firstRegionFace); m_charts.push_back(chart); } } // Compute basis for each chart using the first face normal (all faces have the same normal). m_chartBasis.resize(m_charts.size()); - for (uint32_t c = 0; c < m_charts.size(); c++) - { + for (uint32_t c = 0; c < m_charts.size(); c++) { const uint32_t face = m_chartFaces[m_charts[c].firstFace]; Basis &basis = m_chartBasis[c]; basis.normal = m_data.faceNormals[face]; @@ -5689,8 +5011,7 @@ struct PlanarCharts } private: - struct Chart - { + struct Chart { uint32_t firstFace, faceCount; }; @@ -5704,12 +5025,11 @@ private: Array<Basis> m_chartBasis; }; -struct ClusteredCharts -{ - ClusteredCharts(AtlasData &data, const PlanarCharts &planarCharts) : m_data(data), m_planarCharts(planarCharts), m_texcoords(MemTag::SegmentAtlasMeshData), m_bestTriangles(10), m_placingSeeds(false) {} +struct ClusteredCharts { + ClusteredCharts(AtlasData &data, const PlanarCharts &planarCharts) : + m_data(data), m_planarCharts(planarCharts), m_texcoords(MemTag::SegmentAtlasMeshData), m_bestTriangles(10), m_placingSeeds(false) {} - ~ClusteredCharts() - { + ~ClusteredCharts() { const uint32_t chartCount = m_charts.size(); for (uint32_t i = 0; i < chartCount; i++) { m_charts[i]->~Chart(); @@ -5721,8 +5041,7 @@ struct ClusteredCharts ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const { return m_charts[chartIndex]->faces; } const Basis &chartBasis(uint32_t chartIndex) const { return m_charts[chartIndex]->basis; } - void compute() - { + void compute() { const uint32_t faceCount = m_data.mesh->faceCount(); m_facesLeft = 0; for (uint32_t i = 0; i < faceCount; i++) { @@ -5768,9 +5087,9 @@ struct ClusteredCharts } private: - struct Chart - { - Chart() : faces(MemTag::SegmentAtlasChartFaces) {} + struct Chart { + Chart() : + faces(MemTag::SegmentAtlasChartFaces) {} int id = -1; Basis basis; // Best fit normal. @@ -5784,8 +5103,7 @@ private: uint32_t seed; }; - void placeSeeds(float threshold) - { + void placeSeeds(float threshold) { XA_PROFILE_START(clusteredChartsPlaceSeeds) m_placingSeeds = true; // Instead of using a predefiened number of seeds: @@ -5801,8 +5119,7 @@ private: } // Returns true if any of the charts can grow more. - void growCharts(float threshold) - { + void growCharts(float threshold) { XA_PROFILE_START(clusteredChartsGrow) for (;;) { if (m_facesLeft == 0) @@ -5848,8 +5165,7 @@ private: XA_PROFILE_END(clusteredChartsGrow) } - void resetCharts() - { + void resetCharts() { XA_PROFILE_START(clusteredChartsReset) const uint32_t faceCount = m_data.mesh->faceCount(); for (uint32_t i = 0; i < faceCount; i++) { @@ -5880,8 +5196,7 @@ private: XA_PROFILE_END(clusteredChartsReset) } - bool relocateSeeds() - { + bool relocateSeeds() { XA_PROFILE_START(clusteredChartsRelocateSeeds) bool anySeedChanged = false; const uint32_t chartCount = m_charts.size(); @@ -5894,8 +5209,7 @@ private: return anySeedChanged; } - void fillHoles(float threshold) - { + void fillHoles(float threshold) { XA_PROFILE_START(clusteredChartsFillHoles) while (m_facesLeft > 0) createChart(threshold); @@ -5903,8 +5217,7 @@ private: } #if XA_MERGE_CHARTS - void mergeCharts() - { + void mergeCharts() { XA_PROFILE_START(clusteredChartsMerge) const uint32_t chartCount = m_charts.size(); // Merge charts progressively until there's none left to merge. @@ -5964,7 +5277,7 @@ private: // Merge if chart2 has a single face. // chart1 must have more than 1 face. // chart2 area must be <= 10% of chart1 area. - if (m_sharedBoundaryLengthsNoSeams[cc] > 0.0f && chart->faces.size() > 1 && chart2->faces.size() == 1 && chart2->area <= chart->area * 0.1f) + if (m_sharedBoundaryLengthsNoSeams[cc] > 0.0f && chart->faces.size() > 1 && chart2->faces.size() == 1 && chart2->area <= chart->area * 0.1f) goto merge; // Merge if chart2 has two faces (probably a quad), and chart1 bounds at least 2 of its edges. if (chart2->faces.size() == 2 && m_sharedBoundaryEdgeCountNoSeams[cc] >= 2) @@ -5972,8 +5285,8 @@ private: // Merge if chart2 is wholely inside chart1, ignoring seams. if (m_sharedBoundaryLengthsNoSeams[cc] > 0.0f && equal(m_sharedBoundaryLengthsNoSeams[cc], chart2->boundaryLength, kEpsilon)) goto merge; - if (m_sharedBoundaryLengths[cc] > 0.2f * max(0.0f, chart->boundaryLength - externalBoundaryLength) || - m_sharedBoundaryLengths[cc] > 0.75f * chart2->boundaryLength) + if (m_sharedBoundaryLengths[cc] > 0.2f * max(0.0f, chart->boundaryLength - externalBoundaryLength) || + m_sharedBoundaryLengths[cc] > 0.75f * chart2->boundaryLength) goto merge; continue; merge: @@ -6011,8 +5324,7 @@ private: #endif private: - void createChart(float threshold) - { + void createChart(float threshold) { Chart *chart = XA_NEW(MemTag::Default, Chart); chart->id = (int)m_charts.size(); m_charts.push_back(chart); @@ -6043,15 +5355,13 @@ private: } } - bool isChartBoundaryEdge(const Chart *chart, uint32_t edge) const - { + bool isChartBoundaryEdge(const Chart *chart, uint32_t edge) const { const uint32_t oppositeEdge = m_data.mesh->oppositeEdge(edge); const uint32_t oppositeFace = meshEdgeFace(oppositeEdge); return oppositeEdge == UINT32_MAX || m_faceCharts[oppositeFace] != chart->id; } - bool computeChartBasis(Chart *chart, Basis *basis) - { + bool computeChartBasis(Chart *chart, Basis *basis) { const uint32_t faceCount = chart->faces.size(); m_tempPoints.resize(chart->faces.size() * 3); for (uint32_t i = 0; i < faceCount; i++) { @@ -6059,11 +5369,10 @@ private: for (uint32_t j = 0; j < 3; j++) m_tempPoints[i * 3 + j] = m_data.mesh->position(m_data.mesh->vertexAt(f * 3 + j)); } - return Fit::computeBasis(m_tempPoints.data(), m_tempPoints.size(), basis); + return Fit::computeBasis(m_tempPoints, basis); } - bool isFaceFlipped(uint32_t face) const - { + bool isFaceFlipped(uint32_t face) const { const Vector2 &v1 = m_texcoords[face * 3 + 0]; const Vector2 &v2 = m_texcoords[face * 3 + 1]; const Vector2 &v3 = m_texcoords[face * 3 + 2]; @@ -6071,8 +5380,7 @@ private: return parametricArea < 0.0f; } - void parameterizeChart(const Chart *chart) - { + void parameterizeChart(const Chart *chart) { const uint32_t faceCount = chart->faces.size(); for (uint32_t i = 0; i < faceCount; i++) { const uint32_t face = chart->faces[i]; @@ -6085,8 +5393,7 @@ private: } // m_faceCharts for the chart faces must be set to the chart ID. Needed to compute boundary edges. - bool isChartParameterizationValid(const Chart *chart) - { + bool isChartParameterizationValid(const Chart *chart) { const uint32_t faceCount = chart->faces.size(); // Check for flipped faces in the parameterization. OK if all are flipped. uint32_t flippedFaceCount = 0; @@ -6099,7 +5406,7 @@ private: // Check for boundary intersection in the parameterization. XA_PROFILE_START(clusteredChartsPlaceSeedsBoundaryIntersection) XA_PROFILE_START(clusteredChartsGrowBoundaryIntersection) - m_boundaryGrid.reset(m_texcoords.data()); + m_boundaryGrid.reset(m_texcoords); for (uint32_t i = 0; i < faceCount; i++) { const uint32_t f = chart->faces[i]; for (uint32_t j = 0; j < 3; j++) { @@ -6120,15 +5427,14 @@ private: return true; } - bool addFaceToChart(Chart *chart, uint32_t face) - { + bool addFaceToChart(Chart *chart, uint32_t face) { XA_DEBUG_ASSERT(!m_data.isFaceInChart.get(face)); const uint32_t oldFaceCount = chart->faces.size(); const bool firstFace = oldFaceCount == 0; // Append the face and any coplanar connected faces to the chart faces array. chart->faces.push_back(face); uint32_t coplanarFace = m_planarCharts.nextRegionFace(face); - while (coplanarFace != face) { + while (coplanarFace != face) { XA_DEBUG_ASSERT(!m_data.isFaceInChart.get(coplanarFace)); chart->faces.push_back(coplanarFace); coplanarFace = m_planarCharts.nextRegionFace(coplanarFace); @@ -6140,7 +5446,7 @@ private: // Use the first face normal. // Use any edge as the tangent vector. basis.normal = m_data.faceNormals[face]; - basis.tangent = normalize(m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + 0)) - m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + 1)), kEpsilon); + basis.tangent = normalize(m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + 0)) - m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + 1))); basis.bitangent = cross(basis.normal, basis.tangent); } else { // Use best fit normal. @@ -6199,8 +5505,7 @@ private: } // Returns true if the seed has changed. - bool relocateSeed(Chart *chart) - { + bool relocateSeed(Chart *chart) { // Find the first N triangles that fit the proxy best. const uint32_t faceCount = chart->faces.size(); m_bestTriangles.clear(); @@ -6230,8 +5535,7 @@ private: } // Cost is combined metrics * weights. - float computeCost(Chart *chart, uint32_t face) const - { + float computeCost(Chart *chart, uint32_t face) const { // Estimate boundary length and area: const float newChartArea = computeArea(chart, face); const float newBoundaryLength = computeBoundaryLength(chart, face); @@ -6267,28 +5571,25 @@ private: // Returns a value in [0-1]. // 0 if face normal is coplanar to the chart's best fit normal. // 1 if face normal is perpendicular. - float computeNormalDeviationMetric(Chart *chart, uint32_t face) const - { + float computeNormalDeviationMetric(Chart *chart, uint32_t face) const { // All faces in coplanar regions have the same normal, can use any face. const Vector3 faceNormal = m_data.faceNormals[face]; // Use plane fitting metric for now: return min(1.0f - dot(faceNormal, chart->basis.normal), 1.0f); // @@ normal deviations should be weighted by face area } - float computeRoundnessMetric(Chart *chart, float newBoundaryLength, float newChartArea) const - { + float computeRoundnessMetric(Chart *chart, float newBoundaryLength, float newChartArea) const { const float oldRoundness = square(chart->boundaryLength) / chart->area; const float newRoundness = square(newBoundaryLength) / newChartArea; return 1.0f - oldRoundness / newRoundness; } - float computeStraightnessMetric(Chart *chart, uint32_t firstFace) const - { + float computeStraightnessMetric(Chart *chart, uint32_t firstFace) const { float l_out = 0.0f; // Length of firstFace planar region boundary that doesn't border the chart. float l_in = 0.0f; // Length that does border the chart. const uint32_t planarRegionId = m_planarCharts.regionIdFromFace(firstFace); uint32_t face = firstFace; - for (;;) { + for (;;) { for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) { const float l = m_data.edgeLengths[it.edge()]; if (it.isBoundary()) { @@ -6305,7 +5606,6 @@ private: break; } #if 1 - XA_DEBUG_ASSERT(l_in != 0.0f); // Candidate face must be adjacent to chart. @@ This is not true if the input mesh has zero-length edges. float ratio = (l_out - l_in) / (l_out + l_in); return min(ratio, 0.0f); // Only use the straightness metric to close gaps. #else @@ -6313,8 +5613,7 @@ private: #endif } - bool isNormalSeam(uint32_t edge) const - { + bool isNormalSeam(uint32_t edge) const { const uint32_t oppositeEdge = m_data.mesh->oppositeEdge(edge); if (oppositeEdge == UINT32_MAX) return false; // boundary edge @@ -6334,11 +5633,10 @@ private: return !equal(m_data.faceNormals[f0], m_data.faceNormals[f1], kNormalEpsilon); } - float computeNormalSeamMetric(Chart *chart, uint32_t firstFace) const - { + float computeNormalSeamMetric(Chart *chart, uint32_t firstFace) const { float seamFactor = 0.0f, totalLength = 0.0f; uint32_t face = firstFace; - for (;;) { + for (;;) { for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) { if (it.isBoundary()) continue; @@ -6375,11 +5673,10 @@ private: return seamFactor / totalLength; } - float computeTextureSeamMetric(Chart *chart, uint32_t firstFace) const - { + float computeTextureSeamMetric(Chart *chart, uint32_t firstFace) const { float seamLength = 0.0f, totalLength = 0.0f; uint32_t face = firstFace; - for (;;) { + for (;;) { for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) { if (it.isBoundary()) continue; @@ -6402,11 +5699,10 @@ private: return seamLength / totalLength; } - float computeArea(Chart *chart, uint32_t firstFace) const - { + float computeArea(Chart *chart, uint32_t firstFace) const { float area = chart->area; uint32_t face = firstFace; - for (;;) { + for (;;) { area += m_data.faceAreas[face]; face = m_planarCharts.nextRegionFace(face); if (face == firstFace) @@ -6415,13 +5711,12 @@ private: return area; } - float computeBoundaryLength(Chart *chart, uint32_t firstFace) const - { + float computeBoundaryLength(Chart *chart, uint32_t firstFace) const { float boundaryLength = chart->boundaryLength; // Add new edges, subtract edges shared with the chart. const uint32_t planarRegionId = m_planarCharts.regionIdFromFace(firstFace); uint32_t face = firstFace; - for (;;) { + for (;;) { for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) { const float edgeLength = m_data.edgeLengths[it.edge()]; if (it.isBoundary()) { @@ -6437,11 +5732,10 @@ private: if (face == firstFace) break; } - return max(0.0f, boundaryLength); // @@ Hack! + return max(0.0f, boundaryLength); // @@ Hack! } - bool mergeChart(Chart *owner, Chart *chart, float sharedBoundaryLength) - { + bool mergeChart(Chart *owner, Chart *chart, float sharedBoundaryLength) { const uint32_t oldOwnerFaceCount = owner->faces.size(); const uint32_t chartFaceCount = chart->faces.size(); owner->faces.push_back(chart->faces); @@ -6499,33 +5793,53 @@ private: bool m_placingSeeds; }; -struct Atlas -{ - Atlas() : m_planarCharts(m_data), m_clusteredCharts(m_data, m_planarCharts) {} +struct ChartGeneratorType { + enum Enum { + OriginalUv, + Planar, + Clustered, + Piecewise + }; +}; - uint32_t chartCount() const - { - return m_planarCharts.chartCount() + m_clusteredCharts.chartCount(); +struct Atlas { + Atlas() : + m_originalUvCharts(m_data), m_planarCharts(m_data), m_clusteredCharts(m_data, m_planarCharts) {} + + uint32_t chartCount() const { + return m_originalUvCharts.chartCount() + m_planarCharts.chartCount() + m_clusteredCharts.chartCount(); } - ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const - { + ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const { + if (chartIndex < m_originalUvCharts.chartCount()) + return m_originalUvCharts.chartFaces(chartIndex); + chartIndex -= m_originalUvCharts.chartCount(); if (chartIndex < m_planarCharts.chartCount()) return m_planarCharts.chartFaces(chartIndex); chartIndex -= m_planarCharts.chartCount(); return m_clusteredCharts.chartFaces(chartIndex); } - const Basis &chartBasis(uint32_t chartIndex) const - { + const Basis &chartBasis(uint32_t chartIndex) const { + if (chartIndex < m_originalUvCharts.chartCount()) + return m_originalUvCharts.chartBasis(chartIndex); + chartIndex -= m_originalUvCharts.chartCount(); if (chartIndex < m_planarCharts.chartCount()) return m_planarCharts.chartBasis(chartIndex); chartIndex -= m_planarCharts.chartCount(); return m_clusteredCharts.chartBasis(chartIndex); } - void reset(const Mesh *mesh, const ChartOptions &options) - { + ChartGeneratorType::Enum chartGeneratorType(uint32_t chartIndex) const { + if (chartIndex < m_originalUvCharts.chartCount()) + return ChartGeneratorType::OriginalUv; + chartIndex -= m_originalUvCharts.chartCount(); + if (chartIndex < m_planarCharts.chartCount()) + return ChartGeneratorType::Planar; + return ChartGeneratorType::Clustered; + } + + void reset(const Mesh *mesh, const ChartOptions &options) { XA_PROFILE_START(buildAtlasInit) m_data.options = options; m_data.mesh = mesh; @@ -6533,8 +5847,12 @@ struct Atlas XA_PROFILE_END(buildAtlasInit) } - void compute() - { + void compute() { + if (m_data.options.useInputMeshUvs) { + XA_PROFILE_START(originalUvCharts) + m_originalUvCharts.compute(); + XA_PROFILE_END(originalUvCharts) + } XA_PROFILE_START(planarCharts) m_planarCharts.compute(); XA_PROFILE_END(planarCharts) @@ -6545,17 +5863,143 @@ struct Atlas private: AtlasData m_data; + OriginalUvCharts m_originalUvCharts; PlanarCharts m_planarCharts; ClusteredCharts m_clusteredCharts; }; +struct ComputeUvMeshChartsTaskArgs { + UvMesh *mesh; + Progress *progress; +}; + +// Charts are found by floodfilling faces without crossing UV seams. +struct ComputeUvMeshChartsTask { + ComputeUvMeshChartsTask(ComputeUvMeshChartsTaskArgs *args) : + m_mesh(args->mesh), m_progress(args->progress), m_uvToEdgeMap(MemTag::Default, m_mesh->indices.size()), m_faceAssigned(m_mesh->indices.size() / 3) {} + + void run() { + const uint32_t vertexCount = m_mesh->texcoords.size(); + const uint32_t indexCount = m_mesh->indices.size(); + const uint32_t faceCount = indexCount / 3; + // A vertex can only be assigned to one chart. + m_mesh->vertexToChartMap.resize(vertexCount); + m_mesh->vertexToChartMap.fill(UINT32_MAX); + // Map vertex UV to edge. Face is then edge / 3. + for (uint32_t i = 0; i < indexCount; i++) + m_uvToEdgeMap.add(m_mesh->texcoords[m_mesh->indices[i]]); + // Find charts. + m_faceAssigned.zeroOutMemory(); + for (uint32_t f = 0; f < faceCount; f++) { + if (m_progress->cancel) + return; + m_progress->increment(1); + // Found an unassigned face, see if it can be added. + const uint32_t chartIndex = m_mesh->charts.size(); + if (!canAddFaceToChart(chartIndex, f)) + continue; + // Face is OK, create a new chart with the face. + UvMeshChart *chart = XA_NEW(MemTag::Default, UvMeshChart); + m_mesh->charts.push_back(chart); + chart->material = m_mesh->faceMaterials.isEmpty() ? 0 : m_mesh->faceMaterials[f]; + addFaceToChart(chartIndex, f); + // Walk incident faces and assign them to the chart. + uint32_t f2 = 0; + for (;;) { + bool newFaceAssigned = false; + const uint32_t faceCount2 = chart->faces.size(); + for (; f2 < faceCount2; f2++) { + const uint32_t face = chart->faces[f2]; + for (uint32_t i = 0; i < 3; i++) { + // Add any valid faces with colocal UVs to the chart. + const Vector2 &uv = m_mesh->texcoords[m_mesh->indices[face * 3 + i]]; + uint32_t edge = m_uvToEdgeMap.get(uv); + while (edge != UINT32_MAX) { + const uint32_t newFace = edge / 3; + if (canAddFaceToChart(chartIndex, newFace)) { + addFaceToChart(chartIndex, newFace); + newFaceAssigned = true; + } + edge = m_uvToEdgeMap.getNext(uv, edge); + } + } + } + if (!newFaceAssigned) + break; + } + } + } + +private: + // The chart at chartIndex doesn't have to exist yet. + bool canAddFaceToChart(uint32_t chartIndex, uint32_t face) const { + if (m_faceAssigned.get(face)) + return false; // Already assigned to a chart. + if (m_mesh->faceIgnore.get(face)) + return false; // Face is ignored (zero area or nan UVs). + if (!m_mesh->faceMaterials.isEmpty() && chartIndex < m_mesh->charts.size()) { + if (m_mesh->faceMaterials[face] != m_mesh->charts[chartIndex]->material) + return false; // Materials don't match. + } + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = m_mesh->indices[face * 3 + i]; + if (m_mesh->vertexToChartMap[vertex] != UINT32_MAX && m_mesh->vertexToChartMap[vertex] != chartIndex) + return false; // Vertex already assigned to another chart. + } + return true; + } + + void addFaceToChart(uint32_t chartIndex, uint32_t face) { + UvMeshChart *chart = m_mesh->charts[chartIndex]; + m_faceAssigned.set(face); + chart->faces.push_back(face); + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = m_mesh->indices[face * 3 + i]; + m_mesh->vertexToChartMap[vertex] = chartIndex; + chart->indices.push_back(vertex); + } + } + + UvMesh *const m_mesh; + Progress *const m_progress; + HashMap<Vector2> m_uvToEdgeMap; // Face is edge / 3. + BitArray m_faceAssigned; +}; + +static void runComputeUvMeshChartsTask(void * /*groupUserData*/, void *taskUserData) { + XA_PROFILE_START(computeChartsThread) + ComputeUvMeshChartsTask task((ComputeUvMeshChartsTaskArgs *)taskUserData); + task.run(); + XA_PROFILE_END(computeChartsThread) +} + +static bool computeUvMeshCharts(TaskScheduler *taskScheduler, ArrayView<UvMesh *> meshes, ProgressFunc progressFunc, void *progressUserData) { + uint32_t totalFaceCount = 0; + for (uint32_t i = 0; i < meshes.length; i++) + totalFaceCount += meshes[i]->indices.size() / 3; + Progress progress(ProgressCategory::ComputeCharts, progressFunc, progressUserData, totalFaceCount); + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(nullptr, meshes.length); + Array<ComputeUvMeshChartsTaskArgs> taskArgs; + taskArgs.resize(meshes.length); + for (uint32_t i = 0; i < meshes.length; i++) { + ComputeUvMeshChartsTaskArgs &args = taskArgs[i]; + args.mesh = meshes[i]; + args.progress = &progress; + Task task; + task.userData = &args; + task.func = runComputeUvMeshChartsTask; + taskScheduler->run(taskGroup, task); + } + taskScheduler->wait(&taskGroup); + return !progress.cancel; +} + } // namespace segment namespace param { // Fast sweep in 3 directions -static bool findApproximateDiameterVertices(Mesh *mesh, uint32_t *a, uint32_t *b) -{ +static bool findApproximateDiameterVertices(Mesh *mesh, uint32_t *a, uint32_t *b) { XA_DEBUG_ASSERT(a != nullptr); XA_DEBUG_ASSERT(b != nullptr); const uint32_t vertexCount = mesh->vertexCount(); @@ -6612,10 +6056,9 @@ static bool findApproximateDiameterVertices(Mesh *mesh, uint32_t *a, uint32_t *b // From OpenNL LSCM example. // Computes the coordinates of the vertices of a triangle in a local 2D orthonormal basis of the triangle's plane. -static void projectTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector2 *z0, Vector2 *z1, Vector2 *z2, float epsilon) -{ - Vector3 X = normalize(p1 - p0, epsilon); - Vector3 Z = normalize(cross(X, p2 - p0), epsilon); +static void projectTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector2 *z0, Vector2 *z1, Vector2 *z2) { + Vector3 X = normalize(p1 - p0); + Vector3 Z = normalize(cross(X, p2 - p0)); Vector3 Y = cross(Z, X); Vector3 &O = p0; *z0 = Vector2(0, 0); @@ -6623,8 +6066,83 @@ static void projectTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector2 *z0, Vec *z2 = Vector2(dot(p2 - O, X), dot(p2 - O, Y)); } -static bool computeLeastSquaresConformalMap(Mesh *mesh) -{ +// Conformal relations from Brecht Van Lommel (based on ABF): + +static float vec_angle_cos(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3) { + Vector3 d1 = v1 - v2; + Vector3 d2 = v3 - v2; + return clamp(dot(d1, d2) / (length(d1) * length(d2)), -1.0f, 1.0f); +} + +static float vec_angle(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3) { + float dot = vec_angle_cos(v1, v2, v3); + return acosf(dot); +} + +static void triangle_angles(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, float *a1, float *a2, float *a3) { + *a1 = vec_angle(v3, v1, v2); + *a2 = vec_angle(v1, v2, v3); + *a3 = kPi - *a2 - *a1; +} + +static bool setup_abf_relations(opennl::NLContext *context, int id0, int id1, int id2, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2) { + // @@ IC: Wouldn't it be more accurate to return cos and compute 1-cos^2? + // It does indeed seem to be a little bit more robust. + // @@ Need to revisit this more carefully! + float a0, a1, a2; + triangle_angles(p0, p1, p2, &a0, &a1, &a2); + if (a0 == 0.0f || a1 == 0.0f || a2 == 0.0f) + return false; + float s0 = sinf(a0); + float s1 = sinf(a1); + float s2 = sinf(a2); + if (s1 > s0 && s1 > s2) { + swap(s1, s2); + swap(s0, s1); + swap(a1, a2); + swap(a0, a1); + swap(id1, id2); + swap(id0, id1); + } else if (s0 > s1 && s0 > s2) { + swap(s0, s2); + swap(s0, s1); + swap(a0, a2); + swap(a0, a1); + swap(id0, id2); + swap(id0, id1); + } + float c0 = cosf(a0); + float ratio = (s2 == 0.0f) ? 1.0f : s1 / s2; + float cosine = c0 * ratio; + float sine = s0 * ratio; + // Note : 2*id + 0 --> u + // 2*id + 1 --> v + int u0_id = 2 * id0 + 0; + int v0_id = 2 * id0 + 1; + int u1_id = 2 * id1 + 0; + int v1_id = 2 * id1 + 1; + int u2_id = 2 * id2 + 0; + int v2_id = 2 * id2 + 1; + // Real part + opennl::nlBegin(context, NL_ROW); + opennl::nlCoefficient(context, u0_id, cosine - 1.0f); + opennl::nlCoefficient(context, v0_id, -sine); + opennl::nlCoefficient(context, u1_id, -cosine); + opennl::nlCoefficient(context, v1_id, sine); + opennl::nlCoefficient(context, u2_id, 1); + opennl::nlEnd(context, NL_ROW); + // Imaginary part + opennl::nlBegin(context, NL_ROW); + opennl::nlCoefficient(context, u0_id, sine); + opennl::nlCoefficient(context, v0_id, cosine - 1.0f); + opennl::nlCoefficient(context, u1_id, -sine); + opennl::nlCoefficient(context, v1_id, -cosine); + opennl::nlCoefficient(context, v2_id, 1); + opennl::nlEnd(context, NL_ROW); + return true; +} + +static bool computeLeastSquaresConformalMap(Mesh *mesh) { uint32_t lockedVertex0, lockedVertex1; if (!findApproximateDiameterVertices(mesh, &lockedVertex0, &lockedVertex1)) { // Mesh has no boundaries. @@ -6635,55 +6153,57 @@ static bool computeLeastSquaresConformalMap(Mesh *mesh) opennl::nlSolverParameteri(context, NL_NB_VARIABLES, int(2 * vertexCount)); opennl::nlSolverParameteri(context, NL_MAX_ITERATIONS, int(5 * vertexCount)); opennl::nlBegin(context, NL_SYSTEM); - const Vector2 *texcoords = mesh->texcoords(); + ArrayView<Vector2> texcoords = mesh->texcoords(); for (uint32_t i = 0; i < vertexCount; i++) { opennl::nlSetVariable(context, 2 * i, texcoords[i].x); opennl::nlSetVariable(context, 2 * i + 1, texcoords[i].y); if (i == lockedVertex0 || i == lockedVertex1) { opennl::nlLockVariable(context, 2 * i); opennl::nlLockVariable(context, 2 * i + 1); - } + } } opennl::nlBegin(context, NL_MATRIX); const uint32_t faceCount = mesh->faceCount(); - const Vector3 *positions = mesh->positions(); - const uint32_t *indices = mesh->indices(); + ConstArrayView<Vector3> positions = mesh->positions(); + ConstArrayView<uint32_t> indices = mesh->indices(); for (uint32_t f = 0; f < faceCount; f++) { const uint32_t v0 = indices[f * 3 + 0]; const uint32_t v1 = indices[f * 3 + 1]; const uint32_t v2 = indices[f * 3 + 2]; - Vector2 z0, z1, z2; - projectTriangle(positions[v0], positions[v1], positions[v2], &z0, &z1, &z2, mesh->epsilon()); - double a = z1.x - z0.x; - double b = z1.y - z0.y; - double c = z2.x - z0.x; - double d = z2.y - z0.y; - XA_DEBUG_ASSERT(b == 0.0); - // Note : 2*id + 0 --> u - // 2*id + 1 --> v - uint32_t u0_id = 2 * v0; - uint32_t v0_id = 2 * v0 + 1; - uint32_t u1_id = 2 * v1; - uint32_t v1_id = 2 * v1 + 1; - uint32_t u2_id = 2 * v2; - uint32_t v2_id = 2 * v2 + 1; - // Note : b = 0 - // Real part - opennl::nlBegin(context, NL_ROW); - opennl::nlCoefficient(context, u0_id, -a+c) ; - opennl::nlCoefficient(context, v0_id, b-d) ; - opennl::nlCoefficient(context, u1_id, -c) ; - opennl::nlCoefficient(context, v1_id, d) ; - opennl::nlCoefficient(context, u2_id, a); - opennl::nlEnd(context, NL_ROW); - // Imaginary part - opennl::nlBegin(context, NL_ROW); - opennl::nlCoefficient(context, u0_id, -b+d); - opennl::nlCoefficient(context, v0_id, -a+c); - opennl::nlCoefficient(context, u1_id, -d); - opennl::nlCoefficient(context, v1_id, -c); - opennl::nlCoefficient(context, v2_id, a); - opennl::nlEnd(context, NL_ROW); + if (!setup_abf_relations(context, v0, v1, v2, positions[v0], positions[v1], positions[v2])) { + Vector2 z0, z1, z2; + projectTriangle(positions[v0], positions[v1], positions[v2], &z0, &z1, &z2); + double a = z1.x - z0.x; + double b = z1.y - z0.y; + double c = z2.x - z0.x; + double d = z2.y - z0.y; + XA_DEBUG_ASSERT(b == 0.0); + // Note : 2*id + 0 --> u + // 2*id + 1 --> v + uint32_t u0_id = 2 * v0; + uint32_t v0_id = 2 * v0 + 1; + uint32_t u1_id = 2 * v1; + uint32_t v1_id = 2 * v1 + 1; + uint32_t u2_id = 2 * v2; + uint32_t v2_id = 2 * v2 + 1; + // Note : b = 0 + // Real part + opennl::nlBegin(context, NL_ROW); + opennl::nlCoefficient(context, u0_id, -a + c); + opennl::nlCoefficient(context, v0_id, b - d); + opennl::nlCoefficient(context, u1_id, -c); + opennl::nlCoefficient(context, v1_id, d); + opennl::nlCoefficient(context, u2_id, a); + opennl::nlEnd(context, NL_ROW); + // Imaginary part + opennl::nlBegin(context, NL_ROW); + opennl::nlCoefficient(context, u0_id, -b + d); + opennl::nlCoefficient(context, v0_id, -a + c); + opennl::nlCoefficient(context, u1_id, -d); + opennl::nlCoefficient(context, v1_id, -c); + opennl::nlCoefficient(context, v2_id, a); + opennl::nlEnd(context, NL_ROW); + } } opennl::nlEnd(context, NL_MATRIX); opennl::nlEnd(context, NL_SYSTEM); @@ -6694,7 +6214,7 @@ static bool computeLeastSquaresConformalMap(Mesh *mesh) for (uint32_t i = 0; i < vertexCount; i++) { const double u = opennl::nlGetVariable(context, 2 * i); const double v = opennl::nlGetVariable(context, 2 * i + 1); - mesh->texcoord(i) = Vector2((float)u, (float)v); + texcoords[i] = Vector2((float)u, (float)v); XA_DEBUG_ASSERT(!isNan(mesh->texcoord(i).x)); XA_DEBUG_ASSERT(!isNan(mesh->texcoord(i).y)); } @@ -6702,30 +6222,26 @@ static bool computeLeastSquaresConformalMap(Mesh *mesh) return true; } -#if XA_RECOMPUTE_CHARTS -struct PiecewiseParam -{ - void reset(const Mesh *mesh, uint32_t faceCount) - { +struct PiecewiseParam { + void reset(const Mesh *mesh) { m_mesh = mesh; - m_faceCount = faceCount; + const uint32_t faceCount = m_mesh->faceCount(); const uint32_t vertexCount = m_mesh->vertexCount(); m_texcoords.resize(vertexCount); - m_patch.reserve(m_faceCount); - m_candidates.reserve(m_faceCount); - m_faceInAnyPatch.resize(m_faceCount); + m_patch.reserve(faceCount); + m_candidates.reserve(faceCount); + m_faceInAnyPatch.resize(faceCount); m_faceInAnyPatch.zeroOutMemory(); - m_faceInvalid.resize(m_faceCount); - m_faceInPatch.resize(m_faceCount); + m_faceInvalid.resize(faceCount); + m_faceInPatch.resize(faceCount); m_vertexInPatch.resize(vertexCount); - m_faceToCandidate.resize(m_faceCount); + m_faceToCandidate.resize(faceCount); } ConstArrayView<uint32_t> chartFaces() const { return m_patch; } - const Vector2 *texcoords() const { return m_texcoords.data(); } + ConstArrayView<Vector2> texcoords() const { return m_texcoords; } - bool computeChart() - { + bool computeChart() { // Clear per-patch state. m_patch.clear(); m_candidates.clear(); @@ -6734,8 +6250,9 @@ struct PiecewiseParam m_faceInPatch.zeroOutMemory(); m_vertexInPatch.zeroOutMemory(); // Add the seed face (first unassigned face) to the patch. + const uint32_t faceCount = m_mesh->faceCount(); uint32_t seed = UINT32_MAX; - for (uint32_t f = 0; f < m_faceCount; f++) { + for (uint32_t f = 0; f < faceCount; f++) { if (m_faceInAnyPatch.get(f)) continue; seed = f; @@ -6749,7 +6266,7 @@ struct PiecewiseParam } addFaceToPatch(seed); // Initialize the boundary grid. - m_boundaryGrid.reset(m_texcoords.data(), m_mesh->indices()); + m_boundaryGrid.reset(m_texcoords, m_mesh->indices()); for (Mesh::FaceEdgeIterator it(m_mesh, seed); !it.isDone(); it.advance()) m_boundaryGrid.append(it.edge()); break; @@ -6793,22 +6310,34 @@ struct PiecewiseParam break; } } + // Check for zero area and flipped faces (using area). + for (CandidateIterator it(bestCandidate); !it.isDone(); it.advance()) { + const Vector2 a = m_texcoords[m_mesh->vertexAt(it.current()->face * 3 + 0)]; + const Vector2 b = m_texcoords[m_mesh->vertexAt(it.current()->face * 3 + 1)]; + const Vector2 c = m_texcoords[m_mesh->vertexAt(it.current()->face * 3 + 2)]; + const float area = triangleArea(a, b, c); + if (area <= 0.0f) { + invalid = true; + break; + } + } // Check for boundary intersection. if (!invalid) { XA_PROFILE_START(parameterizeChartsPiecewiseBoundaryIntersection) // Test candidate edges that would form part of the new patch boundary. // Ignore boundary edges that would become internal if the candidate faces were added to the patch. - Array<uint32_t> newBoundaryEdges, ignoreEdges; + m_newBoundaryEdges.clear(); + m_ignoreBoundaryEdges.clear(); for (CandidateIterator candidateIt(bestCandidate); !candidateIt.isDone(); candidateIt.advance()) { for (Mesh::FaceEdgeIterator it(m_mesh, candidateIt.current()->face); !it.isDone(); it.advance()) { const uint32_t oface = it.oppositeFace(); - if (oface == UINT32_MAX || oface >= m_faceCount || !m_faceInPatch.get(oface)) - newBoundaryEdges.push_back(it.edge()); - if (oface != UINT32_MAX && oface < m_faceCount && m_faceInPatch.get(oface)) - ignoreEdges.push_back(it.oppositeEdge()); + if (oface == UINT32_MAX || !m_faceInPatch.get(oface)) + m_newBoundaryEdges.push_back(it.edge()); + if (oface != UINT32_MAX && m_faceInPatch.get(oface)) + m_ignoreBoundaryEdges.push_back(it.oppositeEdge()); } } - invalid = m_boundaryGrid.intersect(m_mesh->epsilon(), newBoundaryEdges, ignoreEdges); + invalid = m_boundaryGrid.intersect(m_mesh->epsilon(), m_newBoundaryEdges, m_ignoreBoundaryEdges); XA_PROFILE_END(parameterizeChartsPiecewiseBoundaryIntersection) } if (invalid) { @@ -6826,11 +6355,11 @@ struct PiecewiseParam removeLinkedCandidates(bestCandidate); // Reset the grid with all edges on the patch boundary. XA_PROFILE_START(parameterizeChartsPiecewiseBoundaryIntersection) - m_boundaryGrid.reset(m_texcoords.data(), m_mesh->indices()); + m_boundaryGrid.reset(m_texcoords, m_mesh->indices()); for (uint32_t i = 0; i < m_patch.size(); i++) { for (Mesh::FaceEdgeIterator it(m_mesh, m_patch[i]); !it.isDone(); it.advance()) { const uint32_t oface = it.oppositeFace(); - if (oface == UINT32_MAX || oface >= m_faceCount || !m_faceInPatch.get(oface)) + if (oface == UINT32_MAX || !m_faceInPatch.get(oface)) m_boundaryGrid.append(it.edge()); } } @@ -6841,8 +6370,7 @@ struct PiecewiseParam } private: - struct Candidate - { + struct Candidate { uint32_t face, vertex; Candidate *prev, *next; // The previous/next candidate with the same vertex. Vector2 position; @@ -6852,10 +6380,14 @@ private: float patchVertexOrient; }; - struct CandidateIterator - { - CandidateIterator(Candidate *head) : m_current(head) { XA_DEBUG_ASSERT(!head->prev); } - void advance() { if (m_current != nullptr) { m_current = m_current->next; } } + struct CandidateIterator { + CandidateIterator(Candidate *head) : + m_current(head) { XA_DEBUG_ASSERT(!head->prev); } + void advance() { + if (m_current != nullptr) { + m_current = m_current->next; + } + } bool isDone() const { return !m_current; } Candidate *current() { return m_current; } @@ -6864,7 +6396,6 @@ private: }; const Mesh *m_mesh; - uint32_t m_faceCount; Array<Vector2> m_texcoords; BitArray m_faceInAnyPatch; // Face is in a previous chart patch or the current patch. Array<Candidate *> m_candidates; // Incident faces to the patch. @@ -6873,9 +6404,9 @@ private: BitArray m_faceInPatch, m_vertexInPatch; // Face/vertex is in the current patch. BitArray m_faceInvalid; // Face cannot be added to the patch - flipped, cost too high or causes boundary intersection. UniformGrid2 m_boundaryGrid; + Array<uint32_t> m_newBoundaryEdges, m_ignoreBoundaryEdges; // Temp arrays used when testing for boundary intersection. - void addFaceToPatch(uint32_t face) - { + void addFaceToPatch(uint32_t face) { XA_DEBUG_ASSERT(!m_faceInPatch.get(face)); XA_DEBUG_ASSERT(!m_faceInAnyPatch.get(face)); m_patch.push_back(face); @@ -6884,7 +6415,7 @@ private: // Find new candidate faces on the patch incident to the newly added face. for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) { const uint32_t oface = it.oppositeFace(); - if (oface == UINT32_MAX || oface >= m_faceCount || m_faceInAnyPatch.get(oface) || m_faceToCandidate[oface]) + if (oface == UINT32_MAX || m_faceInAnyPatch.get(oface) || m_faceToCandidate[oface]) continue; // Found an active edge on the patch front. // Find the free vertex (the vertex that isn't on the active edge). @@ -6900,12 +6431,14 @@ private: } } XA_DEBUG_ASSERT(freeVertex != UINT32_MAX); - // If the free vertex is already in the patch, the face is enclosed by the patch. Add the face to the patch - don't need to assign texcoords. - /*if (m_vertexInPatch.get(freeVertex)) { + if (m_vertexInPatch.get(freeVertex)) { +#if 0 + // If the free vertex is already in the patch, the face is enclosed by the patch. Add the face to the patch - don't need to assign texcoords. freeVertex = UINT32_MAX; - addFaceToPatch(oface, false); + addFaceToPatch(oface); +#endif continue; - }*/ + } // Check this here rather than above so faces enclosed by the patch are always added. if (m_faceInvalid.get(oface)) continue; @@ -6913,8 +6446,7 @@ private: } } - void addCandidateFace(uint32_t patchEdge, float patchVertexOrient, uint32_t face, uint32_t edge, uint32_t freeVertex) - { + void addCandidateFace(uint32_t patchEdge, float patchVertexOrient, uint32_t face, uint32_t edge, uint32_t freeVertex) { XA_DEBUG_ASSERT(!m_faceToCandidate[face]); Vector2 texcoords[3]; orthoProjectFace(face, texcoords); @@ -6960,8 +6492,10 @@ private: uv.x = x + texcoords[localVertex0].x; uv.y = y + texcoords[localVertex0].y; } - if (isNan(texcoords[localFreeVertex].x) || isNan(texcoords[localFreeVertex].y)) + if (isNan(texcoords[localFreeVertex].x) || isNan(texcoords[localFreeVertex].y)) { + m_faceInvalid.set(face); return; + } // Check for local overlap (flipped triangle). // The patch face vertex that isn't on the active edge and the free vertex should be oriented on opposite sides to the active edge. const float freeVertexOrient = orientToEdge(m_texcoords[vertex0], m_texcoords[vertex1], texcoords[localFreeVertex]); @@ -6975,12 +6509,10 @@ private: return; } const float cost = fabsf(stretch - 1.0f); -#if 0 - if (cost > 0.25f) { + if (cost > 0.5f) { m_faceInvalid.set(face); return; } -#endif // Add the candidate. Candidate *candidate = XA_ALLOC(MemTag::Default, Candidate); candidate->face = face; @@ -7017,8 +6549,7 @@ private: it.current()->maxCost = maxCost; } - Candidate *linkedCandidateHead(Candidate *candidate) - { + Candidate *linkedCandidateHead(Candidate *candidate) { Candidate *current = candidate; for (;;) { if (!current->prev) @@ -7028,8 +6559,7 @@ private: return current; } - void removeLinkedCandidates(Candidate *head) - { + void removeLinkedCandidates(Candidate *head) { XA_DEBUG_ASSERT(!head->prev); Candidate *current = head; while (current) { @@ -7046,10 +6576,9 @@ private: } } - void orthoProjectFace(uint32_t face, Vector2 *texcoords) const - { - const Vector3 normal = m_mesh->computeFaceNormal(face); - const Vector3 tangent = normalize(m_mesh->position(m_mesh->vertexAt(face * 3 + 1)) - m_mesh->position(m_mesh->vertexAt(face * 3 + 0)), kEpsilon); + void orthoProjectFace(uint32_t face, Vector2 *texcoords) const { + const Vector3 normal = -m_mesh->computeFaceNormal(face); + const Vector3 tangent = normalize(m_mesh->position(m_mesh->vertexAt(face * 3 + 1)) - m_mesh->position(m_mesh->vertexAt(face * 3 + 0))); const Vector3 bitangent = cross(normal, tangent); for (uint32_t i = 0; i < 3; i++) { const Vector3 &pos = m_mesh->position(m_mesh->vertexAt(face * 3 + i)); @@ -7057,16 +6586,14 @@ private: } } - float parametricArea(const Vector2 *texcoords) const - { + float parametricArea(const Vector2 *texcoords) const { const Vector2 &v1 = texcoords[0]; const Vector2 &v2 = texcoords[1]; const Vector2 &v3 = texcoords[2]; return ((v2.x - v1.x) * (v3.y - v1.y) - (v3.x - v1.x) * (v2.y - v1.y)) * 0.5f; } - float computeStretch(Vector3 p1, Vector3 p2, Vector3 p3, Vector2 t1, Vector2 t2, Vector2 t3) const - { + float computeStretch(Vector3 p1, Vector3 p2, Vector3 p3, Vector2 t1, Vector2 t2, Vector2 t3) const { float parametricArea = ((t2.y - t1.y) * (t3.x - t1.x) - (t3.y - t1.y) * (t2.x - t1.x)) * 0.5f; if (isZero(parametricArea, kAreaEpsilon)) return FLT_MAX; @@ -7080,16 +6607,13 @@ private: } // Return value is positive if the point is one side of the edge, negative if on the other side. - float orientToEdge(Vector2 edgeVertex0, Vector2 edgeVertex1, Vector2 point) const - { + float orientToEdge(Vector2 edgeVertex0, Vector2 edgeVertex1, Vector2 point) const { return (edgeVertex0.x - point.x) * (edgeVertex1.y - point.y) - (edgeVertex0.y - point.y) * (edgeVertex1.x - point.x); } }; -#endif // Estimate quality of existing parameterization. -struct Quality -{ +struct Quality { // computeBoundaryIntersection bool boundaryIntersection = false; @@ -7106,8 +6630,7 @@ struct Quality float conformalMetric = 0.0f; float authalicMetric = 0.0f; - void computeBoundaryIntersection(const Mesh *mesh, UniformGrid2 &boundaryGrid) - { + void computeBoundaryIntersection(const Mesh *mesh, UniformGrid2 &boundaryGrid) { const Array<uint32_t> &boundaryEdges = mesh->boundaryEdges(); const uint32_t boundaryEdgeCount = boundaryEdges.size(); boundaryGrid.reset(mesh->texcoords(), mesh->indices(), boundaryEdgeCount); @@ -7123,11 +6646,11 @@ struct Quality #endif } - void computeFlippedFaces(const Mesh *mesh, uint32_t faceCount, Array<uint32_t> *flippedFaces) - { + void computeFlippedFaces(const Mesh *mesh, Array<uint32_t> *flippedFaces) { totalTriangleCount = flippedTriangleCount = zeroAreaTriangleCount = 0; if (flippedFaces) flippedFaces->clear(); + const uint32_t faceCount = mesh->faceCount(); for (uint32_t f = 0; f < faceCount; f++) { Vector2 texcoord[3]; for (int i = 0; i < 3; i++) { @@ -7159,8 +6682,7 @@ struct Quality flippedFaces->clear(); flippedTriangleCount = 0; } - if (flippedTriangleCount > totalTriangleCount / 2) - { + if (flippedTriangleCount > totalTriangleCount / 2) { // If more than half the triangles are flipped, reverse the flipped / not flipped classification. flippedTriangleCount = totalTriangleCount - flippedTriangleCount; if (flippedFaces) { @@ -7182,10 +6704,10 @@ struct Quality } } - void computeMetrics(const Mesh *mesh, uint32_t faceCount) - { + void computeMetrics(const Mesh *mesh) { totalGeometricArea = totalParametricArea = 0.0f; stretchMetric = maxStretchMetric = conformalMetric = authalicMetric = 0.0f; + const uint32_t faceCount = mesh->faceCount(); for (uint32_t f = 0; f < faceCount; f++) { Vector3 pos[3]; Vector2 texcoord[3]; @@ -7214,7 +6736,7 @@ struct Quality const float a = dot(Ss, Ss); // E const float b = dot(Ss, St); // F const float c = dot(St, St); // G - // Compute eigen-values of the first fundamental form: + // Compute eigen-values of the first fundamental form: const float sigma1 = sqrtf(0.5f * max(0.0f, a + c - sqrtf(square(a - c) + 4 * square(b)))); // gamma uppercase, min eigenvalue. const float sigma2 = sqrtf(0.5f * max(0.0f, a + c + sqrtf(square(a - c) + 4 * square(b)))); // gamma lowercase, max eigenvalue. XA_ASSERT(sigma2 > sigma1 || equal(sigma1, sigma2, kEpsilon)); @@ -7245,347 +6767,261 @@ struct Quality if (totalGeometricArea > 0.0f) { const float normFactor = sqrtf(totalParametricArea / totalGeometricArea); stretchMetric = sqrtf(stretchMetric / totalGeometricArea) * normFactor; - maxStretchMetric *= normFactor; + maxStretchMetric *= normFactor; conformalMetric = sqrtf(conformalMetric / totalGeometricArea); authalicMetric = sqrtf(authalicMetric / totalGeometricArea); } } }; -struct ChartWarningFlags -{ - enum Enum - { - CloseHolesFailed = 1<<1, - FixTJunctionsDuplicatedEdge = 1<<2, - FixTJunctionsFailed = 1<<3, - TriangulateDuplicatedEdge = 1<<4, - }; -}; - -struct ChartCtorBuffers -{ +struct ChartCtorBuffers { Array<uint32_t> chartMeshIndices; Array<uint32_t> unifiedMeshIndices; - Array<uint32_t> boundaryLoops; }; -class Chart -{ +class Chart { public: - Chart(ChartCtorBuffers &buffers, const ParameterizeOptions &options, const Basis &basis, ConstArrayView<uint32_t> faces, const Mesh *sourceMesh, uint32_t chartGroupId, uint32_t chartId) : m_basis(basis), m_mesh(nullptr), m_unifiedMesh(nullptr), m_unmodifiedUnifiedMesh(nullptr), m_type(ChartType::LSCM), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0), m_isInvalid(false) - { + Chart(const Basis &basis, segment::ChartGeneratorType::Enum generatorType, ConstArrayView<uint32_t> faces, const Mesh *sourceMesh, uint32_t chartGroupId, uint32_t chartId) : + m_basis(basis), m_unifiedMesh(nullptr), m_type(ChartType::LSCM), m_generatorType(generatorType), m_tjunctionCount(0), m_originalVertexCount(0), m_isInvalid(false) { XA_UNUSED(chartGroupId); XA_UNUSED(chartId); m_faceToSourceFaceMap.copyFrom(faces.data, faces.length); const uint32_t approxVertexCount = min(faces.length * 3, sourceMesh->vertexCount()); - m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), approxVertexCount, faces.length); m_unifiedMesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), approxVertexCount, faces.length); HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToUnifiedVertexMap(MemTag::Mesh, approxVertexCount), sourceVertexToChartVertexMap(MemTag::Mesh, approxVertexCount); - // Add vertices. - const uint32_t faceCount = m_initialFaceCount = faces.length; + m_originalIndices.resize(faces.length * 3); + // Add geometry. + const uint32_t faceCount = faces.length; for (uint32_t f = 0; f < faceCount; f++) { + uint32_t unifiedIndices[3]; for (uint32_t i = 0; i < 3; i++) { const uint32_t sourceVertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i); - const uint32_t sourceUnifiedVertex = sourceMesh->firstColocal(sourceVertex); + uint32_t sourceUnifiedVertex = sourceMesh->firstColocalVertex(sourceVertex); + if (m_generatorType == segment::ChartGeneratorType::OriginalUv && sourceVertex != sourceUnifiedVertex) { + // Original UVs: don't unify vertices with different UVs; we want to preserve UVs. + if (!equal(sourceMesh->texcoord(sourceVertex), sourceMesh->texcoord(sourceUnifiedVertex), sourceMesh->epsilon())) + sourceUnifiedVertex = sourceVertex; + } uint32_t unifiedVertex = sourceVertexToUnifiedVertexMap.get(sourceUnifiedVertex); if (unifiedVertex == UINT32_MAX) { unifiedVertex = sourceVertexToUnifiedVertexMap.add(sourceUnifiedVertex); - m_unifiedMesh->addVertex(sourceMesh->position(sourceVertex)); + m_unifiedMesh->addVertex(sourceMesh->position(sourceVertex), Vector3(0.0f), sourceMesh->texcoord(sourceVertex)); } if (sourceVertexToChartVertexMap.get(sourceVertex) == UINT32_MAX) { sourceVertexToChartVertexMap.add(sourceVertex); m_vertexToSourceVertexMap.push_back(sourceVertex); m_chartVertexToUnifiedVertexMap.push_back(unifiedVertex); - m_mesh->addVertex(sourceMesh->position(sourceVertex), Vector3(0.0f), sourceMesh->texcoord(sourceVertex)); + m_originalVertexCount++; } - } - } - // Add faces. - for (uint32_t f = 0; f < faceCount; f++) { - uint32_t indices[3], unifiedIndices[3]; - for (uint32_t i = 0; i < 3; i++) { - const uint32_t sourceVertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i); - const uint32_t sourceUnifiedVertex = sourceMesh->firstColocal(sourceVertex); - indices[i] = sourceVertexToChartVertexMap.get(sourceVertex); - XA_DEBUG_ASSERT(indices[i] != UINT32_MAX); + m_originalIndices[f * 3 + i] = sourceVertexToChartVertexMap.get(sourceVertex); + ; + XA_DEBUG_ASSERT(m_originalIndices[f * 3 + i] != UINT32_MAX); unifiedIndices[i] = sourceVertexToUnifiedVertexMap.get(sourceUnifiedVertex); XA_DEBUG_ASSERT(unifiedIndices[i] != UINT32_MAX); } - Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices); - XA_UNUSED(result); - XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); -#if XA_DEBUG - // Unifying colocals may create degenerate edges. e.g. if two triangle vertices are colocal. - for (int i = 0; i < 3; i++) { - const uint32_t index1 = unifiedIndices[i]; - const uint32_t index2 = unifiedIndices[(i + 1) % 3]; - XA_DEBUG_ASSERT(index1 != index2); - } -#endif - result = m_unifiedMesh->addFace(unifiedIndices); - XA_UNUSED(result); - XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); + m_unifiedMesh->addFace(unifiedIndices); } - m_mesh->createBoundaries(); // For AtlasPacker::computeBoundingBox - m_mesh->destroyEdgeMap(); // Only needed it for createBoundaries. m_unifiedMesh->createBoundaries(); - if (meshIsPlanar(*m_unifiedMesh)) { + if (m_generatorType == segment::ChartGeneratorType::Planar) { m_type = ChartType::Planar; return; } - m_unifiedMesh->linkBoundaries(); -#if XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION - m_unifiedMesh->writeObjFile("debug_before_fix_tjunction.obj"); -#endif - bool duplicatedEdge = false, failed = false; - if (options.fixTJunctions) { - XA_PROFILE_START(fixChartMeshTJunctions) - Mesh *fixedUnifiedMesh = meshFixTJunctions(*m_unifiedMesh, &duplicatedEdge, &failed, &m_fixedTJunctionsCount); - XA_PROFILE_END(fixChartMeshTJunctions) - if (fixedUnifiedMesh) { - if (duplicatedEdge) - m_warningFlags |= ChartWarningFlags::FixTJunctionsDuplicatedEdge; - if (failed) - m_warningFlags |= ChartWarningFlags::FixTJunctionsFailed; - m_unmodifiedUnifiedMesh = m_unifiedMesh; - m_unifiedMesh = fixedUnifiedMesh; - m_unifiedMesh->createBoundaries(); - m_unifiedMesh->linkBoundaries(); - m_initialFaceCount = m_unifiedMesh->faceCount(); // Fixing t-junctions rewrites faces. - } - } - if (options.closeHoles) { - // See if there are any holes that need closing. - Array<uint32_t> &boundaryLoops = buffers.boundaryLoops; - meshGetBoundaryLoops(*m_unifiedMesh, boundaryLoops); - if (boundaryLoops.size() > 1) { -#if XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR - const uint32_t faceCountBeforeHolesClosed = m_unifiedMesh->faceCount(); +#if XA_CHECK_T_JUNCTIONS + m_tjunctionCount = meshCheckTJunctions(*m_unifiedMesh); +#if XA_DEBUG_EXPORT_OBJ_TJUNCTION + if (m_tjunctionCount > 0) { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_tjunction.obj", sourceMesh->id(), chartGroupId, chartId); + m_unifiedMesh->writeObjFile(filename); + } #endif - // Closing the holes is not always the best solution and does not fix all the problems. - // We need to do some analysis of the holes and the genus to: - // - Find cuts that reduce genus. - // - Find cuts to connect holes. - // - Use minimal spanning trees or seamster. - XA_PROFILE_START(closeChartMeshHoles) - uint32_t holeCount = 0; -#if XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR - Array<uint32_t> holeFaceCounts; - failed = !meshCloseHoles(m_unifiedMesh, boundaryLoops, m_basis.normal, &holeFaceCounts); -#else - failed = !meshCloseHoles(m_unifiedMesh, boundaryLoops, m_basis.normal, &holeCount, nullptr); #endif - XA_PROFILE_END(closeChartMeshHoles) - m_unifiedMesh->createBoundaries(); - m_unifiedMesh->linkBoundaries(); - meshGetBoundaryLoops(*m_unifiedMesh, boundaryLoops); - if (failed || boundaryLoops.size() > 1) - m_warningFlags |= ChartWarningFlags::CloseHolesFailed; - m_closedHolesCount = holeCount; -#if XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR - if (m_warningFlags & ChartWarningFlags::CloseHolesFailed) { - char filename[256]; - XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_close_holes_error.obj", sourceMesh->id(), chartGroupId, chartId); - FILE *file; - XA_FOPEN(file, filename, "w"); - if (file) { - m_unifiedMesh->writeObjVertices(file); - fprintf(file, "s off\n"); - fprintf(file, "o object\n"); - for (uint32_t i = 0; i < faceCountBeforeHolesClosed; i++) - m_unifiedMesh->writeObjFace(file, i); - uint32_t face = faceCountBeforeHolesClosed; - for (uint32_t i = 0; i < holeFaceCounts.size(); i++) { - fprintf(file, "s off\n"); - fprintf(file, "o hole%u\n", i); - for (uint32_t j = 0; j < holeFaceCounts[i]; j++) { - m_unifiedMesh->writeObjFace(file, face); - face++; - } - } - m_unifiedMesh->writeObjBoundaryEges(file); - m_unifiedMesh->writeObjLinkedBoundaries(file); - fclose(file); - } - } -#endif - } - } } -#if XA_RECOMPUTE_CHARTS - Chart(ChartCtorBuffers &buffers, const Chart *parent, const Mesh *parentMesh, ConstArrayView<uint32_t> faces, const Vector2 *texcoords, const Mesh *sourceMesh) : m_mesh(nullptr), m_unifiedMesh(nullptr), m_unmodifiedUnifiedMesh(nullptr), m_type(ChartType::Piecewise), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0), m_isInvalid(false) - { - const uint32_t faceCount = m_initialFaceCount = faces.length; + Chart(ChartCtorBuffers &buffers, const Chart *parent, const Mesh *parentMesh, ConstArrayView<uint32_t> faces, ConstArrayView<Vector2> texcoords, const Mesh *sourceMesh) : + m_unifiedMesh(nullptr), m_type(ChartType::Piecewise), m_generatorType(segment::ChartGeneratorType::Piecewise), m_tjunctionCount(0), m_originalVertexCount(0), m_isInvalid(false) { + const uint32_t faceCount = faces.length; m_faceToSourceFaceMap.resize(faceCount); for (uint32_t i = 0; i < faceCount; i++) m_faceToSourceFaceMap[i] = parent->m_faceToSourceFaceMap[faces[i]]; // Map faces to parent chart source mesh. // Copy face indices. - m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), m_faceToSourceFaceMap.size() * 3, m_faceToSourceFaceMap.size()); Array<uint32_t> &chartMeshIndices = buffers.chartMeshIndices; chartMeshIndices.resize(sourceMesh->vertexCount()); chartMeshIndices.fillBytes(0xff); + m_unifiedMesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), m_faceToSourceFaceMap.size() * 3, m_faceToSourceFaceMap.size()); + HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToUnifiedVertexMap(MemTag::Mesh, m_faceToSourceFaceMap.size() * 3); // Add vertices. for (uint32_t f = 0; f < faceCount; f++) { for (uint32_t i = 0; i < 3; i++) { const uint32_t vertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i); + const uint32_t sourceUnifiedVertex = sourceMesh->firstColocalVertex(vertex); const uint32_t parentVertex = parentMesh->vertexAt(faces[f] * 3 + i); - if (chartMeshIndices[vertex] == (uint32_t)~0) { - chartMeshIndices[vertex] = m_mesh->vertexCount(); + uint32_t unifiedVertex = sourceVertexToUnifiedVertexMap.get(sourceUnifiedVertex); + if (unifiedVertex == UINT32_MAX) { + unifiedVertex = sourceVertexToUnifiedVertexMap.add(sourceUnifiedVertex); + m_unifiedMesh->addVertex(sourceMesh->position(vertex), Vector3(0.0f), texcoords[parentVertex]); + } + if (chartMeshIndices[vertex] == UINT32_MAX) { + chartMeshIndices[vertex] = m_originalVertexCount; + m_originalVertexCount++; m_vertexToSourceVertexMap.push_back(vertex); - m_mesh->addVertex(sourceMesh->position(vertex), Vector3(0.0f), texcoords[parentVertex]); + m_chartVertexToUnifiedVertexMap.push_back(unifiedVertex); } } } // Add faces. + m_originalIndices.resize(faceCount * 3); for (uint32_t f = 0; f < faceCount; f++) { - uint32_t indices[3]; + uint32_t unifiedIndices[3]; for (uint32_t i = 0; i < 3; i++) { const uint32_t vertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i); - indices[i] = chartMeshIndices[vertex]; + m_originalIndices[f * 3 + i] = chartMeshIndices[vertex]; + const uint32_t unifiedVertex = sourceMesh->firstColocalVertex(vertex); + unifiedIndices[i] = sourceVertexToUnifiedVertexMap.get(unifiedVertex); } - Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices); - XA_UNUSED(result); - XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); + m_unifiedMesh->addFace(unifiedIndices); } - m_mesh->createBoundaries(); // For AtlasPacker::computeBoundingBox - m_mesh->destroyEdgeMap(); // Only needed it for createBoundaries. + m_unifiedMesh->createBoundaries(); // Need to store texcoords for backup/restore so packing can be run multiple times. backupTexcoords(); } -#endif - ~Chart() - { - if (m_mesh) { - m_mesh->~Mesh(); - XA_FREE(m_mesh); + ~Chart() { + if (m_unifiedMesh) { + m_unifiedMesh->~Mesh(); + XA_FREE(m_unifiedMesh); + m_unifiedMesh = nullptr; } - destroyUnifiedMesh(); } bool isInvalid() const { return m_isInvalid; } - ChartType::Enum type() const { return m_type; } - uint32_t warningFlags() const { return m_warningFlags; } - uint32_t closedHolesCount() const { return m_closedHolesCount; } - uint32_t fixedTJunctionsCount() const { return m_fixedTJunctionsCount; } + ChartType type() const { return m_type; } + segment::ChartGeneratorType::Enum generatorType() const { return m_generatorType; } + uint32_t tjunctionCount() const { return m_tjunctionCount; } const Quality &quality() const { return m_quality; } - uint32_t initialFaceCount() const { return m_initialFaceCount; } #if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION const Array<uint32_t> ¶mFlippedFaces() const { return m_paramFlippedFaces; } #endif uint32_t mapFaceToSourceFace(uint32_t i) const { return m_faceToSourceFaceMap[i]; } uint32_t mapChartVertexToSourceVertex(uint32_t i) const { return m_vertexToSourceVertexMap[i]; } - const Mesh *mesh() const { return m_mesh; } - Mesh *mesh() { return m_mesh; } const Mesh *unifiedMesh() const { return m_unifiedMesh; } - const Mesh *unmodifiedUnifiedMesh() const { return m_unmodifiedUnifiedMesh; } + Mesh *unifiedMesh() { return m_unifiedMesh; } - void parameterize(const ParameterizeOptions &options, UniformGrid2 &boundaryGrid) - { - XA_PROFILE_START(parameterizeChartsOrthogonal) - { + // Vertex count of the chart mesh before unifying vertices. + uint32_t originalVertexCount() const { return m_originalVertexCount; } + + uint32_t originalVertexToUnifiedVertex(uint32_t v) const { return m_chartVertexToUnifiedVertexMap[v]; } + + ConstArrayView<uint32_t> originalVertices() const { return m_originalIndices; } + + void parameterize(const ChartOptions &options, UniformGrid2 &boundaryGrid) { + const uint32_t unifiedVertexCount = m_unifiedMesh->vertexCount(); + if (m_generatorType == segment::ChartGeneratorType::OriginalUv) { + } else { // Project vertices to plane. - const uint32_t vertexCount = m_unifiedMesh->vertexCount(); - for (uint32_t i = 0; i < vertexCount; i++) + XA_PROFILE_START(parameterizeChartsOrthogonal) + for (uint32_t i = 0; i < unifiedVertexCount; i++) m_unifiedMesh->texcoord(i) = Vector2(dot(m_basis.tangent, m_unifiedMesh->position(i)), dot(m_basis.bitangent, m_unifiedMesh->position(i))); - } - XA_PROFILE_END(parameterizeChartsOrthogonal) - // Computing charts checks for flipped triangles and boundary intersection. Don't need to do that again here if chart is planar. - if (m_type != ChartType::Planar) { - XA_PROFILE_START(parameterizeChartsEvaluateQuality) - m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid); - m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, nullptr); - m_quality.computeMetrics(m_unifiedMesh, m_initialFaceCount); - XA_PROFILE_END(parameterizeChartsEvaluateQuality) - // Use orthogonal parameterization if quality is acceptable. - if (!m_quality.boundaryIntersection && m_quality.flippedTriangleCount == 0 && m_quality.totalGeometricArea > 0.0f && m_quality.stretchMetric <= 1.1f && m_quality.maxStretchMetric <= 1.25f) - m_type = ChartType::Ortho; - } - if (m_type == ChartType::LSCM) { - XA_PROFILE_START(parameterizeChartsLSCM) - if (options.func) { - options.func(&m_unifiedMesh->position(0).x, &m_unifiedMesh->texcoord(0).x, m_unifiedMesh->vertexCount(), m_unifiedMesh->indices(), m_unifiedMesh->indexCount()); - } - else - computeLeastSquaresConformalMap(m_unifiedMesh); - XA_PROFILE_END(parameterizeChartsLSCM) - XA_PROFILE_START(parameterizeChartsEvaluateQuality) - m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid); + XA_PROFILE_END(parameterizeChartsOrthogonal) + // Computing charts checks for flipped triangles and boundary intersection. Don't need to do that again here if chart is planar. + if (m_type != ChartType::Planar && m_generatorType != segment::ChartGeneratorType::OriginalUv) { + XA_PROFILE_START(parameterizeChartsEvaluateQuality) + m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid); + m_quality.computeFlippedFaces(m_unifiedMesh, nullptr); + m_quality.computeMetrics(m_unifiedMesh); + XA_PROFILE_END(parameterizeChartsEvaluateQuality) + // Use orthogonal parameterization if quality is acceptable. + if (!m_quality.boundaryIntersection && m_quality.flippedTriangleCount == 0 && m_quality.zeroAreaTriangleCount == 0 && m_quality.totalGeometricArea > 0.0f && m_quality.stretchMetric <= 1.1f && m_quality.maxStretchMetric <= 1.25f) + m_type = ChartType::Ortho; + } + if (m_type == ChartType::LSCM) { + XA_PROFILE_START(parameterizeChartsLSCM) + if (options.paramFunc) { + options.paramFunc(&m_unifiedMesh->position(0).x, &m_unifiedMesh->texcoord(0).x, m_unifiedMesh->vertexCount(), m_unifiedMesh->indices().data, m_unifiedMesh->indexCount()); + } else + computeLeastSquaresConformalMap(m_unifiedMesh); + XA_PROFILE_END(parameterizeChartsLSCM) + XA_PROFILE_START(parameterizeChartsEvaluateQuality) + m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid); #if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION - m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, &m_paramFlippedFaces); + m_quality.computeFlippedFaces(m_unifiedMesh, &m_paramFlippedFaces); #else - m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, nullptr); + m_quality.computeFlippedFaces(m_unifiedMesh, nullptr); #endif - // Don't need to call computeMetrics here, that's only used in evaluateOrthoQuality to determine if quality is acceptable enough to use ortho projection. - if (m_quality.boundaryIntersection || m_quality.flippedTriangleCount > 0) - m_isInvalid = true; - XA_PROFILE_END(parameterizeChartsEvaluateQuality) + // Don't need to call computeMetrics here, that's only used in evaluateOrthoQuality to determine if quality is acceptable enough to use ortho projection. + if (m_quality.boundaryIntersection || m_quality.flippedTriangleCount > 0 || m_quality.zeroAreaTriangleCount > 0) + m_isInvalid = true; + XA_PROFILE_END(parameterizeChartsEvaluateQuality) + } } + if (options.fixWinding && m_unifiedMesh->computeFaceParametricArea(0) < 0.0f) { + for (uint32_t i = 0; i < unifiedVertexCount; i++) + m_unifiedMesh->texcoord(i).x *= -1.0f; + } +#if XA_CHECK_PARAM_WINDING + const uint32_t faceCount = m_unifiedMesh->faceCount(); + uint32_t flippedCount = 0; + for (uint32_t i = 0; i < faceCount; i++) { + const float area = m_unifiedMesh->computeFaceParametricArea(i); + if (area < 0.0f) + flippedCount++; + } + if (flippedCount == faceCount) { + XA_PRINT_WARNING("param: all faces flipped\n"); + } else if (flippedCount > 0) { + XA_PRINT_WARNING("param: %u / %u faces flipped\n", flippedCount, faceCount); + } +#endif + #if XA_DEBUG_ALL_CHARTS_INVALID m_isInvalid = true; #endif - // Transfer parameterization from unified mesh to chart mesh. - const uint32_t vertexCount = m_mesh->vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) - m_mesh->texcoord(v) = m_unifiedMesh->texcoord(m_chartVertexToUnifiedVertexMap[v]); - // Can destroy unified mesh now. - // But not if the parameterization is invalid, the unified mesh will be needed for PiecewiseParameterization. - if (!m_isInvalid) - destroyUnifiedMesh(); // Need to store texcoords for backup/restore so packing can be run multiple times. backupTexcoords(); } - Vector2 computeParametricBounds() const - { + Vector2 computeParametricBounds() const { Vector2 minCorner(FLT_MAX, FLT_MAX); Vector2 maxCorner(-FLT_MAX, -FLT_MAX); - const uint32_t vertexCount = m_mesh->vertexCount(); + const uint32_t vertexCount = m_unifiedMesh->vertexCount(); for (uint32_t v = 0; v < vertexCount; v++) { - minCorner = min(minCorner, m_mesh->texcoord(v)); - maxCorner = max(maxCorner, m_mesh->texcoord(v)); + minCorner = min(minCorner, m_unifiedMesh->texcoord(v)); + maxCorner = max(maxCorner, m_unifiedMesh->texcoord(v)); } return (maxCorner - minCorner) * 0.5f; } - void restoreTexcoords() - { - memcpy(m_mesh->texcoords(), m_backupTexcoords.data(), m_mesh->vertexCount() * sizeof(Vector2)); +#if XA_CHECK_PIECEWISE_CHART_QUALITY + void evaluateQuality(UniformGrid2 &boundaryGrid) { + m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid); +#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION + m_quality.computeFlippedFaces(m_unifiedMesh, &m_paramFlippedFaces); +#else + m_quality.computeFlippedFaces(m_unifiedMesh, nullptr); +#endif + if (m_quality.boundaryIntersection || m_quality.flippedTriangleCount > 0 || m_quality.zeroAreaTriangleCount > 0) + m_isInvalid = true; } +#endif -private: - void backupTexcoords() - { - m_backupTexcoords.resize(m_mesh->vertexCount()); - memcpy(m_backupTexcoords.data(), m_mesh->texcoords(), m_mesh->vertexCount() * sizeof(Vector2)); + void restoreTexcoords() { + memcpy(m_unifiedMesh->texcoords().data, m_backupTexcoords.data(), m_unifiedMesh->vertexCount() * sizeof(Vector2)); } - void destroyUnifiedMesh() - { - if (m_unifiedMesh) { - m_unifiedMesh->~Mesh(); - XA_FREE(m_unifiedMesh); - m_unifiedMesh = nullptr; - } - if (m_unmodifiedUnifiedMesh) { - m_unmodifiedUnifiedMesh->~Mesh(); - XA_FREE(m_unmodifiedUnifiedMesh); - m_unmodifiedUnifiedMesh = nullptr; - } - // Don't need this when unified meshes are destroyed. - m_chartVertexToUnifiedVertexMap.destroy(); +private: + void backupTexcoords() { + m_backupTexcoords.resize(m_unifiedMesh->vertexCount()); + memcpy(m_backupTexcoords.data(), m_unifiedMesh->texcoords().data, m_unifiedMesh->vertexCount() * sizeof(Vector2)); } Basis m_basis; - Mesh *m_mesh; Mesh *m_unifiedMesh; - Mesh *m_unmodifiedUnifiedMesh; // Unified mesh before fixing t-junctions. Null if no t-junctions were fixed - ChartType::Enum m_type; - uint32_t m_warningFlags; - uint32_t m_initialFaceCount; // Before fixing T-junctions and/or closing holes. - uint32_t m_closedHolesCount, m_fixedTJunctionsCount; + ChartType m_type; + segment::ChartGeneratorType::Enum m_generatorType; + uint32_t m_tjunctionCount; + + uint32_t m_originalVertexCount; + Array<uint32_t> m_originalIndices; // List of faces of the source mesh that belong to this chart. Array<uint32_t> m_faceToSourceFaceMap; @@ -7604,47 +7040,46 @@ private: bool m_isInvalid; }; -struct CreateAndParameterizeChartTaskArgs -{ - const Basis *basis; +struct CreateAndParameterizeChartTaskGroupArgs { + Progress *progress; ThreadLocal<UniformGrid2> *boundaryGrid; + ThreadLocal<ChartCtorBuffers> *chartBuffers; + const ChartOptions *options; + ThreadLocal<PiecewiseParam> *pp; +}; + +struct CreateAndParameterizeChartTaskArgs { + const Basis *basis; Chart *chart; // output Array<Chart *> charts; // output (if more than one chart) - ThreadLocal<ChartCtorBuffers> *chartBuffers; + segment::ChartGeneratorType::Enum chartGeneratorType; const Mesh *mesh; - const ParameterizeOptions *options; -#if XA_RECOMPUTE_CHARTS - ThreadLocal<PiecewiseParam> *pp; -#endif ConstArrayView<uint32_t> faces; uint32_t chartGroupId; uint32_t chartId; }; -static void runCreateAndParameterizeChartTask(void *userData) -{ - auto args = (CreateAndParameterizeChartTaskArgs *)userData; +static void runCreateAndParameterizeChartTask(void *groupUserData, void *taskUserData) { + XA_PROFILE_START(createChartMeshAndParameterizeThread) + auto groupArgs = (CreateAndParameterizeChartTaskGroupArgs *)groupUserData; + auto args = (CreateAndParameterizeChartTaskArgs *)taskUserData; XA_PROFILE_START(createChartMesh) - args->chart = XA_NEW_ARGS(MemTag::Default, Chart, args->chartBuffers->get(), *args->options, *args->basis, args->faces, args->mesh, args->chartGroupId, args->chartId); + args->chart = XA_NEW_ARGS(MemTag::Default, Chart, *args->basis, args->chartGeneratorType, args->faces, args->mesh, args->chartGroupId, args->chartId); XA_PROFILE_END(createChartMesh) - args->chart->parameterize(*args->options, args->boundaryGrid->get()); + XA_PROFILE_START(parameterizeCharts) + args->chart->parameterize(*groupArgs->options, groupArgs->boundaryGrid->get()); + XA_PROFILE_END(parameterizeCharts) #if XA_RECOMPUTE_CHARTS - if (!args->chart->isInvalid()) + if (!args->chart->isInvalid()) { + XA_PROFILE_END(createChartMeshAndParameterizeThread) return; + } // Recompute charts with invalid parameterizations. XA_PROFILE_START(parameterizeChartsRecompute) Chart *invalidChart = args->chart; - // Fixing t-junctions rewrites unified mesh faces, and we need to map faces back to input mesh. So use the unmodified unified mesh. - const Mesh *invalidMesh = invalidChart->unmodifiedUnifiedMesh(); - uint32_t faceCount = 0; - if (invalidMesh) { - faceCount = invalidMesh->faceCount(); - } else { - invalidMesh = invalidChart->unifiedMesh(); - faceCount = invalidChart->initialFaceCount(); // Not invalidMesh->faceCount(). Don't want faces added by hole closing. - } - PiecewiseParam &pp = args->pp->get(); - pp.reset(invalidMesh, faceCount); + const Mesh *invalidMesh = invalidChart->unifiedMesh(); + PiecewiseParam &pp = groupArgs->pp->get(); + pp.reset(invalidMesh); #if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS char filename[256]; XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_recomputed.obj", args->mesh->id(), args->chartGroupId, args->chartId); @@ -7658,7 +7093,10 @@ static void runCreateAndParameterizeChartTask(void *userData) XA_PROFILE_END(parameterizeChartsPiecewise) if (!facesRemaining) break; - Chart *chart = XA_NEW_ARGS(MemTag::Default, Chart, args->chartBuffers->get(), invalidChart, invalidMesh, pp.chartFaces(), pp.texcoords(), args->mesh); + Chart *chart = XA_NEW_ARGS(MemTag::Default, Chart, groupArgs->chartBuffers->get(), invalidChart, invalidMesh, pp.chartFaces(), pp.texcoords(), args->mesh); +#if XA_CHECK_PIECEWISE_CHART_QUALITY + chart->evaluateQuality(args->boundaryGrid->get()); +#endif args->charts.push_back(chart); #if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS if (file) { @@ -7686,50 +7124,63 @@ static void runCreateAndParameterizeChartTask(void *userData) #endif XA_PROFILE_END(parameterizeChartsRecompute) #endif // XA_RECOMPUTE_CHARTS + XA_PROFILE_END(createChartMeshAndParameterizeThread) + // Update progress. + groupArgs->progress->increment(args->faces.length); } // Set of charts corresponding to mesh faces in the same face group. -class ChartGroup -{ +class ChartGroup { public: - ChartGroup(uint32_t id, const Mesh *sourceMesh, const MeshFaceGroups *sourceMeshFaceGroups, MeshFaceGroups::Handle faceGroup) : m_id(id), m_sourceMesh(sourceMesh), m_sourceMeshFaceGroups(sourceMeshFaceGroups), m_faceGroup(faceGroup), m_faceCount(0), m_paramAddedChartsCount(0), m_paramDeletedChartsCount(0) - { + ChartGroup(uint32_t id, const Mesh *sourceMesh, const MeshFaceGroups *sourceMeshFaceGroups, MeshFaceGroups::Handle faceGroup) : + m_id(id), m_sourceMesh(sourceMesh), m_sourceMeshFaceGroups(sourceMeshFaceGroups), m_faceGroup(faceGroup) { } - ~ChartGroup() - { + ~ChartGroup() { for (uint32_t i = 0; i < m_charts.size(); i++) { m_charts[i]->~Chart(); XA_FREE(m_charts[i]); } } - uint32_t segmentChartCount() const { return m_chartBasis.size(); } uint32_t chartCount() const { return m_charts.size(); } Chart *chartAt(uint32_t i) const { return m_charts[i]; } - uint32_t faceCount() const { return m_faceCount; } - uint32_t paramAddedChartsCount() const { return m_paramAddedChartsCount; } - uint32_t paramDeletedChartsCount() const { return m_paramDeletedChartsCount; } + uint32_t faceCount() const { return m_sourceMeshFaceGroups->faceCount(m_faceGroup); } - void computeChartFaces(const ChartOptions &options, segment::Atlas &atlas) - { + void computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options, Progress *progress, segment::Atlas &atlas, ThreadLocal<UniformGrid2> *boundaryGrid, ThreadLocal<ChartCtorBuffers> *chartBuffers, ThreadLocal<PiecewiseParam> *piecewiseParam) { + // This function may be called multiple times, so destroy existing charts. + for (uint32_t i = 0; i < m_charts.size(); i++) { + m_charts[i]->~Chart(); + XA_FREE(m_charts[i]); + } // Create mesh from source mesh, using only the faces in this face group. XA_PROFILE_START(createChartGroupMesh) Mesh *mesh = createMesh(); XA_PROFILE_END(createChartGroupMesh) // Segment mesh into charts (arrays of faces). #if XA_DEBUG_SINGLE_CHART - m_chartBasis.resize(1); - Fit::computeBasis(&mesh->position(0), mesh->vertexCount(), &m_chartBasis[0]); - m_chartFaces.resize(1 + mesh->faceCount()); - m_chartFaces[0] = mesh->faceCount(); - for (uint32_t i = 0; i < m_chartFaces.size(); i++) - m_chartFaces[i + 1] = i; + XA_UNUSED(options); + XA_UNUSED(atlas); + const uint32_t chartCount = 1; + uint32_t offset; + Basis chartBasis; + Fit::computeBasis(&mesh->position(0), mesh->vertexCount(), &chartBasis); + Array<uint32_t> chartFaces; + chartFaces.resize(1 + mesh->faceCount()); + chartFaces[0] = mesh->faceCount(); + for (uint32_t i = 0; i < chartFaces.size() - 1; i++) + chartFaces[i + 1] = m_faceToSourceFaceMap[i]; + // Destroy mesh. + const uint32_t faceCount = mesh->faceCount(); + mesh->~Mesh(); + XA_FREE(mesh); #else XA_PROFILE_START(buildAtlas) atlas.reset(mesh, options); atlas.compute(); XA_PROFILE_END(buildAtlas) + // Update progress. + progress->increment(faceCount()); #if XA_DEBUG_EXPORT_OBJ_CHARTS char filename[256]; XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_charts.obj", m_sourceMesh->id(), m_id); @@ -7745,7 +7196,6 @@ public: mesh->writeObjFace(file, faces[f]); } mesh->writeObjBoundaryEges(file); - mesh->writeObjLinkedBoundaries(file); fclose(file); } #endif @@ -7754,65 +7204,57 @@ public: mesh->~Mesh(); XA_FREE(mesh); XA_PROFILE_START(copyChartFaces) - // Copy basis. - const uint32_t chartCount = atlas.chartCount(); - m_chartBasis.resize(chartCount); - for (uint32_t i = 0; i < chartCount; i++) - m_chartBasis[i] = atlas.chartBasis(i); + if (progress->cancel) + return; // Copy faces from segment::Atlas to m_chartFaces array with <chart 0 face count> <face 0> <face n> <chart 1 face count> etc. encoding. // segment::Atlas faces refer to the chart group mesh. Map them to the input mesh instead. - m_chartFaces.resize(chartCount + faceCount); + const uint32_t chartCount = atlas.chartCount(); + Array<uint32_t> chartFaces; + chartFaces.resize(chartCount + faceCount); uint32_t offset = 0; for (uint32_t i = 0; i < chartCount; i++) { ConstArrayView<uint32_t> faces = atlas.chartFaces(i); - m_chartFaces[offset++] = faces.length; + chartFaces[offset++] = faces.length; for (uint32_t j = 0; j < faces.length; j++) - m_chartFaces[offset++] = m_faceToSourceFaceMap[faces[j]]; + chartFaces[offset++] = m_faceToSourceFaceMap[faces[j]]; } XA_PROFILE_END(copyChartFaces) #endif - } - -#if XA_RECOMPUTE_CHARTS - void parameterizeCharts(TaskScheduler *taskScheduler, const ParameterizeOptions &options, ThreadLocal<UniformGrid2> *boundaryGrid, ThreadLocal<ChartCtorBuffers> *chartBuffers, ThreadLocal<PiecewiseParam> *piecewiseParam) -#else - void parameterizeCharts(TaskScheduler* taskScheduler, const ParameterizeOptions &options, ThreadLocal<UniformGrid2>* boundaryGrid, ThreadLocal<ChartCtorBuffers>* chartBuffers) -#endif - { - // This function may be called multiple times, so destroy existing charts. - for (uint32_t i = 0; i < m_charts.size(); i++) { - m_charts[i]->~Chart(); - XA_FREE(m_charts[i]); - } - m_paramAddedChartsCount = 0; - const uint32_t chartCount = m_chartBasis.size(); + XA_PROFILE_START(createChartMeshAndParameterizeReal) + CreateAndParameterizeChartTaskGroupArgs groupArgs; + groupArgs.progress = progress; + groupArgs.boundaryGrid = boundaryGrid; + groupArgs.chartBuffers = chartBuffers; + groupArgs.options = &options; + groupArgs.pp = piecewiseParam; + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(&groupArgs, chartCount); Array<CreateAndParameterizeChartTaskArgs> taskArgs; taskArgs.resize(chartCount); taskArgs.runCtors(); // Has Array member. - TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount); - uint32_t offset = 0; + offset = 0; for (uint32_t i = 0; i < chartCount; i++) { CreateAndParameterizeChartTaskArgs &args = taskArgs[i]; - args.basis = &m_chartBasis[i]; - args.boundaryGrid = boundaryGrid; +#if XA_DEBUG_SINGLE_CHART + args.basis = &chartBasis; + args.isPlanar = false; +#else + args.basis = &atlas.chartBasis(i); + args.chartGeneratorType = atlas.chartGeneratorType(i); +#endif args.chart = nullptr; args.chartGroupId = m_id; args.chartId = i; - args.chartBuffers = chartBuffers; - const uint32_t faceCount = m_chartFaces[offset++]; - args.faces = ConstArrayView<uint32_t>(&m_chartFaces[offset], faceCount); - offset += faceCount; + const uint32_t chartFaceCount = chartFaces[offset++]; + args.faces = ConstArrayView<uint32_t>(&chartFaces[offset], chartFaceCount); + offset += chartFaceCount; args.mesh = m_sourceMesh; - args.options = &options; -#if XA_RECOMPUTE_CHARTS - args.pp = piecewiseParam; -#endif Task task; task.userData = &args; task.func = runCreateAndParameterizeChartTask; taskScheduler->run(taskGroup, task); } taskScheduler->wait(&taskGroup); + XA_PROFILE_END(createChartMeshAndParameterizeReal) #if XA_RECOMPUTE_CHARTS // Count charts. Skip invalid ones and include new ones added by recomputing. uint32_t newChartCount = 0; @@ -7830,7 +7272,6 @@ public: if (chart->isInvalid()) { chart->~Chart(); XA_FREE(chart); - m_paramDeletedChartsCount++; continue; } m_charts[current++] = chart; @@ -7838,10 +7279,8 @@ public: // Now add new charts. for (uint32_t i = 0; i < chartCount; i++) { CreateAndParameterizeChartTaskArgs &args = taskArgs[i]; - for (uint32_t j = 0; j < args.charts.size(); j++) { + for (uint32_t j = 0; j < args.charts.size(); j++) m_charts[current++] = args.charts[j]; - m_paramAddedChartsCount++; - } } #else // XA_RECOMPUTE_CHARTS m_charts.resize(chartCount); @@ -7852,15 +7291,14 @@ public: } private: - Mesh *createMesh() - { + Mesh *createMesh() { XA_DEBUG_ASSERT(m_faceGroup != MeshFaceGroups::kInvalid); // Create new mesh from the source mesh, using faces that belong to this group. m_faceToSourceFaceMap.reserve(m_sourceMeshFaceGroups->faceCount(m_faceGroup)); for (MeshFaceGroups::Iterator it(m_sourceMeshFaceGroups, m_faceGroup); !it.isDone(); it.advance()) m_faceToSourceFaceMap.push_back(it.face()); // Only initial meshes has ignored faces. The only flag we care about is HasNormals. - const uint32_t faceCount = m_faceCount = m_faceToSourceFaceMap.size(); + const uint32_t faceCount = m_faceToSourceFaceMap.size(); XA_DEBUG_ASSERT(faceCount > 0); const uint32_t approxVertexCount = min(faceCount * 3, m_sourceMesh->vertexCount()); Mesh *mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, m_sourceMesh->epsilon(), approxVertexCount, faceCount, m_sourceMesh->flags() & MeshFlags::HasNormals); @@ -7889,9 +7327,7 @@ private: XA_DEBUG_ASSERT(indices[i] != UINT32_MAX); } // Don't copy flags - ignored faces aren't used by chart groups, they are handled by InvalidMeshGeometry. - Mesh::AddFaceResult::Enum result = mesh->addFace(indices); - XA_UNUSED(result); - XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); + mesh->addFace(indices); } XA_PROFILE_START(createChartGroupMeshColocals) mesh->createColocals(); @@ -7909,98 +7345,57 @@ private: } const uint32_t m_id; - const Mesh * const m_sourceMesh; - const MeshFaceGroups * const m_sourceMeshFaceGroups; + const Mesh *const m_sourceMesh; + const MeshFaceGroups *const m_sourceMeshFaceGroups; const MeshFaceGroups::Handle m_faceGroup; Array<uint32_t> m_faceToSourceFaceMap; // List of faces of the source mesh that belong to this chart group. - Array<Basis> m_chartBasis; // Copied from segment::Atlas. - Array<uint32_t> m_chartFaces; // Copied from segment::Atlas. Encoding: <chart 0 face count> <face 0> <face n> <chart 1 face count> etc. Array<Chart *> m_charts; - uint32_t m_faceCount; // Set by createMesh(). Used for sorting. - uint32_t m_paramAddedChartsCount; // Number of new charts added by recomputing charts with invalid parameterizations. - uint32_t m_paramDeletedChartsCount; // Number of charts with invalid parameterizations that were deleted, after charts were recomputed. -}; - -// References invalid faces and vertices in a mesh. -struct InvalidMeshGeometry -{ - // Invalid faces have the face groups MeshFaceGroups::kInvalid. - void extract(const Mesh *mesh, const MeshFaceGroups *meshFaceGroups) - { - // Copy invalid faces. - m_faces.clear(); - const uint32_t meshFaceCount = mesh->faceCount(); - for (uint32_t f = 0; f < meshFaceCount; f++) { - if (meshFaceGroups->groupAt(f) == MeshFaceGroups::kInvalid) - m_faces.push_back(f); - } - // Create *unique* list of vertices of invalid faces. - const uint32_t faceCount = m_faces.size(); - m_indices.resize(faceCount * 3); - const uint32_t approxVertexCount = min(faceCount * 3, mesh->vertexCount()); - m_vertexToSourceVertexMap.clear(); - m_vertexToSourceVertexMap.reserve(approxVertexCount); - HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToVertexMap(MemTag::Mesh, approxVertexCount); - for (uint32_t f = 0; f < faceCount; f++) { - const uint32_t face = m_faces[f]; - for (uint32_t i = 0; i < 3; i++) { - const uint32_t vertex = mesh->vertexAt(face * 3 + i); - uint32_t newVertex = sourceVertexToVertexMap.get(vertex); - if (newVertex == UINT32_MAX) { - newVertex = sourceVertexToVertexMap.add(vertex); - m_vertexToSourceVertexMap.push_back(vertex); - } - m_indices[f * 3 + i] = newVertex; - } - } - } - - ConstArrayView<uint32_t> faces() const { return m_faces; } - ConstArrayView<uint32_t> indices() const { return m_indices; } - ConstArrayView<uint32_t> vertices() const { return m_vertexToSourceVertexMap; } - -private: - Array<uint32_t> m_faces, m_indices; - Array<uint32_t> m_vertexToSourceVertexMap; // Map face vertices to vertices of the source mesh. }; -struct ChartGroupComputeChartFacesTaskArgs -{ +struct ChartGroupComputeChartsTaskGroupArgs { ThreadLocal<segment::Atlas> *atlas; - ChartGroup *chartGroup; const ChartOptions *options; Progress *progress; + TaskScheduler *taskScheduler; + ThreadLocal<UniformGrid2> *boundaryGrid; + ThreadLocal<ChartCtorBuffers> *chartBuffers; + ThreadLocal<PiecewiseParam> *piecewiseParam; }; -static void runChartGroupComputeChartFacesJob(void *userData) -{ - auto args = (ChartGroupComputeChartFacesTaskArgs *)userData; +static void runChartGroupComputeChartsTask(void *groupUserData, void *taskUserData) { + auto args = (ChartGroupComputeChartsTaskGroupArgs *)groupUserData; + auto chartGroup = (ChartGroup *)taskUserData; if (args->progress->cancel) return; XA_PROFILE_START(chartGroupComputeChartsThread) - args->chartGroup->computeChartFaces(*args->options, args->atlas->get()); + chartGroup->computeCharts(args->taskScheduler, *args->options, args->progress, args->atlas->get(), args->boundaryGrid, args->chartBuffers, args->piecewiseParam); XA_PROFILE_END(chartGroupComputeChartsThread) } -struct MeshComputeChartFacesTaskArgs -{ - Array<ChartGroup *> *chartGroups; // output - InvalidMeshGeometry *invalidMeshGeometry; // output +struct MeshComputeChartsTaskGroupArgs { ThreadLocal<segment::Atlas> *atlas; const ChartOptions *options; Progress *progress; - const Mesh *sourceMesh; TaskScheduler *taskScheduler; + ThreadLocal<UniformGrid2> *boundaryGrid; + ThreadLocal<ChartCtorBuffers> *chartBuffers; + ThreadLocal<PiecewiseParam> *piecewiseParam; +}; + +struct MeshComputeChartsTaskArgs { + const Mesh *sourceMesh; + Array<ChartGroup *> *chartGroups; // output + InvalidMeshGeometry *invalidMeshGeometry; // output }; #if XA_DEBUG_EXPORT_OBJ_FACE_GROUPS static uint32_t s_faceGroupsCurrentVertex = 0; #endif -static void runMeshComputeChartFacesJob(void *userData) -{ - auto args = (MeshComputeChartFacesTaskArgs *)userData; - if (args->progress->cancel) +static void runMeshComputeChartsTask(void *groupUserData, void *taskUserData) { + auto groupArgs = (MeshComputeChartsTaskGroupArgs *)groupUserData; + auto args = (MeshComputeChartsTaskArgs *)taskUserData; + if (groupArgs->progress->cancel) return; XA_PROFILE_START(computeChartsThread) // Create face groups. @@ -8009,7 +7404,7 @@ static void runMeshComputeChartFacesJob(void *userData) meshFaceGroups->compute(); const uint32_t chartGroupCount = meshFaceGroups->groupCount(); XA_PROFILE_END(createFaceGroups) - if (args->progress->cancel) + if (groupArgs->progress->cancel) goto cleanup; #if XA_DEBUG_EXPORT_OBJ_FACE_GROUPS { @@ -8053,33 +7448,41 @@ static void runMeshComputeChartFacesJob(void *userData) for (uint32_t i = 0; i < chartGroupCount; i++) (*args->chartGroups)[i] = XA_NEW_ARGS(MemTag::Default, ChartGroup, i, args->sourceMesh, meshFaceGroups, MeshFaceGroups::Handle(i)); // Extract invalid geometry via the invalid face group (MeshFaceGroups::kInvalid). - XA_PROFILE_START(extractInvalidMeshGeometry) - args->invalidMeshGeometry->extract(args->sourceMesh, meshFaceGroups); - XA_PROFILE_END(extractInvalidMeshGeometry) - // One task for each chart group - compute chart faces. + { + XA_PROFILE_START(extractInvalidMeshGeometry) + args->invalidMeshGeometry->extract(args->sourceMesh, meshFaceGroups); + XA_PROFILE_END(extractInvalidMeshGeometry) + } + // One task for each chart group - compute charts. { XA_PROFILE_START(chartGroupComputeChartsReal) - Array<ChartGroupComputeChartFacesTaskArgs> taskArgs; - taskArgs.resize(chartGroupCount); - for (uint32_t i = 0; i < chartGroupCount; i++) { - taskArgs[i].atlas = args->atlas; - taskArgs[i].chartGroup = (*args->chartGroups)[i]; - taskArgs[i].options = args->options; - taskArgs[i].progress = args->progress; - } - TaskGroupHandle taskGroup = args->taskScheduler->createTaskGroup(chartGroupCount); + // Sort chart groups by face count. + Array<float> chartGroupSortData; + chartGroupSortData.resize(chartGroupCount); + for (uint32_t i = 0; i < chartGroupCount; i++) + chartGroupSortData[i] = (float)(*args->chartGroups)[i]->faceCount(); + RadixSort chartGroupSort; + chartGroupSort.sort(chartGroupSortData); + // Larger chart groups are added first to reduce the chance of thread starvation. + ChartGroupComputeChartsTaskGroupArgs taskGroupArgs; + taskGroupArgs.atlas = groupArgs->atlas; + taskGroupArgs.options = groupArgs->options; + taskGroupArgs.progress = groupArgs->progress; + taskGroupArgs.taskScheduler = groupArgs->taskScheduler; + taskGroupArgs.boundaryGrid = groupArgs->boundaryGrid; + taskGroupArgs.chartBuffers = groupArgs->chartBuffers; + taskGroupArgs.piecewiseParam = groupArgs->piecewiseParam; + TaskGroupHandle taskGroup = groupArgs->taskScheduler->createTaskGroup(&taskGroupArgs, chartGroupCount); for (uint32_t i = 0; i < chartGroupCount; i++) { Task task; - task.userData = &taskArgs[i]; - task.func = runChartGroupComputeChartFacesJob; - args->taskScheduler->run(taskGroup, task); + task.userData = (*args->chartGroups)[chartGroupCount - i - 1]; + task.func = runChartGroupComputeChartsTask; + groupArgs->taskScheduler->run(taskGroup, task); } - args->taskScheduler->wait(&taskGroup); + groupArgs->taskScheduler->wait(&taskGroup); XA_PROFILE_END(chartGroupComputeChartsReal) } XA_PROFILE_END(computeChartsThread) - args->progress->value++; - args->progress->update(); cleanup: if (meshFaceGroups) { meshFaceGroups->~MeshFaceGroups(); @@ -8087,43 +7490,13 @@ cleanup: } } -struct ParameterizeChartsTaskArgs -{ - TaskScheduler *taskScheduler; - ChartGroup *chartGroup; - const ParameterizeOptions *options; - ThreadLocal<UniformGrid2> *boundaryGrid; - ThreadLocal<ChartCtorBuffers> *chartBuffers; -#if XA_RECOMPUTE_CHARTS - ThreadLocal<PiecewiseParam> *piecewiseParam; -#endif - Progress *progress; -}; - -static void runParameterizeChartsJob(void *userData) -{ - auto args = (ParameterizeChartsTaskArgs *)userData; - if (args->progress->cancel) - return; - XA_PROFILE_START(parameterizeChartsThread) -#if XA_RECOMPUTE_CHARTS - args->chartGroup->parameterizeCharts(args->taskScheduler, *args->options, args->boundaryGrid, args->chartBuffers, args->piecewiseParam); -#else - args->chartGroup->parameterizeCharts(args->taskScheduler, *args->options, args->boundaryGrid, args->chartBuffers); -#endif - XA_PROFILE_END(parameterizeChartsThread) - args->progress->value++; - args->progress->update(); -} - /// An atlas is a set of chart groups. -class Atlas -{ +class Atlas { public: - Atlas() : m_chartsComputed(false), m_chartsParameterized(false) {} + Atlas() : + m_chartsComputed(false) {} - ~Atlas() - { + ~Atlas() { for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) { for (uint32_t j = 0; j < m_meshChartGroups[i].size(); j++) { m_meshChartGroups[i][j]->~ChartGroup(); @@ -8137,22 +7510,25 @@ public: uint32_t meshCount() const { return m_meshes.size(); } const InvalidMeshGeometry &invalidMeshGeometry(uint32_t meshIndex) const { return m_invalidMeshGeometry[meshIndex]; } bool chartsComputed() const { return m_chartsComputed; } - bool chartsParameterized() const { return m_chartsParameterized; } uint32_t chartGroupCount(uint32_t mesh) const { return m_meshChartGroups[mesh].size(); } const ChartGroup *chartGroupAt(uint32_t mesh, uint32_t group) const { return m_meshChartGroups[mesh][group]; } - void addMesh(const Mesh *mesh) - { + void addMesh(const Mesh *mesh) { m_meshes.push_back(mesh); } - bool computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options, ProgressFunc progressFunc, void *progressUserData) - { + bool computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options, ProgressFunc progressFunc, void *progressUserData) { + XA_PROFILE_START(computeChartsReal) #if XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS segment::s_planarRegionsCurrentRegion = segment::s_planarRegionsCurrentVertex = 0; #endif + // Progress is per-face x 2 (1 for chart faces, 1 for parameterized chart faces). + const uint32_t meshCount = m_meshes.size(); + uint32_t totalFaceCount = 0; + for (uint32_t i = 0; i < meshCount; i++) + totalFaceCount += m_meshes[i]->faceCount(); + Progress progress(ProgressCategory::ComputeCharts, progressFunc, progressUserData, totalFaceCount * 2); m_chartsComputed = false; - m_chartsParameterized = false; // Clear chart groups, since this function may be called multiple times. if (!m_meshChartGroups.isEmpty()) { for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) { @@ -8162,27 +7538,20 @@ public: } m_meshChartGroups[i].clear(); } - XA_ASSERT(m_meshChartGroups.size() == m_meshes.size()); // The number of meshes shouldn't have changed. + XA_ASSERT(m_meshChartGroups.size() == meshCount); // The number of meshes shouldn't have changed. } - m_meshChartGroups.resize(m_meshes.size()); + m_meshChartGroups.resize(meshCount); m_meshChartGroups.runCtors(); - m_invalidMeshGeometry.resize(m_meshes.size()); + m_invalidMeshGeometry.resize(meshCount); m_invalidMeshGeometry.runCtors(); // One task per mesh. - const uint32_t meshCount = m_meshes.size(); - Progress progress(ProgressCategory::ComputeCharts, progressFunc, progressUserData, meshCount); - ThreadLocal<segment::Atlas> atlas; - Array<MeshComputeChartFacesTaskArgs> taskArgs; + Array<MeshComputeChartsTaskArgs> taskArgs; taskArgs.resize(meshCount); for (uint32_t i = 0; i < meshCount; i++) { - MeshComputeChartFacesTaskArgs &args = taskArgs[i]; - args.atlas = &atlas; + MeshComputeChartsTaskArgs &args = taskArgs[i]; + args.sourceMesh = m_meshes[i]; args.chartGroups = &m_meshChartGroups[i]; args.invalidMeshGeometry = &m_invalidMeshGeometry[i]; - args.options = &options; - args.progress = &progress; - args.sourceMesh = m_meshes[i]; - args.taskScheduler = taskScheduler; } // Sort meshes by indexCount. Array<float> meshSortData; @@ -8192,105 +7561,53 @@ public: RadixSort meshSort; meshSort.sort(meshSortData); // Larger meshes are added first to reduce the chance of thread starvation. - TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(meshCount); - for (uint32_t i = 0; i < meshCount; i++) { - Task task; - task.userData = &taskArgs[meshSort.ranks()[meshCount - i - 1]]; - task.func = runMeshComputeChartFacesJob; - taskScheduler->run(taskGroup, task); - } - taskScheduler->wait(&taskGroup); - if (progress.cancel) - return false; - m_chartsComputed = true; - return true; - } - - bool parameterizeCharts(TaskScheduler *taskScheduler, const ParameterizeOptions &options, ProgressFunc progressFunc, void *progressUserData) - { - m_chartsParameterized = false; - uint32_t chartGroupCount = 0; - for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) - chartGroupCount += m_meshChartGroups[i].size(); - Progress progress(ProgressCategory::ParameterizeCharts, progressFunc, progressUserData, chartGroupCount); + ThreadLocal<segment::Atlas> atlas; ThreadLocal<UniformGrid2> boundaryGrid; // For Quality boundary intersection. ThreadLocal<ChartCtorBuffers> chartBuffers; -#if XA_RECOMPUTE_CHARTS ThreadLocal<PiecewiseParam> piecewiseParam; -#endif - Array<ParameterizeChartsTaskArgs> taskArgs; - taskArgs.resize(chartGroupCount); - { - uint32_t k = 0; - for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) { - const uint32_t count = m_meshChartGroups[i].size(); - for (uint32_t j = 0; j < count; j++) { - ParameterizeChartsTaskArgs &args = taskArgs[k]; - args.taskScheduler = taskScheduler; - args.chartGroup = m_meshChartGroups[i][j]; - args.options = &options; - args.boundaryGrid = &boundaryGrid; - args.chartBuffers = &chartBuffers; -#if XA_RECOMPUTE_CHARTS - args.piecewiseParam = &piecewiseParam; -#endif - args.progress = &progress; - k++; - } - } - } - // Sort chart groups by face count. - Array<float> chartGroupSortData; - chartGroupSortData.resize(chartGroupCount); - { - uint32_t k = 0; - for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) { - const uint32_t count = m_meshChartGroups[i].size(); - for (uint32_t j = 0; j < count; j++) { - chartGroupSortData[k++] = (float)m_meshChartGroups[i][j]->faceCount(); - } - } - } - RadixSort chartGroupSort; - chartGroupSort.sort(chartGroupSortData); - // Larger chart groups are added first to reduce the chance of thread starvation. - TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroupCount); - for (uint32_t i = 0; i < chartGroupCount; i++) { + MeshComputeChartsTaskGroupArgs taskGroupArgs; + taskGroupArgs.atlas = &atlas; + taskGroupArgs.options = &options; + taskGroupArgs.progress = &progress; + taskGroupArgs.taskScheduler = taskScheduler; + taskGroupArgs.boundaryGrid = &boundaryGrid; + taskGroupArgs.chartBuffers = &chartBuffers; + taskGroupArgs.piecewiseParam = &piecewiseParam; + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(&taskGroupArgs, meshCount); + for (uint32_t i = 0; i < meshCount; i++) { Task task; - task.userData = &taskArgs[chartGroupSort.ranks()[chartGroupCount - i - 1]]; - task.func = runParameterizeChartsJob; + task.userData = &taskArgs[meshSort.ranks()[meshCount - i - 1]]; + task.func = runMeshComputeChartsTask; taskScheduler->run(taskGroup, task); } taskScheduler->wait(&taskGroup); + XA_PROFILE_END(computeChartsReal) if (progress.cancel) return false; - m_chartsParameterized = true; + m_chartsComputed = true; return true; } private: Array<const Mesh *> m_meshes; Array<InvalidMeshGeometry> m_invalidMeshGeometry; // 1 per mesh. - Array<Array<ChartGroup *> > m_meshChartGroups; + Array<Array<ChartGroup *>> m_meshChartGroups; bool m_chartsComputed; - bool m_chartsParameterized; }; } // namespace param namespace pack { -class AtlasImage -{ +class AtlasImage { public: - AtlasImage(uint32_t width, uint32_t height) : m_width(width), m_height(height) - { + AtlasImage(uint32_t width, uint32_t height) : + m_width(width), m_height(height) { m_data.resize(m_width * m_height); memset(m_data.data(), 0, sizeof(uint32_t) * m_data.size()); } - void resize(uint32_t width, uint32_t height) - { + void resize(uint32_t width, uint32_t height) { Array<uint32_t> data; data.resize(width * height); memset(data.data(), 0, sizeof(uint32_t) * data.size()); @@ -8301,8 +7618,7 @@ public: data.moveTo(m_data); } - void addChart(uint32_t chartIndex, const BitImage *image, const BitImage *imageBilinear, const BitImage *imagePadding, int atlas_w, int atlas_h, int offset_x, int offset_y) - { + void addChart(uint32_t chartIndex, const BitImage *image, const BitImage *imageBilinear, const BitImage *imagePadding, int atlas_w, int atlas_h, int offset_x, int offset_y) { const int w = image->width(); const int h = image->height(); for (int y = 0; y < h; y++) { @@ -8328,15 +7644,13 @@ public: } } - void copyTo(uint32_t *dest, uint32_t destWidth, uint32_t destHeight, int padding) const - { + void copyTo(uint32_t *dest, uint32_t destWidth, uint32_t destHeight, int padding) const { for (uint32_t y = 0; y < destHeight; y++) memcpy(&dest[y * destWidth], &m_data[padding + (y + padding) * m_width], destWidth * sizeof(uint32_t)); } #if XA_DEBUG_EXPORT_ATLAS_IMAGES - void writeTga(const char *filename, uint32_t width, uint32_t height) const - { + void writeTga(const char *filename, uint32_t width, uint32_t height) const { Array<uint8_t> image; image.resize(width * height * 3); for (uint32_t y = 0; y < height; y++) { @@ -8378,18 +7692,14 @@ private: Array<uint32_t> m_data; }; -struct Chart -{ +struct Chart { int32_t atlasIndex; uint32_t material; - uint32_t indexCount; - const uint32_t *indices; + ConstArrayView<uint32_t> indices; float parametricArea; float surfaceArea; - Vector2 *vertices; - uint32_t vertexCount; + ArrayView<Vector2> vertices; Array<uint32_t> uniqueVertices; - bool allowRotate; // bounding box Vector2 majorAxis, minorAxis, minCorner, maxCorner; // Mesh only @@ -8398,29 +7708,26 @@ struct Chart Array<uint32_t> faces; Vector2 &uniqueVertexAt(uint32_t v) { return uniqueVertices.isEmpty() ? vertices[v] : vertices[uniqueVertices[v]]; } - uint32_t uniqueVertexCount() const { return uniqueVertices.isEmpty() ? vertexCount : uniqueVertices.size(); } + uint32_t uniqueVertexCount() const { return uniqueVertices.isEmpty() ? vertices.length : uniqueVertices.size(); } }; -struct AddChartTaskArgs -{ - ThreadLocal<BoundingBox2D> *boundingBox; +struct AddChartTaskArgs { param::Chart *paramChart; Chart *chart; // out }; -static void runAddChartTask(void *userData) -{ +static void runAddChartTask(void *groupUserData, void *taskUserData) { XA_PROFILE_START(packChartsAddChartsThread) - auto args = (AddChartTaskArgs *)userData; + auto boundingBox = (ThreadLocal<BoundingBox2D> *)groupUserData; + auto args = (AddChartTaskArgs *)taskUserData; param::Chart *paramChart = args->paramChart; XA_PROFILE_START(packChartsAddChartsRestoreTexcoords) paramChart->restoreTexcoords(); XA_PROFILE_END(packChartsAddChartsRestoreTexcoords) - Mesh *mesh = paramChart->mesh(); + Mesh *mesh = paramChart->unifiedMesh(); Chart *chart = args->chart = XA_NEW(MemTag::Default, Chart); chart->atlasIndex = -1; chart->material = 0; - chart->indexCount = mesh->indexCount(); chart->indices = mesh->indices(); chart->parametricArea = mesh->computeParametricArea(); if (chart->parametricArea < kAreaEpsilon) { @@ -8430,17 +7737,15 @@ static void runAddChartTask(void *userData) } chart->surfaceArea = mesh->computeSurfaceArea(); chart->vertices = mesh->texcoords(); - chart->vertexCount = mesh->vertexCount(); - chart->allowRotate = true; chart->boundaryEdges = &mesh->boundaryEdges(); // Compute bounding box of chart. - BoundingBox2D &bb = args->boundingBox->get(); + BoundingBox2D &bb = boundingBox->get(); bb.clear(); - for (uint32_t v = 0; v < chart->vertexCount; v++) { + for (uint32_t v = 0; v < chart->vertices.length; v++) { if (mesh->isBoundaryVertex(v)) bb.appendBoundaryVertex(mesh->texcoord(v)); } - bb.compute(mesh->texcoords(), mesh->vertexCount()); + bb.compute(mesh->texcoords()); chart->majorAxis = bb.majorAxis; chart->minorAxis = bb.minorAxis; chart->minCorner = bb.minCorner; @@ -8448,10 +7753,8 @@ static void runAddChartTask(void *userData) XA_PROFILE_END(packChartsAddChartsThread) } -struct Atlas -{ - ~Atlas() - { +struct Atlas { + ~Atlas() { for (uint32_t i = 0; i < m_atlasImages.size(); i++) { m_atlasImages[i]->~AtlasImage(); XA_FREE(m_atlasImages[i]); @@ -8475,8 +7778,7 @@ struct Atlas const Array<AtlasImage *> &getImages() const { return m_atlasImages; } float getUtilization(uint32_t atlas) const { return m_utilization[atlas]; } - void addCharts(TaskScheduler *taskScheduler, param::Atlas *paramAtlas) - { + void addCharts(TaskScheduler *taskScheduler, param::Atlas *paramAtlas) { // Count charts. uint32_t chartCount = 0; for (uint32_t i = 0; i < paramAtlas->meshCount(); i++) { @@ -8489,11 +7791,11 @@ struct Atlas if (chartCount == 0) return; // Run one task per chart. + ThreadLocal<BoundingBox2D> boundingBox; + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(&boundingBox, chartCount); Array<AddChartTaskArgs> taskArgs; taskArgs.resize(chartCount); - TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount); uint32_t chartIndex = 0; - ThreadLocal<BoundingBox2D> boundingBox; for (uint32_t i = 0; i < paramAtlas->meshCount(); i++) { const uint32_t chartGroupsCount = paramAtlas->chartGroupCount(i); for (uint32_t j = 0; j < chartGroupsCount; j++) { @@ -8501,7 +7803,6 @@ struct Atlas const uint32_t count = chartGroup->chartCount(); for (uint32_t k = 0; k < count; k++) { AddChartTaskArgs &args = taskArgs[chartIndex]; - args.boundingBox = &boundingBox; args.paramChart = chartGroup->chartAt(k); Task task; task.userData = &taskArgs[chartIndex]; @@ -8518,8 +7819,10 @@ struct Atlas m_charts[i] = taskArgs[i].chart; } - void addUvMeshCharts(UvMeshInstance *mesh) - { + void addUvMeshCharts(UvMeshInstance *mesh) { + // Copy texcoords from mesh. + mesh->texcoords.resize(mesh->mesh->texcoords.size()); + memcpy(mesh->texcoords.data(), mesh->mesh->texcoords.data(), mesh->texcoords.size() * sizeof(Vector2)); BitArray vertexUsed(mesh->texcoords.size()); BoundingBox2D boundingBox; for (uint32_t c = 0; c < mesh->mesh->charts.size(); c++) { @@ -8527,17 +7830,14 @@ struct Atlas Chart *chart = XA_NEW(MemTag::Default, Chart); chart->atlasIndex = -1; chart->material = uvChart->material; - chart->indexCount = uvChart->indices.size(); - chart->indices = uvChart->indices.data(); - chart->vertices = mesh->texcoords.data(); - chart->vertexCount = mesh->texcoords.size(); - chart->allowRotate = mesh->rotateCharts; + chart->indices = uvChart->indices; + chart->vertices = mesh->texcoords; chart->boundaryEdges = nullptr; chart->faces.resize(uvChart->faces.size()); memcpy(chart->faces.data(), uvChart->faces.data(), sizeof(uint32_t) * uvChart->faces.size()); // Find unique vertices. vertexUsed.zeroOutMemory(); - for (uint32_t i = 0; i < chart->indexCount; i++) { + for (uint32_t i = 0; i < chart->indices.length; i++) { const uint32_t vertex = chart->indices[i]; if (!vertexUsed.get(vertex)) { vertexUsed.set(vertex); @@ -8546,14 +7846,13 @@ struct Atlas } // Compute parametric and surface areas. chart->parametricArea = 0.0f; - for (uint32_t f = 0; f < chart->indexCount / 3; f++) { + for (uint32_t f = 0; f < chart->indices.length / 3; f++) { const Vector2 &v1 = chart->vertices[chart->indices[f * 3 + 0]]; const Vector2 &v2 = chart->vertices[chart->indices[f * 3 + 1]]; const Vector2 &v3 = chart->vertices[chart->indices[f * 3 + 2]]; chart->parametricArea += fabsf(triangleArea(v1, v2, v3)); } chart->parametricArea *= 0.5f; - chart->surfaceArea = chart->parametricArea; // Identical for UV meshes. if (chart->parametricArea < kAreaEpsilon) { // When the parametric area is too small we use a rough approximation to prevent divisions by very small numbers. Vector2 minCorner(FLT_MAX, FLT_MAX); @@ -8565,6 +7864,9 @@ struct Atlas const Vector2 bounds = (maxCorner - minCorner) * 0.5f; chart->parametricArea = bounds.x * bounds.y; } + XA_DEBUG_ASSERT(isFinite(chart->parametricArea)); + XA_DEBUG_ASSERT(!isNan(chart->parametricArea)); + chart->surfaceArea = chart->parametricArea; // Identical for UV meshes. // Compute bounding box of chart. // Using all unique vertices for simplicity, can compute real boundaries if this is too slow. boundingBox.clear(); @@ -8580,8 +7882,7 @@ struct Atlas } // Pack charts in the smallest possible rectangle. - bool packCharts(const PackOptions &options, ProgressFunc progressFunc, void *progressUserData) - { + bool packCharts(const PackOptions &options, ProgressFunc progressFunc, void *progressUserData) { if (progressFunc) { if (!progressFunc(ProgressCategory::PackCharts, 0, progressUserData)) return false; @@ -8627,19 +7928,19 @@ struct Atlas // Compute chart scale float scale = 1.0f; if (chart->parametricArea != 0.0f) { - scale = (chart->surfaceArea / chart->parametricArea) * m_texelsPerUnit; + scale = sqrtf(chart->surfaceArea / chart->parametricArea) * m_texelsPerUnit; XA_ASSERT(isFinite(scale)); } // Translate, rotate and scale vertices. Compute extents. Vector2 minCorner(FLT_MAX, FLT_MAX); - if (!chart->allowRotate) { + if (!options.rotateChartsToAxis) { for (uint32_t i = 0; i < chart->uniqueVertexCount(); i++) minCorner = min(minCorner, chart->uniqueVertexAt(i)); } Vector2 extents(0.0f); for (uint32_t i = 0; i < chart->uniqueVertexCount(); i++) { Vector2 &texcoord = chart->uniqueVertexAt(i); - if (chart->allowRotate) { + if (options.rotateChartsToAxis) { const float x = dot(texcoord, chart->majorAxis); const float y = dot(texcoord, chart->minorAxis); texcoord.x = x; @@ -8750,27 +8051,27 @@ struct Atlas // Resize and clear (discard = true) chart images. // Leave room for padding at extents. chartImage.resize(ftoi_ceil(chartExtents[c].x) + options.padding, ftoi_ceil(chartExtents[c].y) + options.padding, true); - if (chart->allowRotate) + if (options.rotateCharts) chartImageRotated.resize(chartImage.height(), chartImage.width(), true); if (options.bilinear) { chartImageBilinear.resize(chartImage.width(), chartImage.height(), true); - if (chart->allowRotate) + if (options.rotateCharts) chartImageBilinearRotated.resize(chartImage.height(), chartImage.width(), true); } // Rasterize chart faces. - const uint32_t faceCount = chart->indexCount / 3; + const uint32_t faceCount = chart->indices.length / 3; for (uint32_t f = 0; f < faceCount; f++) { Vector2 vertices[3]; for (uint32_t v = 0; v < 3; v++) vertices[v] = chart->vertices[chart->indices[f * 3 + v]]; DrawTriangleCallbackArgs args; args.chartBitImage = &chartImage; - args.chartBitImageRotated = chart->allowRotate ? &chartImageRotated : nullptr; + args.chartBitImageRotated = options.rotateCharts ? &chartImageRotated : nullptr; raster::drawTriangle(Vector2((float)chartImage.width(), (float)chartImage.height()), vertices, drawTriangleCallback, &args); } // Expand chart by pixels sampled by bilinear interpolation. if (options.bilinear) - bilinearExpand(chart, &chartImage, &chartImageBilinear, chart->allowRotate ? &chartImageBilinearRotated : nullptr, boundaryEdgeGrid); + bilinearExpand(chart, &chartImage, &chartImageBilinear, options.rotateCharts ? &chartImageBilinearRotated : nullptr, boundaryEdgeGrid); // Expand chart by padding pixels (dilation). if (options.padding > 0) { // Copy into the same BitImage instances for every chart to avoid reallocating BitImage buffers (largest chart is packed first). @@ -8780,7 +8081,7 @@ struct Atlas else chartImage.copyTo(chartImagePadding); chartImagePadding.dilate(options.padding); - if (chart->allowRotate) { + if (options.rotateCharts) { if (options.bilinear) chartImageBilinearRotated.copyTo(chartImagePaddingRotated); else @@ -8815,23 +8116,25 @@ struct Atlas int best_x = 0, best_y = 0; int best_cw = 0, best_ch = 0; int best_r = 0; - for (;;) - { + for (;;) { +#if XA_DEBUG bool firstChartInBitImage = false; - XA_UNUSED(firstChartInBitImage); +#endif if (currentAtlas + 1 > m_bitImages.size()) { // Chart doesn't fit in the current bitImage, create a new one. BitImage *bi = XA_NEW_ARGS(MemTag::Default, BitImage, resolution, resolution); m_bitImages.push_back(bi); atlasSizes.push_back(Vector2i(0, 0)); +#if XA_DEBUG firstChartInBitImage = true; +#endif if (createImage) m_atlasImages.push_back(XA_NEW_ARGS(MemTag::Default, AtlasImage, resolution, resolution)); // Start positions are per-atlas, so create a new one of those too. chartStartPositions.push_back(Vector2i(0, 0)); } XA_PROFILE_START(packChartsFindLocation) - const bool foundLocation = findChartLocation(chartStartPositions[currentAtlas], options.bruteForce, m_bitImages[currentAtlas], chartImageToPack, chartImageToPackRotated, atlasSizes[currentAtlas].x, atlasSizes[currentAtlas].y, &best_x, &best_y, &best_cw, &best_ch, &best_r, options.blockAlign, maxResolution, chart->allowRotate); + const bool foundLocation = findChartLocation(options, chartStartPositions[currentAtlas], m_bitImages[currentAtlas], chartImageToPack, chartImageToPackRotated, atlasSizes[currentAtlas].x, atlasSizes[currentAtlas].y, &best_x, &best_y, &best_cw, &best_ch, &best_r, maxResolution); XA_PROFILE_END(packChartsFindLocation) XA_DEBUG_ASSERT(!(firstChartInBitImage && !foundLocation)); // Chart doesn't fit in an empty, newly allocated bitImage. Shouldn't happen, since charts are resized if they are too big to fit in the atlas. if (maxResolution == 0) { @@ -8849,8 +8152,7 @@ struct Atlas if (best_x + best_cw > atlasSizes[currentAtlas].x || best_y + best_ch > atlasSizes[currentAtlas].y) { for (uint32_t j = 0; j < chartStartPositions.size(); j++) chartStartPositions[j] = Vector2i(0, 0); - } - else { + } else { chartStartPositions[currentAtlas] = Vector2i(best_x, best_y); } } @@ -8897,7 +8199,7 @@ struct Atlas Vector2 &texcoord = chart->uniqueVertexAt(v); Vector2 t = texcoord; if (best_r) { - XA_DEBUG_ASSERT(chart->allowRotate); + XA_DEBUG_ASSERT(options.rotateCharts); swap(t.x, t.y); } texcoord.x = best_x + t.x; @@ -8938,8 +8240,7 @@ struct Atlas } if (m_utilization.size() > 1) { XA_PRINT(" %u: %f%% utilization\n", i, m_utilization[i] * 100.0f); - } - else { + } else { XA_PRINT(" %f%% utilization\n", m_utilization[i] * 100.0f); } } @@ -8958,28 +8259,22 @@ struct Atlas } private: - // IC: Brute force is slow, and random may take too much time to converge. We start inserting large charts in a small atlas. Using brute force is lame, because most of the space - // is occupied at this point. At the end we have many small charts and a large atlas with sparse holes. Finding those holes randomly is slow. A better approach would be to - // start stacking large charts as if they were tetris pieces. Once charts get small try to place them randomly. It may be interesting to try a intermediate strategy, first try - // along one axis and then try exhaustively along that axis. - bool findChartLocation(const Vector2i &startPosition, bool bruteForce, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, bool blockAligned, uint32_t maxResolution, bool allowRotate) - { + bool findChartLocation(const PackOptions &options, const Vector2i &startPosition, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, uint32_t maxResolution) { const int attempts = 4096; - if (bruteForce || attempts >= w * h) - return findChartLocation_bruteForce(startPosition, atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, blockAligned, maxResolution, allowRotate); - return findChartLocation_random(atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, attempts, blockAligned, maxResolution, allowRotate); + if (options.bruteForce || attempts >= w * h) + return findChartLocation_bruteForce(options, startPosition, atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, maxResolution); + return findChartLocation_random(options, atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, attempts, maxResolution); } - bool findChartLocation_bruteForce(const Vector2i &startPosition, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, bool blockAligned, uint32_t maxResolution, bool allowRotate) - { - const int stepSize = blockAligned ? 4 : 1; + bool findChartLocation_bruteForce(const PackOptions &options, const Vector2i &startPosition, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, uint32_t maxResolution) { + const int stepSize = options.blockAlign ? 4 : 1; int best_metric = INT_MAX; // Try two different orientations. for (int r = 0; r < 2; r++) { int cw = chartBitImage->width(); int ch = chartBitImage->height(); if (r == 1) { - if (allowRotate) + if (options.rotateCharts) swap(cw, ch); else break; @@ -9016,15 +8311,14 @@ private: return best_metric != INT_MAX; } - bool findChartLocation_random(const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, int minTrialCount, bool blockAligned, uint32_t maxResolution, bool allowRotate) - { + bool findChartLocation_random(const PackOptions &options, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, int attempts, uint32_t maxResolution) { bool result = false; const int BLOCK_SIZE = 4; int best_metric = INT_MAX; - for (int i = 0; i < minTrialCount; i++) { + for (int i = 0; i < attempts; i++) { int cw = chartBitImage->width(); int ch = chartBitImage->height(); - int r = allowRotate ? m_rand.getRange(1) : 0; + int r = options.rotateCharts ? m_rand.getRange(1) : 0; if (r == 1) swap(cw, ch); // + 1 to extend atlas in case atlas full. We may want to use a higher number to increase probability of extending atlas. @@ -9037,7 +8331,7 @@ private: } int x = m_rand.getRange(xRange); int y = m_rand.getRange(yRange); - if (blockAligned) { + if (options.blockAlign) { x = align(x, BLOCK_SIZE); y = align(y, BLOCK_SIZE); if (maxResolution > 0 && (x > (int)maxResolution - cw || y > (int)maxResolution - ch)) @@ -9062,7 +8356,7 @@ private: *best_y = y; *best_w = cw; *best_h = ch; - *best_r = allowRotate ? r : 0; + *best_r = options.rotateCharts ? r : 0; if (area == w * h) { // Chart is completely inside, do not look at any other location. break; @@ -9072,8 +8366,7 @@ private: return result; } - void addChart(BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int atlas_w, int atlas_h, int offset_x, int offset_y, int r) - { + void addChart(BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int atlas_w, int atlas_h, int offset_x, int offset_y, int r) { XA_DEBUG_ASSERT(r == 0 || r == 1); const BitImage *image = r == 0 ? chartBitImage : chartBitImageRotated; const int w = image->width(); @@ -9096,15 +8389,14 @@ private: } } - void bilinearExpand(const Chart *chart, BitImage *source, BitImage *dest, BitImage *destRotated, UniformGrid2 &boundaryEdgeGrid) const - { + void bilinearExpand(const Chart *chart, BitImage *source, BitImage *dest, BitImage *destRotated, UniformGrid2 &boundaryEdgeGrid) const { boundaryEdgeGrid.reset(chart->vertices, chart->indices); if (chart->boundaryEdges) { const uint32_t edgeCount = chart->boundaryEdges->size(); for (uint32_t i = 0; i < edgeCount; i++) boundaryEdgeGrid.append((*chart->boundaryEdges)[i]); } else { - for (uint32_t i = 0; i < chart->indexCount; i++) + for (uint32_t i = 0; i < chart->indices.length; i++) boundaryEdgeGrid.append(i); } const int xOffsets[] = { -1, 0, 1, -1, 1, -1, 0, 1 }; @@ -9152,13 +8444,11 @@ private: } } - struct DrawTriangleCallbackArgs - { + struct DrawTriangleCallbackArgs { BitImage *chartBitImage, *chartBitImageRotated; }; - static bool drawTriangleCallback(void *param, int x, int y) - { + static bool drawTriangleCallback(void *param, int x, int y) { auto args = (DrawTriangleCallbackArgs *)param; args->chartBitImage->set(x, y); if (args->chartBitImageRotated) @@ -9180,8 +8470,14 @@ private: } // namespace pack } // namespace internal -struct Context -{ +// Used to map triangulated polygons back to polygons. +struct MeshPolygonMapping { + internal::Array<uint8_t> faceVertexCount; // Copied from MeshDecl::faceVertexCount. + internal::Array<uint32_t> triangleToPolygonMap; // Triangle index (mesh face index) to polygon index. + internal::Array<uint32_t> triangleToPolygonIndicesMap; // Triangle indices to polygon indices. +}; + +struct Context { Atlas atlas; internal::Progress *addMeshProgress = nullptr; internal::TaskGroupHandle addMeshTaskGroup; @@ -9190,20 +8486,20 @@ struct Context void *progressUserData = nullptr; internal::TaskScheduler *taskScheduler; internal::Array<internal::Mesh *> meshes; + internal::Array<MeshPolygonMapping *> meshPolygonMappings; internal::Array<internal::UvMesh *> uvMeshes; internal::Array<internal::UvMeshInstance *> uvMeshInstances; + bool uvMeshChartsComputed = false; }; -Atlas *Create() -{ +Atlas *Create() { Context *ctx = XA_NEW(internal::MemTag::Default, Context); memset(&ctx->atlas, 0, sizeof(Atlas)); ctx->taskScheduler = XA_NEW(internal::MemTag::Default, internal::TaskScheduler); return &ctx->atlas; } -static void DestroyOutputMeshes(Context *ctx) -{ +static void DestroyOutputMeshes(Context *ctx) { if (!ctx->atlas.meshes) return; for (int i = 0; i < (int)ctx->atlas.meshCount; i++) { @@ -9224,8 +8520,7 @@ static void DestroyOutputMeshes(Context *ctx) ctx->atlas.meshes = nullptr; } -void Destroy(Atlas *atlas) -{ +void Destroy(Atlas *atlas) { XA_DEBUG_ASSERT(atlas); Context *ctx = (Context *)atlas; if (atlas->utilization) @@ -9244,6 +8539,13 @@ void Destroy(Atlas *atlas) mesh->~Mesh(); XA_FREE(mesh); } + for (uint32_t i = 0; i < ctx->meshPolygonMappings.size(); i++) { + MeshPolygonMapping *mapping = ctx->meshPolygonMappings[i]; + if (mapping) { + mapping->~MeshPolygonMapping(); + XA_FREE(mapping); + } + } for (uint32_t i = 0; i < ctx->uvMeshes.size(); i++) { internal::UvMesh *mesh = ctx->uvMeshes[i]; for (uint32_t j = 0; j < mesh->charts.size(); j++) { @@ -9265,66 +8567,52 @@ void Destroy(Atlas *atlas) #endif } -struct AddMeshTaskArgs -{ - Context *ctx; - internal::Mesh *mesh; -}; - -static void runAddMeshTask(void *userData) -{ +static void runAddMeshTask(void *groupUserData, void *taskUserData) { XA_PROFILE_START(addMeshThread) - auto args = (AddMeshTaskArgs *)userData; // Responsible for freeing this. - internal::Mesh *mesh = args->mesh; - internal::Progress *progress = args->ctx->addMeshProgress; - if (progress->cancel) - goto cleanup; - { - XA_PROFILE_START(addMeshCreateColocals) - mesh->createColocals(); - XA_PROFILE_END(addMeshCreateColocals) + auto ctx = (Context *)groupUserData; + auto mesh = (internal::Mesh *)taskUserData; + internal::Progress *progress = ctx->addMeshProgress; + if (progress->cancel) { + XA_PROFILE_END(addMeshThread) + return; } - if (progress->cancel) - goto cleanup; - progress->value++; - progress->update(); -cleanup: - args->~AddMeshTaskArgs(); - XA_FREE(args); + XA_PROFILE_START(addMeshCreateColocals) + mesh->createColocals(); + XA_PROFILE_END(addMeshCreateColocals) + if (progress->cancel) { + XA_PROFILE_END(addMeshThread) + return; + } + progress->increment(1); XA_PROFILE_END(addMeshThread) } -static internal::Vector3 DecodePosition(const MeshDecl &meshDecl, uint32_t index) -{ +static internal::Vector3 DecodePosition(const MeshDecl &meshDecl, uint32_t index) { XA_DEBUG_ASSERT(meshDecl.vertexPositionData); XA_DEBUG_ASSERT(meshDecl.vertexPositionStride > 0); return *((const internal::Vector3 *)&((const uint8_t *)meshDecl.vertexPositionData)[meshDecl.vertexPositionStride * index]); } -static internal::Vector3 DecodeNormal(const MeshDecl &meshDecl, uint32_t index) -{ +static internal::Vector3 DecodeNormal(const MeshDecl &meshDecl, uint32_t index) { XA_DEBUG_ASSERT(meshDecl.vertexNormalData); XA_DEBUG_ASSERT(meshDecl.vertexNormalStride > 0); return *((const internal::Vector3 *)&((const uint8_t *)meshDecl.vertexNormalData)[meshDecl.vertexNormalStride * index]); } -static internal::Vector2 DecodeUv(const MeshDecl &meshDecl, uint32_t index) -{ +static internal::Vector2 DecodeUv(const MeshDecl &meshDecl, uint32_t index) { XA_DEBUG_ASSERT(meshDecl.vertexUvData); XA_DEBUG_ASSERT(meshDecl.vertexUvStride > 0); return *((const internal::Vector2 *)&((const uint8_t *)meshDecl.vertexUvData)[meshDecl.vertexUvStride * index]); } -static uint32_t DecodeIndex(IndexFormat::Enum format, const void *indexData, int32_t offset, uint32_t i) -{ +static uint32_t DecodeIndex(IndexFormat format, const void *indexData, int32_t offset, uint32_t i) { XA_DEBUG_ASSERT(indexData); if (format == IndexFormat::UInt16) return uint16_t((int32_t)((const uint16_t *)indexData)[i] + offset); return uint32_t((int32_t)((const uint32_t *)indexData)[i] + offset); } -AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint) -{ +AddMeshError AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint) { XA_DEBUG_ASSERT(atlas); if (!atlas) { XA_PRINT_WARNING("AddMesh: atlas is null.\n"); @@ -9337,33 +8625,36 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh } #if XA_PROFILE if (ctx->meshes.isEmpty()) - internal::s_profile.addMeshReal = clock(); + internal::s_profile.addMeshRealStart = std::chrono::high_resolution_clock::now(); #endif // Don't know how many times AddMesh will be called, so progress needs to adjusted each time. if (!ctx->addMeshProgress) { ctx->addMeshProgress = XA_NEW_ARGS(internal::MemTag::Default, internal::Progress, ProgressCategory::AddMesh, ctx->progressFunc, ctx->progressUserData, 1); - } - else { + } else { ctx->addMeshProgress->setMaxValue(internal::max(ctx->meshes.size() + 1, meshCountHint)); } XA_PROFILE_START(addMeshCopyData) const bool hasIndices = meshDecl.indexCount > 0; const uint32_t indexCount = hasIndices ? meshDecl.indexCount : meshDecl.vertexCount; - XA_PRINT("Adding mesh %d: %u vertices, %u triangles\n", ctx->meshes.size(), meshDecl.vertexCount, indexCount / 3); - // Expecting triangle faces. - if ((indexCount % 3) != 0) - return AddMeshError::InvalidIndexCount; - if (hasIndices) { - // Check if any index is out of range. - for (uint32_t i = 0; i < indexCount; i++) { - const uint32_t index = DecodeIndex(meshDecl.indexFormat, meshDecl.indexData, meshDecl.indexOffset, i); - if (index >= meshDecl.vertexCount) - return AddMeshError::IndexOutOfRange; + uint32_t faceCount = indexCount / 3; + if (meshDecl.faceVertexCount) { + faceCount = meshDecl.faceCount; + XA_PRINT("Adding mesh %d: %u vertices, %u polygons\n", ctx->meshes.size(), meshDecl.vertexCount, faceCount); + for (uint32_t f = 0; f < faceCount; f++) { + if (meshDecl.faceVertexCount[f] < 3) + return AddMeshError::InvalidFaceVertexCount; } + } else { + XA_PRINT("Adding mesh %d: %u vertices, %u triangles\n", ctx->meshes.size(), meshDecl.vertexCount, faceCount); + // Expecting triangle faces unless otherwise specified. + if ((indexCount % 3) != 0) + return AddMeshError::InvalidIndexCount; } uint32_t meshFlags = internal::MeshFlags::HasIgnoredFaces; if (meshDecl.vertexNormalData) meshFlags |= internal::MeshFlags::HasNormals; + if (meshDecl.faceMaterialData) + meshFlags |= internal::MeshFlags::HasMaterials; internal::Mesh *mesh = XA_NEW_ARGS(internal::MemTag::Mesh, internal::Mesh, meshDecl.epsilon, meshDecl.vertexCount, indexCount / 3, meshFlags, ctx->meshes.size()); for (uint32_t i = 0; i < meshDecl.vertexCount; i++) { internal::Vector3 normal(0.0f); @@ -9374,17 +8665,42 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh texcoord = DecodeUv(meshDecl, i); mesh->addVertex(DecodePosition(meshDecl, i), normal, texcoord); } + MeshPolygonMapping *meshPolygonMapping = nullptr; + if (meshDecl.faceVertexCount) { + meshPolygonMapping = XA_NEW(internal::MemTag::Default, MeshPolygonMapping); + // Copy MeshDecl::faceVertexCount so it can be used later when building output meshes. + meshPolygonMapping->faceVertexCount.copyFrom(meshDecl.faceVertexCount, meshDecl.faceCount); + // There should be at least as many triangles as polygons. + meshPolygonMapping->triangleToPolygonMap.reserve(meshDecl.faceCount); + meshPolygonMapping->triangleToPolygonIndicesMap.reserve(meshDecl.indexCount); + } const uint32_t kMaxWarnings = 50; uint32_t warningCount = 0; - for (uint32_t i = 0; i < indexCount / 3; i++) { - uint32_t tri[3]; - for (int j = 0; j < 3; j++) - tri[j] = hasIndices ? DecodeIndex(meshDecl.indexFormat, meshDecl.indexData, meshDecl.indexOffset, i * 3 + j) : i * 3 + j; + internal::Array<uint32_t> triIndices; + uint32_t firstFaceIndex = 0; + internal::Triangulator triangulator; + for (uint32_t face = 0; face < faceCount; face++) { + // Decode face indices. + const uint32_t faceVertexCount = meshDecl.faceVertexCount ? (uint32_t)meshDecl.faceVertexCount[face] : 3; + uint32_t polygon[UINT8_MAX]; + for (uint32_t i = 0; i < faceVertexCount; i++) { + if (hasIndices) { + polygon[i] = DecodeIndex(meshDecl.indexFormat, meshDecl.indexData, meshDecl.indexOffset, face * faceVertexCount + i); + // Check if any index is out of range. + if (polygon[i] >= meshDecl.vertexCount) { + mesh->~Mesh(); + XA_FREE(mesh); + return AddMeshError::IndexOutOfRange; + } + } else { + polygon[i] = face * faceVertexCount + i; + } + } + // Ignore faces with degenerate or zero length edges. bool ignore = false; - // Check for degenerate or zero length edges. - for (int j = 0; j < 3; j++) { - const uint32_t index1 = tri[j]; - const uint32_t index2 = tri[(j + 1) % 3]; + for (uint32_t i = 0; i < faceVertexCount; i++) { + const uint32_t index1 = polygon[i]; + const uint32_t index2 = polygon[(i + 1) % 3]; if (index1 == index2) { ignore = true; if (++warningCount <= kMaxWarnings) @@ -9402,119 +8718,136 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh } // Ignore faces with any nan vertex attributes. if (!ignore) { - for (int j = 0; j < 3; j++) { - const internal::Vector3 &pos = mesh->position(tri[j]); + for (uint32_t i = 0; i < faceVertexCount; i++) { + const internal::Vector3 &pos = mesh->position(polygon[i]); if (internal::isNan(pos.x) || internal::isNan(pos.y) || internal::isNan(pos.z)) { if (++warningCount <= kMaxWarnings) - XA_PRINT(" NAN position in face: %d\n", i); + XA_PRINT(" NAN position in face: %d\n", face); ignore = true; break; } if (meshDecl.vertexNormalData) { - const internal::Vector3 &normal = mesh->normal(tri[j]); + const internal::Vector3 &normal = mesh->normal(polygon[i]); if (internal::isNan(normal.x) || internal::isNan(normal.y) || internal::isNan(normal.z)) { if (++warningCount <= kMaxWarnings) - XA_PRINT(" NAN normal in face: %d\n", i); + XA_PRINT(" NAN normal in face: %d\n", face); ignore = true; break; } } if (meshDecl.vertexUvData) { - const internal::Vector2 &uv = mesh->texcoord(tri[j]); + const internal::Vector2 &uv = mesh->texcoord(polygon[i]); if (internal::isNan(uv.x) || internal::isNan(uv.y)) { if (++warningCount <= kMaxWarnings) - XA_PRINT(" NAN texture coordinate in face: %d\n", i); + XA_PRINT(" NAN texture coordinate in face: %d\n", face); ignore = true; break; } } } } - const internal::Vector3 &a = mesh->position(tri[0]); - const internal::Vector3 &b = mesh->position(tri[1]); - const internal::Vector3 &c = mesh->position(tri[2]); - // Check for zero area faces. - float area = 0.0f; - if (!ignore) { - area = internal::length(internal::cross(b - a, c - a)) * 0.5f; - if (area <= internal::kAreaEpsilon) { - ignore = true; - if (++warningCount <= kMaxWarnings) - XA_PRINT(" Zero area face: %d, indices (%d %d %d), area is %f\n", i, tri[0], tri[1], tri[2], area); - } + // Triangulate if necessary. + triIndices.clear(); + if (faceVertexCount == 3) { + triIndices.push_back(polygon[0]); + triIndices.push_back(polygon[1]); + triIndices.push_back(polygon[2]); + } else { + triangulator.triangulatePolygon(mesh->positions(), internal::ConstArrayView<uint32_t>(polygon, faceVertexCount), triIndices); } + // Check for zero area faces. if (!ignore) { - if (internal::equal(a, b, meshDecl.epsilon) || internal::equal(a, c, meshDecl.epsilon) || internal::equal(b, c, meshDecl.epsilon)) { - ignore = true; - if (++warningCount <= kMaxWarnings) - XA_PRINT(" Degenerate face: %d, area is %f\n", i, area); + for (uint32_t i = 0; i < triIndices.size(); i += 3) { + const internal::Vector3 &a = mesh->position(triIndices[i + 0]); + const internal::Vector3 &b = mesh->position(triIndices[i + 1]); + const internal::Vector3 &c = mesh->position(triIndices[i + 2]); + const float area = internal::length(internal::cross(b - a, c - a)) * 0.5f; + if (area <= internal::kAreaEpsilon) { + ignore = true; + if (++warningCount <= kMaxWarnings) + XA_PRINT(" Zero area face: %d, area is %f\n", face, area); + break; + } } } - if (meshDecl.faceIgnoreData && meshDecl.faceIgnoreData[i]) + // User face ignore. + if (meshDecl.faceIgnoreData && meshDecl.faceIgnoreData[face]) ignore = true; - mesh->addFace(tri[0], tri[1], tri[2], ignore); + // User material. + uint32_t material = UINT32_MAX; + if (meshDecl.faceMaterialData) + material = meshDecl.faceMaterialData[face]; + // Add the face(s). + for (uint32_t i = 0; i < triIndices.size(); i += 3) { + mesh->addFace(&triIndices[i], ignore, material); + if (meshPolygonMapping) + meshPolygonMapping->triangleToPolygonMap.push_back(face); + } + if (meshPolygonMapping) { + for (uint32_t i = 0; i < triIndices.size(); i++) + meshPolygonMapping->triangleToPolygonIndicesMap.push_back(triIndices[i]); + } + firstFaceIndex += faceVertexCount; } if (warningCount > kMaxWarnings) XA_PRINT(" %u additional warnings truncated\n", warningCount - kMaxWarnings); XA_PROFILE_END(addMeshCopyData) ctx->meshes.push_back(mesh); + ctx->meshPolygonMappings.push_back(meshPolygonMapping); ctx->paramAtlas.addMesh(mesh); if (ctx->addMeshTaskGroup.value == UINT32_MAX) - ctx->addMeshTaskGroup = ctx->taskScheduler->createTaskGroup(); - AddMeshTaskArgs *taskArgs = XA_NEW(internal::MemTag::Default, AddMeshTaskArgs); // The task frees this. - taskArgs->ctx = ctx; - taskArgs->mesh = mesh; + ctx->addMeshTaskGroup = ctx->taskScheduler->createTaskGroup(ctx); internal::Task task; - task.userData = taskArgs; + task.userData = mesh; task.func = runAddMeshTask; ctx->taskScheduler->run(ctx->addMeshTaskGroup, task); return AddMeshError::Success; } -void AddMeshJoin(Atlas *atlas) -{ +void AddMeshJoin(Atlas *atlas) { XA_DEBUG_ASSERT(atlas); if (!atlas) { XA_PRINT_WARNING("AddMeshJoin: atlas is null.\n"); return; } Context *ctx = (Context *)atlas; - if (!ctx->addMeshProgress) - return; - ctx->taskScheduler->wait(&ctx->addMeshTaskGroup); - ctx->addMeshProgress->~Progress(); - XA_FREE(ctx->addMeshProgress); - ctx->addMeshProgress = nullptr; + if (!ctx->uvMeshes.isEmpty()) { #if XA_PROFILE - XA_PRINT("Added %u meshes\n", ctx->meshes.size()); - internal::s_profile.addMeshReal = clock() - internal::s_profile.addMeshReal; + XA_PRINT("Added %u UV meshes\n", ctx->uvMeshes.size()); + internal::s_profile.addMeshReal = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - internal::s_profile.addMeshRealStart).count()); #endif - XA_PROFILE_PRINT_AND_RESET(" Total (real): ", addMeshReal) - XA_PROFILE_PRINT_AND_RESET(" Copy data: ", addMeshCopyData) - XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", addMeshThread) - XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", addMeshCreateColocals) + XA_PROFILE_PRINT_AND_RESET(" Total: ", addMeshReal) + XA_PROFILE_PRINT_AND_RESET(" Copy data: ", addMeshCopyData) #if XA_PROFILE_ALLOC - XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc) + XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc) #endif - XA_PRINT_MEM_USAGE + XA_PRINT_MEM_USAGE + } else { + if (!ctx->addMeshProgress) + return; + ctx->taskScheduler->wait(&ctx->addMeshTaskGroup); + ctx->addMeshProgress->~Progress(); + XA_FREE(ctx->addMeshProgress); + ctx->addMeshProgress = nullptr; +#if XA_PROFILE + XA_PRINT("Added %u meshes\n", ctx->meshes.size()); + internal::s_profile.addMeshReal = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - internal::s_profile.addMeshRealStart).count()); +#endif + XA_PROFILE_PRINT_AND_RESET(" Total (real): ", addMeshReal) + XA_PROFILE_PRINT_AND_RESET(" Copy data: ", addMeshCopyData) + XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", addMeshThread) + XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", addMeshCreateColocals) +#if XA_PROFILE_ALLOC + XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc) +#endif + XA_PRINT_MEM_USAGE #if XA_DEBUG_EXPORT_OBJ_FACE_GROUPS - internal::param::s_faceGroupsCurrentVertex = 0; + internal::param::s_faceGroupsCurrentVertex = 0; #endif + } } -struct EdgeKey -{ - EdgeKey() {} - EdgeKey(const EdgeKey &k) : v0(k.v0), v1(k.v1) {} - EdgeKey(uint32_t v0, uint32_t v1) : v0(v0), v1(v1) {} - bool operator==(const EdgeKey &k) const { return v0 == k.v0 && v1 == k.v1; } - - uint32_t v0; - uint32_t v1; -}; - -AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl) -{ +AddMeshError AddUvMesh(Atlas *atlas, const UvMeshDecl &decl) { XA_DEBUG_ASSERT(atlas); if (!atlas) { XA_PRINT_WARNING("AddUvMesh: atlas is null.\n"); @@ -9525,13 +8858,18 @@ AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl) XA_PRINT_WARNING("AddUvMesh: Meshes and UV meshes cannot be added to the same atlas.\n"); return AddMeshError::Error; } - const bool decoded = (decl.indexCount <= 0); - const uint32_t indexCount = decoded ? decl.vertexCount : decl.indexCount; +#if XA_PROFILE + if (ctx->uvMeshInstances.isEmpty()) + internal::s_profile.addMeshRealStart = std::chrono::high_resolution_clock::now(); +#endif + XA_PROFILE_START(addMeshCopyData) + const bool hasIndices = decl.indexCount > 0; + const uint32_t indexCount = hasIndices ? decl.indexCount : decl.vertexCount; XA_PRINT("Adding UV mesh %d: %u vertices, %u triangles\n", ctx->uvMeshes.size(), decl.vertexCount, indexCount / 3); // Expecting triangle faces. if ((indexCount % 3) != 0) return AddMeshError::InvalidIndexCount; - if (!decoded) { + if (hasIndices) { // Check if any index is out of range. for (uint32_t i = 0; i < indexCount; i++) { const uint32_t index = DecodeIndex(decl.indexFormat, decl.indexData, decl.indexOffset, i); @@ -9539,319 +8877,266 @@ AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl) return AddMeshError::IndexOutOfRange; } } + // Create a mesh instance. internal::UvMeshInstance *meshInstance = XA_NEW(internal::MemTag::Default, internal::UvMeshInstance); - meshInstance->texcoords.resize(decl.vertexCount); - for (uint32_t i = 0; i < decl.vertexCount; i++) { - internal::Vector2 texcoord = *((const internal::Vector2 *)&((const uint8_t *)decl.vertexUvData)[decl.vertexStride * i]); - // Set nan values to 0. - if (internal::isNan(texcoord.x) || internal::isNan(texcoord.y)) - texcoord.x = texcoord.y = 0.0f; - meshInstance->texcoords[i] = texcoord; - } - meshInstance->rotateCharts = decl.rotateCharts; + meshInstance->mesh = nullptr; + ctx->uvMeshInstances.push_back(meshInstance); // See if this is an instance of an already existing mesh. internal::UvMesh *mesh = nullptr; for (uint32_t m = 0; m < ctx->uvMeshes.size(); m++) { if (memcmp(&ctx->uvMeshes[m]->decl, &decl, sizeof(UvMeshDecl)) == 0) { - meshInstance->mesh = mesh = ctx->uvMeshes[m]; + mesh = ctx->uvMeshes[m]; + XA_PRINT(" instance of a previous UV mesh\n"); break; } } if (!mesh) { // Copy geometry to mesh. - meshInstance->mesh = mesh = XA_NEW(internal::MemTag::Default, internal::UvMesh); + mesh = XA_NEW(internal::MemTag::Default, internal::UvMesh); + ctx->uvMeshes.push_back(mesh); mesh->decl = decl; + if (decl.faceMaterialData) { + mesh->faceMaterials.resize(decl.indexCount / 3); + memcpy(mesh->faceMaterials.data(), decl.faceMaterialData, mesh->faceMaterials.size() * sizeof(uint32_t)); + } mesh->indices.resize(decl.indexCount); for (uint32_t i = 0; i < indexCount; i++) - mesh->indices[i] = decoded ? i : DecodeIndex(decl.indexFormat, decl.indexData, decl.indexOffset, i); - mesh->vertexToChartMap.resize(decl.vertexCount); - for (uint32_t i = 0; i < mesh->vertexToChartMap.size(); i++) - mesh->vertexToChartMap[i] = UINT32_MAX; - // Calculate charts (incident faces). - internal::HashMap<internal::Vector2> vertexToFaceMap(internal::MemTag::Default, indexCount); // Face is index / 3 - const uint32_t faceCount = indexCount / 3; - for (uint32_t i = 0; i < indexCount; i++) - vertexToFaceMap.add(meshInstance->texcoords[mesh->indices[i]]); - internal::BitArray faceAssigned(faceCount); - faceAssigned.zeroOutMemory(); - for (uint32_t f = 0; f < faceCount; f++) { - if (faceAssigned.get(f)) - continue; - // Found an unassigned face, create a new chart. - internal::UvMeshChart *chart = XA_NEW(internal::MemTag::Default, internal::UvMeshChart); - chart->material = decl.faceMaterialData ? decl.faceMaterialData[f] : 0; - // Walk incident faces and assign them to the chart. - faceAssigned.set(f); - chart->faces.push_back(f); - for (;;) { - bool newFaceAssigned = false; - const uint32_t faceCount2 = chart->faces.size(); - for (uint32_t f2 = 0; f2 < faceCount2; f2++) { - const uint32_t face = chart->faces[f2]; - for (uint32_t i = 0; i < 3; i++) { - const internal::Vector2 &texcoord = meshInstance->texcoords[meshInstance->mesh->indices[face * 3 + i]]; - uint32_t mapIndex = vertexToFaceMap.get(texcoord); - while (mapIndex != UINT32_MAX) { - const uint32_t face2 = mapIndex / 3; // 3 vertices added per face. - // Materials must match. - if (!faceAssigned.get(face2) && (!decl.faceMaterialData || decl.faceMaterialData[face] == decl.faceMaterialData[face2])) { - faceAssigned.set(face2); - chart->faces.push_back(face2); - newFaceAssigned = true; - } - mapIndex = vertexToFaceMap.getNext(mapIndex); - } - } - } - if (!newFaceAssigned) + mesh->indices[i] = hasIndices ? DecodeIndex(decl.indexFormat, decl.indexData, decl.indexOffset, i) : i; + mesh->texcoords.resize(decl.vertexCount); + for (uint32_t i = 0; i < decl.vertexCount; i++) + mesh->texcoords[i] = *((const internal::Vector2 *)&((const uint8_t *)decl.vertexUvData)[decl.vertexStride * i]); + // Validate. + mesh->faceIgnore.resize(decl.indexCount / 3); + mesh->faceIgnore.zeroOutMemory(); + const uint32_t kMaxWarnings = 50; + uint32_t warningCount = 0; + for (uint32_t f = 0; f < indexCount / 3; f++) { + bool ignore = false; + uint32_t tri[3]; + for (uint32_t i = 0; i < 3; i++) + tri[i] = mesh->indices[f * 3 + i]; + // Check for nan UVs. + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = tri[i]; + if (internal::isNan(mesh->texcoords[vertex].x) || internal::isNan(mesh->texcoords[vertex].y)) { + ignore = true; + if (++warningCount <= kMaxWarnings) + XA_PRINT(" NAN texture coordinate in vertex %u\n", vertex); break; + } } - for (uint32_t i = 0; i < chart->faces.size(); i++) { - for (uint32_t j = 0; j < 3; j++) { - const uint32_t vertex = meshInstance->mesh->indices[chart->faces[i] * 3 + j]; - chart->indices.push_back(vertex); - mesh->vertexToChartMap[vertex] = mesh->charts.size(); + // Check for zero area faces. + if (!ignore) { + const internal::Vector2 &v1 = mesh->texcoords[tri[0]]; + const internal::Vector2 &v2 = mesh->texcoords[tri[1]]; + const internal::Vector2 &v3 = mesh->texcoords[tri[2]]; + const float area = fabsf(((v2.x - v1.x) * (v3.y - v1.y) - (v3.x - v1.x) * (v2.y - v1.y)) * 0.5f); + if (area <= internal::kAreaEpsilon) { + ignore = true; + if (++warningCount <= kMaxWarnings) + XA_PRINT(" Zero area face: %d, indices (%d %d %d), area is %f\n", f, tri[0], tri[1], tri[2], area); } } - mesh->charts.push_back(chart); + if (ignore) + mesh->faceIgnore.set(f); } - ctx->uvMeshes.push_back(mesh); - } else { - XA_PRINT(" instance of a previous UV mesh\n"); + if (warningCount > kMaxWarnings) + XA_PRINT(" %u additional warnings truncated\n", warningCount - kMaxWarnings); } - XA_PRINT(" %u charts\n", meshInstance->mesh->charts.size()); - ctx->uvMeshInstances.push_back(meshInstance); + meshInstance->mesh = mesh; + XA_PROFILE_END(addMeshCopyData) return AddMeshError::Success; } -void ComputeCharts(Atlas *atlas, ChartOptions options) -{ +void ComputeCharts(Atlas *atlas, ChartOptions options) { if (!atlas) { XA_PRINT_WARNING("ComputeCharts: atlas is null.\n"); return; } Context *ctx = (Context *)atlas; - if (!ctx->uvMeshInstances.isEmpty()) { - XA_PRINT_WARNING("ComputeCharts: This function should not be called with UV meshes.\n"); - return; - } AddMeshJoin(atlas); - if (ctx->meshes.isEmpty()) { - XA_PRINT_WARNING("ComputeCharts: No meshes. Call AddMesh first.\n"); - return; - } - XA_PRINT("Computing charts\n"); - XA_PROFILE_START(computeChartsReal) - if (!ctx->paramAtlas.computeCharts(ctx->taskScheduler, options, ctx->progressFunc, ctx->progressUserData)) { - XA_PRINT(" Cancelled by user\n"); - return; - } - XA_PROFILE_END(computeChartsReal) - // Count charts. - uint32_t chartCount = 0; - const uint32_t meshCount = ctx->meshes.size(); - for (uint32_t i = 0; i < meshCount; i++) { - for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { - const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); - chartCount += chartGroup->segmentChartCount(); - } - } - XA_PRINT(" %u charts\n", chartCount); -#if XA_PROFILE - XA_PRINT(" Chart groups\n"); - uint32_t chartGroupCount = 0; - for (uint32_t i = 0; i < meshCount; i++) { - XA_PRINT(" Mesh %u: %u chart groups\n", i, ctx->paramAtlas.chartGroupCount(i)); - chartGroupCount += ctx->paramAtlas.chartGroupCount(i); - } - XA_PRINT(" %u total\n", chartGroupCount); -#endif - XA_PROFILE_PRINT_AND_RESET(" Total (real): ", computeChartsReal) - XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", computeChartsThread) - XA_PROFILE_PRINT_AND_RESET(" Create face groups: ", createFaceGroups) - XA_PROFILE_PRINT_AND_RESET(" Extract invalid mesh geometry: ", extractInvalidMeshGeometry) - XA_PROFILE_PRINT_AND_RESET(" Chart group compute charts (real): ", chartGroupComputeChartsReal) - XA_PROFILE_PRINT_AND_RESET(" Chart group compute charts (thread): ", chartGroupComputeChartsThread) - XA_PROFILE_PRINT_AND_RESET(" Create chart group mesh: ", createChartGroupMesh) - XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", createChartGroupMeshColocals) - XA_PROFILE_PRINT_AND_RESET(" Create boundaries: ", createChartGroupMeshBoundaries) - XA_PROFILE_PRINT_AND_RESET(" Build atlas: ", buildAtlas) - XA_PROFILE_PRINT_AND_RESET(" Init: ", buildAtlasInit) - XA_PROFILE_PRINT_AND_RESET(" Planar charts: ", planarCharts) - XA_PROFILE_PRINT_AND_RESET(" Clustered charts: ", clusteredCharts) - XA_PROFILE_PRINT_AND_RESET(" Place seeds: ", clusteredChartsPlaceSeeds) - XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", clusteredChartsPlaceSeedsBoundaryIntersection) - XA_PROFILE_PRINT_AND_RESET(" Relocate seeds: ", clusteredChartsRelocateSeeds) - XA_PROFILE_PRINT_AND_RESET(" Reset: ", clusteredChartsReset) - XA_PROFILE_PRINT_AND_RESET(" Grow: ", clusteredChartsGrow) - XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", clusteredChartsGrowBoundaryIntersection) - XA_PROFILE_PRINT_AND_RESET(" Merge: ", clusteredChartsMerge) - XA_PROFILE_PRINT_AND_RESET(" Fill holes: ", clusteredChartsFillHoles) - XA_PROFILE_PRINT_AND_RESET(" Copy chart faces: ", copyChartFaces) -#if XA_PROFILE_ALLOC - XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc) -#endif - XA_PRINT_MEM_USAGE -} - -void ParameterizeCharts(Atlas *atlas, ParameterizeOptions options) -{ - if (!atlas) { - XA_PRINT_WARNING("ParameterizeCharts: atlas is null.\n"); - return; - } - Context *ctx = (Context *)atlas; - if (!ctx->uvMeshInstances.isEmpty()) { - XA_PRINT_WARNING("ParameterizeCharts: This function should not be called with UV meshes.\n"); - return; - } - if (!ctx->paramAtlas.chartsComputed()) { - XA_PRINT_WARNING("ParameterizeCharts: ComputeCharts must be called first.\n"); + if (ctx->meshes.isEmpty() && ctx->uvMeshInstances.isEmpty()) { + XA_PRINT_WARNING("ComputeCharts: No meshes. Call AddMesh or AddUvMesh first.\n"); return; } - atlas->atlasCount = 0; - atlas->height = 0; - atlas->texelsPerUnit = 0; - atlas->width = 0; - if (atlas->utilization) { + // Reset atlas state. This function may be called multiple times, or again after PackCharts. + if (atlas->utilization) XA_FREE(atlas->utilization); - atlas->utilization = nullptr; - } - if (atlas->image) { + if (atlas->image) XA_FREE(atlas->image); - atlas->image = nullptr; - } DestroyOutputMeshes(ctx); - XA_PRINT("Parameterizing charts\n"); - XA_PROFILE_START(parameterizeChartsReal) - if (!ctx->paramAtlas.parameterizeCharts(ctx->taskScheduler, options, ctx->progressFunc, ctx->progressUserData)) { - XA_PRINT(" Cancelled by user\n"); + memset(&ctx->atlas, 0, sizeof(Atlas)); + XA_PRINT("Computing charts\n"); + if (!ctx->meshes.isEmpty()) { + if (!ctx->paramAtlas.computeCharts(ctx->taskScheduler, options, ctx->progressFunc, ctx->progressUserData)) { + XA_PRINT(" Cancelled by user\n"); return; - } - XA_PROFILE_END(parameterizeChartsReal) - const uint32_t meshCount = ctx->meshes.size(); - uint32_t chartCount = 0, chartsWithHolesCount = 0, holesCount = 0, chartsWithTJunctionsCount = 0, tJunctionsCount = 0, orthoChartsCount = 0, planarChartsCount = 0, lscmChartsCount = 0, piecewiseChartsCount = 0, chartsAddedCount = 0, chartsDeletedCount = 0; - for (uint32_t i = 0; i < meshCount; i++) { - for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { - const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); - for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { - const internal::param::Chart *chart = chartGroup->chartAt(k); -#if XA_PRINT_CHART_WARNINGS - if (chart->warningFlags() & internal::param::ChartWarningFlags::CloseHolesFailed) - XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): failed to close holes\n", chartCount, i, j, k); - if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsDuplicatedEdge) - XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions created non-manifold geometry\n", chartCount, i, j, k); - if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsFailed) - XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions failed\n", chartCount, i, j, k); - if (chart->warningFlags() & internal::param::ChartWarningFlags::TriangulateDuplicatedEdge) - XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): triangulation created non-manifold geometry\n", chartCount, i, j, k); -#endif - holesCount += chart->closedHolesCount(); - if (chart->closedHolesCount() > 0) - chartsWithHolesCount++; - tJunctionsCount += chart->fixedTJunctionsCount(); - if (chart->fixedTJunctionsCount() > 0) - chartsWithTJunctionsCount++; - if (chart->type() == ChartType::Planar) - planarChartsCount++; - else if (chart->type() == ChartType::Ortho) - orthoChartsCount++; - else if (chart->type() == ChartType::LSCM) - lscmChartsCount++; - else if (chart->type() == ChartType::Piecewise) - piecewiseChartsCount++; - } - chartCount += chartGroup->chartCount(); - chartsAddedCount += chartGroup->paramAddedChartsCount(); - chartsDeletedCount += chartGroup->paramDeletedChartsCount(); - } - } - if (holesCount > 0) - XA_PRINT(" %u holes closed in %u charts\n", holesCount, chartsWithHolesCount); - if (tJunctionsCount > 0) - XA_PRINT(" %u t-junctions fixed in %u charts\n", tJunctionsCount, chartsWithTJunctionsCount); - XA_PRINT(" %u planar charts, %u ortho charts, %u LSCM charts, %u piecewise charts\n", planarChartsCount, orthoChartsCount, lscmChartsCount, piecewiseChartsCount); - if (chartsDeletedCount > 0) { - XA_PRINT(" %u charts with invalid parameterizations replaced with %u new charts\n", chartsDeletedCount, chartsAddedCount); + } + uint32_t chartsWithTJunctionsCount = 0, tJunctionCount = 0, orthoChartsCount = 0, planarChartsCount = 0, lscmChartsCount = 0, piecewiseChartsCount = 0, originalUvChartsCount = 0; + uint32_t chartCount = 0; + const uint32_t meshCount = ctx->meshes.size(); + for (uint32_t i = 0; i < meshCount; i++) { + for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); + for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { + const internal::param::Chart *chart = chartGroup->chartAt(k); + tJunctionCount += chart->tjunctionCount(); + if (chart->tjunctionCount() > 0) + chartsWithTJunctionsCount++; + if (chart->type() == ChartType::Planar) + planarChartsCount++; + else if (chart->type() == ChartType::Ortho) + orthoChartsCount++; + else if (chart->type() == ChartType::LSCM) + lscmChartsCount++; + else if (chart->type() == ChartType::Piecewise) + piecewiseChartsCount++; + if (chart->generatorType() == internal::segment::ChartGeneratorType::OriginalUv) + originalUvChartsCount++; + } + chartCount += chartGroup->chartCount(); + } + } + if (tJunctionCount > 0) + XA_PRINT(" %u t-junctions found in %u charts\n", tJunctionCount, chartsWithTJunctionsCount); XA_PRINT(" %u charts\n", chartCount); - } - uint32_t chartIndex = 0, invalidParamCount = 0; - for (uint32_t i = 0; i < meshCount; i++) { - for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { - const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); - for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { - internal::param::Chart *chart = chartGroup->chartAt(k); - const internal::param::Quality &quality = chart->quality(); + XA_PRINT(" %u planar, %u ortho, %u LSCM, %u piecewise\n", planarChartsCount, orthoChartsCount, lscmChartsCount, piecewiseChartsCount); + if (originalUvChartsCount > 0) + XA_PRINT(" %u with original UVs\n", originalUvChartsCount); + uint32_t chartIndex = 0, invalidParamCount = 0; + for (uint32_t i = 0; i < meshCount; i++) { + for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); + for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { + internal::param::Chart *chart = chartGroup->chartAt(k); + const internal::param::Quality &quality = chart->quality(); #if XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION - { - char filename[256]; - XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_after_parameterization.obj", chartIndex); - chart->unifiedMesh()->writeObjFile(filename); - } -#endif - const char *type = "LSCM"; - if (chart->type() == ChartType::Planar) - type = "planar"; - else if (chart->type() == ChartType::Ortho) - type = "ortho"; - else if (chart->type() == ChartType::Piecewise) - type = "piecewise"; - if (chart->isInvalid()) { - if (quality.boundaryIntersection) { - XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, self-intersecting boundary.\n", chartIndex, i, j, k, type); - } - if (quality.flippedTriangleCount > 0) { - XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, %u / %u flipped triangles.\n", chartIndex, i, j, k, type, quality.flippedTriangleCount, quality.totalTriangleCount); + { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_after_parameterization.obj", chartIndex); + chart->unifiedMesh()->writeObjFile(filename); } - invalidParamCount++; +#endif + const char *type = "LSCM"; + if (chart->type() == ChartType::Planar) + type = "planar"; + else if (chart->type() == ChartType::Ortho) + type = "ortho"; + else if (chart->type() == ChartType::Piecewise) + type = "piecewise"; + if (chart->isInvalid()) { + if (quality.boundaryIntersection) { + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, self-intersecting boundary.\n", chartIndex, i, j, k, type); + } + if (quality.flippedTriangleCount > 0) { + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, %u / %u flipped triangles.\n", chartIndex, i, j, k, type, quality.flippedTriangleCount, quality.totalTriangleCount); + } + if (quality.zeroAreaTriangleCount > 0) { + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, %u / %u zero area triangles.\n", chartIndex, i, j, k, type, quality.zeroAreaTriangleCount, quality.totalTriangleCount); + } + invalidParamCount++; #if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION - char filename[256]; - XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_invalid_parameterization.obj", chartIndex); - const internal::Mesh *mesh = chart->unifiedMesh(); - FILE *file; - XA_FOPEN(file, filename, "w"); - if (file) { - mesh->writeObjVertices(file); - fprintf(file, "s off\n"); - fprintf(file, "o object\n"); - for (uint32_t f = 0; f < mesh->faceCount(); f++) - mesh->writeObjFace(file, f); - if (!chart->paramFlippedFaces().isEmpty()) { - fprintf(file, "o flipped_faces\n"); - for (uint32_t f = 0; f < chart->paramFlippedFaces().size(); f++) - mesh->writeObjFace(file, chart->paramFlippedFaces()[f]); + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_invalid_parameterization.obj", chartIndex); + const internal::Mesh *mesh = chart->unifiedMesh(); + FILE *file; + XA_FOPEN(file, filename, "w"); + if (file) { + mesh->writeObjVertices(file); + fprintf(file, "s off\n"); + fprintf(file, "o object\n"); + for (uint32_t f = 0; f < mesh->faceCount(); f++) + mesh->writeObjFace(file, f); + if (!chart->paramFlippedFaces().isEmpty()) { + fprintf(file, "o flipped_faces\n"); + for (uint32_t f = 0; f < chart->paramFlippedFaces().size(); f++) + mesh->writeObjFace(file, chart->paramFlippedFaces()[f]); + } + mesh->writeObjBoundaryEges(file); + fclose(file); } - mesh->writeObjBoundaryEges(file); - mesh->writeObjLinkedBoundaries(file); - fclose(file); - } #endif + } + chartIndex++; } - chartIndex++; } } + if (invalidParamCount > 0) + XA_PRINT_WARNING(" %u charts with invalid parameterizations\n", invalidParamCount); +#if XA_PROFILE + XA_PRINT(" Chart groups\n"); + uint32_t chartGroupCount = 0; + for (uint32_t i = 0; i < meshCount; i++) { +#if 0 + XA_PRINT(" Mesh %u: %u chart groups\n", i, ctx->paramAtlas.chartGroupCount(i)); +#endif + chartGroupCount += ctx->paramAtlas.chartGroupCount(i); + } + XA_PRINT(" %u total\n", chartGroupCount); +#endif + XA_PROFILE_PRINT_AND_RESET(" Compute charts total (real): ", computeChartsReal) + XA_PROFILE_PRINT_AND_RESET(" Compute charts total (thread): ", computeChartsThread) + XA_PROFILE_PRINT_AND_RESET(" Create face groups: ", createFaceGroups) + XA_PROFILE_PRINT_AND_RESET(" Extract invalid mesh geometry: ", extractInvalidMeshGeometry) + XA_PROFILE_PRINT_AND_RESET(" Chart group compute charts (real): ", chartGroupComputeChartsReal) + XA_PROFILE_PRINT_AND_RESET(" Chart group compute charts (thread): ", chartGroupComputeChartsThread) + XA_PROFILE_PRINT_AND_RESET(" Create chart group mesh: ", createChartGroupMesh) + XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", createChartGroupMeshColocals) + XA_PROFILE_PRINT_AND_RESET(" Create boundaries: ", createChartGroupMeshBoundaries) + XA_PROFILE_PRINT_AND_RESET(" Build atlas: ", buildAtlas) + XA_PROFILE_PRINT_AND_RESET(" Init: ", buildAtlasInit) + XA_PROFILE_PRINT_AND_RESET(" Planar charts: ", planarCharts) + if (options.useInputMeshUvs) { + XA_PROFILE_PRINT_AND_RESET(" Original UV charts: ", originalUvCharts) + } + XA_PROFILE_PRINT_AND_RESET(" Clustered charts: ", clusteredCharts) + XA_PROFILE_PRINT_AND_RESET(" Place seeds: ", clusteredChartsPlaceSeeds) + XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", clusteredChartsPlaceSeedsBoundaryIntersection) + XA_PROFILE_PRINT_AND_RESET(" Relocate seeds: ", clusteredChartsRelocateSeeds) + XA_PROFILE_PRINT_AND_RESET(" Reset: ", clusteredChartsReset) + XA_PROFILE_PRINT_AND_RESET(" Grow: ", clusteredChartsGrow) + XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", clusteredChartsGrowBoundaryIntersection) + XA_PROFILE_PRINT_AND_RESET(" Merge: ", clusteredChartsMerge) + XA_PROFILE_PRINT_AND_RESET(" Fill holes: ", clusteredChartsFillHoles) + XA_PROFILE_PRINT_AND_RESET(" Copy chart faces: ", copyChartFaces) + XA_PROFILE_PRINT_AND_RESET(" Create chart mesh and parameterize (real): ", createChartMeshAndParameterizeReal) + XA_PROFILE_PRINT_AND_RESET(" Create chart mesh and parameterize (thread): ", createChartMeshAndParameterizeThread) + XA_PROFILE_PRINT_AND_RESET(" Create chart mesh: ", createChartMesh) + XA_PROFILE_PRINT_AND_RESET(" Parameterize charts: ", parameterizeCharts) + XA_PROFILE_PRINT_AND_RESET(" Orthogonal: ", parameterizeChartsOrthogonal) + XA_PROFILE_PRINT_AND_RESET(" LSCM: ", parameterizeChartsLSCM) + XA_PROFILE_PRINT_AND_RESET(" Recompute: ", parameterizeChartsRecompute) + XA_PROFILE_PRINT_AND_RESET(" Piecewise: ", parameterizeChartsPiecewise) + XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", parameterizeChartsPiecewiseBoundaryIntersection) + XA_PROFILE_PRINT_AND_RESET(" Evaluate quality: ", parameterizeChartsEvaluateQuality) +#if XA_PROFILE_ALLOC + XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc) +#endif + XA_PRINT_MEM_USAGE + } else { + XA_PROFILE_START(computeChartsReal) + if (!internal::segment::computeUvMeshCharts(ctx->taskScheduler, ctx->uvMeshes, ctx->progressFunc, ctx->progressUserData)) { + XA_PRINT(" Cancelled by user\n"); + return; + } + XA_PROFILE_END(computeChartsReal) + ctx->uvMeshChartsComputed = true; + // Count charts. + uint32_t chartCount = 0; + const uint32_t meshCount = ctx->uvMeshes.size(); + for (uint32_t i = 0; i < meshCount; i++) + chartCount += ctx->uvMeshes[i]->charts.size(); + XA_PRINT(" %u charts\n", chartCount); + XA_PROFILE_PRINT_AND_RESET(" Total (real): ", computeChartsReal) + XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", computeChartsThread) } - if (invalidParamCount > 0) - XA_PRINT_WARNING(" %u charts with invalid parameterizations\n", invalidParamCount); - XA_PROFILE_PRINT_AND_RESET(" Total (real): ", parameterizeChartsReal) - XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", parameterizeChartsThread) - XA_PROFILE_PRINT_AND_RESET(" Create chart mesh: ", createChartMesh) - XA_PROFILE_PRINT_AND_RESET(" Fix t-junctions: ", fixChartMeshTJunctions) - XA_PROFILE_PRINT_AND_RESET(" Close holes: ", closeChartMeshHoles) - XA_PROFILE_PRINT_AND_RESET(" Orthogonal: ", parameterizeChartsOrthogonal) - XA_PROFILE_PRINT_AND_RESET(" LSCM: ", parameterizeChartsLSCM) - XA_PROFILE_PRINT_AND_RESET(" Recompute: ", parameterizeChartsRecompute) - XA_PROFILE_PRINT_AND_RESET(" Piecewise: ", parameterizeChartsPiecewise) - XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", parameterizeChartsPiecewiseBoundaryIntersection) - XA_PROFILE_PRINT_AND_RESET(" Evaluate quality: ", parameterizeChartsEvaluateQuality) #if XA_PROFILE_ALLOC XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc) #endif XA_PRINT_MEM_USAGE } -void PackCharts(Atlas *atlas, PackOptions packOptions) -{ +void PackCharts(Atlas *atlas, PackOptions packOptions) { // Validate arguments and context state. if (!atlas) { XA_PRINT_WARNING("PackCharts: atlas is null.\n"); @@ -9867,10 +9152,9 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) XA_PRINT_WARNING("PackCharts: ComputeCharts must be called first.\n"); return; } - if (!ctx->paramAtlas.chartsParameterized()) { - XA_PRINT_WARNING("PackCharts: ParameterizeCharts must be called first.\n"); - return; - } + } else if (!ctx->uvMeshChartsComputed) { + XA_PRINT_WARNING("PackCharts: ComputeCharts must be called first.\n"); + return; } if (packOptions.texelsPerUnit < 0.0f) { XA_PRINT_WARNING("PackCharts: PackOptions::texelsPerUnit is negative.\n"); @@ -9893,8 +9177,7 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) if (!ctx->uvMeshInstances.isEmpty()) { for (uint32_t i = 0; i < ctx->uvMeshInstances.size(); i++) packAtlas.addUvMeshCharts(ctx->uvMeshInstances[i]); - } - else + } else packAtlas.addCharts(ctx->taskScheduler, &ctx->paramAtlas); XA_PROFILE_END(packChartsAddCharts) XA_PROFILE_START(packCharts) @@ -9946,16 +9229,35 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) uint32_t chartIndex = 0; for (uint32_t i = 0; i < atlas->meshCount; i++) { Mesh &outputMesh = atlas->meshes[i]; + MeshPolygonMapping *meshPolygonMapping = ctx->meshPolygonMappings[i]; + // One polygon can have many triangles. Don't want to process the same polygon more than once when counting indices, building chart faces etc. + internal::BitArray polygonTouched; + if (meshPolygonMapping) { + polygonTouched.resize(meshPolygonMapping->faceVertexCount.size()); + polygonTouched.zeroOutMemory(); + } // Count and alloc arrays. - const internal::param::InvalidMeshGeometry &invalid = ctx->paramAtlas.invalidMeshGeometry(i); + const internal::InvalidMeshGeometry &invalid = ctx->paramAtlas.invalidMeshGeometry(i); outputMesh.vertexCount += invalid.vertices().length; outputMesh.indexCount += invalid.faces().length * 3; for (uint32_t cg = 0; cg < ctx->paramAtlas.chartGroupCount(i); cg++) { const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, cg); for (uint32_t c = 0; c < chartGroup->chartCount(); c++) { const internal::param::Chart *chart = chartGroup->chartAt(c); - outputMesh.vertexCount += chart->mesh()->vertexCount(); - outputMesh.indexCount += chart->mesh()->faceCount() * 3; + outputMesh.vertexCount += chart->originalVertexCount(); + const uint32_t faceCount = chart->unifiedMesh()->faceCount(); + if (meshPolygonMapping) { + // Map triangles back to polygons and count the polygon vertices. + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t polygon = meshPolygonMapping->triangleToPolygonMap[chart->mapFaceToSourceFace(f)]; + if (!polygonTouched.get(polygon)) { + polygonTouched.set(polygon); + outputMesh.indexCount += meshPolygonMapping->faceVertexCount[polygon]; + } + } + } else { + outputMesh.indexCount += faceCount * 3; + } outputMesh.chartCount++; } } @@ -9966,7 +9268,7 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) // Copy mesh data. uint32_t firstVertex = 0; { - const internal::param::InvalidMeshGeometry &mesh = ctx->paramAtlas.invalidMeshGeometry(i); + const internal::InvalidMeshGeometry &mesh = ctx->paramAtlas.invalidMeshGeometry(i); internal::ConstArrayView<uint32_t> faces = mesh.faces(); internal::ConstArrayView<uint32_t> indices = mesh.indices(); internal::ConstArrayView<uint32_t> vertices = mesh.vertices(); @@ -9991,23 +9293,50 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, cg); for (uint32_t c = 0; c < chartGroup->chartCount(); c++) { const internal::param::Chart *chart = chartGroup->chartAt(c); - const internal::Mesh *mesh = chart->mesh(); + const internal::Mesh *unifiedMesh = chart->unifiedMesh(); + const uint32_t faceCount = unifiedMesh->faceCount(); +#if XA_CHECK_PARAM_WINDING + uint32_t flippedCount = 0; + for (uint32_t f = 0; f < faceCount; f++) { + const float area = mesh->computeFaceParametricArea(f); + if (area < 0.0f) + flippedCount++; + } + const char *type = "LSCM"; + if (chart->type() == ChartType::Planar) + type = "planar"; + else if (chart->type() == ChartType::Ortho) + type = "ortho"; + else if (chart->type() == ChartType::Piecewise) + type = "piecewise"; + if (flippedCount > 0) { + if (flippedCount == faceCount) { + XA_PRINT_WARNING("chart %u (%s): all face flipped\n", chartIndex, type); + } else { + XA_PRINT_WARNING("chart %u (%s): %u / %u faces flipped\n", chartIndex, type, flippedCount, faceCount); + } + } +#endif // Vertices. - for (uint32_t v = 0; v < mesh->vertexCount(); v++) { + for (uint32_t v = 0; v < chart->originalVertexCount(); v++) { Vertex &vertex = outputMesh.vertexArray[firstVertex + v]; vertex.atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex; XA_DEBUG_ASSERT(vertex.atlasIndex >= 0); vertex.chartIndex = (int32_t)chartIndex; - const internal::Vector2 &uv = mesh->texcoord(v); + const internal::Vector2 &uv = unifiedMesh->texcoord(chart->originalVertexToUnifiedVertex(v)); vertex.uv[0] = internal::max(0.0f, uv.x); vertex.uv[1] = internal::max(0.0f, uv.y); vertex.xref = chart->mapChartVertexToSourceVertex(v); } // Indices. - for (uint32_t f = 0; f < mesh->faceCount(); f++) { + for (uint32_t f = 0; f < faceCount; f++) { const uint32_t indexOffset = chart->mapFaceToSourceFace(f) * 3; - for (uint32_t j = 0; j < 3; j++) - outputMesh.indexArray[indexOffset + j] = firstVertex + mesh->vertexAt(f * 3 + j); + for (uint32_t j = 0; j < 3; j++) { + uint32_t outIndex = indexOffset + j; + if (meshPolygonMapping) + outIndex = meshPolygonMapping->triangleToPolygonIndicesMap[outIndex]; + outputMesh.indexArray[outIndex] = firstVertex + chart->originalVertices()[f * 3 + j]; + } } // Charts. Chart *outputChart = &outputMesh.chartArray[meshChartIndex]; @@ -10015,14 +9344,38 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) XA_DEBUG_ASSERT(atlasIndex >= 0); outputChart->atlasIndex = (uint32_t)atlasIndex; outputChart->type = chart->isInvalid() ? ChartType::Invalid : chart->type(); - outputChart->faceCount = mesh->faceCount(); - outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount); - for (uint32_t f = 0; f < outputChart->faceCount; f++) - outputChart->faceArray[f] = chart->mapFaceToSourceFace(f); + if (meshPolygonMapping) { + // Count polygons. + polygonTouched.zeroOutMemory(); + outputChart->faceCount = 0; + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t polygon = meshPolygonMapping->triangleToPolygonMap[chart->mapFaceToSourceFace(f)]; + if (!polygonTouched.get(polygon)) { + polygonTouched.set(polygon); + outputChart->faceCount++; + } + } + // Write polygons. + outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount); + polygonTouched.zeroOutMemory(); + uint32_t of = 0; + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t polygon = meshPolygonMapping->triangleToPolygonMap[chart->mapFaceToSourceFace(f)]; + if (!polygonTouched.get(polygon)) { + polygonTouched.set(polygon); + outputChart->faceArray[of++] = polygon; + } + } + } else { + outputChart->faceCount = faceCount; + outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount); + for (uint32_t f = 0; f < outputChart->faceCount; f++) + outputChart->faceArray[f] = chart->mapFaceToSourceFace(f); + } outputChart->material = 0; meshChartIndex++; chartIndex++; - firstVertex += mesh->vertexCount(); + firstVertex += chart->originalVertexCount(); } } XA_DEBUG_ASSERT(outputMesh.vertexCount == firstVertex); @@ -10102,28 +9455,21 @@ void PackCharts(Atlas *atlas, PackOptions packOptions) XA_PRINT_MEM_USAGE } -void Generate(Atlas *atlas, ChartOptions chartOptions, ParameterizeOptions parameterizeOptions, PackOptions packOptions) -{ +void Generate(Atlas *atlas, ChartOptions chartOptions, PackOptions packOptions) { if (!atlas) { XA_PRINT_WARNING("Generate: atlas is null.\n"); return; } Context *ctx = (Context *)atlas; - if (!ctx->uvMeshInstances.isEmpty()) { - XA_PRINT_WARNING("Generate: This function should not be called with UV meshes.\n"); - return; - } - if (ctx->meshes.isEmpty()) { - XA_PRINT_WARNING("Generate: No meshes. Call AddMesh first.\n"); + if (ctx->meshes.isEmpty() && ctx->uvMeshInstances.isEmpty()) { + XA_PRINT_WARNING("Generate: No meshes. Call AddMesh or AddUvMesh first.\n"); return; } ComputeCharts(atlas, chartOptions); - ParameterizeCharts(atlas, parameterizeOptions); PackCharts(atlas, packOptions); } -void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc, void *progressUserData) -{ +void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc, void *progressUserData) { if (!atlas) { XA_PRINT_WARNING("SetProgressCallback: atlas is null.\n"); return; @@ -10133,37 +9479,33 @@ void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc, void *progress ctx->progressUserData = progressUserData; } -void SetAlloc(ReallocFunc reallocFunc, FreeFunc freeFunc) -{ +void SetAlloc(ReallocFunc reallocFunc, FreeFunc freeFunc) { internal::s_realloc = reallocFunc; internal::s_free = freeFunc; } -void SetPrint(PrintFunc print, bool verbose) -{ +void SetPrint(PrintFunc print, bool verbose) { internal::s_print = print; internal::s_printVerbose = verbose; } -const char *StringForEnum(AddMeshError::Enum error) -{ +const char *StringForEnum(AddMeshError error) { if (error == AddMeshError::Error) return "Unspecified error"; if (error == AddMeshError::IndexOutOfRange) return "Index out of range"; + if (error == AddMeshError::InvalidFaceVertexCount) + return "Invalid face vertex count"; if (error == AddMeshError::InvalidIndexCount) return "Invalid index count"; return "Success"; } -const char *StringForEnum(ProgressCategory::Enum category) -{ +const char *StringForEnum(ProgressCategory category) { if (category == ProgressCategory::AddMesh) return "Adding mesh(es)"; if (category == ProgressCategory::ComputeCharts) return "Computing charts"; - if (category == ProgressCategory::ParameterizeCharts) - return "Parameterizing charts"; if (category == ProgressCategory::PackCharts) return "Packing charts"; if (category == ProgressCategory::BuildOutputMeshes) @@ -10172,3 +9514,96 @@ const char *StringForEnum(ProgressCategory::Enum category) } } // namespace xatlas + +#if XATLAS_C_API +static_assert(sizeof(xatlas::Chart) == sizeof(xatlasChart), "xatlasChart size mismatch"); +static_assert(sizeof(xatlas::Vertex) == sizeof(xatlasVertex), "xatlasVertex size mismatch"); +static_assert(sizeof(xatlas::Mesh) == sizeof(xatlasMesh), "xatlasMesh size mismatch"); +static_assert(sizeof(xatlas::Atlas) == sizeof(xatlasAtlas), "xatlasAtlas size mismatch"); +static_assert(sizeof(xatlas::MeshDecl) == sizeof(xatlasMeshDecl), "xatlasMeshDecl size mismatch"); +static_assert(sizeof(xatlas::UvMeshDecl) == sizeof(xatlasUvMeshDecl), "xatlasUvMeshDecl size mismatch"); +static_assert(sizeof(xatlas::ChartOptions) == sizeof(xatlasChartOptions), "xatlasChartOptions size mismatch"); +static_assert(sizeof(xatlas::PackOptions) == sizeof(xatlasPackOptions), "xatlasPackOptions size mismatch"); + +#ifdef __cplusplus +extern "C" { +#endif + +xatlasAtlas *xatlasCreate() { + return (xatlasAtlas *)xatlas::Create(); +} + +void xatlasDestroy(xatlasAtlas *atlas) { + xatlas::Destroy((xatlas::Atlas *)atlas); +} + +xatlasAddMeshError xatlasAddMesh(xatlasAtlas *atlas, const xatlasMeshDecl *meshDecl, uint32_t meshCountHint) { + return (xatlasAddMeshError)xatlas::AddMesh((xatlas::Atlas *)atlas, *(const xatlas::MeshDecl *)meshDecl, meshCountHint); +} + +void xatlasAddMeshJoin(xatlasAtlas *atlas) { + xatlas::AddMeshJoin((xatlas::Atlas *)atlas); +} + +xatlasAddMeshError xatlasAddUvMesh(xatlasAtlas *atlas, const xatlasUvMeshDecl *decl) { + return (xatlasAddMeshError)xatlas::AddUvMesh((xatlas::Atlas *)atlas, *(const xatlas::UvMeshDecl *)decl); +} + +void xatlasComputeCharts(xatlasAtlas *atlas, const xatlasChartOptions *chartOptions) { + xatlas::ComputeCharts((xatlas::Atlas *)atlas, chartOptions ? *(xatlas::ChartOptions *)chartOptions : xatlas::ChartOptions()); +} + +void xatlasPackCharts(xatlasAtlas *atlas, const xatlasPackOptions *packOptions) { + xatlas::PackCharts((xatlas::Atlas *)atlas, packOptions ? *(xatlas::PackOptions *)packOptions : xatlas::PackOptions()); +} + +void xatlasGenerate(xatlasAtlas *atlas, const xatlasChartOptions *chartOptions, const xatlasPackOptions *packOptions) { + xatlas::Generate((xatlas::Atlas *)atlas, chartOptions ? *(xatlas::ChartOptions *)chartOptions : xatlas::ChartOptions(), packOptions ? *(xatlas::PackOptions *)packOptions : xatlas::PackOptions()); +} + +void xatlasSetProgressCallback(xatlasAtlas *atlas, xatlasProgressFunc progressFunc, void *progressUserData) { + xatlas::ProgressFunc pf; + *(void **)&pf = (void *)progressFunc; + xatlas::SetProgressCallback((xatlas::Atlas *)atlas, pf, progressUserData); +} + +void xatlasSetAlloc(xatlasReallocFunc reallocFunc, xatlasFreeFunc freeFunc) { + xatlas::SetAlloc((xatlas::ReallocFunc)reallocFunc, (xatlas::FreeFunc)freeFunc); +} + +void xatlasSetPrint(xatlasPrintFunc print, bool verbose) { + xatlas::SetPrint((xatlas::PrintFunc)print, verbose); +} + +const char *xatlasAddMeshErrorString(xatlasAddMeshError error) { + return xatlas::StringForEnum((xatlas::AddMeshError)error); +} + +const char *xatlasProgressCategoryString(xatlasProgressCategory category) { + return xatlas::StringForEnum((xatlas::ProgressCategory)category); +} + +void xatlasMeshDeclInit(xatlasMeshDecl *meshDecl) { + xatlas::MeshDecl init; + memcpy(meshDecl, &init, sizeof(init)); +} + +void xatlasUvMeshDeclInit(xatlasUvMeshDecl *uvMeshDecl) { + xatlas::UvMeshDecl init; + memcpy(uvMeshDecl, &init, sizeof(init)); +} + +void xatlasChartOptionsInit(xatlasChartOptions *chartOptions) { + xatlas::ChartOptions init; + memcpy(chartOptions, &init, sizeof(init)); +} + +void xatlasPackOptionsInit(xatlasPackOptions *packOptions) { + xatlas::PackOptions init; + memcpy(packOptions, &init, sizeof(init)); +} + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // XATLAS_C_API diff --git a/thirdparty/xatlas/xatlas.h b/thirdparty/xatlas/xatlas.h index cc47f4837e..fc40d9d49c 100644 --- a/thirdparty/xatlas/xatlas.h +++ b/thirdparty/xatlas/xatlas.h @@ -31,35 +31,30 @@ Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com> #pragma once #ifndef XATLAS_H #define XATLAS_H +#include <stddef.h> #include <stdint.h> namespace xatlas { -struct ChartType -{ - enum Enum - { - Planar, - Ortho, - LSCM, - Piecewise, - Invalid - }; +enum class ChartType { + Planar, + Ortho, + LSCM, + Piecewise, + Invalid }; // A group of connected faces, belonging to a single atlas. -struct Chart -{ +struct Chart { uint32_t *faceArray; uint32_t atlasIndex; // Sub-atlas index. uint32_t faceCount; - ChartType::Enum type; + ChartType type; uint32_t material; }; // Output vertex. -struct Vertex -{ +struct Vertex { int32_t atlasIndex; // Sub-atlas index. -1 if the vertex doesn't exist in any atlas. int32_t chartIndex; // -1 if the vertex doesn't exist in any chart. float uv[2]; // Not normalized - values are in Atlas width and height range. @@ -67,8 +62,7 @@ struct Vertex }; // Output mesh. -struct Mesh -{ +struct Mesh { Chart *chartArray; uint32_t *indexArray; Vertex *vertexArray; @@ -83,16 +77,15 @@ static const uint32_t kImageIsBilinearBit = 0x40000000; static const uint32_t kImageIsPaddingBit = 0x20000000; // Empty on creation. Populated after charts are packed. -struct Atlas -{ +struct Atlas { uint32_t *image; Mesh *meshes; // The output meshes, corresponding to each AddMesh call. + float *utilization; // Normalized atlas texel utilization array. E.g. a value of 0.8 means 20% empty space. atlasCount in length. uint32_t width; // Atlas width in texels. uint32_t height; // Atlas height in texels. uint32_t atlasCount; // Number of sub-atlases. Equal to 0 unless PackOptions resolution is changed from default (0). uint32_t chartCount; // Total number of charts in all meshes. uint32_t meshCount; // Number of output meshes. Equal to the number of times AddMesh was called. - float *utilization; // Normalized atlas texel utilization array. E.g. a value of 0.8 means 20% empty space. atlasCount in length. float texelsPerUnit; // Equal to PackOptions texelsPerUnit if texelsPerUnit > 0, otherwise an estimated value to match PackOptions resolution. }; @@ -101,73 +94,76 @@ Atlas *Create(); void Destroy(Atlas *atlas); -struct IndexFormat -{ - enum Enum - { - UInt16, - UInt32 - }; +enum class IndexFormat { + UInt16, + UInt32 }; // Input mesh declaration. -struct MeshDecl -{ +struct MeshDecl { const void *vertexPositionData = nullptr; const void *vertexNormalData = nullptr; // optional const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator. const void *indexData = nullptr; // optional - - // Optional. indexCount / 3 (triangle count) in length. + + // Optional. Must be faceCount in length. // Don't atlas faces set to true. Ignored faces still exist in the output meshes, Vertex uv is set to (0, 0) and Vertex atlasIndex to -1. const bool *faceIgnoreData = nullptr; + // Optional. Must be faceCount in length. + // Only faces with the same material will be assigned to the same chart. + const uint32_t *faceMaterialData = nullptr; + + // Optional. Must be faceCount in length. + // Polygon / n-gon support. Faces are assumed to be triangles if this is null. + const uint8_t *faceVertexCount = nullptr; + uint32_t vertexCount = 0; uint32_t vertexPositionStride = 0; uint32_t vertexNormalStride = 0; // optional uint32_t vertexUvStride = 0; // optional uint32_t indexCount = 0; int32_t indexOffset = 0; // optional. Add this offset to all indices. - IndexFormat::Enum indexFormat = IndexFormat::UInt16; + uint32_t faceCount = 0; // Optional if faceVertexCount is null. Otherwise assumed to be indexCount / 3. + IndexFormat indexFormat = IndexFormat::UInt16; // Vertex positions within epsilon distance of each other are considered colocal. float epsilon = 1.192092896e-07F; }; -struct AddMeshError -{ - enum Enum - { - Success, // No error. - Error, // Unspecified error. - IndexOutOfRange, // An index is >= MeshDecl vertexCount. - InvalidIndexCount // Not evenly divisible by 3 - expecting triangles. - }; +enum class AddMeshError { + Success, // No error. + Error, // Unspecified error. + IndexOutOfRange, // An index is >= MeshDecl vertexCount. + InvalidFaceVertexCount, // Must be >= 3. + InvalidIndexCount // Not evenly divisible by 3 - expecting triangles. }; // Add a mesh to the atlas. MeshDecl data is copied, so it can be freed after AddMesh returns. -AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint = 0); +AddMeshError AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint = 0); // Wait for AddMesh async processing to finish. ComputeCharts / Generate call this internally. void AddMeshJoin(Atlas *atlas); -struct UvMeshDecl -{ +struct UvMeshDecl { const void *vertexUvData = nullptr; const void *indexData = nullptr; // optional - const uint32_t *faceMaterialData = nullptr; // Optional. Faces with different materials won't be assigned to the same chart. Must be indexCount / 3 in length. + const uint32_t *faceMaterialData = nullptr; // Optional. Overlapping UVs should be assigned a different material. Must be indexCount / 3 in length. uint32_t vertexCount = 0; uint32_t vertexStride = 0; uint32_t indexCount = 0; int32_t indexOffset = 0; // optional. Add this offset to all indices. - IndexFormat::Enum indexFormat = IndexFormat::UInt16; - bool rotateCharts = true; + IndexFormat indexFormat = IndexFormat::UInt16; }; -AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl); +AddMeshError AddUvMesh(Atlas *atlas, const UvMeshDecl &decl); + +// Custom parameterization function. texcoords initial values are an orthogonal parameterization. +typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount); + +struct ChartOptions { + ParameterizeFunc paramFunc = nullptr; -struct ChartOptions -{ float maxChartArea = 0.0f; // Don't grow charts to be larger than this. 0 means no limit. float maxBoundaryLength = 0.0f; // Don't grow charts to have a longer boundary than this. 0 means no limit. @@ -180,26 +176,31 @@ struct ChartOptions float maxCost = 2.0f; // If total of all metrics * weights > maxCost, don't grow chart. Lower values result in more charts. uint32_t maxIterations = 1; // Number of iterations of the chart growing and seeding phases. Higher values result in better charts. + + bool useInputMeshUvs = false; // Use MeshDecl::vertexUvData for charts. + bool fixWinding = false; // Enforce consistent texture coordinate winding. }; // Call after all AddMesh calls. Can be called multiple times to recompute charts with different options. void ComputeCharts(Atlas *atlas, ChartOptions options = ChartOptions()); -// Custom parameterization function. texcoords initial values are an orthogonal parameterization. -typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount); +struct PackOptions { + // Charts larger than this will be scaled down. 0 means no limit. + uint32_t maxChartSize = 0; -struct ParameterizeOptions -{ - ParameterizeFunc func = nullptr; - bool closeHoles = true; // If the custom parameterization function works with multiple boundaries, this can be set to false to improve performance. - bool fixTJunctions = true; // If meshes don't have T-junctions, this can be set to false to improve performance. -}; + // Number of pixels to pad charts with. + uint32_t padding = 0; + + // Unit to texel scale. e.g. a 1x1 quad with texelsPerUnit of 32 will take up approximately 32x32 texels in the atlas. + // If 0, an estimated value will be calculated to approximately match the given resolution. + // If resolution is also 0, the estimated value will approximately match a 1024x1024 atlas. + float texelsPerUnit = 0.0f; -// Call after ComputeCharts. Can be called multiple times to re-parameterize charts with a different ParameterizeFunc. -void ParameterizeCharts(Atlas *atlas, ParameterizeOptions options = ParameterizeOptions()); + // If 0, generate a single atlas with texelsPerUnit determining the final resolution. + // If not 0, and texelsPerUnit is not 0, generate one or more atlases with that exact resolution. + // If not 0, and texelsPerUnit is 0, texelsPerUnit is estimated to approximately match the resolution. + uint32_t resolution = 0; -struct PackOptions -{ // Leave space around charts for texels that would be sampled by bilinear filtering. bool bilinear = true; @@ -212,44 +213,29 @@ struct PackOptions // Create Atlas::image bool createImage = false; - // Charts larger than this will be scaled down. 0 means no limit. - uint32_t maxChartSize = 0; - - // Number of pixels to pad charts with. - uint32_t padding = 0; + // Rotate charts to the axis of their convex hull. + bool rotateChartsToAxis = true; - // Unit to texel scale. e.g. a 1x1 quad with texelsPerUnit of 32 will take up approximately 32x32 texels in the atlas. - // If 0, an estimated value will be calculated to approximately match the given resolution. - // If resolution is also 0, the estimated value will approximately match a 1024x1024 atlas. - float texelsPerUnit = 0.0f; - - // If 0, generate a single atlas with texelsPerUnit determining the final resolution. - // If not 0, and texelsPerUnit is not 0, generate one or more atlases with that exact resolution. - // If not 0, and texelsPerUnit is 0, texelsPerUnit is estimated to approximately match the resolution. - uint32_t resolution = 0; + // Rotate charts to improve packing. + bool rotateCharts = true; }; -// Call after ParameterizeCharts. Can be called multiple times to re-pack charts with different options. +// Call after ComputeCharts. Can be called multiple times to re-pack charts with different options. void PackCharts(Atlas *atlas, PackOptions packOptions = PackOptions()); -// Equivalent to calling ComputeCharts, ParameterizeCharts and PackCharts in sequence. Can be called multiple times to regenerate with different options. -void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), ParameterizeOptions parameterizeOptions = ParameterizeOptions(), PackOptions packOptions = PackOptions()); +// Equivalent to calling ComputeCharts and PackCharts in sequence. Can be called multiple times to regenerate with different options. +void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), PackOptions packOptions = PackOptions()); // Progress tracking. -struct ProgressCategory -{ - enum Enum - { - AddMesh, - ComputeCharts, - ParameterizeCharts, - PackCharts, - BuildOutputMeshes - }; +enum class ProgressCategory { + AddMesh, + ComputeCharts, + PackCharts, + BuildOutputMeshes }; // May be called from any thread. Return false to cancel. -typedef bool (*ProgressFunc)(ProgressCategory::Enum category, int progress, void *userData); +typedef bool (*ProgressFunc)(ProgressCategory category, int progress, void *userData); void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc = nullptr, void *progressUserData = nullptr); @@ -263,8 +249,8 @@ typedef int (*PrintFunc)(const char *, ...); void SetPrint(PrintFunc print, bool verbose); // Helper functions for error messages. -const char *StringForEnum(AddMeshError::Enum error); -const char *StringForEnum(ProgressCategory::Enum category); +const char *StringForEnum(AddMeshError error); +const char *StringForEnum(ProgressCategory category); } // namespace xatlas |